Last active
February 6, 2024 13:58
-
-
Save MarkTiedemann/04afba0866e182aa7c4ba3c6dbc789ed to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const rawString = Symbol(); | |
export interface RawString { | |
[rawString]: string; | |
}; | |
export function raw(str: string): Readonly<RawString> { | |
const obj: RawString = Object.create(null); | |
obj[rawString] = str; | |
return Object.freeze(obj); | |
} | |
export type Argument = | |
| number | |
| string | |
| string[] | |
| (() => string) | |
| (() => string)[] | |
| Readonly<RawString>; | |
export function html({ raw }: TemplateStringsArray, ...args: Argument[]) { | |
return () => { | |
const len = raw.length - 1; | |
let html = ""; | |
for (let i = 0; i < len; i++) { | |
html += raw[i] + stringify(args[i]); | |
} | |
return html + raw[len]; | |
}; | |
} | |
export function stringify(arg: Argument) { | |
switch (typeof arg) { | |
case "number": return arg.toString(); | |
case "string": return escape(arg); | |
case "function": return arg(); | |
default: { | |
if (rawString in arg) { | |
return arg[rawString]; | |
} else { | |
let html = ""; | |
for (const x of arg) { | |
html += stringify(x); | |
} | |
return html; | |
} | |
} | |
} | |
} | |
export function escape(str: string) { | |
return str.replace(/[&<>"']/g, c => `&#${c.charCodeAt(0)};`); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Superseded by https://github.com/MarkTiedemann/html