如何在 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"添加成功):\mboxsiunitx

% 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) 是硬編碼的。您必須修改 Latexdiff 的原始程式碼才能在此清單中包含 \cref 。在程式碼中尋找以下行:

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,這不起作用,因為演算法期望「引用」命令恰好有一個非可選參數。

引用命令的問題是由於與 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

請注意,這將使用 \mbox 命令包圍 \SI 的所有實例,包括那些新增或刪除的區塊之外的實例。另外,如果任何 \SI 指令的參數是巢狀的,即包含大括號,或 SI 參數之間有空格或換行符,這將導致錯誤

答案3

你可以在 LaTeX 端透過一些 hack 來解決這個問題

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

這適用於大多數“簡單”情況。

相關內容