什么是latex分文件编写,为什么要分
一篇大的文章或者书籍,包含很多章节,各个章节很可能是由不同的作者分别编写的。无论是在编写还是修订阶段,大量的修改是难免的,如果对于每一个修改,都要去复制粘贴地合并到同一个文件里面,很容易出现纰漏,另外还极大地降低了开发效率。即使是使用软件开发过程中常见的版本管理工具来进行,也面临很多同步问题。这显然是与latex出现的初衷向违背的。
因而latex允许我们将一个大的源文件拆分许多个小的源文件(按章节),并通过另一个文件将它们组合起来。可以近似地理解为C/C++语言中的头文件。
这样各个部分可以独立编写,非常方便合作编写和审阅修订。
怎么分
一般来说latex提供了两种包含子文件的方法:
\input 和 \include
一般编写书籍的时候使用\include,并且一章一个文件,因为它会自动给每个被include的部分创建一个新页。而写论文的时候多用\input。
需要提一下,导言区只需要宿主文件有就可以了,被包含的文件会沿用它。
用法
\input{chapter1}
\include{chapter2}
注意不加.tex的后缀。
区别
\input
它完全相当于C/C++语言中的#include,可以理解为只起一个文本替换的作用。
因而,它可以嵌套使用。可以在任何位置使用(特别强调一下:可以在导言区使用)。
但是,任何一个子文件修改后,都需要对全文进行重新编译。所以对于编译有好几百页的书籍来说用它来管理章节是不太方便的(但是各个章节内部可以使用它),但对于论文,这点额外时间完全可以接受。
由于它只是一个文本替换,因而如果想只编译某些章节,那么所有的自动编号都会根据现在的内容重新编排。即如果第一章有3个公式,那么第二章的第一个公式应该是“公式4”,如果我把第一章的\input注释掉,那么第二章第一个公式会是“公式1”。同样的情况还出现在图标、章节等所有自动编号上。
\include
为了实现不改变最终效果(编号等资源的显示)的部分章节调试,可以使用\include和与之配套的\includeonly。
它类似于编程中编译好的库文件。
它只能用在正文区,用来引入正文。
每个\include的部分开始时会新起一页。
在某个部分修改的时候,针对宿主文件的重新编译不会影响其他文件。因而很节约编译时间。
如果只想在生成的文件中显示部分章节,不需要对正文区的\include 做任何操作,只需要在导言区写诸如\includeonly{chapter1,chapter3,chapter14}的一句就可以了。它表示只生成第1、3、14章。并且它不会因为把显示中间的章节,就把它们的自动编号空过去(但是如果在正文区注释掉了,那就另当别论了)。
一个论文的例子
很多朋友学些latex都是为了编写论文,下面我就写一个关于论文的例子说明一下怎么用。
----------------my_paper.tex--------------
\documentclass{article}
%导言区\usepackage{...}
\begin{document}
\input{1-abstract}
\input{2-introduction}
\input{3-model}
\input{4-data}
\input{5-solve}
\input{6-conclusion}
\input{7-acknowledgment}
\bibliography{ref}
\bibliographystyle{abbrv}
\end{document}
----------------1-abstract.tex---------------
\begin{abstract}
This paper .....
\end{abstract}
-----------------2-introduction.tex------------
\section{Introduction}
..........
----------------3-model.tex----------------
\section{Model}
............
\begin{equation}
........
\end{equation}
\subsection{Provement}
..............
一些经验技巧
在上面例子中,如果只想看看第三章的某个公式、某个图片显示的效果如何,需要编译宿主文件。这对于较大的文件而言依然比较麻烦。另外对于很多ide环境(尤其是windows平台常用的WinEdt),默认是编译当前正在编辑的文件,而这个文件由于不包含完整的结果信息,无法编译,比较麻烦。
一个解决方便就是使用类似C/C++中的条件编译的概念,让编译器去判断,如果当前是只希望编辑一个子文件,就补充上完整的结构信息。
条件编译
latex可以使用:
\ifx...
...
\else
...
\fi
的结构执行条件指令。这在一些会议期刊所提供的latex模板中很常见,多是用来根据编译器版本选择合适的包和参数。
我们可以利用它来实现自动补完结构信息的功能。
如果你有C/C++语言的相关知识,下面的概念会非常好理解,如果没有也没有关系,只需要按照后面“一个论文的例子2.0”中黑体的部分操作就可以了。
我们可以在宿主文件中定义(\def)一个编译期常量,然后让各个子文件去检测这个常量是否存在,如果不存在就写入结构信息。
例如:
\def的用法是这样的:
\def\my_variable{hello}
它定义了一个名为“my_variable”的宏,它的内容是“hello”。
再在各个子文件中使用\ifx\my_variable\undefine 来检测这个宏是否没有定义(latex没有提供"\defined"来检测是否已定义),并添加相应的内容。
一个论文的例子2.0
由于导言区在每个独立编译的部分都中要使用,所以在这里可以将它也独立成一个文件(命名为0-preamble.tex)。
----------------my_paper.tex--------------
\input{0-preamble}
\def\all_in_one{all_in_one}
\begin{document}
\input{1-abstract}
\input{2-introduction}
\input{3-model}
\input{4-data}
\input{5-solve}
\input{6-conclusion}
\input{7-acknowledgment}
\bibliography{ref}
\bibliographystyle{abbrv}
\end{document}
----------------0-preamble.tex---------------
\documentclass{article}
%导言区\usepackage{...}
----------------3-model.tex----------------
\ifx\all_in_one\undefined
\input{0-preamble}
\begin{document}
\fi
\section{Model}
............
\begin{equation}
........
\end{equation}
\subsection{Provement}
..............
\ifx\all_in_one\undefined
\end{document}
\fi