ill-identified diary

5 million yen salary expected.

[pandoc] [LaTeX]はてなブログの執筆環境を考える

概要

  • markdown 記法は楽だがはてなブログTeX記法がTeXじゃない! 時間を掛けたくない!

  • LyX + pandoc なら楽. 一部問題があるが変換に成功.

これまで markdown 記法でブログを書いてきたのだが, このモードでは TeX の構文と相性が悪く, TeX といいつつ似て非なるコードを書くことを強いられ, 記事作成時間が増大する原因となっていた. これらの問題の詳細については以下2点参照.

特に後者で言及されている「markdown 記法では数式にアンパサンドを使えない」という致命的な問題は, markdown 記法を諦めるほか解決方法がない.

そこで, 数式を TeX で書く際に便利な LyX を利用しようということを思いついた. 結果としてmarkdown は諦めることになるが, 数式入力の手間が大幅に減るので時間短縮になるのではないかと思う. markdown だと 箇条書きやセクションタイトルをメタ文字1つで初められるのは大きいが, でもショートカットキーを使えば似たような速さになると思う. 何より, 複雑な数式を手早く書けるというのが利点 (逆に数式をあまり書かないなら, この方法は魅力的ではない) になる.

この方法を利用する場合, 一旦ブログの設定で, markdown 記法をはてな記法に変更しなければならない. どの記法を使うかは記事が個別に作成された時点で決まるので, これを変更したからといって過去の記事もはてな記法で書き直す必要はない (上記の記事参照). また, 記事作成画面の左上のタブでも記法を変更できるが, あくまでプレビューのみで実際に投稿した記事には適用されないので注意.

.tex から .html への変換

ドキュメントの .lyx は内部的には独自のマクロを使った .tex ファイルなので, .tex への変換も容易だ. そこで, で原稿を作成したら, .tex 形式で書き出す.

ただし, プリアンブルで設定したマクロが反映されない. ブログ記事に含まれるのは文章, 画像, 数式くらいだということと, もともとの の仕様を考えると, テキストエディタでの編集と違って自前のマクロ定義に頼る機会は少ないが.

そこで, .tex 形式で出力した原稿を, pandoc を使って実行する.

pandoc -s --mathjax -f latex -t html hogehoge.tex > output.html

これだけで, .tex.html へ変換される. ここで指定したタイプライタ体も, html 変換の際に <code>...</code> タグが補われる. -s --mathjaxスタンドアロンな文書ファイルを作成という意味で, html のヘッダに mathjax の読み込みスクリプトを追加する. ブログに書く上ではこの部分は必要ないのだが, これを指定しない場合, インライン数式が html タグで表現されてしまう. インライン数式も mathjax で統一したい場合, -s --mathjax を付けたほうが良い.

また, .tex の場合は --bibliography オプションで .bib ファイルを指定し, 参考文献も利用できる (pandoc-citeproc のインストールが必要).

加えて, このままではマクロが反映されない. マクロを反映する場合は, -f latex の後に +latex_macros という拡張オプションを追加する. マクロの展開のためか, 若干時間がかかるが, ブログに投稿する程度の文章量なら問題になるほどではなさそうだ.

pandoc -s --mathjax -f latex+latex_macros -t html --bibliography hogehoge.bib hogehoge.tex > output.html

これだけですぐにブラウザで見ることができるが, はてなブログで適切に表示するには, 多少の加工が必要になる.

html 出力の調整

実際に必要なのは <body>...</body> 部分なので, sed を使って抽出する. また, そのまま使うには, mathjax 環境を \[ ... \], \( ... \)はてな記法[tex: ... ]に直す必要がある. mathjax 本来の場合も一応表示はできるが, はてなキーワードと競合し, mathjax 数式に変換できない場合がある. はてなキーワードへの自動リンクは課金で無効化できるらしいが, 自分は吝嗇家なのであくまで無料でできる方法を試す. 最終的に, 以下のようなスクリプト texhatena.sh を作成した.

#! /bin/bash
if [ "$1" == "" ]
then
	echo please specify file name!
	exit
fi

if [ "$2" != "" ]
then
	bib="--bibliography $2"
else
	bib=""
fi

if [ "$3" != "" ]
then
	csl="--csl=$3"
else
	csl=""
