使用以下宏时,我遇到了一些有趣的错误。大部分情况下,它都能正常工作,但在 之后会出现多余的空格\noindent
(但在 之后不会出现\newline
)。我尝试使用\loop
或\whiledo
(来自ifthen
),但会出现堆栈溢出。当我尝试重复符号时,会发生非常奇怪的事情&
(日志显示一切正常,直到 TeX 抛出一个额外的\fi
)。
\documentclass{article}
\tracingmacros=1
\newcounter{tempcount}
\newcommand{\append}[3]{ % #1 = start of text, #2 = text to repeat, #3 = number of repetitions
\ifnum #3>0%
\setcounter{tempcount}{#3}%
\addtocounter{tempcount}{-1}%
\append{#1#2}{#2}{\arabic{tempcount}}
\else #1 \fi}
\begin{document}
\noindent\append{c}{c}{0}
\noindent\append{c}{c}{1}
\noindent\append{c}{c}{2}
\noindent\append{c}{c}{3}
\noindent\begin{tabular}{\append{c}{c}{2}}
1&2&3\\
\append{start}{&test}{1}\\
\append{start}{&test}{2}
\end{tabular}
\end{document}
我应该说一下,我玩过但\noexpand
无济于事。
答案1
您的\append
宏无法在参数中起作用tabular
,只要宏完全可扩展,就可以使用;但事实并非如此,因为它包含赋值。
tabular
这是使用 LaTeX3 函数的快速版本。请注意,这在if已加载的参数中不起作用array
,因为此包禁用扩展参数。
但是,输入l*{2}{c}
参数似乎并不复杂,不需要宏。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\append}{mmm}
{
#1\prg_replicate:nn{#3}{#2}
}
\ExplSyntaxOff
\begin{document}
\noindent\append{c}{c}{0}
\noindent\append{cd}{c}{1}
\noindent\append{c}{c}{2}
\noindent\append{c}{c}{3}
\noindent\begin{tabular}{\append{l}{c}{2}}
1&2&3\\
\append{start}{&test}{1}\\
\append{start}{&test}{2}
\end{tabular}
\end{document}
答案2
真的没有必要重新发明轮子。有许多循环包可用于迭代序列。我用过multido
以下:
\documentclass{article}
\usepackage{multido}% http://ctan.org/pkg/multido
\makeatletter
\newcommand{\append}[3]{ % #1 = start of text, #2 = text to repeat, #3 = number of repetitions
\def\@looop{#1}% start of text
\ifnum#3>0\multido{\iA=1+1}{#3}{\g@addto@macro\@looop{#2}}\fi% text to repeat
\@looop}% Execute
\makeatother
\begin{document}
\noindent\append{c}{c}{0}
\noindent\append{c}{c}{1}
\noindent\append{c}{c}{2}
\noindent\append{c}{c}{3}
\noindent\begin{tabular}{*{3}{c}}
1 & 2 & 3 \\
\append{start}{&test}{1} \\
\append{start}{&test}{2}
\end{tabular}
\end{document}
其思想是构造一个\@looop
包含起始元素的宏,并使用 添加重复元素。然后,在的\g@addto@macro
末尾执行 。\append
\@looop
请注意,tabular
列规范已经使用样式提供了一种复制/重复的类型*{<num>}{<col spec>}
,其中列规范<col spec>
重复<num>
多次。
答案3
这些空格是由于在 的定义中\append
,在左括号和注释之间有一个额外的空格。在 之前还有一个\else
。我是这样写的:
\newcommand{\append}[3]{%
% #1 = start of text, #2 = text to repeat, #3 = number of repetitions
\ifnum #3>0
\setcounter{tempcount}{#3}%
\addtocounter{tempcount}{-1}%
\append{#1#2}{#2}{\arabic{tempcount}}%
\else
#1%
\fi}
其余部分都有效,除非您尝试\append
在 的参数中使用tabular
。 问题是\append
在需要列信息之前不会扩展 。 如果您也希望它能正常工作,我建议您遵循@Werner 的回答。 重新发明一切是不值得的。 但是,如果必须这样做,您需要了解宏扩展的精确工作原理。
答案4
其他人已经解释了空格的来源,以及 的参数tabular
必须完全可扩展的事实。其他错误来自这样的事实:在 的第一次扩展之后\append
,TeX 看到的是&
,并且宏代码的不同部分出现在对齐的不同单元中。您需要延迟识别 & 符号的时间点。下面的代码在此示例中有效,但我不能说它是否在其他地方也有效:
\def\amp{&}
\noindent
\begin{tabular}{ccc}
1&2&3\\
\append{start}{\amp test}{1}\\
\append{start}{\amp test}{2}
\end{tabular}