blog / src /components /cms /markdown-preview.ts
cacode's picture
Upload 434 files
96dd062 verified
import katex from "katex";
import { marked } from "marked";
marked.setOptions({
breaks: true,
gfm: true,
});
function renderInlineMath(expression: string) {
try {
return katex.renderToString(expression, {
displayMode: false,
throwOnError: false,
});
} catch {
return expression;
}
}
function renderBlockMath(expression: string) {
try {
return `<div class="admin-katex-block">${katex.renderToString(expression, {
displayMode: true,
throwOnError: false,
})}</div>`;
} catch {
return expression;
}
}
function replaceMathSegments(markdown: string) {
const codeTokens: string[] = [];
const codeTokenPattern = /```[\s\S]*?```|`[^`\n]+`/g;
let prepared = markdown.replace(codeTokenPattern, (match) => {
const token = `@@ADMIN_CODE_TOKEN_${codeTokens.length}@@`;
codeTokens.push(match);
return token;
});
prepared = prepared.replace(/\$\$([\s\S]+?)\$\$/g, (_, expression: string) =>
renderBlockMath(expression.trim()),
);
prepared = prepared.replace(
/(^|[^\$\\])\$([^\n$]+?)\$/g,
(_, prefix: string, expression: string) =>
`${prefix}${renderInlineMath(expression.trim())}`,
);
return prepared.replace(/@@ADMIN_CODE_TOKEN_(\d+)@@/g, (_, index: string) => {
const tokenIndex = Number.parseInt(index, 10);
return codeTokens[tokenIndex] ?? "";
});
}
export function renderMarkdownPreview(markdown: string) {
return marked.parse(replaceMathSegments(markdown || "")) as string;
}