使用标记循环生成 LaTeX 表格

使用标记循环生成 LaTeX 表格

我正在尝试为自己创建一个模板类型的 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}

是的,我知道垂直线不好看;这是一个特殊用例,不适用于专业排版,请忽略

输出:

MWE 输出

有没有什么解决办法可以让所有地方都得到 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}

相关内容