1

Consider the following two simple .tex files:

test_old.tex:

\documentclass{article}
\usepackage{amsmath}

\begin{document}

$a \begin{pmatrix}a & b\end{pmatrix}$

\end{document}

and test_new.tex:

\documentclass{article}
\usepackage{amsmath}

\begin{document}

$a_2 \begin{pmatrix}a & b\end{pmatrix}$

\end{document}

Using latexdiff to highlight the differences between these two documents (using latexdiff 1.2.0 on windows 10) generates the following diff.tex file:

\documentclass{article}
%DIF LATEXDIFF DIFFERENCE FILE
%DIF DEL .\test_old.tex   Tue Mar 21 15:42:30 2017
%DIF ADD .\test_new.tex   Tue Mar 21 15:42:31 2017
\usepackage{amsmath}
%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}

%DIF <  $\mathcal C\begin{pmatrix}a & b\end{pmatrix}$
\DIFdelbegin \DIFdel{$a \begin{pmatrix}a & b\end{pmatrix}$
}\DIFdelend %DIF >  $\mathcal C_2 \begin{pmatrix}a & b\end{pmatrix}$
\DIFaddbegin \DIFadd{$a_2 \begin{pmatrix}a & b\end{pmatrix}$
}\DIFaddend 

\end{document}

Compiling this file results in the following errors:

...\diff.tex:30: Forbidden control sequence found while scanning use of \UL@word. [}]
...\diff.tex:30: Paragraph ended before \UL@word was complete. [}]
...\diff.tex:34: Missing } inserted. [\end{document}]

What causes this? And how can I prevent it?

13
  • @campa I agree, but was afraid of removing something useful. And it appears I already did removing hyperref. Thanks for pointing out, I'll edit
    – glS
    Mar 20 '17 at 12:41
  • @campa adding back hyperref seems to only remove the very first error. I also tried to remove some parts of the code that seemed more unlikely to be causing issues. Most of the code is from the preamble added by latexdiff now, and I'm not sure what can I remove of that
    – glS
    Mar 20 '17 at 12:50
  • 1
    There are several different errors. The first one (after the edit) is due to calling \st in math mode; then \DIFdel is used wrongly e.g. in the last equation, where it encloses \begin{gathered}; and at some point ulem fails too, though I haven't found out yet exactly where. As for not being sure about what can be removed: if the error still shows up, then the removed line wasn't responsible :-)
    – campa
    Mar 20 '17 at 12:58
  • 1
    Using soul (\st) and \uwave for this type of automatic marking is asking for trouble. Beside this the nesting is wrong for the gathered environment. Mar 20 '17 at 13:02
  • @campa latexdiff usually works decently enough (in my experience at least), so I'm wondering why all these errors now. In the case of the gathered I guess the nesting error is not fixable simply redefining the macro is it? That would require fixing the latexdiff script itself.
    – glS
    Mar 20 '17 at 13:06
2

The reason this fails is because the ulem underlining commands break, if the inline-math expression has an array environment. This can be made to work by encapsulating the math expression using \mbox{$...$} (this would have to be done either in both old and new file, or in the resulting diff). As this is a known weakness of ulem latexdiff contained code to add the \mbox to its output where needed.

However, there was a pattern matching bug in latexdiff preventing this from working properly. At the time of writing this bug is fixed in the development version on github but not yet included in a release (it will be included from 1.2.1 onwards). If you do not want to clone the github version, you can apply these two patches by hand:

    $begin2=pos($delblock) - $len2;
    $mathblock="%\n\\mbox{$AUXCMD\n$1\n}$AUXCMD\n";
-   next unless $mathblock =~ m/\{$ARRENV\}/ ;
+   next unless ( $mathblock =~ /ARRAYBLOCK/ or $mathblock =~m/\{$ARRENV\};
    substr($delblock,$begin2,$len2)=$mathblock;
    pos($delblock) = $begin2 + length($mathblock);

and

@@ -2608,7 +2615,7 @@ sub postprocess {
    $len2=length($&);
    $begin2=pos($addblock) - $len2;
    $mathblock="%\n\\mbox{$AUXCMD\n$1\n}$AUXCMD\n";
-   next unless $mathblock =~ m/\{$ARRENV\}/ ;
+   next unless ( $mathblock =~ /ARRAYBLOCK/ or $mathblock =~ m/\{$ARRENV\}/) ;
    substr($addblock,$begin2,$len2)=$mathblock;
    pos($addblock) = $begin2 + length($mathblock);
   }
2
  • thanks for the answer. Which expression do you mean we should wrap? The one in old version, in the new one, or in the diff?
    – glS
    Mar 22 '17 at 17:16
  • I have edited the question to clarify. Actually if it is identical in old and new file, there should be no problem
    – frederik
    Mar 23 '17 at 8:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.