Files
Morten Olsen 7adf03c83f cleanup
2023-03-28 08:10:46 +02:00

92 lines
2.3 KiB
TypeScript

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 };