fi
eval pandoc -s --mathjax -f latex+latex_macros -t html $bib $csl $1 |
sed -n -e '/<body>/, /<\/body>/p'| sed -r '/^(<body>)|(<\/body>)/d' |
sed -e 's/&amp;/\&/g' |
sed -e 's/&lt;/</g' | sed -e 's/&gt;/>/g' | 
perl  -pe 's;<span\s+class="math">\\\((.+?)\\\)</span>;<span  class="math">[tex: \1 ]</span>;ig' |
sed -r -e 's;<span class="math">\\\[;<span class="math">[tex:;' |
sed -r -e 's;\\\]</span>;]</span>;' |
sed -r -e 's/\\begin\{aligned\}/\\begin{align}/' |
sed -r -e 's/\\end\{aligned\}/\\end{align}/' |
perl -pe 's;<a.*?href="(.+?)".*?>.*?</a>;[\1:title];ig' > `dirname $1`/out_`basename $1`.html

2015/3/5 上記のコードは実際使ってみるといろいろと無理があるので, pandoc 活用の参考程度に考えてください. そのうち更新します

2015/3/15 インライン数式を[tex: ...]に変換するためにperl正規表現を追加. bibファイルに続きcslファイルを第3引数として使えるように修正. テキスト中のurlを全てタイトル付きのリンクにするはてな記法 ([http://....:title]) に変換するよう修正. また,数式付番のために aligned 環境を全て align に変換するように修正. ただし数式番号の相互参照がうまくいかない

これを使って, texhatena.sh foo.tex (hoge.bib) のようにすれば, out_foo.tex.html という名称で出力される. bib ファイルの指定は任意.

ただし, このままだと上記のプログム部分は単に <pre><code>...</code></pre> で囲われるだけなので, はてな記法シンタックスハイライトが適用されない. とりあえず今回は手動で調整した.

数式

\align 環境で必要なアンパサンドも出力できる. ただし, 上のスクリプトを見れば分かるように, html 出力用に & と出力される. [tex: ] 内ではこれは無効なので, 通常のアンパサンドに置換している. 以下, 数式の出力確認.

\begin{aligned}
\alpha\beta\gamma\theta\tau\eta= & \varDelta\varPhi\varOmega,\\
c= & \iint f(x,y)dxdy,\\
\mathbf{A}= & \begin{bmatrix}a & b\\
c & d
\end{bmatrix},\\
X= & \{a,\, b\, c\}\\
\boldsymbol{e}= & [e_{1}\, e_{2}\, e_{3}]^{\prime}\\
\left(\frac{1}{2}\right)^{-1}= & 2\\
\boldsymbol{b}_{\mathit{OLS}}= & \left[\mathbf{X}^{\prime}\mathbf{X}\right]^{-1}\mathbf{X}^{\prime}\boldsymbol{y}.\end{aligned}

しかし, ここで,  \boldsymbol{e} = ... \boldsymbol{b}_{\mathit{OLS}}= の式で, ブラケットで囲んだ行列がうまく表示されなかった. 数式でブラケット [ ... ] \left[ .... \right] を使う場合, 右側 ]\] とブラケットをエスケープしないとダメらしい. というわけでここだけ手動で直した. ブラケットを多用する場合はどうしたものか... なお, 変換後に align 環境が aligned という見慣れない環境に変換されるが, aligned は mathjax 独自の環境なので問題ない.

インラインの数式も表示される  \alpha,\,\beta,\,\gamma\,\cdots.

ただし, [tex: ... ] を使うと, 数式内のブラケット [ ] にもバックスラッシュのエスケープが必要になる. Haskell構文解析も知識がないのでこの変換の自動化はまだ未対応. こちらも手動で調整.

参考文献の引用

bib ファイルはテスト用に以下のようなものを用意した.

@book{test,
title={テスト本},
author={テスト太郎},
year={2010},
publisher={テスト出版}
}
@book{test2,
title={続・テスト本},
author={テスト太郎},
year={2010},
publisher={テスト出版}
}
@article{testarticle,
title={Paper on the Test},
author={Test, John},
year={2014},
journal={Journal of Test}
}

以下, \cite{} の引用テスト:

“近年の引用テストについては テスト太郎 (2010a), テスト太郎 (2010b) が詳しい. また, 最新の研究では Test (2014) が引用テストの最新の成果を示してくれている.”

これで 出力されたファイルに, 参照トークンと文末の参考文献リストが作成されていれば成功である. なお, 引用スタイルは --cls= オプションで csl ファイルを指定することで変更できるらしい.

参考文献


Pandoc - About Pandoc http://johnmacfarlane.net/pandoc/

sky_y 2015. 多様なフォーマットに対応!ドキュメント変換ツールPandocを知ろう http://qiita.com/sky_y/items/80bcd0f353ef5b8980ee#6-2

Fujiwara, Yuki 2014. Pandoc ユーザーズガイド 日本語版http://sky-y.github.io/site-pandoc-jp/users-guide/

Test, John. 2014. “Paper on the Test.” Journal of Test.

テスト太郎. 2010a. テスト本. テスト出版.

———. 2010b. 続・テスト本. テスト出版.