@travetto/email-inky
Version:
Email Inky templating module
65 lines (56 loc) • 3.05 kB
text/typescript
import { JSXElement } from '@travetto/email-inky/jsx-runtime';
import { castTo } from '@travetto/runtime';
import { RenderProvider, RenderState } from '../types';
import { RenderContext } from './context';
const visit = ({ recurse }: RenderState<JSXElement, RenderContext>): Promise<string> => recurse();
const ignore = async ({ recurse: _ }: RenderState<JSXElement, RenderContext>): Promise<string> => '';
export const Markdown: RenderProvider<RenderContext> = {
finalize: (text) => {
text = text
.replace(/(\[[^\]]+\]\([^)]+\))([A-Za-z0-9$]+)/g, (_, link, v) => v === 's' ? _ : `${link} ${v}`)
.replace(/(\S)\n(#)/g, (_, l, r) => `${l}\n\n${r}`);
return text;
},
For: async ({ recurse, props }) => `{{#${props.attr}}}${await recurse()}{{/${props.attr}}}`,
If: async ({ recurse, props }) => `{{#${props.attr}}}${await recurse()}{{/${props.attr}}}`,
Unless: async ({ recurse, props }) => `{{^${props.attr}}}${await recurse()}{{/${props.attr}}}`,
Value: async ({ props }) => props.raw ? `{{{${props.attr}}}}` : `{{${props.attr}}}`,
strong: async ({ recurse }) => `**${await recurse()}**`,
hr: async () => '\n------------------\n',
HLine: async () => '\n------------------\n',
br: async () => '\n\n',
p: async ({ recurse }) => `${await recurse()}\n\n`,
em: async ({ recurse }) => `*${await recurse()}*`,
ul: async ({ recurse }) => `\n${await recurse()}`,
ol: async ({ recurse }) => `\n${await recurse()}`,
li: async ({ recurse, stack }) => {
const parent = stack.reverse().find(x => x.type === 'ol' || x.type === 'ul');
const depth = stack.filter(x => x.type === 'ol' || x.type === 'ul').length;
return `${' '.repeat(depth)}${(parent && parent.type === 'ol') ? '1.' : '* '} ${await recurse()}\n`;
},
th: async ({ recurse }) => `|${await recurse()}`,
td: async ({ recurse }) => `|${await recurse()}`,
tr: async ({ recurse }) => `${await recurse()}|\n`,
thead: async ({ recurse }) => {
const row = await recurse();
return `${row}${row.replace(/[^|\n]/g, '-')}`;
},
h1: async ({ recurse }) => `\n# ${await recurse()}\n\n`,
h2: async ({ recurse }) => `\n## ${await recurse()}\n\n`,
h3: async ({ recurse }) => `\n### ${await recurse()}\n\n`,
h4: async ({ recurse }) => `\n#### ${await recurse()}\n\n`,
a: async ({ recurse, props }) => `\n[${await recurse()}](${(castTo<{ href: string }>(props)).href})\n`,
Button: async ({ recurse, props }) => `\n[${await recurse()}](${props.href})\n`,
InkyTemplate: visit,
Callout: visit, Center: visit, Container: visit,
Column: visit, Wrapper: visit, Row: visit, BlockGrid: visit,
Menu: async ({ recurse }) => `\n${await recurse()}`,
Item: async ({ recurse, stack, props }) => {
const depth = stack.filter(x => x.type === 'Menu').length;
return `${' '.repeat(depth)}* [${await recurse()}](${props.href})\n`;
},
Spacer: async () => '\n\n',
Summary: ignore, Title: ignore,
img: ignore,
div: visit, title: visit, span: visit, center: visit, table: visit, tbody: visit, small: visit
};