Support negative comment offsets
This commit is contained in:
parent
ea00d550fe
commit
90e1664ed6
|
|
@ -555,6 +555,94 @@ Rest: 5:00 50%
|
|||
`);
|
||||
});
|
||||
|
||||
it("parses intervals with negative comment offsets", () => {
|
||||
expect(
|
||||
parse(`
|
||||
Name: My Workout
|
||||
Interval: 10:00 90%
|
||||
@ 0:10 Find your rythm.
|
||||
@ -0:10 Final push. YOU GOT IT!
|
||||
|
||||
Rest: 5:00 50%
|
||||
@ -4:30 Great effort!
|
||||
@ -2:00 Cool down well after all of this.
|
||||
`),
|
||||
).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"author": "",
|
||||
"description": "",
|
||||
"intervals": Array [
|
||||
Object {
|
||||
"cadence": undefined,
|
||||
"comments": Array [
|
||||
Object {
|
||||
"loc": Object {
|
||||
"col": 4,
|
||||
"row": 3,
|
||||
},
|
||||
"offset": Duration {
|
||||
"seconds": 10,
|
||||
},
|
||||
"text": "Find your rythm.",
|
||||
},
|
||||
Object {
|
||||
"loc": Object {
|
||||
"col": 4,
|
||||
"row": 4,
|
||||
},
|
||||
"offset": Duration {
|
||||
"seconds": 590,
|
||||
},
|
||||
"text": "Final push. YOU GOT IT!",
|
||||
},
|
||||
],
|
||||
"duration": Duration {
|
||||
"seconds": 600,
|
||||
},
|
||||
"intensity": ConstantIntensity {
|
||||
"_value": 0.9,
|
||||
},
|
||||
"type": "Interval",
|
||||
},
|
||||
Object {
|
||||
"cadence": undefined,
|
||||
"comments": Array [
|
||||
Object {
|
||||
"loc": Object {
|
||||
"col": 4,
|
||||
"row": 7,
|
||||
},
|
||||
"offset": Duration {
|
||||
"seconds": 30,
|
||||
},
|
||||
"text": "Great effort!",
|
||||
},
|
||||
Object {
|
||||
"loc": Object {
|
||||
"col": 4,
|
||||
"row": 8,
|
||||
},
|
||||
"offset": Duration {
|
||||
"seconds": 180,
|
||||
},
|
||||
"text": "Cool down well after all of this.",
|
||||
},
|
||||
],
|
||||
"duration": Duration {
|
||||
"seconds": 300,
|
||||
},
|
||||
"intensity": ConstantIntensity {
|
||||
"_value": 0.5,
|
||||
},
|
||||
"type": "Rest",
|
||||
},
|
||||
],
|
||||
"name": "My Workout",
|
||||
"tags": Array [],
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
it("throws error when comment offset is outside of interval length", () => {
|
||||
expect(() =>
|
||||
parse(`
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ const parseHeader = (tokens: Token[]): [Header, Token[]] => {
|
|||
return [header, tokens];
|
||||
};
|
||||
|
||||
const parseIntervalComments = (tokens: Token[]): [Comment[], Token[]] => {
|
||||
const parseIntervalComments = (tokens: Token[], intervalDuration: Duration): [Comment[], Token[]] => {
|
||||
const comments: Comment[] = [];
|
||||
while (tokens[0]) {
|
||||
const [start, offset, text, ...rest] = tokens;
|
||||
|
|
@ -72,7 +72,8 @@ const parseIntervalComments = (tokens: Token[]): [Comment[], Token[]] => {
|
|||
throw new ParseError(`Expected [comment text] instead got ${tokenToString(text)}`, text?.loc || offset.loc);
|
||||
}
|
||||
comments.push({
|
||||
offset: new Duration(offset.value),
|
||||
// when offset is negative, recalculate it based on interval length
|
||||
offset: new Duration(offset.value >= 0 ? offset.value : intervalDuration.seconds + offset.value),
|
||||
text: text.value,
|
||||
loc: offset.loc,
|
||||
});
|
||||
|
|
@ -115,7 +116,7 @@ const parseIntervalParams = (type: IntervalType, tokens: Token[], loc: SourceLoc
|
|||
intensity = new FreeIntensity();
|
||||
}
|
||||
|
||||
const [comments, rest] = parseIntervalComments(tokens);
|
||||
const [comments, rest] = parseIntervalComments(tokens, duration);
|
||||
|
||||
return [{ type, duration, intensity, cadence, comments }, rest];
|
||||
};
|
||||
|
|
|
|||
|
|
@ -89,16 +89,17 @@ const tokenizeParams = (text: string, loc: SourceLocation): Token[] => {
|
|||
};
|
||||
|
||||
const tokenizeComment = (line: string, row: number): Token[] | undefined => {
|
||||
const [, commentHead, offset, commentText] = line.match(/^(\s*@\s*)([0-9:]+)(.*?)$/) || [];
|
||||
const [, commentHead, minus, offset, commentText] = line.match(/^(\s*@\s*)(-?)([0-9:]+)(.*?)$/) || [];
|
||||
if (!commentHead) {
|
||||
return undefined;
|
||||
}
|
||||
const sign = minus ? -1 : 1;
|
||||
if (!DURATION_REGEX.test(offset)) {
|
||||
throw new ParseError("Invalid comment offset", { row, col: commentHead.length });
|
||||
}
|
||||
return [
|
||||
{ type: "comment-start", loc: { row, col: line.indexOf("@") } },
|
||||
{ type: "duration", value: toSeconds(offset), loc: { row, col: commentHead.length } },
|
||||
{ type: "duration", value: sign * toSeconds(offset), loc: { row, col: commentHead.length } },
|
||||
{ type: "text", value: commentText.trim(), loc: { row, col: commentHead.length + offset.length } },
|
||||
];
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue