6

This question already has an answer here:

Why do these two MWEs produce different effects?

\documentclass{article}
\usepackage{etoolbox}
\makeatletter
\def\aeloaded{Not loaded}
\def\aechanged{Not changed}
\patchcmd{\l@section}
         {#1\nobreak\hfil}
         {#1\nobreak 
          \xleaders\hbox{$\m@th
            \mkern \@dotsep mu\hbox{--}\mkern \@dotsep
            mu$}
          \hfil}
         {\def\aechanged{Yes}}
         {\def\aechanged{No}}%
\def\aeloaded{LOADED}
\makeatother
\pagestyle{empty}
\begin{document}

\begin{tabular}{ll}
Did \verb=article.cls= load? & \aeloaded \\
Did \verb=\patchcmd=  work?   & \aechanged
\end{tabular}

\end{document}

which generates:

enter image description here

But,

\documentclass{article}
\usepackage{etoolbox}
\makeatletter
\def\aeloaded{Not loaded}
\def\aechanged{Not changed}
\@ifclassloaded{article}
  {\patchcmd{\l@section}
            {#1\nobreak\hfil}
            {#1\nobreak 
             \xleaders\hbox{$\m@th
               \mkern \@dotsep mu\hbox{--}\mkern \@dotsep
               mu$}
             \hfil}
            {\def\aechanged{Yes}}
            {\def\aechanged{No}}%
   \def\aeloaded{LOADED}
 }{\def\aeloaded{load FAILED}}
\makeatother
\pagestyle{empty}
\begin{document}

\begin{tabular}{ll}
Did \verb=article.cls= load? & \aeloaded \\
Did \verb=\patchcmd=  work?   & \aechanged
\end{tabular}

\end{document}

generates:

enter image description here

marked as duplicate by Werner, Guido, Heiko Oberdiek, Andrew Swann, Ulrich Schwarz Jun 19 '13 at 6:20

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • You can issue \tracingpatches in the preamble and etoolbox debugs the patching process to the log. Removing #1 from the input will work in this case, \nobreak\hfil only appears once in the definition of \l@section anyway. Using a conditional in \@ifclassloaded and then using that conditional for \patchcmd does work. – Qrrbrbirlbel Jun 19 '13 at 1:43
6

You can let etoolbox debug the patching process by issuing \tracingpatches in the preamble. The log will contain useful (?) information why the patching failed.

With your code the log will contain:

[debug] tracing \patchcmd on input line 18
[debug] analyzing '\l@section'
[debug] ++ control sequence is defined
[debug] ++ control sequence is a macro
[debug] -- nested patching command and parameters in patch
[debug] -> the patching command seems to be nested in the
[debug]    argument to some other command
[debug] -> the patch text seems to contain # characters
[debug] -> either avoid nesting or use # characters with
[debug]    category code 12 in the patch text
[debug] -> simply doubling the # characters will not work

(The macro \@ifclassloaded will simply issue \@firstoftwo or \@secondoftwo.)

If one would be using \catcode`\#=12 for the \patchcmd macro one would, of course, get:

[debug] -> the macro may have been defined under a category
[debug]    code regime different from the current one

Avoiding nesting seems easier (besides not using #1 at all).

Code

\documentclass{article}
\usepackage{etoolbox}
\makeatletter
\def\aeloaded{Not loaded}
\def\aechanged{Not changed}
\tracingpatches
\@ifclassloaded{article}{\def\aeloaded{LOADED}\@tempswatrue}
                        {\def\aeloaded{load FAILED}\@tempswafalse}
\if@tempswa
  \patchcmd{\l@section}
           {#1\nobreak\hfil}
           {#1\nobreak 
            \xleaders\hbox{$\m@th
               \mkern \@dotsep mu\hbox{--}\mkern \@dotsep
               mu$}
             \hfil}
            {\def\aechanged{Yes}}
            {\def\aechanged{No}}%
\fi
\makeatother
\pagestyle{empty}
\begin{document}
\begin{tabular}{ll}
Did \verb=article.cls= load? & \aeloaded \\
Did \verb=\patchcmd=  work?   & \aechanged
\end{tabular}
\end{document}

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