此代码:
\documentclass{article}
\begin{document}
\def\a{}
\newcounter{mycounter}
\def\b#1{
\def\p{#1}
\ifnum\value{mycounter}=0
\long\xdef\a{\a\rule{3mm}{3mm}\par #1}
\else
\long\xdef\a{\a #1\ }
\fi
}
\b{A}\b{B}\b{C}\b{D}\b{E}\b{F}
\setcounter{mycounter}{1}
\b{G}\b{H}\b{I}\b{J}\b{K}
\a
\end{document}
抛出错误:
"!Paragraph ended before \@newctr was complete.<to be read again>\par b{A}"
发生了什么?
答案1
它不能这样工作:\rule
执行未在 中执行的作业\xdef
。
你可能想说
\expandafter\gdef\expandafter\a\expandafter{\a\rule{3mm}{3mm}\par #1\ }
另一行也是类似。没有参数\long
,所以没用\a
。
看起来您想在 的扩展中添加一些内容\a
,但\xdef
“一直扩展”,而您只需要在 的第一级扩展中获取\a
。 的序列\expandafter
就可以做到这一点。但是,有一种更有效的方法来定义您的宏:
\makeatletter
\def\b#1{%
\def\p{#1}%
\ifnum\value{mycounter}=0
\g@addto@macro\a{\rule{3mm}{3mm}\par #1}%
\else
\g@addto@macro\a{#1\ }%
\fi
}
\makeatother
该宏\g@addto@macro
位于 LaTeX 内核中,其效果正是将第二个参数(全局)附加到第一个参数的替换文本中,该宏应该是一个宏。