From 1bb2f75b2c393cd5c4625a8e765b9d4aa13f4c0b Mon Sep 17 00:00:00 2001 From: YangFong Date: Fri, 6 Sep 2024 23:11:18 +0800 Subject: [PATCH] chore: extract mdkatex --- src/utils/MDKatex.d.ts | 8 ++++ src/utils/MDKatex.js | 92 +++++++++++++++++++++++++++++++++++++ src/utils/renderer.ts | 102 +---------------------------------------- 3 files changed, 101 insertions(+), 101 deletions(-) create mode 100644 src/utils/MDKatex.d.ts create mode 100644 src/utils/MDKatex.js diff --git a/src/utils/MDKatex.d.ts b/src/utils/MDKatex.d.ts new file mode 100644 index 000000000..a07e0746e --- /dev/null +++ b/src/utils/MDKatex.d.ts @@ -0,0 +1,8 @@ +import type { KatexOptions } from 'katex' +import type { MarkedExtension } from 'marked' + +export interface MarkedKatexOptions extends KatexOptions { + nonStandard?: boolean +} + +export function MDKatex(options?: MarkedKatexOptions): MarkedExtension diff --git a/src/utils/MDKatex.js b/src/utils/MDKatex.js new file mode 100644 index 000000000..dd1dc37d6 --- /dev/null +++ b/src/utils/MDKatex.js @@ -0,0 +1,92 @@ +const inlineRule = /^(\${1,2})(?!\$)((?:\\.|[^\\\n])*?(?:\\.|[^\\\n$]))\1(?=[\s?!.,:?!。,:]|$)/ +const inlineRuleNonStandard = /^(\${1,2})(?!\$)((?:\\.|[^\\\n])*?(?:\\.|[^\\\n$]))\1/ // Non-standard, even if there are no spaces before and after $ or $$, try to parse + +const blockRule = /^(\${1,2})\n((?:\\[\s\S]|[^\\])+?)\n\1(?:\n|$)/ + +function createRenderer(options, newlineAfter) { + return (token) => { + window.MathJax.texReset() + const mjxContainer = window.MathJax.tex2svg(token.text, { display: newlineAfter }) + const svg = mjxContainer.firstChild + const width = svg.style[`min-width`] || svg.getAttribute(`width`) + svg.removeAttribute(`width`) + svg.style.width = width + if (newlineAfter) { + svg.style.margin = `auto` + return `
${svg.outerHTML}
` + } + else { + return `${svg.outerHTML}` + } + } +} + +function inlineKatex(options, renderer) { + const nonStandard = options && options.nonStandard + const ruleReg = nonStandard ? inlineRuleNonStandard : inlineRule + return { + name: `inlineKatex`, + level: `inline`, + start(src) { + let index + let indexSrc = src + + while (indexSrc) { + index = indexSrc.indexOf(`$`) + if (index === -1) { + return + } + const f = nonStandard ? index > -1 : index === 0 || indexSrc.charAt(index - 1) === ` ` + if (f) { + const possibleKatex = indexSrc.substring(index) + + if (possibleKatex.match(ruleReg)) { + return index + } + } + + indexSrc = indexSrc.substring(index + 1).replace(/^\$+/, ``) + } + }, + tokenizer(src) { + const match = src.match(ruleReg) + if (match) { + return { + type: `inlineKatex`, + raw: match[0], + text: match[2].trim(), + displayMode: match[1].length === 2, + } + } + }, + renderer, + } +} + +function blockKatex(options, renderer) { + return { + name: `blockKatex`, + level: `block`, + tokenizer(src) { + const match = src.match(blockRule) + if (match) { + return { + type: `blockKatex`, + raw: match[0], + text: match[2].trim(), + displayMode: match[1].length === 2, + } + } + }, + renderer, + } +} + +export function MDKatex(options = {}) { + return { + extensions: [ + inlineKatex(options, createRenderer(options, false)), + blockKatex(options, createRenderer(options, true)), + ], + } +} diff --git a/src/utils/renderer.ts b/src/utils/renderer.ts index c5b9bea49..0ae40b69a 100644 --- a/src/utils/renderer.ts +++ b/src/utils/renderer.ts @@ -1,114 +1,14 @@ import type { Renderer, RendererObject, Tokens } from 'marked' import { marked } from 'marked' import hljs from 'highlight.js' -import markedKatex from 'marked-katex-extension' import mermaid from 'mermaid' import { toMerged } from 'es-toolkit' import type { PropertiesHyphen } from 'csstype' -import katex from 'katex' +import { MDKatex } from './MDKatex' import type { ExtendedProperties, IOpts, ThemeStyles } from '@/types' -// console.log(`MathJax`, window.MathJax) - -const inlineRule = /^(\${1,2})(?!\$)((?:\\.|[^\\\n])*?(?:\\.|[^\\\n$]))\1(?=[\s?!.,:?!。,:]|$)/ -const inlineRuleNonStandard = /^(\${1,2})(?!\$)((?:\\.|[^\\\n])*?(?:\\.|[^\\\n$]))\1/ // Non-standard, even if there are no spaces before and after $ or $$, try to parse - -const blockRule = /^(\${1,2})\n((?:\\[\s\S]|[^\\])+?)\n\1(?:\n|$)/ -function MDKatex(options = {}) { - return { - extensions: [ - inlineKatex(options, createRenderer(options, false)), - blockKatex(options, createRenderer(options, true)), - ], - } -} - -function createRenderer(options, newlineAfter) { - return (token) => { - window.MathJax.texReset() - const mjxContainer = window.MathJax.tex2svg(token.text, { display: newlineAfter }) - const svg = mjxContainer.firstChild - const width = svg.style[`min-width`] || svg.getAttribute(`width`) - svg.removeAttribute(`width`) - svg.style.width = width - if (newlineAfter) { - svg.style.margin = `auto` - return `
${svg.outerHTML}
` - } - else { - return `${svg.outerHTML}` - } - } -} - -function inlineKatex(options, renderer) { - const nonStandard = options && options.nonStandard - const ruleReg = nonStandard ? inlineRuleNonStandard : inlineRule - return { - name: `inlineKatex`, - level: `inline`, - start(src) { - let index - let indexSrc = src - - while (indexSrc) { - index = indexSrc.indexOf(`$`) - if (index === -1) { - return - } - const f = nonStandard ? index > -1 : index === 0 || indexSrc.charAt(index - 1) === ` ` - if (f) { - const possibleKatex = indexSrc.substring(index) - - if (possibleKatex.match(ruleReg)) { - return index - } - } - - indexSrc = indexSrc.substring(index + 1).replace(/^\$+/, ``) - } - }, - tokenizer(src, tokens) { - const match = src.match(ruleReg) - if (match) { - return { - type: `inlineKatex`, - raw: match[0], - text: match[2].trim(), - displayMode: match[1].length === 2, - } - } - }, - renderer, - } -} - -function blockKatex(options, renderer) { - return { - name: `blockKatex`, - level: `block`, - tokenizer(src, tokens) { - const match = src.match(blockRule) - if (match) { - return { - type: `blockKatex`, - raw: match[0], - text: match[2].trim(), - displayMode: match[1].length === 2, - } - } - }, - renderer, - } -} - marked.use( - // markedKatex({ - // throwOnError: false, - // output: `html`, - // nonStandard: true, - // }), MDKatex({ throwOnError: false, output: `html`,