Skip to content

Instantly share code, notes, and snippets.

@GauBen
Last active April 17, 2021 16:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GauBen/2def29b79e369ba74765de31cc40402d to your computer and use it in GitHub Desktop.
Save GauBen/2def29b79e369ba74765de31cc40402d to your computer and use it in GitHub Desktop.
function loop<T>(arr: T[], fn: (a: T, i: Number, arr: T[]) => string) {
return arr.reduce((a, b, i, arr) => a + fn(b, i, arr), '');
}
function escapeHtml(str: string)
{
const map =
{
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#039;'
};
// @ts-ignore
return str.replace(/[&<>"']/g, m => map[m]);
}
class UnsafeString extends String {
toString() {
return escapeHtml(this.safe())
}
safe() {
return String.prototype.toString.call(this)
}
}
function render<T>(data: T, tpl: (data: T) => string) {
const wrap: <U extends Object>(s: U) => U = s => {
if (typeof s === 'string') return new UnsafeString(s)
if (typeof s !== 'object') return s
const wrapped: any = s.constructor()
for (const i in s) {
wrapped[i] = wrap(s[i])
}
return wrapped
}
return tpl(wrap(data))
}
const content = render({
people: [
{ name: "<b>Person 1</b>", age: 21 },
{ name: "Person 2", age: 42 }
]
}, d => `Here are some people:
${loop(d.people, person => `- ${person.name} (${person.age}yo)\n`)}`);
console.log(content);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment