var fs = require('fs'); var marked = require('marked'); var path = require('path'); module.exports = toHTML; function toHTML(input, filename, template, cb) { var lexed = marked.lexer(input); fs.readFile(template, 'utf8', function(er, template) { if (er) return cb(er); render(lexed, filename, template, cb); }); } function render(lexed, filename, template, cb) { // get the section var section = getSection(lexed); filename = path.basename(filename, '.markdown'); lexed = parseLists(lexed); // generate the table of contents. // this mutates the lexed contents in-place. buildToc(lexed, filename, function(er, toc) { if (er) return cb(er); template = template.replace(/__FILENAME__/g, filename); template = template.replace(/__SECTION__/g, section); template = template.replace(/__VERSION__/g, process.version); template = template.replace(/__TOC__/g, toc); // content has to be the last thing we do with // the lexed tokens, because it's destructive. content = marked.parser(lexed); template = template.replace(/__CONTENT__/g, content); cb(null, template); }); } // just update the list item text in-place. // lists that come right after a heading are what we're after. function parseLists(input) { var state = null; var depth = 0; var output = []; output.links = input.links; input.forEach(function(tok) { if (state === null) { if (tok.type === 'heading') { state = 'AFTERHEADING'; } output.push(tok); return; } if (state === 'AFTERHEADING') { if (tok.type === 'code') return; if (tok.type === 'list_start') { state = 'LIST'; if (depth === 0) { output.push({ type:'html', text: '