68 lines
1.6 KiB
TypeScript
68 lines
1.6 KiB
TypeScript
|
|
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);
|
|
}
|
|
};
|
|
}
|