mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
190 lines
6.6 KiB
JavaScript
190 lines
6.6 KiB
JavaScript
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Stefan Goessner - 2017-18. All rights reserved.
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
* Modified by Le Tan for MathJax support in VNote.
|
|
* We mark all the formulas and enclose them with $ in class 'tex-to-render' for
|
|
* further processing by MathJax.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
'use strict';
|
|
|
|
function texmath(md, options) {
|
|
let delimiters = ['dollars'];
|
|
if (options && options.delimiters) {
|
|
delimiters = options.delimiters;
|
|
}
|
|
|
|
for (let i = 0; i < delimiters.length; ++i) {
|
|
let deli = delimiters[i];
|
|
if (deli in texmath.rules) {
|
|
for (let rule of texmath.rules[deli].inline) {
|
|
md.inline.ruler.before('escape', rule.name, texmath.inline(rule)); // ! important
|
|
md.renderer.rules[rule.name] = (tokens, idx) => rule.tmpl.replace(/\$1/,texmath.render(tokens[idx].content,false));
|
|
}
|
|
|
|
for (let rule of texmath.rules[deli].block) {
|
|
md.block.ruler.before('fence', rule.name, texmath.block(rule));
|
|
md.renderer.rules[rule.name] = (tokens, idx) => rule.tmpl.replace(/\$2/,tokens[idx].info) // equation number
|
|
.replace(/\$1/,texmath.render(tokens[idx].content,true));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
texmath.applyRule = function(rule, str, beg) {
|
|
let pre, match, post;
|
|
rule.rex.lastIndex = beg;
|
|
pre = str.startsWith(rule.tag,beg) && (!rule.pre || rule.pre(str,beg));
|
|
match = pre && rule.rex.exec(str);
|
|
if (match) {
|
|
match.lastIndex = rule.rex.lastIndex;
|
|
post = !rule.post || rule.post(str, match.lastIndex-1);
|
|
}
|
|
rule.rex.lastIndex = 0;
|
|
return post && match;
|
|
}
|
|
|
|
texmath.inline = (rule) =>
|
|
function(state, silent) {
|
|
let res = texmath.applyRule(rule, state.src, state.pos);
|
|
if (res) {
|
|
if (!silent) {
|
|
let token = state.push(rule.name, 'math', 0);
|
|
token.content = res[1]; // group 1 from regex ..
|
|
token.markup = rule.tag;
|
|
}
|
|
state.pos = res.lastIndex;
|
|
}
|
|
return !!res;
|
|
}
|
|
|
|
texmath.block = (rule) =>
|
|
function(state, begLine, endLine, silent) {
|
|
let res = texmath.applyRule(rule, state.src, state.bMarks[begLine] + state.tShift[begLine]);
|
|
if (res) {
|
|
if (!silent) {
|
|
let token = state.push(rule.name, 'math', 0);
|
|
token.block = true;
|
|
token.content = res[1];
|
|
token.info = res[2];
|
|
token.markup = rule.tag;
|
|
}
|
|
for (let line=begLine, endpos=res.lastIndex-1; line < endLine; line++)
|
|
if (endpos >= state.bMarks[line] && endpos <= state.eMarks[line]) { // line for end of block math found ...
|
|
state.line = line+1;
|
|
break;
|
|
}
|
|
state.pos = res.lastIndex;
|
|
}
|
|
return !!res;
|
|
}
|
|
|
|
texmath.render = function(tex, isblock) {
|
|
let res;
|
|
if (isblock) {
|
|
res = '$$$$' + tex + '$$$$';
|
|
} else {
|
|
res = '$$' + tex + '$$';
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
texmath.$_pre = (str,beg) => {
|
|
let prv = beg > 0 ? str[beg-1].charCodeAt(0) : false;
|
|
return !prv || prv !== 0x5c // no backslash,
|
|
&& (prv < 0x30 || prv > 0x39); // no decimal digit .. before opening '$'
|
|
}
|
|
texmath.$_post = (str,end) => {
|
|
let nxt = str[end+1] && str[end+1].charCodeAt(0);
|
|
return !nxt || nxt < 0x30 || nxt > 0x39; // no decimal digit .. after closing '$'
|
|
}
|
|
|
|
texmath.rules = {
|
|
brackets: {
|
|
inline: [
|
|
{ name: 'math_inline',
|
|
rex: /\\\((.+?)\\\)/gy,
|
|
tmpl: '<x-eq class="tex-to-render">$1</x-eq>',
|
|
tag: '\\('
|
|
}
|
|
],
|
|
block: [
|
|
{ name: 'math_block_eqno',
|
|
rex: /\\\[(.+?)\\\]\s*?\(([^)$\r\n]+?)\)\s*$/gmy,
|
|
tmpl: '<x-eqs><x-eqn class="tex-to-render">$1</x-eqn><span>($2)</span></x-eqs>',
|
|
tag: '\\['
|
|
},
|
|
{ name: 'math_block',
|
|
rex: /\\\[(.+?)\\\]\s*$/gmy,
|
|
tmpl: '<x-eqn class="tex-to-render">$1</x-eqn>',
|
|
tag: '\\['
|
|
}
|
|
]
|
|
},
|
|
gitlab: {
|
|
inline: [
|
|
{ name: 'math_inline',
|
|
rex: /\$`(.+?)`\$/gy,
|
|
tmpl: '<x-eq class="tex-to-render">$1</x-eq>',
|
|
tag: '$`'
|
|
}
|
|
],
|
|
block: [
|
|
{ name: 'math_block_eqno',
|
|
rex: /`{3}math\s+?([^`]+?)\s+?`{3}\s*?\(([^)$\r\n]+?)\)\s*$/gmy,
|
|
tmpl: '<x-eqs><x-eqn class="tex-to-render">$1</x-eqn><span>($2)</span></x-eqs>',
|
|
tag: '```math'
|
|
},
|
|
{ name: 'math_block',
|
|
rex: /`{3}math\s+?([^`]+?)\s+?`{3}\s*$/gmy,
|
|
tmpl: '<x-eqn class="tex-to-render">$1</x-eqn>',
|
|
tag: '```math'
|
|
}
|
|
]
|
|
},
|
|
dollars: {
|
|
inline: [
|
|
{ name: 'math_inline',
|
|
rex: /\$(\S[^$\r\n]*?[^\s\\]{1}?)\$/gy,
|
|
tmpl: '<x-eq class="tex-to-render">$1</x-eq>',
|
|
tag: '$',
|
|
pre: texmath.$_pre,
|
|
post: texmath.$_post
|
|
},
|
|
{ name: 'math_single',
|
|
rex: /\$([^$\s\\]{1}?)\$/gy,
|
|
tmpl: '<x-eq class="tex-to-render">$1</x-eq>',
|
|
tag: '$',
|
|
pre: texmath.$_pre,
|
|
post: texmath.$_post
|
|
}
|
|
],
|
|
block: [
|
|
{ name: 'math_block_eqno',
|
|
rex: /\${2}([^$]*?)\${2}\s*?\(([^)$\r\n]+?)\)\s*$/gmy,
|
|
tmpl: '<x-eqs><x-eqn class="tex-to-render">$1</x-eqn><span>($2)</span></x-eqs>',
|
|
tag: '$$'
|
|
},
|
|
{ name: 'math_block',
|
|
rex: /\${2}([^$]*?)\${2}\s*$/gmy,
|
|
tmpl: '<x-eqn class="tex-to-render">$1</x-eqn>',
|
|
tag: '$$'
|
|
}
|
|
]
|
|
},
|
|
raw: {
|
|
inline: [],
|
|
block: [
|
|
{
|
|
name: 'math_block',
|
|
rex: /(\\begin\s*\{([^{}\s\r\n]+)\}(?:[^\\]|\\(?!end\s*\{\2\}))*\\end\s*\{\2\})\s*$/gmy,
|
|
tmpl: '<x-eqn class="tex-to-render">$1</x-eqn>',
|
|
tag: '\\begin'
|
|
}
|
|
]
|
|
}
|
|
};
|
|
|
|
if (typeof module === "object" && module.exports)
|
|
module.exports = texmath;
|