在以下方案中,为什么我必须隐藏&
在宏(\samp
)中才能使其起作用?
\documentclass{article}
\usepackage{catoptions}
\makeatletter
\cptnewcounts{rowcnt,colcnt,maxrow,maxcol}
\def\docols{%
\global\advance\colcnt\@ne
\the\numexpr\rowcnt*\colcnt\relax
\ifnum\colcnt=\maxcol\stopcol\fi
\samp\docols
}
\def\stopcol#1\docols{\fi}
\def\samp{&}
\def\dorows{%
\global\advance\rowcnt\@ne
\global\colcnt\z@
\docols
\ifnum\rowcnt=\maxrow\stoprow\fi
\scr\dorows
}
\def\stoprow#1\dorows{\fi\crcr}
\def\scr{\cr}
\makeatother
\begin{document}
\maxrow4 \maxcol3
$$\vbox{\halign{&\ \hfil#\hfil\strut\cr\dorows}}$$
\end{document}
答案1
扩展\dorows
是一次性完成的,生成表格主体,然后 TeX 才会开始扩展它,寻找&
和\cr
标记(如果你将它们隐藏在宏中)。否则 TeX 将看到&
并停止该列,插入你和五部分,对其进行排版并存储起来。因此,可怕的\endtemplate
标记将在 的参数中找到自己的出路\stopcol
。
相反,如果你将&
和\cr
放入宏中,这些宏将不会被扩展,直到\dorows
它完成工作并且表将被安全地构建。
\cr
请注意不是外部:问题与 完全相同\stopcol
,但 不同\stoprow
。
您可以通过如下方式更改输入来查看这一点:
\documentclass{article}
\usepackage{catoptions}
\makeatletter
\cptnewcounts{rowcnt,colcnt,maxrow,maxcol}
\newtoks\ahmed
\def\docols{%
\global\advance\colcnt\@ne
\global\ahmed=\expandafter{\the\expandafter\ahmed\the\numexpr\rowcnt*\colcnt\relax}%
\ifnum\colcnt=\maxcol\stopcol\fi
\global\ahmed=\expandafter{\the\ahmed\samp}\docols
}
\def\stopcol#1\docols{\fi}
\def\samp{&}
\def\dorows{%
\global\advance\rowcnt\@ne
\global\colcnt\z@
\docols
\ifnum\rowcnt=\maxrow\stoprow\fi
\global\ahmed=\expandafter{\the\ahmed\scr}\dorows
}
\def\stoprow#1\dorows{\fi\global\ahmed=\expandafter{\the\ahmed\crcr}}
\def\scr{\cr}
\makeatother
\begin{document}
\maxrow4 \maxcol3
$$\vbox{\halign{&\ \hfil#\hfil\strut\cr\dorows\showthe\ahmed\the\ahmed}}$$
\end{document}
该\show
命令将输出
> 1&2&3\cr 2&4&6\cr 3&6&9\cr 4&8&12\crcr .
l.27 ... \hfil#\hfil\strut\cr\dorows\showthe\ahmed
\the\ahmed}}$$
通过这种方法,能使用&
和\cr
,因为它们将受到令牌寄存器分配的括号的保护。