Skip to content

Commit

Permalink
chore: extract mdkatex
Browse files Browse the repository at this point in the history
  • Loading branch information
YangFong committed Sep 6, 2024
1 parent cb21736 commit 1bb2f75
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 101 deletions.
8 changes: 8 additions & 0 deletions src/utils/MDKatex.d.ts
Original file line number Diff line number Diff line change
@@ -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
92 changes: 92 additions & 0 deletions src/utils/MDKatex.js
Original file line number Diff line number Diff line change
@@ -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 `<section style="text-align: center; overflow: auto;">${svg.outerHTML}</section>`
}
else {
return `<span style="display: inline-block;">${svg.outerHTML}</span>`
}
}
}

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)),
],
}
}
102 changes: 1 addition & 101 deletions src/utils/renderer.ts
Original file line number Diff line number Diff line change
@@ -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 `<section style="text-align: center; overflow: auto;">${svg.outerHTML}</section>`
}
else {
return `<span style="display: inline-block;">${svg.outerHTML}</span>`
}
}
}

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`,
Expand Down

0 comments on commit 1bb2f75

Please sign in to comment.