md2html 3.65 KB
#!/usr/bin/env node

// Imports
var fs = require('fs');
var marked = require('marked');
var highlight = require('highlight.js');
var katex = require('katex');
var yargs = require('yargs');
var extend = require('util')._extend;


// Constants
var template = '<!DOCTYPE html> <html lang="fr"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta charset="UTF-8"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.11.0/styles/xcode.min.css" integrity="sha256-OED7Gmqde0cMVVeo1zVd+3fBD4EST32D4h9YT7KY0aY=" crossorigin="anonymous" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.7.1/katex.min.css" integrity="sha384-wITovz90syo1dJWVh32uuETPVEtGigN07tkttEqPv+uR2SE/mbQcG7ATL28aI9H0" crossorigin="anonymous"> <style type="text/css"> image { max-width: 100 % } </style> <title>%TITLE%</title> </head> <body> <main class="page-content" aria-label="Content"> %BODY% </main> </body> </html>'


// Understanding
var argv = yargs
    .usage("Usage: $0 [options]")
    .example('$0 -i doc.md -o doc.html', 'Convert doc.md to HTML using the default template')
    .help('h')
    .alias('h', 'help')

    .describe('i', 'Input file')
    .alias('i', 'input')
    .default('i', '/dev/stdin')

    .describe('o', 'Output file')
    .alias('o', 'output')
    .default('o', '/dev/stdout')

    .describe('t', 'Template file (%BODY% is replaced by the text)')
    .alias('t', 'template')

    .argv;

if (argv.t) {
    template = fs.readFileSync(argv.t, "utf8");
}


// Settings

var extraLangages = {
    avrpseudo: function (hljs) {
        lang = extend({}, highlight.getLanguage('avrasm'));
        lang.keywords.keyword += 'Si Alors Sinon FinSi TantQue FinTantQue Pour FinPour allant de à ←';
        lang.keywords.keyword += 'Lire Sortir sur Appeler Retourner';
        lang.keywords.keyword += 'DecalerDroite DecalerGauche';
        lang.keywords.built_in += ' vrai faux';
        return lang;
    },
    avrasmplus: function (hljs) {
        lang = extend({}, highlight.getLanguage('avrasm'));
        lang.keywords.keyword += ' si saut alors et ou if then goto && || <-';
        lang.contains.push({
            className: 'meta',
            begin: /@\w+/,
        });
        return lang;
    },
};

for (lang in extraLangages) {
    // This must be done before any call to highlight.highlight :/
    highlight.registerLanguage(lang, extraLangages[lang]);
}

var renderer = new marked.Renderer();
marked.setOptions({
    highlight: function (code, lang) {
        if (highlight.getLanguage(lang)) {
            return highlight.highlight(lang, code).value;
        } else {
            // if (extraLangages[lang]) {
            //     highlight.registerLanguage(lang, extraLangages[lang]);
            //     return highlight.highlight(lang, code).value;
            // } else {
            // }
            console.warn("Unknown language: " + lang);
            return highlight.highlightAuto(code).value;
        }
    }
});


// Processing
markdownString = fs.readFileSync(argv.i, "utf8");

// TeX
markdownString = markdownString.replace(/\\\$/g, '&dollar;')
markdownString = markdownString.replace(/\$\$([\s\S]+)\$\$/gm, function(glob, formula) {
    return katex.renderToString(formula, {displayMode: true});
});
markdownString = markdownString.replace(/\$([^$]+)\$/g, function(glob, formula) {
    return katex.renderToString(formula, {displayMode: false});
});

// Conversion
htmlString = marked(markdownString, {renderer: renderer});
fullHtmlString = template.replace('%BODY%', htmlString);

// Saving
if (argv.o == '/dev/stdout') {
    console.log(fullHtmlString);
} else {
    fs.writeFileSync(argv.o, fullHtmlString);
}