node.jsでmarkdownからHTMLを生成する

というより、このhtmlの作成方法について。

全体のソースコードはここを参照。

やりたいこと

ディレクトリ構成

以下の様なフォルダ構成にする。

./
├- template     //templateファイルの格納場所
├- md           //markdownファイルの格納場所
├- html         //htmlファイル出力先
app.js          //script本体

markdownファイルを取得する

fs.readdirで指定されたディレクトリ内のファイル一覧を取得できる。 fs.statでファイル情報を取得できるが、非同期処理を繰り返すとcallbackでコードが読みづらくなるため、今回は同期処理statSyncを使用する。

ディレクトリ内のファイルを更新日時の降順で列挙するサンプル

var fs = require("fs"),
    path = require("path"),
    util = require("util");

var md = { keys: [], files: {} };

//markdown directory
var md_dir = path.join(__dirname, "md");

fs.readdir(md_dir, function(err, files){
    files.forEach(function(file){
        var fp = path.join(md_dir, file),
            st = fs.statSync(fp);

        //更新日時 (同じ更新日時だとkeyが重複するので、名前も使用)
        var key = util.format("%d-%s", st.mtime.getTime(), file);
        md.keys.push(key);
        md.files[key] = {
            path: fp,
            mtime: st.mtime
        };
    }); //end forEach

    //更新日時の降順に並び替え
    md.keys = md.keys.sort().reverse();
    md.keys.forEach(function(key){
        console.log(md.files[key].path, md.files[key].mtime);
    });
});

markdown -> html変換

markedを使用すれば、簡単に変換可能

var marked = require("marked");
console.log(marked("`hoge` テスト"));
// -> <p><code>hoge</code> テスト</p>

コード部分のhighlight

highlight.jsを使用する。

markedで生成されるhtmlのコード部分をhighlight.jsで装飾されるように オプション設定を行う。

var marked = require("marked"),
    here = require("here").here;

marked.setOptions({
    highlight: function (code) {
        return require('highlight.js').highlightAuto(code).value;
    }
});

var md = here(/*
```js
var message = "hello, world!";
console.log(message);
```
*/).unindent();

console.log(marked(md));

※ here内のバッククォートは全角に変換しているが、実際は半角で入力すること。

<pre><code class="lang-js">var <span class="hljs-keyword">message</span> = <span class="hljs-string">"hello, world!"</span>;
console.log(<span class="hljs-keyword">message</span>);
</code></pre>

実際にブラウザでhtmlを表示する際にhighlight.jsでコード部分を装飾するには、 cssとjsを読み込む必要がある。

これらの読み込み処理はtemplate部分に記述しておく。

<link rel="stylesheet" href="http://yandex.st/highlightjs/8.0/styles/default.min.css">
<script src="http://yandex.st/highlightjs/8.0/highlight.min.js"></script>

templateにhtmlを埋め込む

ejsを使用する。

var here = require("here").here,
    ejs = require("ejs");

var tmpl = here(/*
<!doctype html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title><%= title %></title>
</head>
<body>
    <%- content %>
</body>
</html>
*/).unindent();

console.log(ejs.render(tmpl, { title: "test", content: "<p>Hello!!</p>" }));
<!doctype html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>test</title>
</head>
<body>
    <p>Hello!!</p>
</body>
</html>

これらを組み合わせて一連の処理とする

Qを使って、 それぞれを一連の処理として組み合わせる。