Capture position information for bare & quoted words that don't contain dynamic interpolations

This commit is contained in:
Tangent Wantwight 2023-11-18 20:48:57 -05:00
parent da8429f6df
commit f5b79af2be
4 changed files with 32 additions and 26 deletions

View File

@ -10,6 +10,7 @@ exports[`Parsing Notcl Misc Big mess of markup 1`] = `
"pos": 5,
},
{
"pos": 8,
"text": "Hello, World!",
},
],
@ -63,6 +64,7 @@ exports[`Parsing Notcl Misc Big mess of markup 1`] = `
"pos": 219,
},
{
"pos": 224,
"text": "Beware!",
},
],
@ -72,6 +74,7 @@ exports[`Parsing Notcl Misc Big mess of markup 1`] = `
"pos": 238,
},
{
"pos": 243,
"text": "All text should be quoted, it's clearer that way. & blockquotes already should contain paragraphs. (maybe normalize nested paragraphs)",
},
],

View File

@ -52,12 +52,20 @@ b`)
expect(
parse(String.raw`a\\
b`)
).toEqual([true, [[{ text: "a\\" }], [{ bare: "b", pos: 4 }]]]));
).toEqual([true, [[{ text: "a\\", pos: 0 }], [{ bare: "b", pos: 4 }]]]));
it("does not split commands on folded newlines with escaped backslashes", () =>
expect(
parse(String.raw`a\\\
b`)
).toEqual([true, [[{ text: "a\\" }, { bare: "b", pos: 4 }]]]));
).toEqual([
true,
[
[
{ text: "a\\", pos: 0 },
{ bare: "b", pos: 4 },
],
],
]));
it("accepts semicolons as command separators", () =>
expect(parse("a;b")).toEqual([
@ -130,13 +138,13 @@ b`)
]));
it("accepts empty quotes", () =>
expect(parse('""')).toEqual([true, [[{ text: "" }]]]));
expect(parse('""')).toEqual([true, [[{ text: "", pos: 0 }]]]));
it("accepts quoted words", () =>
expect(parse('"a"')).toEqual([true, [[{ text: "a" }]]]));
expect(parse('"a"')).toEqual([true, [[{ text: "a", pos: 0 }]]]));
it("accepts quoted words with spaces", () =>
expect(parse('"a b"')).toEqual([true, [[{ text: "a b" }]]]));
expect(parse('"a b"')).toEqual([true, [[{ text: "a b", pos: 0 }]]]));
it("allows escaped quotes inside a quote", () =>
expect(parse('"a\\"b"')).toEqual([true, [[{ text: 'a"b' }]]]));
expect(parse('"a\\"b"')).toEqual([true, [[{ text: 'a"b', pos: 0 }]]]));
it("must close quoted words", () =>
expect(parse('"a b')).toMatchObject([false, {}]));
@ -145,18 +153,18 @@ b`)
expect(parse('""a')).toMatchObject([false, {}]));
it("accepts escaped spaces", () =>
expect(parse("a\\ b")).toEqual([true, [[{ text: "a b" }]]]));
expect(parse("a\\ b")).toEqual([true, [[{ text: "a b", pos: 0 }]]]));
it("treats a non-leading quote as a plain character", () =>
expect(parse('a"')).toEqual([true, [[{ bare: 'a"', pos: 0 }]]]));
it("treats a non-leading brace as a plain character", () =>
expect(parse("a{")).toEqual([true, [[{ bare: "a{", pos: 0 }]]]));
it("treats an escaped quote as a plain character", () =>
expect(parse('\\"')).toEqual([true, [[{ text: '"' }]]]));
expect(parse('\\"')).toEqual([true, [[{ text: '"', pos: 0 }]]]));
it("treats an escaped brace as a plain character", () =>
expect(parse("\\{")).toEqual([true, [[{ text: "{" }]]]));
expect(parse("\\{")).toEqual([true, [[{ text: "{", pos: 0 }]]]));
it("treats a quoted brace as a plain character", () =>
expect(parse('"{"')).toEqual([true, [[{ text: "{" }]]]));
expect(parse('"{"')).toEqual([true, [[{ text: "{", pos: 0 }]]]));
});
describe("backslash interpolation", () => {});
@ -239,10 +247,7 @@ b`)
[
[
{
pieces: [
{ script: [[{ bare: "a", pos: 1 }]] },
{ bare: "b", pos: 3 },
],
pieces: [{ script: [[{ bare: "a", pos: 1 }]] }, { bare: "b" }],
},
],
],
@ -254,9 +259,9 @@ b`)
[
{
pieces: [
{ bare: "a", pos: 0 },
{ bare: "a" },
{ script: [[{ bare: "b", pos: 2 }]] },
{ bare: "c", pos: 4 },
{ bare: "c" },
],
},
],
@ -268,10 +273,7 @@ b`)
[
[
{
pieces: [
{ bare: "a", pos: 0 },
{ script: [[{ bare: "b", pos: 2 }]] },
],
pieces: [{ bare: "a" }, { script: [[{ bare: "b", pos: 2 }]] }],
},
],
],

View File

@ -36,10 +36,10 @@ function bareWordTmpl(charRegex: RegExp) {
Bracket,
Regex(charRegex)
.expects("CHAR")
.map(([text], index) => ({ bare: text, pos: index }))
.map(([text]) => ({ bare: text }))
)
)
).map(([, pieces]) => SimplifyWord(pieces));
).map(([, pieces], pos) => SimplifyWord(pieces, pos));
}
const QuotedWord = Sequence(
@ -55,7 +55,7 @@ const QuotedWord = Sequence(
)
),
Regex(/"/y).expects('"')
).map(([, pieces]) => SimplifyWord(pieces));
).map(([, pieces], pos) => SimplifyWord(pieces, pos));
const Brace: Pattern<string> = Sequence(
Regex(/\{/y).expects("{"),

View File

@ -101,7 +101,8 @@ function IsTextPiece(piece: InterpolatedPiece | undefined): piece is TextPiece {
}
export function SimplifyWord(
pieces: InterpolatedPiece[]
pieces: InterpolatedPiece[],
sourcePosition?: SourcePos
): InterpolatedWord | BareWord | TextWord | HtmlWord {
const consolidated: InterpolatedPiece[] = [];
for (const piece of pieces) {
@ -114,9 +115,9 @@ export function SimplifyWord(
}
if (consolidated.length == 0) {
return { text: "" };
return { text: "", pos: sourcePosition };
} else if (consolidated.length == 1 && IsTextPiece(consolidated[0])) {
return consolidated[0];
return { ...consolidated[0], pos: sourcePosition };
} else {
return { pieces: consolidated };
}