我正在尝试修补美国管理公司的宏,\AMCopenShow
使用命名etoolbox
。
但是,我收到一个错误,它给出了很多选项,但我不知道如何解决,或者甚至不知道是否可以解决。
[debug] tracing \patchcmd on input line 64
[debug] analyzing '\AMCopenShow'
[debug] ++ control sequence is defined
[debug] ++ control sequence is a macro
[debug] -- macro cannot be retokenized cleanly
[debug] -> the macro may have been defined under a category
[debug] code regime different from the current one
[debug] -> the replacement text may contain special control
[debug] sequence tokens formed with \csname...\endcsname;
[debug] -> the replacement text may contain carriage return,
[debug] newline, or similar characters
我怎样才能成功修补该命令?没有该软件的代码可以通过此示例重现:
\documentclass{article}
\usepackage{etoolbox}
% from automultiplechoice.sty
\makeatletter
\newcommand\AMCopenShow[4]{
\ifAMC@ensemble\def\AMCid@name{#3}\AMCid@quest=#4\fi%
\ifAMC@ensemble\ifAMCformulaire@dedans%
\AMC@amclog{AUTOQCM[Q=\the\AMCid@quest]^^J}%
\fi\fi%
{\setkeys{AMCOpen}{#1}%
\ifKV@AMCOpen@lineup%
\ifAMC@ensemble\else\par\fi%
\ifAMC@correc\smash{\AMCopen@answer}\fi\dotfill%
\else%
\hspace*{.5em}\linebreak[1]\hspace*{\fill}%
\fi%
{\AMCnoCompleteMulti%
\def\AMCbeginAnswer{}\def\AMCendAnswer{}%
\def\AMCanswer##1##2{\ifAMC@ensemble ##1\else%
\ifAMC@inside@box ##1\else{\AMCboxOutsideLetter{##1}{##2}}\fi\fi%
\hspace{\AMCopen@Hspace}}%
\fboxsep=\AMCopen@boxmargin%
\fboxrule=\AMCopen@boxframerule%
\fcolorbox{\AMCocol@BoxFrameRule}{\AMCocol@Background}{%
\ifAMC@ensemble\AMCopen@question%
\ifx\@empty\AMCopen@question\@empty\else\hspace{\AMCopen@Hspace}\fi%
\fi%
\begin{choicescustom}[o]%
\ifx\AMCocol@Foreground\@empty\@empty\else%
\def\AMC@boxcolor{\AMCocol@Foreground}%
\fi%
#2%
\ifKV@AMCOpen@scan\else\AMCdontScan\fi%
\ifKV@AMCOpen@annotate\else\AMCdontAnnotate\fi%
\end{choicescustom}%
\ifx\@empty\AMCotextReserved\@empty%
\hspace{-\AMCopen@Hspace}%
\else%
\ifx\AMCocol@Foreground\@empty\@empty%
\AMCotextReserved%
\else%
\textcolor{\AMCocol@Foreground}{\AMCotextReserved}%
\fi%
\fi%
}}%
\ifKV@AMCOpen@lineup\else%
\par\nobreak\noindent%
\hspace*{\fill}{%
\fboxrule=\AMCopen@framerule%
\fcolorbox{\AMCocol@FrameRule}{white}{%
\csname\AMCopen@contentcommand\endcsname
}}%
\vspace{7mm}\par%
\fi%
}%
\ifAMC@ensemble\ifAMCformulaire@dedans%
\AMC@amclog{AUTOQCM[FQ]^^J}%
\fi\fi%
}
\makeatother
\tracingpatches
\patchcmd{\AMCopenShow}{\vspace{-7mm}\par}{\vspace{0mm}\par}{}{\PackageWarning{this}{No patch}}
\begin{document}
\end{document}
更新
egreg 的 hack 帮助修补了宏。但遗憾的是它不起作用。修复宏可能破坏了包内定义的某些东西。
破坏补丁的问题示例:
\documentclass{article}
\usepackage[box,lang=ES]{automultiplechoice}
\usepackage{regexpatch}
\makeatletter
% get rid of the initial space
\begingroup
\toks0=\expandafter{\AMCopenShow{#1}{#2}{#3}{#4}}
\toks0=\expandafter\expandafter\expandafter{\expandafter\@gobble\the\toks0}
\edef\x{\endgroup
\noexpand\renewcommand\noexpand\AMCopenShow[4]{\the\toks0}
}\x
% do the real patch; \ddt is just a signal for raising an error if
% the patch doesn't succeed
\xpatchcmd{\AMCopenShow}{\vspace{7mm}\par}{\vspace{0mm}\par}{}{\ddt}
\makeatother
\begin{document}
\element{general}{
\begin{question}{Yaounde}
What is the capital city of Cameroon?
\AMCOpen{lineup=true,hspace=0.1mm,boxmargin=0.1ex}{\wrongchoice{$>$}\scoring{1}\correctchoice{$<$}\scoring{2}}
\end{question}
}
\element{general}{
\begin{question}{id2}
\begin{choicescustom}[o]
\wrongchoice[T]{}
\correctchoice[F]{}
\end{choicescustom}
This is a True or False question.
\end{question}
}
\onecopy{1}{
\insertgroup{general}
}
\end{document}
答案1
问题是您要修补的替换文本包含^^J
并且etoolbox
不喜欢这样的宏。
该regexpatch
软件包能够做到这一点,但它似乎拒绝修补编写错误的宏,例如\AMCopenShow
,它在开头有一个不受保护的行尾。*
因此,我们首先需要摆脱这个空间,这可以通过标准方法实现:
\begingroup
\toks0=\expandafter{\AMCopenShow{#1}{#2}{#3}{#4}}
\toks0=\expandafter\expandafter\expandafter{\expandafter\@gobble\the\toks0}
\edef\x{\endgroup
\noexpand\renewcommand\noexpand\AMCopenShow[4]{\the\toks0}
}\x
如果\vspace{7mm}
出现在替换文本的外括号级别,则可以用类似的方式进行修补。但是,regexpatch
现在可以修补宏。完整代码:
\documentclass{article}
\usepackage{automultiplechoice}
\usepackage{regexpatch}
\makeatletter
% get rid of the initial space
\begingroup
\toks0=\expandafter{\AMCopenShow{#1}{#2}{#3}{#4}}
\toks0=\expandafter\expandafter\expandafter{\expandafter\@gobble\the\toks0}
\edef\x{\endgroup
\noexpand\renewcommand\noexpand\AMCopenShow[4]{\the\toks0}
}\x
% do the real patch; \ddt is just a signal for raising an error if
% the patch doesn't succeed
\xpatchcmd{\AMCopenShow}{\vspace{7mm}\par}{\vspace{0mm}\par}{}{\ddt}
\makeatother
\begin{document}
\footnotesize\texttt{\meaning\AMCopenShow}
\end{document}
*说实话,这个问题会被解决