余白の書きなぐり

aueweのブログ

quickrunで部分コンパイル (LaTeXが捗る)

Vim Advent Calendar 2013 の24日目の記事です。 昨日は @thincaさんの submode.vim で特定の条件の時だけ submode に入るでした。

さて今日は、昨日担当者のthincaさん作の quickrun というVimプラグインの、 hook/eval/template という機能を紹介します。 この機能はLaTeXで数式や表を作成する際に大変役立つのですが、 あまり使われてない様子なので布教します。

一部だけコンパイルしたい

LaTeXを書くときに間違えやすい箇所といえば、数式(あるいは表)です。 そこで何度も 「書く→コンパイル→書く→コンパイル→修正→コンパイル...」 という作業を繰り返すわけですが、 文章全体をコンパイルするのは不毛 じゃないですか? 具体的には以下の様な点でアホだと思います。

  • 今書いてる数式のpdfを見たい。他の箇所はいらない(邪魔)
  • 特にpdfが複数ページだと、編集箇所を見つけるのが大変面倒
  • コンパイルに時間がかかる
  • pdfのサイズも増える

そこで部分コンパイルの出番です。

具体的にやりたいこと

  • visual-mode で選択した箇所をコンパイル
  • normal-mode で align 環境にいる場合、その数式部分だけコンパイル

とりあえず以上を目標にします。 align環境だけでなく、tabular環境等に拡張するのは容易です。

quickrunのtemplate機能を使う

quickrunの使い方は去年のVACの記事 quickrun.vim について語る にまとまっているので、既知とします。

さてquickrunにtemplateという機能があることを冒頭で述べましたが、 簡単に説明すると 「予めテンプレートを作成しておき、その中の %s を元のソースファイルに置き変える」 という機能です 詳細はhelpの quickrun-module-hook/eval という項目に載っています。 今回のテンプレートとしては

プリアンブル
\begin{document}
%s
\end{document}

みたいなのを作っておけばよさそうです。

このtemplate機能、イイ線いってるものの、実現したい内容とは少し違います。 テンプレート内の %s が元のソースファイルの一部に置き変わって欲しいのであって、全体が置き換わっては意味がありません。

そこで使うのが quickrunの 実行モード という機能です。 要するに visual-mode から mode -v でquickrunを起動すると、 選択領域が一時ファイルに書きだされた後、実行されます。 詳細はhelpの

  • quickrun-option-mode
  • quickrun-option-tempfile

を参照してください。

実装

現在の僕の .vim/ftplugin/tex.vim は以下の様な感じです。

visual-modeでLaTeXファイルの一部を選択し、 <Space>sすれば、そこだけコンパイルされた tmptex.pdf が生成されます。 またalign環境内で <Space>sすれば、その環境内の数式が入った tmptex.pdf が生成されます。

let g:quickrun_config.tmptex = {
\   'exec': [
\           'mv %s %a/tmptex.latex',
\           'platex -output-directory=%a %a/tmptex.latex',
\           'dvipdfmx -o %a/tmptex.pdf %a/tmptex.dvi',
\           ],
\
\   'outputter' : 'quickfix',
\                 
\   'hook/eval/enable'   : 1,
\   'hook/eval/cd'       : "%s:r",
\
\   'hook/eval/template' : '\documentclass{jarticle}'
\                         .'\usepackage{amsthm,amssymb,amsmath}'
\                         .'\begin{document}'
\                         .'%s'
\                         .'\end{document}', 
\
\   'hook/sweep/files'   : [ 
\                          '%a/tmptex.latex',
\                          '%a/tmptex.log',
\                          '%a/tmptex.aux',
\                          '%a/tmptex.dvi'
\                          ],
\}

vnoremap <silent><buffer> <Space>s  <ESC>:<C-u>
\let @x = expand("%:p:h:gs?\\\\?/?")<CR>
\gv:<C-u>quickrun -mode v -type tmptex -args @x<CR>

nnoremap <silent><buffer> <Space>s  :<C-u>
\let @x = expand("%:p:h:gs?\\\\?/?")<CR>
\mx
\?begin.*align<CR>V
\/end.*align<CR>
\:<C-u>quickrun -mode v -type tmptex -args @x<CR>
\`x

なんかごちゃごちゃしていますが、 まず let g:quickrun_config.tmptex の部分から見ていきます。

execの部分は、 要するに tmptex.pdf を得るための手続きが書かれています。 quickrunを呼び出す際に、LaTeXファイルの存在するパスを %a の引数として受け取ります。 %sは一時ファイル (visual-modeで選択した文字列が入っている) の名前です。

hook/eval/templateは、各自が最強のプリアンブルを容易する場所です。 hook/sweepは、コンパイル時の副産物を自動消去する設定です。

次に vnoremap の部分を見ます。 let @x = expand("%:p:h:gs?\\\\?/?") の部分は、LaTeXファイルの存在するパスを 文字列として @x 変数に格納しています。 その後、quickrunを-mode v で呼び出して、-args @x で引数として前述したファイルパスを渡しています。

最後の nnoremap の部分については、 vnoremap する前に begin{align}end{align}の文字列を探してvisual選択してるだけなので割愛します。


vnoremapnnoremap周辺の設定がごちゃごちゃしています。 もっと簡潔に書きたいので、強い vimmer の天啓が下るよう祈ります。

他のマークアップ系言語でも、 template と mode -v のコンボは威力を発揮する気がします。