feat: 升级 Katex 公示支持中文

This commit is contained in:
purocean
2021-06-25 15:54:02 +08:00
parent 7d0b685418
commit 4967ef7e02
6 changed files with 218 additions and 20 deletions
+1 -1
View File
@@ -75,10 +75,10 @@
"eslint-plugin-vue": "^7.11.1",
"github-markdown-css": "^4.0.0",
"highlight.js": "^11.0.1",
"katex": "^0.13.11",
"lodash-es": "^4.17.21",
"markdown-it": "^12.0.6",
"markdown-it-attrs": "^4.0.0",
"markdown-it-katex": "^2.0.3",
"markdown-it-multimd-table": "^4.1.0",
"mermaid": "^8.10.2",
"monaco-editor": "^0.25.2",
-2
View File
@@ -44,7 +44,6 @@ import { debounce } from 'lodash-es'
import { useStore } from 'vuex'
import { computed, defineComponent, nextTick, onBeforeUnmount, onMounted, ref, toRefs, watch } from 'vue'
import Markdown from 'markdown-it'
import katex from 'markdown-it-katex'
import MarkdownItAttrs from 'markdown-it-attrs'
import MultimdTable from 'markdown-it-multimd-table'
@@ -59,7 +58,6 @@ import 'highlight.js/styles/atom-one-dark.css'
import 'katex/dist/katex.min.css'
const markdown = Markdown({ linkify: true, breaks: true, html: true, })
.use(katex)
.use(MarkdownItAttrs)
.use(MultimdTable, { multiline: true })
+204
View File
@@ -0,0 +1,204 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable prefer-const */
// https://raw.githubusercontent.com/waylonflinn/markdown-it-katex/master/index.js
/* eslint-disable camelcase */
/* Process inline math */
/*
Like markdown-it-simplemath, this is a stripped down, simplified version of:
https://github.com/runarberg/markdown-it-math
It differs in that it takes (a subset of) LaTeX as input and relies on KaTeX
for rendering output.
*/
import katex from 'katex'
import { Plugin } from '@fe/useful/plugin'
// Test if potential opening or closing delimieter
// Assumes that there is a "$" at state.src[pos]
function isValidDelim (state: any, pos: number) {
let prevChar; let nextChar
const max = state.posMax
let can_open = true
let can_close = true
prevChar = pos > 0 ? state.src.charCodeAt(pos - 1) : -1
nextChar = pos + 1 <= max ? state.src.charCodeAt(pos + 1) : -1
// Check non-whitespace conditions for opening and closing, and
// check that closing delimeter isn't followed by a number
if (prevChar === 0x20/* " " */ || prevChar === 0x09/* \t */ ||
(nextChar >= 0x30/* "0" */ && nextChar <= 0x39/* "9" */)) {
can_close = false
}
if (nextChar === 0x20/* " " */ || nextChar === 0x09/* \t */) {
can_open = false
}
return {
can_open: can_open,
can_close: can_close
}
}
function math_inline (state: any, silent: boolean) {
let start, match, token, res, pos, esc_count
if (state.src[state.pos] !== '$') { return false }
res = isValidDelim(state, state.pos)
if (!res.can_open) {
if (!silent) { state.pending += '$' }
state.pos += 1
return true
}
// First check for and bypass all properly escaped delimieters
// This loop will assume that the first leading backtick can not
// be the first character in state.src, which is known since
// we have found an opening delimieter already.
start = state.pos + 1
match = start
while ((match = state.src.indexOf('$', match)) !== -1) {
// Found potential $, look for escapes, pos will point to
// first non escape when complete
pos = match - 1
while (state.src[pos] === '\\') { pos -= 1 }
// Even number of escapes, potential closing delimiter found
if (((match - pos) % 2) === 1) { break }
match += 1
}
// No closing delimter found. Consume $ and continue.
if (match === -1) {
if (!silent) { state.pending += '$' }
state.pos = start
return true
}
// Check if we have empty content, ie: $$. Do not parse.
if (match - start === 0) {
if (!silent) { state.pending += '$$' }
state.pos = start + 1
return true
}
// Check for valid closing delimiter
res = isValidDelim(state, match)
if (!res.can_close) {
if (!silent) { state.pending += '$' }
state.pos = start
return true
}
if (!silent) {
token = state.push('math_inline', 'math', 0)
token.markup = '$'
token.content = state.src.slice(start, match)
}
state.pos = match + 1
return true
}
function math_block (state: any, start: number, end: number, silent: boolean) {
let firstLine; let lastLine; let next; let lastPos; let found = false; let token
let pos = state.bMarks[start] + state.tShift[start]
let max = state.eMarks[start]
if (pos + 2 > max) { return false }
if (state.src.slice(pos, pos + 2) !== '$$') { return false }
pos += 2
firstLine = state.src.slice(pos, max)
if (silent) { return true }
if (firstLine.trim().slice(-2) === '$$') {
// Single line expression
firstLine = firstLine.trim().slice(0, -2)
found = true
}
for (next = start; !found;) {
next++
if (next >= end) { break }
pos = state.bMarks[next] + state.tShift[next]
max = state.eMarks[next]
if (pos < max && state.tShift[next] < state.blkIndent) {
// non-empty line with negative indent should stop the list:
break
}
if (state.src.slice(pos, max).trim().slice(-2) === '$$') {
lastPos = state.src.slice(0, max).lastIndexOf('$$')
lastLine = state.src.slice(pos, lastPos)
found = true
}
}
state.line = next + 1
token = state.push('math_block', 'math', 0)
token.block = true
token.content = (firstLine && firstLine.trim() ? firstLine + '\n' : '') +
state.getLines(start + 1, next, state.tShift[start], true) +
(lastLine && lastLine.trim() ? lastLine : '')
token.map = [start, state.line]
token.markup = '$$'
return true
}
function math_plugin (md: any, options: any) {
// Default options
options = options || {}
// set KaTeX as the renderer for markdown-it-simplemath
const katexInline = function (latex: any) {
options.displayMode = false
try {
return katex.renderToString(latex, options)
} catch (error) {
if (options.throwOnError) { console.log(error) }
return latex
}
}
const inlineRenderer = function (tokens: any, idx: any) {
return katexInline(tokens[idx].content)
}
const katexBlock = function (latex: any) {
options.displayMode = true
try {
return '<p>' + katex.renderToString(latex, options) + '</p>'
} catch (error) {
console.log(error)
if (options.throwOnError) { console.log(error) }
return latex
}
}
const blockRenderer = function (tokens: any, idx: any) {
return katexBlock(tokens[idx].content) + '\n'
}
md.inline.ruler.after('escape', 'math_inline', math_inline)
md.block.ruler.after('blockquote', 'math_block', math_block, {
alt: ['paragraph', 'reference', 'blockquote', 'list']
})
md.renderer.rules.math_inline = inlineRenderer
md.renderer.rules.math_block = blockRenderer
}
export default {
name: 'markdown-toc',
register: ctx => {
ctx.markdown.registerPlugin(math_plugin)
}
} as Plugin
+1
View File
@@ -10,3 +10,4 @@ declare module 'markdown-it-multimd-table'
declare module 'markdown-it-katex'
declare module '@json-editor/json-editor'
declare module 'mermaid/dist/mermaid.js'
declare module 'katex'
+2
View File
@@ -13,6 +13,7 @@ import markdownLink from '@fe/plugins/markdown-link'
import markdownTaskList from '@fe/plugins/markdown-task-list'
import markdownFootnote from '@/renderer/plugins/markdown-footnote'
import transformImgOutLink from '@fe/plugins/transform-img-out-link'
import markdownItKatex from '@/renderer/plugins/markdown-it-katex'
import copyText from '@fe/plugins/copy-text'
import tableCellEdit from '@fe/plugins/table-cell-edit'
import switchTodo from '@fe/plugins/switch-todo'
@@ -39,6 +40,7 @@ export default [
markdownLink,
markdownTaskList,
markdownFootnote,
markdownItKatex,
transformImgOutLink,
copyText,
tableCellEdit,
+10 -17
View File
@@ -1456,6 +1456,11 @@ commander@^5.0.0:
resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae"
integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==
commander@^6.0.0:
version "6.2.1"
resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c"
integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==
component-bind@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1"
@@ -3731,12 +3736,12 @@ jsprim@^1.2.2:
json-schema "0.2.3"
verror "1.10.0"
katex@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/katex/-/katex-0.6.0.tgz#12418e09121c05c92041b6b3b9fb6bab213cb6f3"
integrity sha1-EkGOCRIcBckgQbazuftrqyE8tvM=
katex@^0.13.11:
version "0.13.11"
resolved "https://registry.yarnpkg.com/katex/-/katex-0.13.11.tgz#66138ebf173f25ef130cd3a3ea3ea1d12a3f1362"
integrity sha512-yJBHVIgwlAaapzlbvTpVF/ZOs8UkTj/sd46Fl8+qAf2/UiituPYVeapVD8ADZtqyRg/qNWUKt7gJoyYVWLrcXw==
dependencies:
match-at "^0.1.0"
commander "^6.0.0"
keygrip@~1.1.0:
version "1.1.0"
@@ -3967,13 +3972,6 @@ markdown-it-attrs@^4.0.0:
resolved "https://registry.yarnpkg.com/markdown-it-attrs/-/markdown-it-attrs-4.0.0.tgz#eadae3ea0c7d17c5e83b98a4ec95a47f4e4960f5"
integrity sha512-uLjtdCmhhmL3BuZsReYkFxk74qKjj5ahe34teBpOCJ4hYZZl7/ftLyXWLowngC2moRkbLEvKwN/7TMwbhbHE/A==
markdown-it-katex@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/markdown-it-katex/-/markdown-it-katex-2.0.3.tgz#d7b86a1aea0b9d6496fab4e7919a18fdef589c39"
integrity sha1-17hqGuoLnWSW+rTnkZoY/e9YnDk=
dependencies:
katex "^0.6.0"
markdown-it-multimd-table@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/markdown-it-multimd-table/-/markdown-it-multimd-table-4.1.0.tgz#5c23eba9ceda580dc5c7301927a01610e0ee37b9"
@@ -4003,11 +4001,6 @@ markdown-it@^12.0.6:
mdurl "^1.0.1"
uc.micro "^1.0.5"
match-at@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/match-at/-/match-at-0.1.1.tgz#25d040d291777704d5e6556bbb79230ec2de0540"
integrity sha512-h4Yd392z9mST+dzc+yjuybOGFNOZjmXIPKWjxBd1Bb23r4SmDOsk2NYCU2BMUBGbSpZqwVsZYNq26QS3xfaT3Q==
matcher@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/matcher/-/matcher-3.0.0.tgz#bd9060f4c5b70aa8041ccc6f80368760994f30ca"