如何从 AMC 软件包中修补 AMCOpen

如何从 AMC 软件包中修补 AMCOpen

我正在尝试修补美国管理公司的宏,\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}

在此处输入图片描述

*说实话,这个问题会被解决

相关内容