Files
gitbook/lib/parse/page.js
T
2014-04-08 15:01:12 -07:00

92 lines
2.4 KiB
JavaScript

var _ = require('lodash');
var marked = require('marked');
var hljs = require('highlight.js');
var lex = require('./lex');
var renderer = require('./renderer');
var lnormalize = require('../utils/lang').normalize;
// Synchronous highlighting with highlight.js
marked.setOptions({
highlight: function (code, lang) {
try {
return hljs.highlight(lang, code).value;
} catch(e) {
return hljs.highlightAuto(code).value;
}
}
});
// Render a section using our custom renderer
function render(section, _options) {
// Copy section
section = _.toArray(section);
// marked's Render expects this, we don't use it yet
section.links = {};
// Build options using defaults and our custom renderer
var options = _.extend({}, marked.defaults, {
renderer: renderer(null, _options)
});
return marked.parser(section, options);
}
function parsePage(src, options) {
options = options || {};
// Lex if not already lexed
return (_.isArray(src) ? src : lex(src))
.map(function(section) {
// Transform given type
if(section.type === 'exercise') {
var nonCodeNodes = _.reject(section, {
'type': 'code'
});
var codeNodes = _.filter(section, {
'type': 'code'
});
// Languages in code blocks
var langs = _.pluck(codeNodes, 'lang').map(lnormalize);
// Check that they are all the same
var validLangs = _.all(_.map(langs, function(lang) {
return lang && lang === langs[0];
}));
// Main language
var lang = validLangs ? langs[0] : null;
return {
id: section.id,
type: section.type,
content: render(nonCodeNodes),
lang: lang,
code: {
base: codeNodes[0].text,
solution: codeNodes[1].text,
validation: codeNodes[2].text,
// Context is optional
context: codeNodes[3] ? codeNodes[3].text : null,
}
};
}
// Render normal pages
return {
id: section.id,
type: section.type,
content: render(section, options)
};
});
}
// Exports
module.exports = parsePage;