如何使用 for 循环输入文件

如何使用 for 循环输入文件

假设我正在写一本有 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.tex10.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

相关内容