我的文档结构有
- 一个带序言的文件(即
MainTex
) - 以及代表每个章节的大约 75 个单独
.tex
文件(即Chapter_01
,,Chapter_02
..., )。Chapter_75
我正在使用\include
命令创建一个大的 PDF 文件,输出是MainTex.pdf
。到目前为止,生活一切都很美好。
如果我必须为每个章节创建单独的 PDF,那么我是否需要对每个章节名称运行 75 次并手动重命名 PDF 以匹配章节名称。因为如果我仅包含Chapter_01
并运行,它会创建名为 的 PDF MainTex.pdf
。
有什么方法可以自动化这个工作流程吗?
答案1
假设您的主文件是maintex.tex
:
\documentclass[a4paper]{book}
\begin{document}
\include{chap01}
\include{chap02}
\include{chap03}
\end{document}
然后,您可以通过从命令行调用来编译第 1 章
pdflatex -jobname=thechap01 "\includeonly{chap01}\input{maintex}"
为了一次性完成所有操作,命令可能是(bash shell)
for i in chap*.tex; do j=${i%.tex}; pdflatex -jobname=the$j "\includeonly{$j}\input{maintex}"; done
有必要将输出文件名从 更改chap01
为其他名称,否则读取文件.aux
会导致无限循环。之后可以轻松重命名获取的 PDF 文件(或在同一命令中,通过; mv the$j.pdf $j.pdf
在 之前添加done
)。
答案2
是的,支持此工作流程,但必须从一开始就执行,而不是事后执行。这就是我的意思。
这subfiles
包裹提供了一种方法,可以将单独的子文件包含在主.tex
文件中(使用\include
或\includeonly
),但这些子文件本身也可以编译。包应该包含在主文件中,而每个子文件都有一个工作前言。然后,您可以使用标准 bash 脚本迭代(循环)各个子文件(在您的例子中是章节),并使用、或.tex
编译每个章节。例如,在 DOS 下,以下内容应该有效:latex
pdflatex
xelatex
for /f %%a IN ('dir /b Chapter_??.tex') do call pdflatex %%a
您可能必须运行整个脚本至少两次才能使每章中的引用发挥作用。
这standalone
文档类提供了类似的功能,document
在编译主程序时跳过包含文件的前言,只考虑环境中包含的内容.tex
。但是,包含的文件可以单独编译。
这种方式编译的主要缺点是跨章节引用,并且每章的页码都会重新开始1
。前者可以使用xr
包裹,而后者可以通过在文档前言中插入相应的页码修改(通过\setcounter{page}{...}
)来解决,甚至可以从主文件中读取.aux
。无论如何,如果设置不正确,这种操作可能很难掌握。
答案3
这是一种利用神奇的arara
@egreg's
实施解决方案的工具
main.tex
% arara: makechapters: {items: [lions, zebras]}
\documentclass{report}
\begin{document}
\include{lions}
\include{zebras}
\end{document}
你打电话时
arara main.tex
您将获得lions.pdf
和zebras.pdf
。您可以在参数中列出任意数量的章节文件,如果您不想先编译,items
也可以选择设置。默认值为,我建议仅在您 100% 确定必要的文件是最新的时才将其关闭。compileAll: off
main.tex
compileAll: on
.aux
对于大型文档来说,这可能需要一段时间,但这是您在离开办公桌之前设置运行的事情。
makechapters.yaml
!config
# Make chapter files rule for arara
# author: Chris Hughes
# last edited by: cmh, May 20th 2013
# http://tex.stackexchange.com/questions/31334/how-to-create-individual-chapter-pdfs
# requires arara 3.0+
#
# Sample usage: Assume you have the following directives in main.tex, with chapter files
# lions.tex, zebras.tex
#
# % arara: makechapters: {items: [lions]}
# % arara: makechapters: {items: [lions, zebras]}
# % arara: makechapters: {items: [lions, zebras], compileAll: no}
# % arara: makechapters: {items: [lions, zebras], compileAll: yes}
#
# which will create lions.pdf, zebras.pdf
#
# Note that, by default, this compiles main.tex first so that all of the necessary .aux
# files are generated- this is vital for cross referencing to work, particularly in
# the case of a *forward* cross reference (e.g chapter 2 refers to chapter 3).
#
# If you set compileAll to false/no/off, then it will *not* compile the main file
# first- be careful with this one, as the necessary .aux files may not be present, and
# your cross references may break.
identifier: makechapters
name: MakeChapters
commands:
- <arara> @{ isTrue( compileAll, engine.concat(' "').concat(file).concat('"') )}
- <arara> @{engine} -jobname=tmpCMH "\includeonly{@{item}}\input{@{file}}"
- <arara> @{engine} -jobname=tmpCMH "\includeonly{@{item}}\input{@{file}}"
- <arara> @{ isWindows( "cmd /c move", "mv" ) } tmpCMH.pdf @{item}.pdf
arguments:
- identifier: engine
flag: <arara> @{parameters.engine}
default: pdflatex
- identifier: compileAll
flag: <arara> @{parameters.compileAll}
default: true
答案4
我正在尝试以下方法。让主文件包含以下内容:
\documentclass{...}
\usepackage{newclude}
\def\inmaster{1}
\ifdefined\subonly\includeonly{\subonly}\fi
\begin{document}
\include{subone}
\include{subtwo}
\end{document}
子文件以如下方式开始(无前言或\begin{document}
):
\ifdefined\inmaster\else\def\subonly{\jobname}\input{master}\fi
\chapter{Chapter Name}
...
最后,使所有.aux
文件都进行符号链接,例如使用 bash 命令
for f in *.tex; do ln -s master.aux ${f%.tex}.aux; done
现在可以单独编译主文件以生成包含所有章节的输出,同样,可以单独编译每个单独的章节文件以生成仅包含该章节的输出(但仍然会正确编号并可以引用其他章节中的标签)。
这样做的好处是,一旦设置好,每个.tex
文件都可以像平常一样进行编译;不需要花哨的 makefile、脚本或编译工具。然而,它的缺点是需要初始设置符号链接(特别是需要支持它们的操作系统)。但人们可以用符号链接换取稍微复杂一点的编译,例如用以下代码编译每个章节文件
cp master.aux chapterone.aux && pdflatex chapterone
无论哪种方式,脚本都可以轻松循环遍历章节文件并对其进行全部编译。