强制扩展命令参数中的计数器值

强制扩展命令参数中的计数器值

在下面的 MWE 中,我想在将它们传递给时\envnum扩展它们 ,但只有第一个被扩展。请注意和之间的不同输出\itemnum\cmdwithexpandedargs\wlog\printcmd之间的不同输出,这仍然让我很感兴趣。

\documentclass{letter}

\newcounter{nenv}
\newcommand\printcmd{}

\makeatletter
\newcommand\cmdwithexpandedargs[1]{%
    \g@addto@macro\printcmd{#1 - }
}
\makeatother

\newenvironment{test}{%
    \stepcounter{nenv}%
    \let\olditem\item
    \renewcommand\item{%
        \olditem
        \xdef\envnum{\arabic{nenv}}%
        \xdef\itemnum{\alph{enumi}}%
        \wlog{\envnum.\itemnum}
        \expandafter\cmdwithexpandedargs\expandafter{\envnum\itemnum}%
    }%
    \begin{enumerate}%
}{\end{enumerate}}

\begin{document}
\begin{test}
  \item one
  \item two 
\end{test}
\begin{test}
  \item one
  \item two
  \item three
\end{test}
\printcmd
\end{document}

输出\wlog“1.a - 1.b - 2.a - 2.b - 2.c”是我想要的,但这不是\printcmd:“1c - 1c - 2c - 2c - 2c”。如果需要,我在这里接受 LaTeX3 (expl3) 解决方案!

答案1

您不仅需要扩展\envnum,还需要扩展\itemnum。这意味着一行被修改为\expandafter\expandafter\expandafter\cmdwithexpandedargs\expandafter\expandafter\expandafter{\expandafter\envnum\itemnum}。第一轮扩展后,\itemnum扩展了,保留了您开始时的内容\expandafter\cmdwithexpandedargs\expandafter{\envnum\itemnum}。第二轮扩展后\envnum,您就可以开始了。

\documentclass{letter}

\newcounter{nenv}
\newcommand\printcmd{}

\makeatletter
\newcommand\cmdwithexpandedargs[1]{%
    \g@addto@macro\printcmd{#1 - }
}
\makeatother

\newenvironment{test}{%
    \stepcounter{nenv}%
    \let\olditem\item
    \renewcommand\item{%
        \olditem
        \xdef\envnum{\arabic{nenv}}%
        \xdef\itemnum{\alph{enumi}}%
        \wlog{\envnum.\itemnum}
        \expandafter\expandafter\expandafter\cmdwithexpandedargs\expandafter\expandafter\expandafter{\expandafter\envnum\itemnum}%
    }%
    \begin{enumerate}%
}{\end{enumerate}}

\begin{document}
\begin{test}
  \item one
  \item two 
\end{test}
\begin{test}
  \item one
  \item two
  \item three
\end{test}
\printcmd
\end{document}

在此处输入图片描述


后记

我从 Christian Tellechea 那里得到了一些神奇的代码:

% CODE FROM CHRISTIAN TELLECHEA
\makeatletter
\def\expandtimes(#1)#2#{\exp@ntimes@i(#1){#2}}
\def\exp@ntimes@i(#1)#2#3{%
    \ifnum#1>0 \expandafter\exec@first\else\expandafter\exec@second\fi
    {\expandafter\exp@second\expandafter{\expandafter\expandtimes\expandafter(\number%
      \numexpr#1-1)#2}}{#2}{#3}%
}
\long\def\exec@first#1#2{#1}
\long\def\exec@second#1#2{#2}
\long\def\swap@arg#1#2{#2{#1}}
\long\def\exp@second#1#2{\expandafter\swap@arg\expandafter{#2}{#1}}
\makeatother
%

如果将其添加到序言中,将允许将多重扩展语法压缩为

\expandtimes(3)\cmdwithexpandedargs{\expandafter\envnum\itemnum}

以达到相同的结果。

答案2

区别在于,\itemnum当你将它传递给\cmdwithexpandedargs,但\wlog完全扩展了它的参数。

你可以更有效地做到这一点:

\documentclass{letter}

\newcounter{nenv}
\newcommand\printcmd{}

\makeatletter
\newenvironment{test}{%
    \stepcounter{nenv}%
    \let\olditem\item
    \renewcommand\item{%
        \olditem
        \xdef\printcmd{\printcmd\arabic{nenv}\alph{enumi} - }%
        \wlog{\arabic{nenv}.\alph{enumi}}%
    }%
    \begin{enumerate}%
}{\end{enumerate}}
\makeatother

\begin{document}
\begin{test}
  \item one
  \item two 
\end{test}
\begin{test}
  \item one
  \item two
  \item three
\end{test}
\printcmd
\end{document}

无需单独进行\xdef(全局实际上是无用的,可以简单进行\edef)。

在此处输入图片描述

在日志文件中你发现

1.a
1.b
2.a
2.b
2.c

如果您想使用\cmdwithexpandedargs,那么您可以不用\expandafter或使用花哨的代码。

\makeatletter
\newcommand\cmdwithexpandedargs[1]{%
    \g@addto@macro\printcmd{#1 - }
}
\makeatother

\newenvironment{test}{%
    \stepcounter{nenv}%
    \let\olditem\item
    \renewcommand\item{%
        \olditem
        \wlog{\arabic{nenv}.\alph{enumi}}
        \begingroup\edef\x{\endgroup
          \noexpand\cmdwithexpandedargs{\arabic{nenv}\alph{enumi}}%
        }\x
    }%
    \begin{enumerate}%
}{\end{enumerate}}

相关内容