2016年6月24日

latexdiff

latexdiffをたまに使っている.なんかいろいろ詰まったりすることも多い(だいたいdiff.texのコンパイルに失敗する)ので,少しマニュアルを読んでみたり,動かして試してみた.

何か?

LaTeXソースファイルの「diff」をとるPerlスクリプト.結果としてLaTeXソースファイルをはき出すので,それをコンパイルすると差分が見やすい形で表示される.例えばこんな感じ.

インストール

TeX Live,W32TeXには既に含まれている.ただし,W32TeXは別途Perlをインストールする必要がある.

使い方

古いファイルold.texと新しいファイルnew.texを比較したいならば,コマンドラインから

> latexdiff old.tex new.tex > diff.tex
とすることで,diff.texが生成される.これをLaTeXでコンパイルすれば,old.texとnew.texの差分を示すファイルが生成される.

diff.texには次が含まれる.

  • 差分表示に必要なマクロ.\DIFから始まるいくつかのマクロの定義がプリアンブルに挿入される.
  • 削除された部分は
    \DIFdelbegin \DIFdel{<削除された部分>}\DIFdelend
    となり,追加された部分は
    \DIFaddbegin \DIFadd{<追加された部分>}\DIFaddend
    となる.ただし,削除された部分や追加された部分にコマンドが含まれる場合,\DIFdel{}\DIFadd{}はそのコマンドが「セーフかどうか」で挙動を変更する.以下の「セーフコマンド」を参照.
  • 削除されたコメントの前には%DIF <が,追加されたコメントの後には%DIF >が挿入される.

なお既定では,\DIFdelは赤くなり打ち消し線がつき,\DIFaddは青くなり波下線がつく.\DIFdelbegin\DIFdelend\DIFaddbegin\DIFaddendは空になっている.

マクロ定義は-tオプションや-sオプションで変更できる.個人的には(今は)

> latexdiff -t CFONT -s COLOR old.tex new.tex > diff.tex
がよいような気がしている.(単に削除部分を赤く,追加部分を青くする設定.)*1

\input\includeを使っているファイルの差分をとりたい時には,--flattenオプションを指定するとよいかも.\input\includeの部分を,実際に読み込まれているファイルの中身に置き換えてくれるらしい.\includeonlyも考慮されるっぽい.

コンパイルエラー

出力されたLaTeXソースファイルであるが,コンパイルが通らないこともある.数式部分でコンパイルエラーが起こった場合,困ったときは--math-matkupで解決することがある.デフォルトは--math-markup=2であるが,この2の値を1,0と下げていくと,だんだん「おおらかに」処理するようになり*2,結果としてコンパイルの通るソースを生成してくれる可能性がある.ただし,--math-markup=0は削除された数式がコメントアウトされてしまうので,あまりお勧めしない.また--math-markup=3はより細かくみるモード*3

セーフコマンド

上述の通り,latexdiffは差分に対して\DIFadd{}/\DIFdel{}を挿入するが,複雑なマクロに対してこの挿入が行われると不都合なことがある.そのような場合は,これらのコマンドを「セーフでない」とする必要がある.セーフなコマンドには「セーフコマンド」と「テキストコマンド」の二種類がある.例えば\cmd{old}\cmd{new}と変化していたならば,

  • \cmdがセーフコマンドならば,
    \DIFdel{\cmd{old}}\DIFadd{\cmd{new}}
  • \cmdがテキストコマンドならば,
    \cmd{\DIFdel{old}\DIFadd{new}}
  • セーフでないならば
    %DIFDELCMD < \cmd{old}
    %DIFDELCMD < %%%
    \cmd{new}
    
と変化する*4.デフォルトでいくつか登録がされている他,\newcommandなどで定義された命令は「セーフコマンド」として登録される*5.--append-textcmdオプションを使って,
> latexdiff --append-textcmd="cmda,cmdb" old.tex new.tex > diff.tex
とすると,\cmda\cmdbがテキストコマンドとして登録される.逆に\cmdをセーフでないコマンドとするには,--exclude-safecmdコマンドを使い
> latexdiff --exclude-safecmd="cmd" old.tex new.tex > diff.tex
とする.現状のセーフコマンドやテキストコマンドは--show-safecmdオプションや--show-textcmdオプションをつけて実行することで確認できる*6

あとはcontext1cmdとかcontext2cmdとかあるみたい.基本的にはテキストコマンドのように振る舞うけど,コマンド自身の削除が行われた場合はセーフコマンドと同じような挙動になるようだ.1と2の違いはよくわからない…….

数式

数式部分に使われる環境に対していくつか指定が可能.もし問題が起こったらいじってみるといいかも?設定ファイルに書いて,-cオプションで読み込む*7

> latexdiff -c config old.tex new.tex > diff.tex
で設定ファイルconfigが読み込める.設定ファイルはVARNAME=variableという形で並べていけばいいみたい.次がある.

MATHENV
ディスプレイ数式を出す環境名を正規表現で指定する.デフォルトは(?:equation[*]?|displaymath)[*]?.
MATHARRENV
表組みなディスプレイ数式を表す環境名を正規表現で指定する.デフォルトは(?:eqnarray|align|alignat|gather|multline|flalign)[*]?
ARRENV
これに入れておくと\mboxで囲まれることがあるらしい(よくわからない).デフォルトは(?:array|[pbvBV]?matrix|smallmatrix|cases|split)

latexdiff-vc

バージョンコントロールシステムと使うことが想定されているやつ.gitと使う場合..

> latexdiff-vc --git -d diff -r HEAD~5 a.tex

これでHEAD~5のa.texと今のa.texが比較されて,diffフォルダに差分が吐き出される(-d diffオプションが指定されているので).HEAD~5はgitの記法なのでそちらを参照のこと.吐き出されるのはソースファイルなのでこれをコンパイルすればよい.latexdiffが受け付けるオプションも受け付けられる.次のように-r HEAD~5の前に入れるようだ.

> latexdiff-vc --git -d diff --append-textcmd="cmda,cmdb" -r HEAD~5 a.tex
*1
打ち消し線や波下線が着くスタイルでは,改行が抑制されてはみ出してしまったり,コンパイルに失敗したりすることがあるので,-t CFONTオプションにより,\DIFdel\DIFaddの定義を変更している.また-s COLORオプションにより\DIFdelbegin\DIFdelend\DIFaddbegin\DIFaddbeginを,色の変更を行うように変更している.-tや-sは他にも引数があり,それに応じて差分表示のスタイルが変わる.
*2
以下の「セーフコマンド」に対応させると,だいたい次のような感じ.--math-markup=2は数式をテキストコマンドとして,--math-markup=1はセーフコマンドとして,--math-markup=0はセーフでないコマンドとして扱う.
*3
従ってコンパイルエラーが発生した時にはむしろ事情を複雑にしそうだが,これでうまくいったこともある.
*4
実際には更に\DIFdelbegin等の挿入も行われる.
*5
\newcommand\cmd[1]{#1}のように定義しちゃうと除外される模様.きちんと\newcommand{\cmd}[1]{#1}と定義しよう.
*6
正規表現で得られる.
*7
以下には数式関連のみ書くが,他にもいくつか設定項目がある.

1 件のコメント:

  1. ちょうど latexdiff を使ってみようと思ってたらこの記事がヒットして助かりました.

    返信削除

コメントの追加にはサードパーティーCookieの許可が必要です