読者です 読者をやめる 読者になる 読者になる

Markdown で書いた文書を LaTeX でリアルタイムでタイプセット(Pandoc と latexmk を利用)

TeX Vim

この記事は KainokiKaede Advent Calendar 2014 23日目の記事です(大嘘)

Markdown で原稿を書いて、リアルタイムで TeX ファイルに変換・タイプセット ということをやりたかった。

流れ

main.texhoge.md とを作る。 main.tex の中で hoge.tex をインクルードしておく。 hoge.md から Pandoc で hoge.tex を作る。すると latexmk が更新に反応して pdf を作ってくれる。みたいな流れを考えた。

なぜ Pandoc だけで pdf 作成までやらないかというと、テンプレートを書くのがめんどいというのが一つ。章ごとにわけてタイプセットしたいというのが一つ(md ファイルを分割する方法があるのかもしれないけれども調べていない)。

ファイル構造は次のような感じになる。

main.tex (内部で hoge.tex を input)
hoge.md (編集対象)
hoge.tex (自動的に生成される・編集しない)

コード

とりあえず超てけとーだけど、ファイルの更新をチェックして勝手に Pandoc を回すコードを組んだ。select というモジュールを使った。

import select
import argparse
import os

def watchfile(filename):
    outfilename = filename.split('.')[0]+'.tex'
    f = open(filename)
    # when monitoring a directory: f = os.open("foo", os.O_RDONLY)
    kq = select.kqueue()
    ke = select.kevent(f, filter=select.KQ_FILTER_VNODE,
        flags=select.KQ_EV_ADD | select.KQ_EV_ENABLE | select.KQ_EV_CLEAR,
        fflags=select.KQ_NOTE_DELETE | select.KQ_NOTE_WRITE)
    events = kq.control([ke], 0, None)
    while True:
        r_events = kq.control([ke], 1, None)
        for event in r_events:
            print event
            if event.fflags & select.KQ_NOTE_DELETE:
                print "file was deleted!"
            if event.fflags & select.KQ_NOTE_WRITE:
                os.system('pandoc -i {0} -o {1}'.format(filename, outfilename))
                print "file was updated!"
    f.close()


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('filename')
    args = parser.parse_args()

    watchfile(args.filename)
$ python automd2tex.py hoge.md

で、自動的に更新があったら Pandoc を動かして tex にするようにした。 つまり1窓でこれを、もう1窓で latexmk を動かせば md を更新すると pdf が自動生成される。 bashrc のエイリアスを使って、 md2tex hoge.md で同じ効果が得られるようにした。

でもなんつうか、これ auto じゃなくてもよくね。どうせ md とか Vim でしか書かないんだから、quickrun 的な発想で

autocmd FileType markdown nnoremap gpa :<C-u>! pandoc -i "%:p” -o "%:p:r”.tex<CR>

こんなんでできないの?(できた) 一応これで md で tex を書けるようになったけどなんかめんどいですね。