在下面的 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}}