latexdiff でコマンドを保護または mbox 化するにはどうすればよいですか?

latexdiff でコマンドを保護または mbox 化するにはどうすればよいですか?

latexdiffでは、引用コマンドが で保護され、デフォルトのスタイルで適切に印刷されるようになっています。やなどの\mboxで保護される他のコマンドを追加するにはどうすればよいでしょうか。\mbox\SI{}{}\cref{}

new.tex

% arara: pdflatexmk
\documentclass{article}
\usepackage{siunitx}
\begin{document}
This is the new text \SI{300}{\meter\per\second}
\end{document}

old.tex

% arara: pdflatexmk
\documentclass{article}
\usepackage{siunitx}
\begin{document}
This is the old text \SI{600}{\meter\per\second}
\end{document}

出力latexdiff --append-safecmd="SI"(コンパイルは失敗しますが、コマンド\mboxの前後にを追加するとsiunitx成功します):

% arara: pdflatexmk
%DIF LATEXDIFF DIFFERENCE FILE
%DIF DEL test_old.tex   Sun Dec 21 11:40:33 2014
%DIF ADD test.tex       Sun Dec 21 11:40:38 2014
\documentclass{article}
\usepackage{siunitx}
%DIF PREAMBLE EXTENSION ADDED BY LATEXDIFF
%DIF UNDERLINE PREAMBLE %DIF PREAMBLE
\RequirePackage[normalem]{ulem} %DIF PREAMBLE
\RequirePackage{color}\definecolor{RED}{rgb}{1,0,0}\definecolor{BLUE}{rgb}{0,0,1} %DIF PREAMBLE
\providecommand{\DIFadd}[1]{{\protect\color{blue}\uwave{#1}}} %DIF PREAMBLE
\providecommand{\DIFdel}[1]{{\protect\color{red}\sout{#1}}}                      %DIF PREAMBLE
%DIF SAFE PREAMBLE %DIF PREAMBLE
\providecommand{\DIFaddbegin}{} %DIF PREAMBLE
\providecommand{\DIFaddend}{} %DIF PREAMBLE
\providecommand{\DIFdelbegin}{} %DIF PREAMBLE
\providecommand{\DIFdelend}{} %DIF PREAMBLE
%DIF FLOATSAFE PREAMBLE %DIF PREAMBLE
\providecommand{\DIFaddFL}[1]{\DIFadd{#1}} %DIF PREAMBLE
\providecommand{\DIFdelFL}[1]{\DIFdel{#1}} %DIF PREAMBLE
\providecommand{\DIFaddbeginFL}{} %DIF PREAMBLE
\providecommand{\DIFaddendFL}{} %DIF PREAMBLE
\providecommand{\DIFdelbeginFL}{} %DIF PREAMBLE
\providecommand{\DIFdelendFL}{} %DIF PREAMBLE
%DIF END PREAMBLE EXTENSION ADDED BY LATEXDIFF

\begin{document}
This is the \DIFdelbegin \DIFdel{old text \SI{600}{\meter\per\second}
 }\DIFdelend \DIFaddbegin \DIFadd{new text \SI{300}{\meter\per\second}
 }\DIFaddend\end{document}

答え1

以下のオプションで定義されている場合、他のコマンドは引用コマンドと同等に扱われます。

--append-mboxsafecmd="cmd1,cmd2,..."

(latexdiff バージョン 1.1.0 以上が必要です)。siunitx パッケージが検出されると、これは自動的に実行されます\SI

答え2

これを行う簡単な方法はありません。引用コマンドは現在 (1.0.4) ハードコードされています。このリストに \cref を含めるには、latexdiff のソース コードを変更する必要があります。コード内で次の行を探します。

if ( defined $packages{"apacite"}  ) {
  print STDERR "DEBUG apacite citation commands\n"  if $debug;
  $citpatsafe=qr/^(?:mask)?(?:full|short)?cite(?:A|author|year)?(?:NP)?$/;
  $citpat='(?:mask)?(?:full|short|no)?cite(?:A|author|year|meta)?(?:NP)?';
} else {
  # citation command pattern for all other citation schemes
  $citpatsafe=qr/^cite.*$/;
  $citpat='(?:cite\w*|nocite)';
};

そしてelse節の行を次のように変更します。

  $citpatsafe=qr/^(?:cite.*|cref)$/;
  $citpat='(?:cite\w*|nocite|cref)';

(テストされていませんが、動作するはずです)。\SI の場合、アルゴリズムでは 'citation' コマンドにオプションではない引数が 1 つだけあると想定されているため、これは動作しません。

引用コマンドの問題は、ulem パッケージとの非互換性から生じており、おそらく siunitx でも同じことが当てはまります。回避策としては、別のマークアップ スタイル (例: CFONT、オプション -t CFONT) を試してから、\SI、\cref を安全なコマンドとして定義することをお勧めします。

非常に汚い回避策として、次のワンライナーを使用して、latexdiff 出力を後処理してから、latex/pdflatex に渡して \SI コマンドを保護します。

perl -pne 's/\\SI\{(.*?)}{(.*?)\}/\\mbox{\\SI{$1}{$2}}/g' file-diff.tex > file-diff-mod.tex

\SI のすべてのインスタンスは、追加または削除されたブロックの外側も含めて \mbox コマンドで囲まれることに注意してください。また、\SI コマンドの引数がネストされている場合、つまり中括弧が含まれている場合、または SI の引数の間にスペースや改行がある場合は、エラーが発生します。

答え3

LaTeX側でハックのようなものを使ってこれを解決することができます

\makeatletter
\AtBeginDocument{
  \let\UL@SI\SI
  \renewcommand\SI[3][]{\mbox{\UL@SI[#1]{#2}{#3}}}
}
\makeatother

これはほとんどの「単純な」ケースで機能します。

関連情報