mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 05:49:53 +08:00
markdown-it: use markdown-it-texmath to get rid of escape of MathJax
This commit is contained in:
parent
027c8abd17
commit
35be1516ed
@ -199,6 +199,7 @@ In VNote, almost everything is configurable, such as background color, font, and
|
||||
- [markdown-it-front-matter](https://github.com/craigdmckenna/markdown-it-front-matter) (MIT License)
|
||||
- [markdown-it-imsize](https://github.com/tatsy/markdown-it-imsize) (Unknown) (Thanks @Kinka for help)
|
||||
- [markdown-it-emoji](https://github.com/markdown-it/markdown-it-emoji) (MIT License)
|
||||
- [markdown-it-texmath](https://github.com/goessner/markdown-it-texmath) (MIT License)
|
||||
- [mermaid 7.0.0](https://github.com/knsv/mermaid) (MIT License)
|
||||
- [MathJax](https://www.mathjax.org/) (Apache-2.0)
|
||||
- [showdown](https://github.com/showdownjs/showdown) (Unknown)
|
||||
|
@ -200,6 +200,7 @@ VNote中,几乎一切都是可以定制的,例如背景颜色、字体以及
|
||||
- [markdown-it-front-matter](https://github.com/craigdmckenna/markdown-it-front-matter) (MIT License)
|
||||
- [markdown-it-imsize](https://github.com/tatsy/markdown-it-imsize) (Unknown) (Thanks @Kinka for help)
|
||||
- [markdown-it-emoji](https://github.com/markdown-it/markdown-it-emoji) (MIT License)
|
||||
- [markdown-it-texmath](https://github.com/goessner/markdown-it-texmath) (MIT License)
|
||||
- [mermaid 7.0.0](https://github.com/knsv/mermaid) (MIT License)
|
||||
- [MathJax](https://www.mathjax.org/) (Apache-2.0)
|
||||
- [showdown](https://github.com/showdownjs/showdown) (Unknown)
|
||||
|
@ -108,6 +108,8 @@ mdit = mdit.use(window.markdownitFootnote);
|
||||
|
||||
mdit = mdit.use(window["markdown-it-imsize.js"]);
|
||||
|
||||
mdit = mdit.use(texmath, { delimiters: 'dollars' });
|
||||
|
||||
var mdHasTocSection = function(markdown) {
|
||||
var n = markdown.search(/(\n|^)\[toc\]/i);
|
||||
return n != -1;
|
||||
@ -150,8 +152,20 @@ var updateText = function(text) {
|
||||
// If you add new logics after handling MathJax, please pay attention to
|
||||
// finishLoading logic.
|
||||
if (VEnableMathjax) {
|
||||
var texToRender = document.getElementsByClassName('tex-to-render');
|
||||
var nrTex = texToRender.length;
|
||||
if (nrTex == 0) {
|
||||
finishOneAsyncJob();
|
||||
return;
|
||||
}
|
||||
|
||||
var eles = [];
|
||||
for (var i = 0; i < nrTex; ++i) {
|
||||
eles.push(texToRender[i]);
|
||||
}
|
||||
|
||||
try {
|
||||
MathJax.Hub.Queue(["Typeset", MathJax.Hub, contentDiv, postProcessMathJax]);
|
||||
MathJax.Hub.Queue(["Typeset", MathJax.Hub, eles, postProcessMathJax]);
|
||||
} catch (err) {
|
||||
content.setLog("err: " + err);
|
||||
finishOneAsyncJob();
|
||||
@ -196,3 +210,49 @@ var handleMetaData = function() {
|
||||
pre.appendChild(code);
|
||||
contentDiv.insertAdjacentElement('afterbegin', pre);
|
||||
};
|
||||
|
||||
var postProcessMathJaxWhenMathjaxReady = function() {
|
||||
var all = MathJax.Hub.getAllJax();
|
||||
for (var i = 0; i < all.length; ++i) {
|
||||
var node = all[i].SourceElement().parentNode;
|
||||
if (VRemoveMathjaxScript) {
|
||||
// Remove the SourceElement.
|
||||
try {
|
||||
node.removeChild(all[i].SourceElement());
|
||||
} catch (err) {
|
||||
content.setLog("err: " + err);
|
||||
}
|
||||
}
|
||||
|
||||
if (node.tagName.toLowerCase() == 'code') {
|
||||
var pre = node.parentNode;
|
||||
var p = document.createElement('p');
|
||||
p.innerHTML = node.innerHTML;
|
||||
pre.parentNode.replaceChild(p, pre);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var handleMathjaxReady = function() {
|
||||
if (!VEnableMathjax) {
|
||||
return;
|
||||
}
|
||||
|
||||
var texToRender = document.getElementsByClassName('tex-to-render');
|
||||
var nrTex = texToRender.length;
|
||||
if (nrTex == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var eles = [];
|
||||
for (var i = 0; i < nrTex; ++i) {
|
||||
eles.push(texToRender[i]);
|
||||
}
|
||||
|
||||
try {
|
||||
MathJax.Hub.Queue(["Typeset", MathJax.Hub, eles, postProcessMathJaxWhenMathjaxReady]);
|
||||
} catch (err) {
|
||||
content.setLog("err: " + err);
|
||||
finishOneAsyncJob();
|
||||
}
|
||||
};
|
||||
|
@ -92,6 +92,10 @@ if (typeof VOS == 'undefined') {
|
||||
VOS = 'win';
|
||||
}
|
||||
|
||||
if (typeof handleMathjaxReady == 'undefined') {
|
||||
var handleMathjaxReady = function() {};
|
||||
}
|
||||
|
||||
// Whether highlight special blocks like puml, flowchart.
|
||||
var highlightSpecialBlocks = false;
|
||||
|
||||
@ -1181,6 +1185,7 @@ var addClassToCodeBlock = function() {
|
||||
// Add the class to pre.
|
||||
pare.classList.add("lang-mathjax");
|
||||
pare.classList.add("language-mathjax");
|
||||
pare.classList.add("tex-to-render");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1268,7 +1273,11 @@ var postProcessMathJax = function() {
|
||||
var node = all[i].SourceElement().parentNode;
|
||||
if (VRemoveMathjaxScript) {
|
||||
// Remove the SourceElement.
|
||||
node.removeChild(all[i].SourceElement());
|
||||
try {
|
||||
node.removeChild(all[i].SourceElement());
|
||||
} catch (err) {
|
||||
content.setLog("err: " + err);
|
||||
}
|
||||
}
|
||||
|
||||
if (node.tagName.toLowerCase() == 'code') {
|
||||
|
@ -43,6 +43,11 @@ var previewMathJax = function(identifier, id, timeStamp, text, isHtml) {
|
||||
p = htmlToElement(text);
|
||||
if (isEmptyMathJax(p.textContent)) {
|
||||
p = null;
|
||||
} else if (p.tagName.toLowerCase() != 'p') {
|
||||
// Need to wrap it in a <p>, or domtoimage won't work.
|
||||
var tp = document.createElement('p');
|
||||
tp.appendChild(p);
|
||||
p = tp;
|
||||
}
|
||||
} else {
|
||||
p = document.createElement('p');
|
||||
|
@ -35,3 +35,7 @@ Tatsuya Yatagawa
|
||||
# [markdown-it-emoji](https://github.com/markdown-it/markdown-it-emoji)
|
||||
v1.4.0
|
||||
Vitaly Puzrin
|
||||
|
||||
# [markdown-it-texmath](https://github.com/goessner/markdown-it-texmath)
|
||||
v0.0.0
|
||||
Stefan Goessner
|
||||
|
155
src/utils/markdown-it/markdown-it-texmath.js
Normal file
155
src/utils/markdown-it/markdown-it-texmath.js
Normal file
@ -0,0 +1,155 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 = options && options.delimiters || 'dollars';
|
||||
|
||||
if (delimiters in texmath.rules) {
|
||||
for (let rule of texmath.rules[delimiters].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[delimiters].block) {
|
||||
md.block.ruler.before('fence', rule.name, texmath.block(rule));
|
||||
md.renderer.rules[rule.name] = (tokens, idx) => rule.tmpl.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.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',
|
||||
rex: /\\\[(.+?)\\\]/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',
|
||||
rex: /`{3}math\s+?([^`]+?)\s+?`{3}/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',
|
||||
rex: /\${2}([^$]*?)\${2}/gmy,
|
||||
tmpl: '<x-eqn class="tex-to-render">$1</x-eqn>',
|
||||
tag: '$$'
|
||||
}
|
||||
]
|
||||
},
|
||||
};
|
||||
|
||||
if (typeof module === "object" && module.exports)
|
||||
module.exports = texmath;
|
@ -639,6 +639,8 @@ QString VUtils::generateHtmlTemplate(const QString &p_template,
|
||||
bool p_wkhtmltopdf,
|
||||
bool p_addToc)
|
||||
{
|
||||
bool mathjaxTypeSetOnLoad = true;
|
||||
|
||||
QString jsFile, extraFile;
|
||||
switch (p_conType) {
|
||||
case MarkdownConverterType::Marked:
|
||||
@ -659,7 +661,8 @@ QString VUtils::generateHtmlTemplate(const QString &p_template,
|
||||
"<script src=\"qrc" + VNote::c_markdownitAnchorExtraFile + "\"></script>\n" +
|
||||
"<script src=\"qrc" + VNote::c_markdownitTaskListExtraFile + "\"></script>\n" +
|
||||
"<script src=\"qrc" + VNote::c_markdownitImsizeExtraFile + "\"></script>\n" +
|
||||
"<script src=\"qrc" + VNote::c_markdownitFootnoteExtraFile + "\"></script>\n";
|
||||
"<script src=\"qrc" + VNote::c_markdownitFootnoteExtraFile + "\"></script>\n" +
|
||||
"<script src=\"qrc" + VNote::c_markdownitTexMathExtraFile + "\"></script>\n";
|
||||
|
||||
const MarkdownitOption &opt = g_config->getMarkdownitOption();
|
||||
|
||||
@ -696,6 +699,8 @@ QString VUtils::generateHtmlTemplate(const QString &p_template,
|
||||
.arg(opt.m_metadata ? QStringLiteral("true") : QStringLiteral("false"))
|
||||
.arg(opt.m_emoji ? QStringLiteral("true") : QStringLiteral("false"));
|
||||
extraFile += optJs;
|
||||
|
||||
mathjaxTypeSetOnLoad = false;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -734,10 +739,12 @@ QString VUtils::generateHtmlTemplate(const QString &p_template,
|
||||
extraFile += "<script type=\"text/x-mathjax-config\">"
|
||||
"MathJax.Hub.Config({\n"
|
||||
" tex2jax: {inlineMath: [['$','$'], ['\\\\(','\\\\)']],\n"
|
||||
"processEscapes: true,\n"
|
||||
"processClass: \"tex2jax_process|language-mathjax|lang-mathjax\"},\n"
|
||||
"processEscapes: true,\n"
|
||||
"processClass: \"tex2jax_process|language-mathjax|lang-mathjax\"},\n"
|
||||
" showProcessingMessages: false,\n"
|
||||
" skipStartupTypeset: " + QString("%1,\n").arg(mathjaxTypeSetOnLoad ? "false" : "true") +
|
||||
" messageStyle: \"none\"});\n"
|
||||
"MathJax.Hub.Register.StartupHook(\"End\", function() { handleMathjaxReady(); });\n"
|
||||
"</script>\n"
|
||||
"<script type=\"text/javascript\" async src=\"" + mj + "\"></script>\n" +
|
||||
"<script>var VEnableMathjax = true;</script>\n";
|
||||
|
@ -42,6 +42,7 @@ const QString VNote::c_markdownitFootnoteExtraFile = ":/utils/markdown-it/markdo
|
||||
const QString VNote::c_markdownitFrontMatterExtraFile = ":/utils/markdown-it/markdown-it-front-matter.js";
|
||||
const QString VNote::c_markdownitImsizeExtraFile = ":/utils/markdown-it/markdown-it-imsize.min.js";
|
||||
const QString VNote::c_markdownitEmojiExtraFile = ":/utils/markdown-it/markdown-it-emoji.min.js";
|
||||
const QString VNote::c_markdownitTexMathExtraFile = ":/utils/markdown-it/markdown-it-texmath.js";
|
||||
|
||||
const QString VNote::c_showdownJsFile = ":/resources/showdown.js";
|
||||
const QString VNote::c_showdownExtraFile = ":/utils/showdown/showdown.min.js";
|
||||
|
@ -53,6 +53,7 @@ public:
|
||||
static const QString c_markdownitFrontMatterExtraFile;
|
||||
static const QString c_markdownitImsizeExtraFile;
|
||||
static const QString c_markdownitEmojiExtraFile;
|
||||
static const QString c_markdownitTexMathExtraFile;
|
||||
|
||||
// Showdown
|
||||
static const QString c_showdownJsFile;
|
||||
|
@ -265,5 +265,6 @@
|
||||
<file>resources/view_image.css</file>
|
||||
<file>resources/icons/decrease_outline_level.svg</file>
|
||||
<file>resources/icons/increase_outline_level.svg</file>
|
||||
<file>utils/markdown-it/markdown-it-texmath.js</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
Loading…
x
Reference in New Issue
Block a user