使用 foreach 包含章节

使用 foreach 包含章节

我在主目录中名为 chapters 的目录中有单独的 .tex 文件。我想包含/输入这些文件。经过一番研究,可能可以找到类似下面的解决方案。不幸的是,我得到了“未定义的控制序列”。

   \ForEach \i in {1,...,10}{
    \InputIfFileExists{chapters/\i.tex}
   }

答案1

一些评论:

  • \ForEach可能由某些包定义,但语法看起来像pgf\foreachTeX/LaTeX 区分大小写。 至少pgffor应该加载包,除非pgf使用 TikZ 或。

  • \i对于包含文本文件来说,这是一个非常糟糕的名称,因为\i在某些语言中可能会使用,它通常会生成一个没有点的“i”:ı。因此,本示例使用\ChapterNumber

  • \InputIfFileExists接受三个参数,文件名和两个代码参数(分别表示文件存在和丢失的情况)。

  • 似乎包含了章节文件,这些文件应该以页面边界开始和结束。然后\include是更好的选择。它在内部使用\InputIfFileExists。因此,如果章节尚未编写,编译将继续进行而不会出现错误。然后在控制台/日志文件上打印提醒,例如:

    No file chapters/7.tex.
    

    如果文件是通过 输入的\include,那么很容易使用 只编译一章\includeonly

完整示例如下:

\documentclass{book}
\usepackage{pgffor}
\begin{document}
\foreach \ChapterNumber in {1, ..., 10} {
  \include{chapters/\ChapterNumber}
}
\end{document}

\foreach将循环体放入一个组中。如果局部定义不应泄露到章节之外,这可能是一个优点。或者一个缺点,例如,如果简介章节定义了一些应该在其他章节中使用的东西。

没有组且没有附加包的循环:

\documentclass{book}
\begin{document}   

\makeatletter
\newcounter{FileNumber}
\@whilenum\value{FileNumber}<10 \do{%
  \stepcounter{FileNumber}
  \makeatother
  \include{chapters/\number\value{FileNumber}}%
}
\makeatother  

\end{document}

但我认为,如果章节文件名包含真实名称而不是数字,则文档的结构会更容易理解:

\include{chapters/Introduction}
\include{chapters/History}
\include{chapters/Theory}
\include{chapters/Setup}
\include{chapters/Experiments}
\include{chapters/Results}
\include{chapters/Summary}

可以添加折衷数字以在目录列表中显示正确的章节排序顺序:

\include{chapters/01-Introduction}
...
\include{chapters/10-Summary}

答案2

你应该\foreach在做完之后使用

\usepackage{pgffor}

(或\usepackage{tikz})。但是,有一个问题\foreach:每个循环都是以组为单位执行的,因此您需要将文件包含在一个组中,这可能会产生不良后果。

\i如果在其中一个文件中使用,也会被错误解释。

解决方案:

\newtoks\listoffilestoinput
\foreach \i in {1,...,10}{%
   \edef\temp{%
     \the\listoffiles
     \noexpand\InputIfFileExists{chapters/\i.tex}{}{}%
   }%
   \global\listoffilestoinput=\expandafter{\temp}
}
\the\listoffilestoinput

不要忘记以下参数\InputIfFileExists

当然,如果您愿意的话,您\include也可以使用:\InputIfFileExists

\newtoks\listoffiles
\foreach \i in {1,...,10}{%
   \edef\temp{%
     \the\listoffilestoinput
     \noexpand\include{chapters/\i}%
   }%
   \global\listoffilestoinput=\expandafter{\temp}
}
\the\listoffilestoinput

请注意,不应添加扩展\include(它是可选的\InputIfFileExists,其中.tex如果没有扩展则隐含)。

您甚至可以在序言中定义的宏中抽象它。

\newtoks\listoffilestoinput
\newcommand{\multiinclude}[3][\i]{%
   \global\listoffilestoinput={}% reinitialize
   \foreach #1 in {#2}{%
     \edef\temp{%
       \the\listoffilestoinput
       \noexpand\include{#3}%
       %\noexpand\InputIfFileExists{#3}{}{}% alternative version
     }%
   \the\listoffilestoinput
}

然后在文档中你可以使用

\multiinclude{1,...,10}{chapters/\i}

或者

\multiinclude[\ChapterNumber]{1,...,10}{{chapters/\ChapterNumber}

第一个强制参数是 的列表\foreach,第二个强制参数是模板。可选参数(默认\i)是要使用的变量。

请注意,使用此方法(与您使用的形式无关),变量\i只是暂时使用,即使已经定义也不会产生任何副作用(当然,前提是您不使用\foreach\include作为变量名);\i非常适合此目的。

相关内容