Add helpers for working with words
This commit is contained in:
parent
c39b4a4931
commit
1eb6d179be
2 changed files with 99 additions and 5 deletions
60
src/words.test.ts
Normal file
60
src/words.test.ts
Normal file
|
@ -0,0 +1,60 @@
|
|||
import { AsHtml, AsText, Concat } from "./words";
|
||||
|
||||
describe("Text Words", () => {
|
||||
test.each([
|
||||
[{ enchanted: "apple" }, "apple"],
|
||||
[{ enchanted: "<pie>" }, "<pie>"],
|
||||
[{ text: "banana" }, "banana"],
|
||||
[{ text: "<b>kiwi" }, "<b>kiwi"],
|
||||
[{ html: "<b>cherry</b>" }, "<b>cherry</b>"],
|
||||
])("AsText(%s)", (word, expected) => expect(AsText(word)).toEqual(expected));
|
||||
|
||||
test.each([
|
||||
[{ enchanted: "apple" }, "apple"],
|
||||
[{ enchanted: "<pie>" }, "<pie>"],
|
||||
[{ text: "banana" }, "banana"],
|
||||
[{ text: "<b>kiwi" }, "<b>kiwi"],
|
||||
[{ html: "<b>cherry</b>" }, "<b>cherry</b>"],
|
||||
])("AsHtml(%s)", (word, expected) => expect(AsHtml(word)).toEqual(expected));
|
||||
|
||||
test.each([
|
||||
[null, { enchanted: "1" }, { text: "1" }],
|
||||
[null, { enchanted: ">1" }, { text: ">1" }],
|
||||
[null, { text: "2" }, { text: "2" }],
|
||||
[null, { text: "<b>3</b>" }, { text: "<b>3</b>" }],
|
||||
[null, { html: "2" }, { html: "2" }],
|
||||
[null, { html: "<b>3</b>" }, { html: "<b>3</b>" }],
|
||||
[{ enchanted: "&pple" }, { enchanted: "1" }, { text: "&pple1" }],
|
||||
[{ enchanted: "&pple" }, { enchanted: ">1" }, { text: "&pple>1" }],
|
||||
[{ enchanted: "&pple" }, { text: "2" }, { text: "&pple2" }],
|
||||
[{ enchanted: "&pple" }, { text: "<b>3</b>" }, { text: "&pple<b>3</b>" }],
|
||||
[{ enchanted: "&pple" }, { html: "2" }, { html: "&pple2" }],
|
||||
[
|
||||
{ enchanted: "&pple" },
|
||||
{ html: "<b>3</b>" },
|
||||
{ html: "&pple<b>3</b>" },
|
||||
],
|
||||
[{ text: "<b>anana" }, { enchanted: "1" }, { text: "<b>anana1" }],
|
||||
[{ text: "<b>anana" }, { enchanted: ">1" }, { text: "<b>anana>1" }],
|
||||
[{ text: "<b>anana" }, { text: "2" }, { text: "<b>anana2" }],
|
||||
[{ text: "<b>anana" }, { text: "<b>3</b>" }, { text: "<b>anana<b>3</b>" }],
|
||||
[{ text: "<b>anana" }, { html: "2" }, { html: "<b>anana2" }],
|
||||
[
|
||||
{ text: "<b>anana" },
|
||||
{ html: "<b>3</b>" },
|
||||
{ html: "<b>anana<b>3</b>" },
|
||||
],
|
||||
[{ html: "<img />" }, { enchanted: "1" }, { html: "<img />1" }],
|
||||
[{ html: "<img />" }, { enchanted: ">1" }, { html: "<img />>1" }],
|
||||
[{ html: "<img />" }, { text: "2" }, { html: "<img />2" }],
|
||||
[
|
||||
{ html: "<img />" },
|
||||
{ text: "<b>3</b>" },
|
||||
{ html: "<img /><b>3</b>" },
|
||||
],
|
||||
[{ html: "<img />" }, { html: "2" }, { html: "<img />2" }],
|
||||
[{ html: "<img />" }, { html: "<b>3</b>" }, { html: "<img /><b>3</b>" }],
|
||||
])("Concat(%s, %s)", (left, right, expected) =>
|
||||
expect(Concat(left, right)).toEqual(expected)
|
||||
);
|
||||
});
|
44
src/words.ts
44
src/words.ts
|
@ -1,3 +1,5 @@
|
|||
import { escapeHtml } from "./helpers";
|
||||
|
||||
/**
|
||||
* A word whose value is text with provenance- this literal value appeared in the source
|
||||
* code, and was not the result of any backslash, variable, or command substitutions.
|
||||
|
@ -29,7 +31,7 @@ export type HtmlWord = {
|
|||
html: string;
|
||||
};
|
||||
|
||||
export type TextPiece = TextWord;
|
||||
export type TextPiece = EnchantedWord | TextWord | HtmlWord;
|
||||
export type VariablePiece = { variable: string };
|
||||
export type ScriptPiece = { script: Script };
|
||||
export type InterpolatedPiece = TextPiece | VariablePiece | ScriptPiece;
|
||||
|
@ -42,18 +44,50 @@ export type InterpolatedWord = {
|
|||
pieces: InterpolatedPiece[];
|
||||
};
|
||||
|
||||
export function AsText(word: TextPiece): string {
|
||||
if ("enchanted" in word) {
|
||||
return word.enchanted;
|
||||
} else if ("text" in word) {
|
||||
return word.text;
|
||||
} else if ("html" in word) {
|
||||
return word.html;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
export function AsHtml(word: TextPiece): string {
|
||||
if ("enchanted" in word) {
|
||||
return escapeHtml(word.enchanted);
|
||||
} else if ("text" in word) {
|
||||
return escapeHtml(word.text);
|
||||
} else if ("html" in word) {
|
||||
return word.html;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
// safely concatenate text pieces, converting as needed
|
||||
export function Concat(left: TextPiece, right: TextPiece) {
|
||||
return { text: left.text + right.text };
|
||||
export function Concat(left: TextPiece | null, right: TextPiece) {
|
||||
if (left === null) {
|
||||
return "enchanted" in right ? { text: right.enchanted } : right;
|
||||
}
|
||||
if ("html" in left || "html" in right) {
|
||||
return { html: AsHtml(left) + AsHtml(right) };
|
||||
} else {
|
||||
return { text: AsText(left) + AsText(right) };
|
||||
}
|
||||
}
|
||||
|
||||
function IsTextPiece(piece: InterpolatedPiece | undefined): piece is TextPiece {
|
||||
return piece ? "text" in piece : false;
|
||||
return piece
|
||||
? "text" in piece || "enchanted" in piece || "html" in piece
|
||||
: false;
|
||||
}
|
||||
|
||||
export function SimplifyWord(
|
||||
pieces: InterpolatedPiece[]
|
||||
): InterpolatedWord | TextWord {
|
||||
): InterpolatedWord | EnchantedWord | TextWord | HtmlWord {
|
||||
const consolidated: InterpolatedPiece[] = [];
|
||||
for (const piece of pieces) {
|
||||
const top = consolidated[consolidated.length - 1];
|
||||
|
|
Loading…
Reference in a new issue