import { marked } from 'marked'; import katex = require('katex'); import type { KatexOptions } from 'katex'; import { MarkdownOptions } from './render'; export interface KatexToken extends marked.Tokens.Generic { text: string; } export function katex_block_ext(renderer: marked.Renderer, opts: MarkdownOptions) : marked.TokenizerExtension & marked.RendererExtension { return { name: 'katex_block', level: 'block', start: (src) => src.match(/^\$\$/)?.index, tokenizer(src, tokens) { const rule = /^\$\$((?:[^\$]|\$(?!\$))+)\$\$/; const match = rule.exec(src); if (match) { return { type: 'katex_block', raw: match[0], text: match[1] }; } }, renderer(token: KatexToken) { const katex_opts: KatexOptions = { displayMode: true, // true == "block" output: 'html', macros: opts.katex_macros, }; return (katex as any).renderToString(token.text, katex_opts); } }; } export function katex_inline_ext(renderer: marked.Renderer, opts: MarkdownOptions) : marked.TokenizerExtension & marked.RendererExtension { return { name: 'katex_inline', level: 'inline', start: (src) => src.match(/\$/)?.index, tokenizer(src, tokens) { const rule = /^\$([^\n\s](?:[^\n\$]*[^\n\s])?)\$/; const match = rule.exec(src); if (match) { return { type: 'katex_inline', raw: match[0], text: match[1] }; } }, renderer(token: KatexToken) { const katex_opts: KatexOptions = { displayMode: false, // false == "inline" output: 'html', macros: opts.katex_macros, }; return (katex as any).renderToString(token.text, katex_opts); } }; }