/*--------------------------------------------------------------------------------------------- * 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: '$1', tag: '\\(' } ], block: [ { name: 'math_block_eqno', rex: /\\\[(.+?)\\\]\s*?\(([^)$\r\n]+?)\)\s*$/gmy, tmpl: '$1($2)', tag: '\\[' }, { name: 'math_block', rex: /\\\[(.+?)\\\]\s*$/gmy, tmpl: '$1', tag: '\\[' } ] }, gitlab: { inline: [ { name: 'math_inline', rex: /\$`(.+?)`\$/gy, tmpl: '$1', tag: '$`' } ], block: [ { name: 'math_block_eqno', rex: /`{3}math\s+?([^`]+?)\s+?`{3}\s*?\(([^)$\r\n]+?)\)\s*$/gmy, tmpl: '$1($2)', tag: '```math' }, { name: 'math_block', rex: /`{3}math\s+?([^`]+?)\s+?`{3}\s*$/gmy, tmpl: '$1', tag: '```math' } ] }, dollars: { inline: [ { name: 'math_inline', rex: /\$(\S[^$\r\n]*?[^\s\\]{1}?)\$/gy, tmpl: '$1', tag: '$', pre: texmath.$_pre, post: texmath.$_post }, { name: 'math_single', rex: /\$([^$\s\\]{1}?)\$/gy, tmpl: '$1', tag: '$', pre: texmath.$_pre, post: texmath.$_post } ], block: [ { name: 'math_block_eqno', rex: /\${2}([^$]*?)\${2}\s*?\(([^)$\r\n]+?)\)\s*$/gmy, tmpl: '$1($2)', tag: '$$' }, { name: 'math_block', rex: /\${2}([^$]*?)\${2}\s*$/gmy, tmpl: '$1', tag: '$$' } ] }, raw: { inline: [], block: [ { name: 'math_block', rex: /(\\begin\s*\{([^{}\s\r\n]+)\}(?:[^\\]|\\(?!end\s*\{\2\}))*\\end\s*\{\2\})\s*$/gmy, tmpl: '$1', tag: '\\begin' } ] } }; if (typeof module === "object" && module.exports) module.exports = texmath;