syntax highlight + TOC scroll + other content parsing improvements
This commit is contained in:
@@ -9,7 +9,10 @@ var Promise = require('bluebird'),
|
||||
mdFootnote = require('markdown-it-footnote'),
|
||||
mdExternalLinks = require('markdown-it-external-links'),
|
||||
mdExpandTabs = require('markdown-it-expand-tabs'),
|
||||
mdAttrs = require('markdown-it-attrs'),
|
||||
hljs = require('highlight.js'),
|
||||
slug = require('slug'),
|
||||
cheerio = require('cheerio'),
|
||||
_ = require('lodash');
|
||||
|
||||
// Load plugins
|
||||
@@ -17,7 +20,15 @@ var Promise = require('bluebird'),
|
||||
var mkdown = md({
|
||||
html: true,
|
||||
linkify: true,
|
||||
typography: true
|
||||
typography: true,
|
||||
highlight: function (str, lang) {
|
||||
if (lang && hljs.getLanguage(lang)) {
|
||||
try {
|
||||
return '<pre class="hljs"><code>' + hljs.highlight(lang, str, true).value + '</code></pre>';
|
||||
} catch (__) {}
|
||||
}
|
||||
return '<pre class="hljs"><code>' + hljs.highlightAuto(str).value + '</code></pre>';
|
||||
}
|
||||
})
|
||||
.use(mdEmoji)
|
||||
.use(mdTaskLists)
|
||||
@@ -33,7 +44,8 @@ var mkdown = md({
|
||||
})
|
||||
.use(mdExpandTabs, {
|
||||
tabWidth: 4
|
||||
});
|
||||
})
|
||||
.use(mdAttrs);
|
||||
|
||||
// Rendering rules
|
||||
|
||||
@@ -41,13 +53,23 @@ mkdown.renderer.rules.emoji = function(token, idx) {
|
||||
return '<i class="twa twa-' + token[idx].markup + '"></i>';
|
||||
};
|
||||
|
||||
// Parse markdown headings tree
|
||||
mkdown.inline.ruler.push('internal_link', (state) => {
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* Parse markdown content and build TOC tree
|
||||
*
|
||||
* @param {(Function|string)} content Markdown content
|
||||
* @return {Array} TOC tree
|
||||
*/
|
||||
const parseTree = (content) => {
|
||||
|
||||
let tokens = md().parse(content, {});
|
||||
let tocArray = [];
|
||||
|
||||
//-> Extract headings and their respective levels
|
||||
|
||||
for (let i = 0; i < tokens.length; i++) {
|
||||
if (tokens[i].type !== "heading_close") {
|
||||
continue
|
||||
@@ -75,6 +97,12 @@ const parseTree = (content) => {
|
||||
}
|
||||
}
|
||||
|
||||
//-> Exclude levels deeper than 2
|
||||
|
||||
_.remove(tocArray, (n) => { return n.level > 2; });
|
||||
|
||||
//-> Build tree from flat array
|
||||
|
||||
return _.reduce(tocArray, (tree, v) => {
|
||||
let treeLength = tree.length - 1;
|
||||
if(v.level < 2) {
|
||||
@@ -98,23 +126,42 @@ const parseTree = (content) => {
|
||||
};
|
||||
let lastNodePath = GetNodePath();
|
||||
let lastNode = _.get(tree[treeLength], lastNodePath);
|
||||
lastNode.push({
|
||||
content: v.content,
|
||||
anchor: v.anchor,
|
||||
nodes: []
|
||||
});
|
||||
_.set(tree[treeLength], lastNodePath, lastNode);
|
||||
if(lastNode) {
|
||||
lastNode.push({
|
||||
content: v.content,
|
||||
anchor: v.anchor,
|
||||
nodes: []
|
||||
});
|
||||
_.set(tree[treeLength], lastNodePath, lastNode);
|
||||
}
|
||||
}
|
||||
return tree;
|
||||
}, []);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse markdown content to HTML
|
||||
*
|
||||
* @param {String} content Markdown content
|
||||
* @return {String} HTML formatted content
|
||||
*/
|
||||
const parseContent = (content) => {
|
||||
|
||||
let output = mkdown.render(content);
|
||||
let cr = cheerio.load(output);
|
||||
cr('table').addClass('table is-bordered is-striped is-narrow');
|
||||
output = cr.html();
|
||||
|
||||
return output;
|
||||
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
|
||||
parse(content) {
|
||||
return {
|
||||
html: mkdown.render(content),
|
||||
html: parseContent(content),
|
||||
tree: parseTree(content)
|
||||
};
|
||||
}
|
||||
|
Reference in New Issue
Block a user