表を含むtexファイルをlatexdiffするときの注意点
前提
texファイルを編集しているとき,差分をチェックするためにlatexdiffを使用しているとする。
latexdiffについて注意すべき点は様々あるが,ここでは表があるときに遭遇する可能性が決して高くはない,しかしありえないわけでもない注意点の1つについて書きとめておく。
結果として,表の変更をlatexdiffで完璧にチェックするのは難しく,諦める場合が多くなりそうだという感覚がした。
latexdiffではtex文書の差分をチェックできるが,表のスタイル変更もチェックできるのかをここでは確認する。以下の表を具体例とする。
\begin{tabular}{|cc|} \hline
A & B \\ \hline
C & D \\ \hline
\end{tabular}
ここで,左右両端の縦罫線を削除することを考える。つまり,以下のような表に変更したいとする。
これを実現するため,以下のコードに修正する。
\begin{tabular}{cc} \hline
A & B \\ \hline
C & D \\ \hline
\end{tabular}
念のため述べておくと,1行目の|cc|
をcc
にしたのみである。
これに対し,latexdiffで差分texファイルを出力する。
\DIFdelbegin %DIFDELCMD < \begin{tabular}{|cc|} %%%
\DIFdelend \DIFaddbegin \begin{tabular}{cc} \DIFaddend \hline
A & B \\ \hline
C & D \\ \hline
\end{tabular}
以下,これを例にlatexdiffについていくつか簡単に述べる。
latexdiffの概要
latexdiffはプリアンブルに独自コマンドを追加し,それを用いて
- 追加部分:
\DIFaddbegin...\DIFadd{...}...\DIFaddend
- 削除部分:
\DIFdelbegin...\DIFdel{...}...\DIFdelend
とマークアップする。
前掲の表を見返すと,最初の2行が差分のマークアップに該当する。
ただし\DIFadd{...}
や\DIFdel{...}
はないことがわかる。
\DIFaddbegin...\DIFadd{...}...\DIFaddend
型のマークアップは本文やセーフコマンド[1]に対して適用されるもので,\begin{tabular}{...}
はセーフでないコマンドのためこうなっている。
マークアップされた箇所はデフォルトでは,
- 追加部分:波下線+青字
- 削除部分:打ち消し線+赤字
と表示される。
この2種類だけではなく,他にもフロート用のコマンドなどもあるが詳細は省く。
latexdiffのオプション
いくつかのオプションでコマンドの定義を調整できる。
ここではマークアップに関連する2種類についてみる。
日本語文書では,線を使用するマークアップは改行で問題が生じるとウェブ上でもよく報告されている。
対策としてシンプルなのは,-t CFONT
とすることである。
ここで-t ...
はメジャータイプと呼ばれるもののオプションを指定し,\DIFadd{...}
などを調整する。
-t CFONT
とすることで,マークアップされた箇所は
- 追加部分(
\DIFadd{...}
):青字+サンセリフ体 - 削除部分(
\DIFdel{...}
):赤字+\scriptsize
となるように定義される。
同様に-s COLOR
などとするケースも見かけるだろう。
ここで-s ...
はサブタイプと呼ばれるもののオプションを指定し,\DIFaddbegin
\DIFaddend
などを調整する。
デフォルトでは-s SAFE
で,これは\DIFaddbegin
\DIFaddend
などの定義を空にしており,スタイルはあくまでメジャータイプで設定しているという前提のようである。
-s COLOR
とすることで,マークアップされた箇所は
- 追加部分の開始(
\DIFaddbegin
):青色に - 追加部分の終了(
\DIFaddend
):黒色に
となるように定義される[2]。
問題と原因
ここで最初の状態にあるtexファイルを(ファイル名はmain.tex)に対して,先ほどみた-t CFONT
と-s COLOR
を使用してlatexdiffする。
これは,日本語文書(例として扱っている表にはアルファベットしかないが)を書いていれば使用される可能性が高い。
texファイルをgitで管理しているとして,縦罫線がある最初の状態でコミットし,そのあと縦罫線を削除して保存したうえで
latexdiff-vc -e utf8 -t CFONT -s COLOR --git --force -r HEAD main.tex
とすることで,差分のtexファイルを得られる。再掲する。
\DIFdelbegin %DIFDELCMD < \begin{tabular}{|cc|} %%%
\DIFdelend \DIFaddbegin \begin{tabular}{cc} \DIFaddend \hline
A & B \\ \hline
C & D \\ \hline
\end{tabular}
このtexファイルはコンパイルができない。
原因は,2行目の\hline
は表の行頭に配置されなければならないのに[3],latexdiffしたことによってその前にコマンド\DIFaddend
が入ってしまったことである。
ためしに,プリアンブルの\DIFaddend
の定義を手で空にしてみるとコンパイルできることがわかる。
-t CFONT
は\DIFadd{...}
などを調整するので,いまは関係がない。
-s COLOR
は\DIFaddbegin
\DIFaddend
などを調整するので関係する。
したがって,サブタイプの設定に関連する事項を変えればよい。
解決策
もとの目的は表のスタイル変更をlatexdiffでチェックできるか,ということだった。
差分のtexファイルをコンパイルできるようにはなったとして,この目的が達成されるかどうかは別だが,ひとまずはコンパイルできないことに対する解決策を思いつくままに列挙する。
-
-s
はデフォルトのままにする - 表の中身に
\hline
のような見た目に関するコマンドが入らないよう,tabularrayパッケージを使うなどする - 表をPICTUREENVに加える
- 表をFLAOTENVに加える
1と2は,コンパイルできても変更後のtexファイルのコンパイル結果と同じになり,表に変更があったかどうかはわからない。
3と4について,より詳しく説明する。
PICTUREENVに追加する方法
latexdiffは,PICTUREENVで指定された環境内にはマークアップをしないようにする。
デフォルトでは,正規表現を用いて(?:picture|DIFnomarkup)[\w\d*@]*
と設定されている。
ここにtabular環境がマッチするようにすればよいので,
--config="PICTUREENV=(?:picture|DIFnomarkup|tabular)[\w\d*@]*"
などをlatexdiffコマンドに加える。
差分texファイルとそのコンパイル結果は次の通りである。
\DIFdelbegin %DIFDELCMD < \begin{tabular}{|cc|} \hline
%DIFDELCMD < A & B \\ \hline
%DIFDELCMD < C & D \\ \hline
%DIFDELCMD < \end{tabular}
%DIFDELCMD < %%%
\DIFdelend \DIFaddbegin \begin{tabular}{cc} \hline
A & B \\ \hline
C & D \\ \hline
\end{tabular}
\DIFaddend
PICTUREENVに追加されたことによって,変更前の表全体が削除部分として,変更後の表全体が追加部分として扱われ,コンパイル結果では青くなっている。
問題点としては,PICTUREENVであるがゆえに,たとえば表内の文字修正など細かい部分がマークアップされなくなることがある。
FLOATENVに追加する方法
latexdiffは,FLOATENVで指定された環境をフロートと認識して,\DIFadd{...}
などとは別のコマンドでマークアップする。
デフォルトでは,正規表現を用いて(?:figure|table|plate)[\w\d*@]*
と設定されている。
ここにtabular環境がマッチするようにすればよいので,
--config="FLOATENV= (?:figure|table|plate|tabular)[\w\d*@]*"
などをlatexdiffコマンドに加える。
差分texファイルとそのコンパイル結果は次の通りである。
\DIFdelbegin %DIFDELCMD < \begin{tabular}{|cc|} %%%
\DIFdelendFL \DIFaddbeginFL \begin{tabular}{cc} \DIFaddendFL \hline
A & B \\ \hline
C & D \\ \hline
\end{tabular}
\DIFaddbeginFL
などがフロート用のコマンドである。
その定義は空で,\hline
の直前にある\DIFaddendFL
も同様である。
よってコンパイル可能となるが,よく見ると1行目から2行目にかけて\DIFdelbegin...\DIFdelendFL...
となっている。
したがって,\DIFdelbegin
の効果で表全体が赤くなっている(素朴に考えればフロート用コマンドで\DIFdelbeginFL
となるように思われるが,なぜこのような仕様なのかはよくわからなかった)。
問題点としては,表内のマークアップじたいは残っているため,もしフロート用コマンドに何か設定するようにしてしまった場合などはコンパイルできないことである。
なお,ここまであえて触れなかったが,実は表全体をtable環境内に置いてもコンパイル可能になる。
むしろ表をtable環境を用いて文書中に配置する場合が多いと思われるが,tabular環境単独で用いたい場合も決してなくはない。
また,table環境内に置いてコンパイルすると,結果は解決策1,2と同様に表に変更があったかどうかはわからない。
まとめ
ここで扱った表はきわめてシンプルなものだが,実際に書かれるのはより複雑な表だろう。
表の形やスタイルもこみいるし,セル内には数式や各種パッケージで定義されたコマンドに自作コマンドなどが入ってくることもある。
そのように考えると変更があった表を完璧にlatexdiffするのは非常に難しく,もっとも汎用的という意味でマシな解決策は,表内のマークアップは諦めPICTUREENVに追加する方法と思われる[4]。
-
セーフコマンドについては,マニュアルか https://abenori.blogspot.com/2016/06/latexdiff.html などを参照。 ↩︎
-
マニュアルには,
-s COLOR
とした場合について"An alternative way of marking added passages in blue, and deleted ones in red. (It is recommeneded to use instead the main types to effect col- ored markup, although in some cases coloring with dvipscol can be more complete, for example with citation commands)."とある。 ↩︎ -
https://ja.overleaf.com/learn/latex/Errors/Misplaced_\noalign などを参照。より細かくいうと,
\hline
の定義は\noalign{...}
で,この\noalign{...}
が行頭にないといけない。 ↩︎ -
latexdiffのこちらのissueでも表に対する様々な取り組みが見られると同時に,開発者がPICTUREENVにtabularを追加する方法を(明確に満足いくものではないと留保したうえで)提案している。 https://github.com/ftilmann/latexdiff/issues/5 ↩︎
Discussion