マークダウンから html に変換コンバーターを bash で書いた。

pandocとか使えば良いやんって話だけど、自家製で作りたいお年頃ですよね。

とは言っても、既存のものをガッツリ使用するのでサクッと作れてしまった。

require

  1. マークダウンのスタイルを整えてくれるやつ
  2. マークダウンを HTML にしてくれるやつ
  3. コードにハイライト入れてくれるやつ

を使います。

マークダウンを HTML にしてくれるやつ のインストール

npm install -g marked

ファイル構成

.
├── footer.html
├── header.html
├── hoge.md
├── parse.sh
└── style.css

hoge.md

今回のターゲット

footer.html

<!-- highlight.js パーサー-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
</body>

</html>

header.html

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <!-- markdown 全体 css -->
    <link href="https://rawgithub.com/jasonm23/markdown-css-themes/gh-pages/markdown7.css" rel="stylesheet">
    </link>
    <!-- markdown highlight.js css-->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/styles/vs.min.css">
    <!-- 調整用 css -->
    <link rel="stylesheet" type="text/css" href="style.css">
</head>

<body>

style.css

.hljs {
  background: none;
}

.code-title {
  display: inline-block;
  padding: 2px 4px;
  color: #333;
  transform: translateY(-0.5em);
  padding-bottom: 0;
  font-weight: bold;
  background-color: #999;
}

メインコード

headerfooterはテンプレートで使用し、マークダウンを HTML に変換した結果をサンドイッチする形をとります。

parse.sh

#!/bin/bash -eu
# @(#) セルフパーサー

if [ ${1##*.} != "md" ] || [ ! -f $1 ]; then
    echo [error] $1 is not markdown or valid file
    exit 0
fi

tmpfile=$(mktemp)

cat $1 |
    marked |
    sed 's/<code class="language-\([^:]*:\)\([^"]*\)">/<div class="code-title">\2<\/div><code class="language-\1\2">/g' >${tmpfile}

cat header.html ${tmpfile} footer.html >${1%.*}.html

rm ${tmpfile}

  1. とりあえず申し訳程度に入力形式をmdに絞って、ファイルの存在を確かめてあげてから
  2. 一時ファイルにマークダウンを HTML に変換した結果を格納
  3. あとはテンプレートでサンドイッチ

としました。

間に使っている sed 処理は、マークダウンのコード部分にタイトルを挿入するためのやつです

blog top page

正直これをしたいがためにマークダウン コンバーターを作りました。

ただ CSS をいじれば良いだけなのに無駄に労力を使った感じです。

動作検証

これが

hoge.md

# H1
## H2

\`\`\`python:main.py
import numpy as np

arr = np.array([1, 2, 3])
\`\`\`

> 参照
sh parse.sh hoge.md

hoge.html

こうなって

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <!-- markdown 全体 css -->
    <link href="https://rawgithub.com/jasonm23/markdown-css-themes/gh-pages/markdown7.css" rel="stylesheet">
    </link>
    <!-- markdown highlight.js css-->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/styles/vs.min.css">
    <!-- 調整用 css -->
    <link rel="stylesheet" type="text/css" href="style.css">
</head>

<body><h1 id="h1">H1</h1>
<h2 id="h2">H2</h2>
<pre><div class="code-title">main.py</div><code class="language-python:main.py">import numpy as np

arr = np.array([1, 2, 3])</code></pre>
<blockquote>
<p>参照</p>
</blockquote>

<!-- highlight.js パーサー-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
</body>

</html>

blowser

こうなります blog top page

やりたかったコードのタイトル部分もうまくできていて良きです。

まとめ

Github でドキュメント作るときに変なプラグインを入れずに作れるので良さそう