我正在尝试为自己创建一个模板类型的 LaTeX 文档,我可以在文档开头附近设置一个数字(就像一个变量),文档后面会有一个表格,其行数与该数字相同。此外,第一列将有一个递增的数字列表。因此,如果我将“变量”设置为 5,我将得到一个表格,其中第一列的数字从 1 到 5。
我已经关注这位专业人士回答类似的问题,使用 token 创建此表。我的问题是我无法像我希望的那样在第一列中获得数字。这是一个 MWE
\documentclass{article}
\def\numberoflines{10}
\newcounter{i}
\setcounter{i}{0}
\newtoks\tabtoks
\newcommand*\addtabtoks[1]{\tabtoks\expandafter{\the\tabtoks#1}}
\newcommand*\resettabtoks{\tabtoks{}}
\newcommand*\printtabtoks{\the\tabtoks}
\begin{document}
\resettabtoks
\loop\ifnum\thei<\numberoflines
\addtabtoks{\thei & \\ \hline}
\stepcounter{i}
\repeat
\begin{tabular}{| c | c |}
\hline
number & empty \\
\hline
\printtabtoks
\end{tabular}
\end{document}
是的,我知道垂直线不好看;这是一个特殊用例,不适用于专业排版,请忽略
输出:
有没有什么解决办法可以让所有地方都得到 1-10 而不是 10?
提前致谢!
答案1
主要问题是你没有扩展\thei
,因此令牌寄存器将包含
\thei & \\ \hline
\thei & \\ \hline
\thei & \\ \hline
\thei & \\ \hline
\thei & \\ \hline
\thei & \\ \hline
\thei & \\ \hline
\thei & \\ \hline
\thei & \\ \hline
然而,
\expandafter\addtabtoks\expandafter{\thei & \\ \hline}
不起作用,因为 的第一级扩展\thei
是\arabic{i}
;进一步扩展会给出\number\c@i
,并且需要进行第三次扩展,从而导致 的重复次数高达 14 次\expandafter
。不理想。
最简单的技巧是强制扩展
\expandafter\addtabtoks\expandafter{\romannumeral-`Q\thei & \\ \hline}
也\stepcounter{i}
应移至该指令之前。
\documentclass{article}
\def\numberoflines{10}
\newcounter{i}
\setcounter{i}{0}
\newtoks\tabtoks
\newcommand*\addtabtoks[1]{\tabtoks\expandafter{\the\tabtoks#1}}
\newcommand*\resettabtoks{\tabtoks{}}
\newcommand*\printtabtoks{\the\tabtoks}
\begin{document}
\resettabtoks
\loop\ifnum\thei<\numberoflines
\stepcounter{i}
\expandafter\addtabtoks\expandafter{\romannumeral-`Q\thei & \\ \hline}
\repeat
\showthe\tabtoks
\begin{tabular}{| c | c |}
\hline
number & empty \\
\hline
\printtabtoks
\end{tabular}
\end{document}
您可能会发现以下解决方案更好。可以在运行时指定任意数量的行。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\makerows}{m}
{
\int_step_function:nN { #1 } \__bertalanp_mr_row:n
}
\cs_new:Nn \__bertalanp_mr_row:n { #1 & \\ \hline }
\ExplSyntaxOff
\begin{document}
\begin{tabular}{| c | c |}
\hline
number & empty \\
\hline
\makerows{10}
\end{tabular}
\end{document}
答案2
三种方法可以即时执行此操作而无需预先积累令牌,使用xinttools
。第一种方法仅使用计数器。
使用普通 LaTeX 计数器进行扩展复制
抱歉,\romannumeral
但这是使用 的语法\xintreplicate
。如果您愿意,请定义\newcommand{\xintReplicate}{\romannumeral\xintreplicate}
以隐藏它并使用\xintReplicate
。
\documentclass{article}
\usepackage{xinttools}
\newcounter{i}
\newcommand{\makerows}[1]{%
\romannumeral\xintreplicate{#1}{\stepcounter{i}\thei&\\\hline}%
}
\begin{document}
\setcounter{i}{0}
\begin{tabular}{| c | c |}
\hline
number & empty \\
\hline
\makerows{10}
\end{tabular}
\end{document}
接下来的三种方法不使用计数器。
带有魔术循环索引的可扩展循环
这是一个完全可扩展的循环;使用起来有点微妙。参数#1
被假定为明确的数字(行尾空格在\ifnum
测试中终止它们)。
\documentclass{article}
\usepackage{xinttools}
\newcommand{\makerows}[1]{%
\xintiloop[1+1]
\xintiloopindex & \\ \hline
\unless\ifnum\xintiloopindex=#1
\repeat
}
\begin{document}
\begin{tabular}{| c | c |}
\hline
number & empty \\
\hline
\makerows{10}
\end{tabular}
\end{document}
xintFor 循环遍历整数(默认从 1 开始),并带有 Break
这里的##1
被封装在 中\numexpr
,因此需要\number
。
\documentclass{article}
\usepackage{xinttools}
\newcommand{\makerows}[1]{%
\xintFor ##1 in \xintintegers
\do
{\number##1 & \\ \hline
\ifnum#1=##1\expandafter\xintBreakFor\fi}%
}
\begin{document}
\begin{tabular}{| c | c |}
\hline
number & empty \\
\hline
\makerows{10}
\end{tabular}
\end{document}
xintFor 循环,带有预先计算的整数列表
这里##1
是数字标记。
\documentclass{article}
\usepackage{xinttools}
\newcommand{\makerows}[1]{%
\xintFor* ##1 in {\xintSeq{1}{#1}}
\do
{##1 & \\ \hline}%
}
\begin{document}
\begin{tabular}{| c | c |}
\hline
number & empty \\
\hline
\makerows{10}
\end{tabular}
\end{document}
输出(当然,这四种方法都相同)
答案3
您需要进行更多扩展。因为只\thei
存储了宏,并且会在排版时执行(即在 i=10 时结束时)。
\documentclass{article}
\def\numberoflines{10}
\newcounter{i}
\setcounter{i}{0}
\newtoks\tabtoks
\newcommand*\addtabtoks[1]{\tabtoks\expandafter{\the\tabtoks#1}}
\newcommand*\resettabtoks{\tabtoks{}}
\newcommand*\printtabtoks{\the\tabtoks}
\begin{document}
\resettabtoks
\loop\ifnum\value{i}<\numberoflines
\expandafter\addtabtoks\expandafter{\expanded{\arabic{i}} & \\ \hline}
\stepcounter{i}
\repeat
\begin{tabular}{| c | c |}
\hline
number & empty \\
\hline
\printtabtoks
\end{tabular}
\end{document}
编辑: \expanded
目前仅适用于 LuaLaTeX。以下是更通用的版本:
\documentclass{article}
\def\numberoflines{10}
\newcounter{i}
\setcounter{i}{0}
\newtoks\tabtoks
\newcommand*\addtabtoks[1]{\tabtoks\expandafter{\the\tabtoks#1}}
\newcommand*\resettabtoks{\tabtoks{}}
\newcommand*\printtabtoks{\the\tabtoks}
\begin{document}
\resettabtoks
\loop\ifnum\value{i}<\numberoflines
\edef\tmpi{\thei}
\expandafter\addtabtoks\expandafter{\tmpi & \\ \hline}
\stepcounter{i}
\repeat
\begin{tabular}{| c | c |}
\hline
number & empty \\
\hline
\printtabtoks
\end{tabular}
\end{document}