为什么在使用 \@ifclassloaded 时 \patchcmd 不起作用?

为什么在使用 \@ifclassloaded 时 \patchcmd 不起作用?

为什么这两个MWE会产生不同的效果?

\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}

生成:

在此处输入图片描述

但,

\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}

生成:

在此处输入图片描述

答案1

您可以etoolbox通过发出前言来调试修补过程\tracingpatches。日志将包含修补失败原因的有用信息(?)。

使用您的代码,日志将包含:

[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

(该宏\@ifclassloaded将简单地发出\@firstoftwo\@secondoftwo。)

如果使用宏的话\catcode`\#=12\patchcmd当然会得到:

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

#1避免嵌套似乎更容易(除了根本不使用)。

代码

\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}

相关内容