假设我正在写一本有 45 个章节的书(在单独的文件中等1.tex
2.tex
),并且我想将它们输入到main.tex
。 我该如何为此编写 for 循环?
答案1
由于它是关于输入包含 LaTeX 文档章节的文件,我认为 -command\include
是输入文件的适当命令。但是,如果您愿意,您可以轻松地用\include
的实例替换的实例。\input
编辑:从切换到时遗留的问题\input
,\include
我错误地将文件扩展名“ .tex”保留为⟨文件名数字部分后的标记⟩。与 不同\input
,\include
您无需提供扩展名 .tex — 扩展名 .tex 由\include
-command 自动添加。现在已纠正此问题。
尾部递归循环可能可以解决问题。
这里有一个指定文件名的循环:
\newcommand\noneofone[1]{}%
\newcommand\firstofone[1]{#1}%
\newcommand\includeloop[2]{%
\ifx\relax#2\expandafter\noneofone\else\expandafter\firstofone\fi
{\include{#1#2}\includeloop{#1}}%
}%
\includeloop{./chapters/}{filename1}{filename2}{filename3}{filename4}{filename5}%
{filename6}{filename7}{filename8}{filename9}{filename10}%
{filename11}{filename12}{filename13}{filename14}{filename15}%
{filename16}{filename17}{filename18}{filename19}{filename20}%
{filename21}{filename22}{filename23}{filename24}{filename25}%
{filename26}{filename27}{filename28}{filename29}{filename30}%
{filename31}{filename32}{filename33}{filename34}{filename35}%
{filename36}{filename37}{filename38}{filename39}{filename40}%
{filename41}{filename42}{filename43}{filename44}{filename45}\relax
如果所有文件名都具有相同的模式,则可以根据计数进行循环:
句法:
\includepatternloop{⟨lower bound of number range⟩}%
{⟨upper bound of number range⟩}%
{⟨tokens before number-component of filename⟩}%
{⟨tokens after number-component of filename⟩}%
{⟨directory/file-path⟩}%
产生一系列
\include{%
⟨directory/file-path⟩%
⟨tokens before number-component of filename⟩%
⟨number-component of filename⟩%
⟨tokens after number-component of filename⟩%
}
代码
\newcommand\exchange[2]{#2#1}%
\newcommand\includepatternloop[5]{%
\include{#5#3#1#4}%
\ifnum#1<\expandafter\exchange\expandafter{\number#2}{} %
\exchange{\expandafter\includepatternloop\expandafter{\number\numexpr#1+1\relax}{#2}{#3}{#4}{#5}}%
\fi
}%
\includepatternloop{1}{45}{File}{of45Files}{./chapters/}%
获取一个序列:
\include{./chapters/File1of45Files}%
\include{./chapters/File2of45Files}%
...
\include{./chapters/File45of45Files}%
如果您不想,\ifnum#1<\expandafter\exchange\expandafter{\number#2}{} %
您可以引入另一个宏,该宏适用\number
于在实际开始循环之前对事物进行规范化:
\newcommand\exchange[2]{#2#1}%
\newcommand\includepatternloop[2]{%
\expandafter\exchange\expandafter{\expandafter{\number#2}}{\includepatternloopinternal{#1}}%
}%
\newcommand\includepatternloopinternal[5]{%
\include{#5#3#1#4}%
\ifnum#1<#2 %
\exchange{\expandafter\includepatternloopinternal\expandafter{\number\numexpr#1+1\relax}{#2}{#3}{#4}{#5}}%
\fi
}%
\includepatternloop{1}{45}{File}{of45Files}{./chapters/}%
答案2
您可以定义一个涵盖一系列数字的通用循环来执行各种任务。
\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand{\genericloop}{mmm}
{
\zmkm_genericloop:nnn { #1 } { #2 } { #3 }
}
\cs_new_protected:Nn \__zmkm_genericloop_task:n { } % initialize
\cs_new_protected:Nn \zmkm_genericloop:nnn
{
\cs_set_protected:Nn \__zmkm_genericloop_task:n { #3 }
\int_step_function:nnN { #1 } { #2 } \__zmkm_genericloop_task:n
}
\ExplSyntaxOff
\begin{document}
\genericloop{1}{45}{\input{./chapters/#1.tex}}
\end{document}
其思想是使用 来对第一个和第二个参数指定的范围内的每个数字\int_step_function:nnN
重复执行 Scratch 函数。第三个参数是要使用的模板,其中代表循环中的当前数字。\__zmkm_genericloop_task:n
\genericloop
#1
为了检查一切是否正常,我使用以下命令重现控制台输出
\genericloop{1}{10}{\typeout{\string\input{./chapters/#1.tex}}
我们得到
\input{./chapters/1.tex}
\input{./chapters/2.tex}
\input{./chapters/3.tex}
\input{./chapters/4.tex}
\input{./chapters/5.tex}
\input{./chapters/6.tex}
\input{./chapters/7.tex}
\input{./chapters/8.tex}
\input{./chapters/9.tex}
\input{./chapters/10.tex}
如果章节有编号怎么办?01.tex
我们可以定义一个“填充”函数。09.tex
10.tex
\documentclass{article}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\padding}{mm}
{
\prg_replicate:nn { #1-\str_count:n { #2 } } { 0 } #2
}
\NewDocumentCommand{\genericloop}{mmm}
{
\zmkm_genericloop:nnn { #1 } { #2 } { #3 }
}
\cs_new_protected:Nn \__zmkm_genericloop_task:n { } % initialize
\cs_new_protected:Nn \zmkm_genericloop:nnn
{
\cs_set_protected:Nn \__zmkm_genericloop_task:n { #3 }
\int_step_function:nnN { #1 } { #2 } \__zmkm_genericloop_task:n
}
\ExplSyntaxOff
\begin{document}
\genericloop{1}{10}{\typeout{\string\input{./chapters/\padding{2}{#1}.tex}}}
\end{document}
控制台输出为
\input{./chapters/01.tex}
\input{./chapters/02.tex}
\input{./chapters/03.tex}
\input{./chapters/04.tex}
\input{./chapters/05.tex}
\input{./chapters/06.tex}
\input{./chapters/07.tex}
\input{./chapters/08.tex}
\input{./chapters/09.tex}
\input{./chapters/10.tex}
当然你会打电话
\genericloop{1}{45}{\input{./chapters/\padding{2}{#1}.tex}}
如果你想输入01.tex
最多45.tex
。
答案3
在 OpTeX 中,我们可以这样做:
\fornum 1..45 \do {\input{#1.tex}}
\bye