import { decode } from 'html-entities'; import { existsSync } from 'fs'; import { resolve } from 'path'; const latexTypes = ['', 'section', 'subsection', 'paragraph', 'subparagraph']; const sanitize = (text?: string) => { if (!text) { return ''; } return decode(text) .replace('&', '\\&') .replace('_', '\\_') .replace(/([^\\])\}/g, '$1\\}') .replace(/([^\\])\{/g, '$1\\{') .replace(/[^\\]\[/g, '\\[') .replace(/#/g, '\\#'); }; type Renderer = (depth: number) => { heading?: (text: string, depth: number) => string; code?: (input: string) => string; text?: (input: string) => string; paragraph?: (input: string) => string; list?: (input: string) => string; listitem?: (input: string) => string; link?: (href: string, text: string) => string; strong?: (text: string) => string; em?: (text: string) => string; codespan?: (code: string) => string; image?: (link: string) => string; }; const renderer = (outerDepth: number, cwd: string) => ({ heading: (text: string, depth: number) => { return `\\${latexTypes[outerDepth + depth]}{${sanitize(text)}}\n\n`; }, code: (input: string) => { return ` \\begin{lstlisting} ${input} \\end{lstlisting} `; }, text: (input: string) => { return sanitize(input); }, blockquote: (input: string) => { return sanitize(input); }, paragraph: (input: string) => { return `${input}\n\n`; }, list: (input: string) => { return ` \\begin{itemize} ${input} \\end{itemize} `; }, listitem: (input: string) => { return `\\item{${input}}`; }, link: (href: string, text: string) => { if (!text || text === href) { return `\\url{${sanitize(href)}}`; } return `${sanitize(text)} (\\url{${sanitize(href)}})`; }, strong: (text: string) => { return `\\textbf{${sanitize(text)}}`; }, em: (text: string) => { return `\\textbf{${sanitize(text)}}`; }, codespan: (code: string) => { return `\\texttt{${sanitize(code)}}`; }, image: (link: string) => { const path = resolve(cwd, link); if (!existsSync(path)) { return `Online image not supported ${path}`; } return ` \\noindent\\includegraphics[width=\\linewidth]{${path}} `; }, }); export type { Renderer }; export { sanitize, renderer };