我在主目录中名为 chapters 的目录中有单独的 .tex 文件。我想包含/输入这些文件。经过一番研究,可能可以找到类似下面的解决方案。不幸的是,我得到了“未定义的控制序列”。
\ForEach \i in {1,...,10}{
\InputIfFileExists{chapters/\i.tex}
}
答案1
一些评论:
\ForEach
可能由某些包定义,但语法看起来像pgf
。\foreach
TeX/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
非常适合此目的。