mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
290 lines
7.4 KiB
JavaScript
290 lines
7.4 KiB
JavaScript
var nameCounter = 0;
|
|
var toc = []; // Table of Content as a list
|
|
|
|
var getHeadingLevel = function(h) {
|
|
var level = 1;
|
|
switch (h) {
|
|
case 'h1':
|
|
break;
|
|
|
|
case 'h2':
|
|
level += 1;
|
|
break;
|
|
|
|
case 'h3':
|
|
level += 2;
|
|
break;
|
|
|
|
case 'h4':
|
|
level += 3;
|
|
break;
|
|
|
|
case 'h5':
|
|
level += 4;
|
|
break;
|
|
|
|
case 'h6':
|
|
level += 5;
|
|
break;
|
|
|
|
default:
|
|
level += 6;
|
|
break;
|
|
}
|
|
return level;
|
|
}
|
|
|
|
// There is a VMarkdownitOption struct passed in.
|
|
// var VMarkdownitOption = { html, breaks, linkify, sub, sup };
|
|
var mdit = window.markdownit({
|
|
html: VMarkdownitOption.html,
|
|
breaks: VMarkdownitOption.breaks,
|
|
linkify: VMarkdownitOption.linkify,
|
|
typographer: false,
|
|
langPrefix: 'lang-',
|
|
highlight: function(str, lang) {
|
|
if (lang && (!specialCodeBlock(lang) || highlightSpecialBlocks)) {
|
|
if (lang === 'wavedrom') {
|
|
lang = 'json';
|
|
}
|
|
|
|
if (hljs.getLanguage(lang)) {
|
|
return hljs.highlight(lang, str, true).value;
|
|
} else {
|
|
return hljs.highlightAuto(str).value;
|
|
}
|
|
}
|
|
|
|
// Use external default escaping.
|
|
return '';
|
|
}
|
|
});
|
|
|
|
mdit = mdit.use(window.markdownitHeadingAnchor, {
|
|
anchorClass: 'vnote-anchor',
|
|
addHeadingID: true,
|
|
addHeadingAnchor: true,
|
|
anchorIcon: '#',
|
|
slugify: function(md, s) {
|
|
return 'toc_' + nameCounter++;
|
|
},
|
|
headingHook: function(openToken, inlineToken, anchor) {
|
|
toc.push({
|
|
level: getHeadingLevel(openToken.tag),
|
|
anchor: anchor,
|
|
title: mdit.utils.escapeHtml(inlineToken.content)
|
|
});
|
|
}
|
|
});
|
|
|
|
// Enable file: scheme.
|
|
var validateLinkMDIT = mdit.validateLink;
|
|
var fileSchemeRE = /^file:/;
|
|
mdit.validateLink = function(url) {
|
|
var str = url.trim().toLowerCase();
|
|
return fileSchemeRE.test(str) ? true : validateLinkMDIT(url);
|
|
};
|
|
|
|
mdit = mdit.use(window.markdownitTaskLists);
|
|
|
|
if (VMarkdownitOption.sub) {
|
|
mdit = mdit.use(window.markdownitSub);
|
|
}
|
|
|
|
if (VMarkdownitOption.sup) {
|
|
mdit = mdit.use(window.markdownitSup);
|
|
}
|
|
|
|
var metaDataText = null;
|
|
if (VMarkdownitOption.metadata) {
|
|
mdit = mdit.use(window.markdownitFrontMatter, function(text){
|
|
metaDataText = text;
|
|
});
|
|
}
|
|
|
|
if (VMarkdownitOption.emoji) {
|
|
mdit = mdit.use(window.markdownitEmoji);
|
|
mdit.renderer.rules.emoji = function(token, idx) {
|
|
return '<span class="emoji emoji_' + token[idx].markup + '">' + token[idx].content + '</span>';
|
|
};
|
|
}
|
|
|
|
mdit = mdit.use(window.markdownitFootnote);
|
|
|
|
mdit = mdit.use(window["markdown-it-imsize.js"]);
|
|
|
|
if (typeof texmath != 'undefined') {
|
|
mdit = mdit.use(texmath, { delimiters: ['dollars', 'raw'] });
|
|
}
|
|
|
|
mdit.use(window.markdownitContainer, 'alert', {
|
|
validate: function(params) {
|
|
return params.trim().match(/^alert-\S+$/);
|
|
},
|
|
|
|
render: function (tokens, idx) {
|
|
let type = tokens[idx].info.trim().match(/^(alert-\S+)$/);
|
|
if (tokens[idx].nesting === 1) {
|
|
// opening tag
|
|
let alertClass = type[1];
|
|
return '<div class="alert ' + alertClass + '" role="alert">';
|
|
} else {
|
|
// closing tag
|
|
return '</div>\n';
|
|
}
|
|
}
|
|
});
|
|
|
|
var mdHasTocSection = function(markdown) {
|
|
var n = markdown.search(/(\n|^)\[toc\]/i);
|
|
return n != -1;
|
|
};
|
|
|
|
var markdownToHtml = function(markdown, needToc) {
|
|
toc = [];
|
|
nameCounter = 0;
|
|
var html = mdit.render(markdown);
|
|
if (needToc) {
|
|
return html.replace(/<p>\[TOC\]<\/p>/ig, '<div class="vnote-toc"></div>');
|
|
} else {
|
|
return html;
|
|
}
|
|
};
|
|
|
|
var updateText = function(text) {
|
|
if (VAddTOC) {
|
|
text = "[TOC]\n\n" + text;
|
|
}
|
|
|
|
startFreshRender();
|
|
|
|
// There is at least one async job for MathJax.
|
|
asyncJobsCount = 1;
|
|
metaDataText = null;
|
|
|
|
var needToc = mdHasTocSection(text);
|
|
var html = markdownToHtml(text, needToc);
|
|
contentDiv.innerHTML = html;
|
|
handleToc(needToc);
|
|
insertImageCaption();
|
|
setupImageView();
|
|
handleMetaData();
|
|
renderMermaid('lang-mermaid');
|
|
renderFlowchart(['lang-flowchart', 'lang-flow']);
|
|
renderWavedrom('lang-wavedrom');
|
|
renderPlantUML('lang-puml');
|
|
renderGraphviz('lang-dot');
|
|
addClassToCodeBlock();
|
|
addCopyButtonToCodeBlock();
|
|
renderCodeBlockLineNumber();
|
|
|
|
// 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(["resetEquationNumbers",MathJax.InputJax.TeX],
|
|
["Typeset", MathJax.Hub, eles, postProcessMathJax]);
|
|
} catch (err) {
|
|
content.setLog("err: " + err);
|
|
finishOneAsyncJob();
|
|
}
|
|
} else {
|
|
finishOneAsyncJob();
|
|
}
|
|
};
|
|
|
|
var highlightText = function(text, id, timeStamp) {
|
|
highlightSpecialBlocks = true;
|
|
var html = mdit.render(text);
|
|
highlightSpecialBlocks = false;
|
|
content.highlightTextCB(html, id, timeStamp);
|
|
};
|
|
|
|
var textToHtml = function(identifier, id, timeStamp, text, inlineStyle) {
|
|
var html = mdit.render(text);
|
|
if (inlineStyle) {
|
|
var container = textHtmlDiv;
|
|
container.innerHTML = html;
|
|
html = getHtmlWithInlineStyles(container);
|
|
container.innerHTML = "";
|
|
}
|
|
|
|
content.textToHtmlCB(identifier, id, timeStamp, html);
|
|
};
|
|
|
|
// Add a PRE containing metaDataText if it is not empty.
|
|
var handleMetaData = function() {
|
|
if (!metaDataText || metaDataText.length == 0) {
|
|
return;
|
|
}
|
|
|
|
var pre = document.createElement('pre');
|
|
var code = document.createElement('code');
|
|
code.classList.add(VMetaDataCodeClass);
|
|
|
|
var text = hljs.highlight('yaml', metaDataText, true).value;
|
|
code.innerHTML = text;
|
|
|
|
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(["resetEquationNumbers",MathJax.InputJax.TeX],
|
|
["Typeset", MathJax.Hub, eles, postProcessMathJaxWhenMathjaxReady]);
|
|
} catch (err) {
|
|
content.setLog("err: " + err);
|
|
finishOneAsyncJob();
|
|
}
|
|
};
|