From 6ca93d661566e3a8f60315d8312d8c324dc7c455 Mon Sep 17 00:00:00 2001 From: Tangent Wantwight Date: Sat, 18 Nov 2023 16:59:26 -0500 Subject: [PATCH] Allow words to carry source position information, stripped on manipulation --- src/words.test.ts | 11 +++++++++++ src/words.ts | 15 +++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/words.test.ts b/src/words.test.ts index 13488ff..729e039 100644 --- a/src/words.test.ts +++ b/src/words.test.ts @@ -53,4 +53,15 @@ describe("Text Words", () => { ])("Concat(%s, %s)", (left, right, expected) => expect(Concat(left, right)).toEqual(expected) ); + + test.each([ + [null, { bare: "1", pos: 13 }, { text: "1", pos: 13 }], + [null, { text: "2", pos: 13 }, { text: "2", pos: 13 }], + [null, { html: "3", pos: 13 }, { html: "3", pos: 13 }], + [{ bare: "4", pos: 13 }, { bare: "5", pos: 15 }, { text: "45" }], + [{ html: "6", pos: 13 }, { html: "7", pos: 15 }, { html: "67" }], + ])( + "Concat(%s, %s) strips source position when combining words", + (left, right, expected) => expect(Concat(left, right)).toEqual(expected) + ); }); diff --git a/src/words.ts b/src/words.ts index c46e79f..c4884c8 100644 --- a/src/words.ts +++ b/src/words.ts @@ -1,4 +1,6 @@ -import { escapeHtml } from "./helpers"; +import { escapeHtml } from './helpers'; + +export type SourcePos = number; /** * A word whose value is text with provenance- this literal value appeared in the source code, @@ -15,13 +17,15 @@ import { escapeHtml } from "./helpers"; */ export type BareWord = { bare: string; + pos?: SourcePos; }; /** - * A word whose value is plain text, with no special provenance. + * A word whose value is plain text */ export type TextWord = { text: string; + pos?: SourcePos; }; /** @@ -78,9 +82,12 @@ export function AsHtml(word: TextPiece | ErrorResult): string { } // safely concatenate text pieces, converting as needed -export function Concat(left: TextPiece | null, right: TextPiece) { +export function Concat( + left: TextPiece | null, + right: TextPiece +): TextWord | HtmlWord { if (left === null) { - return "bare" in right ? { text: right.bare } : right; + return "bare" in right ? { text: right.bare, pos: right.pos } : right; } if ("html" in left || "html" in right) { return { html: AsHtml(left) + AsHtml(right) };