standalone 是一个文档类,用来把单个构件(图、TikZ 图形、表格等)排成一个自成一体的文档。输出会紧贴内容裁切:得到的 PDF 只含图本身,没有外围页面、页码或页边距。配合同名包使用时,这个图文件可以不加修改地用 \input 拉入主文档。它是 Martin Scharrer 编写的常用包,让同一张图既能单独使用,也能作为大文档的一部分使用。
standalone 的用途
编写大型文档时,常会想把图和 TikZ 图形拆成单独文件,再拉入正文。但如果要单独编译这种图文件来检查,就得反复补上 \documentclass、\begin{document} 之类的外壳,而且输出只是图停在一张正文用大白页的角落里。standalone 类 同时解决这两个问题。只要在图文件开头写 \documentclass{standalone},就能单独编译这一块,输出也会紧贴内容尺寸裁切成 PDF(或 DVI/PS),没有页码、页眉或页脚。
standalone 有两面。一个是在图文件中使用的类(\documentclass{standalone}),另一个是在主文档中加载的包(\usepackage{standalone})。类负责“把一块单独排出来”,包负责“把那一块并入主文档”,二者是一组。先从类看起。
standalone 类和包都需要 xkeyval 包。包这一侧还需要 currfile(内部使用 filehook)来跟踪被包含文件的名称,并需要 gincltex 和 filemod 来实现构建为图像的功能。这些都随 TeX Live 和 MiKTeX 提供。
作为类使用
用法和普通 LaTeX 文档一样。用 \documentclass{standalone} 选择类,在导言区加载图所需的包(TikZ 就是 tikz 等),然后把内容直接写在 \begin{document} 和 \end{document} 之间。该类默认启用 crop 选项(见下文),把输出裁切到内容大小。
\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\draw (0,0) rectangle (2,1) node[midway] {Example};
\end{tikzpicture}
\end{document}单独编译时,会得到一页只含这个矩形、紧贴外边界裁切的 PDF。写的时候有两点要注意:内容前后不要留空行,并且让 \begin{document} 和 \end{document} 各自单独成行。standalone 类会把全部内容当作一个块处理,所以末尾空行会被读成宽度为 \linewidth 的段落,可能在图右侧产生多余空白。
排 TikZ 图时,方便的做法是使用 tikz 选项,如 \documentclass[tikz]{standalone}。它会加载 tikz 包,并把 tikzpicture 环境配置为单独裁切成一页(内部设置 multi=tikzpicture 和 varwidth=false)。PSTricks 图也有对应的 pstricks 选项。
主要类选项
选项写在方括号中,用逗号分隔。standalone 的大多数选项是布尔值:省略值就得到 true;除非另有说明,初始值为 false。这些选项不会传给下层类(默认是 article),而是由 standalone 自己解释,以避免名称冲突。主要选项如下。
| 选项 | 作用 | 默认值 |
|---|---|---|
crop | 把内容装入盒子,并把页面裁到内容大小加边距 | true(自 v1.0 起) |
border | 裁切时加上的边距(别名 margin)。1 个值=四边,2 个值=水平/垂直,4 个值=左/下/右/上 | 0pt |
varwidth | 用 varwidth 环境包住内容,使含段落的内容也采用自然宽度;varwidth=<width> 设置上限 | off |
tikz | 加载 tikz,并把每个 tikzpicture 裁成单独一页(设置 multi=tikzpicture、varwidth=false) | off |
multi | 允许多页内容,每页分别裁切;可以指定标记一页的环境名 | off |
class | 选择要加载的底层类(如 class=report) | article |
preview | 通过 preview 包裁切的旧方法;与 crop 互斥,可在 TikZ 渐变出问题时作为后备 | off |
beamer | 禁用裁切,改把内容排在一个空白 beamer 帧上 | off |
最常用的是 border。写成 \documentclass[border=5pt]{standalone} 时,裁切后的图四边都会有 5pt 边距。要传递多个用空格分隔的值时,把整个值放进花括号,例如 border={10pt 5pt}。由于 border 和 varwidth 不具有全局效果,可以稍后用 \standaloneconfig{...} 修改:在导言区,或在启用 multi 时甚至在文档中途。
有一点历史差异。v1.0 以前默认使用 preview 选项,默认边距也约为 0.5bp。自 v1.0 起默认变为 crop,边距也改为 0pt。若要恢复旧行为,可以在配置文件中写 \standaloneconfig{preview,border=0.50001bp},或把这些显式写成选项。
作为包并入主文档
包是 standalone 的另一面。在主文档导言区尽量早加载 \usepackage{standalone} 后,该包会重新定义 \documentclass,使你用 \input 读入图文件时,从图文件的 \documentclass 到 \begin{document} 之间的内容都被跳过。图文件的 document 环境被当作普通 TeX 分组处理,而主文档真正的 document 环境不受影响(\end{document} 后面的内容也会被忽略)。结果就是,包含时图文件的导言区被剥离,单写 \input{figure} 就只把内容流入正文。
前提是,图文件需要的所有包也必须由主文档自己加载。因为图文件的导言区在包含时会被跳过,所以 tikz 等包必须由主文档加载。下面是官方示例:主文档加载 standalone 包,并在 figure 环境中用 \input 包含一张图。
\documentclass{article}
% load the standalone package early
\usepackage{standalone}
% load everything the sub-files need
\usepackage{tikz}
\begin{document}
% ...
\begin{figure}
\input{figure}% the standalone file from above
\caption{A sub-file}
\end{figure}
% ...
\end{document}要点是,同一个 figure.tex 无论单独编译还是经由主文档使用,都能一字不改地工作。单独编译会得到裁切好的一页 PDF;从主文档 \input 时,则只把图放进正文。建议把浮动体交给主文档管理:figure 环境、标题和标签放在主文档中,standalone 文件里只写内容本身(在 standalone 类中,float 默认是 false,以便 crop/preview 工作)。
如果希望主文档自动收集图文件导言区,可写 \usepackage[subpreambles=true]{standalone}。这样每个图文件的导言区会汇总到辅助文件中,并在下一次处理时拉入主文档。再加上 sort 选项后,各图加载的包及其选项会去重汇总,并通过 \PassOptionsToPackage 加载,以避免选项冲突。若想手动复制到主导言区,print 选项会输出清单。
构建为图像,以及相近机制
standalone 还可以不包含源文件,而是把图烘成图像后再包含。在主文档中把 \input{figure} 改写为 \includestandalone{figure},它会在需要时单独编译图文件生成图像(例如 PDF),再用 \includegraphics 读入。好处是复杂图不必每次都重新编译,主文档构建会更快。不过此功能会调用外部命令,因此编译时需要 -shell-escape 选项。
此外,convert、png、jpg、svg 等选项会启用转换功能,把 standalone 文件本身导出为图像(需要外部转换工具)。当你想把一张图单独作为 PNG 或 SVG 发布时很方便。
还有两个目标相近的机制:subfiles 和 TikZ 的 external 库。subfiles 的方向相反:子文件导入*主*文档的导言区,而 standalone 可以让子文件的导言区被导入*主*文档。因此,standalone 适合把一张图在多个文档中复用(论文、演示、学位论文等),subfiles 适合主文件与子文件一对一的关系。TikZ 的 external 则从主文件写出临时图像,方向也与 standalone 相反。
放入正文前的检查
standalone 文件的价值在于“单独就能通过”,所以在放入主文档前,先只构建图文件并用眼睛检查 PDF。毕业论文或论文中常常只替换图,因此按图的含义命名,例如 figures/experiment-flow.tex,而正文只写 \input{figures/experiment-flow},会让替换、复用和审阅都更简单。
- 检查边距。 如果边缘被裁掉,加上
border=2pt或border=5pt;如果边距太宽,先怀疑末尾空行或多余的\par。 - 保持导言区一致。 图中使用的包和设置,例如
tikz、颜色或字体,也必须由主文档加载。子文件导言区在包含时通常会被跳过。 - 浮动体放在主文件。
figure环境、标题和标签放在主文档中,standalone 文件只留下图本身。 - 提交前重新构建。 如果使用
\includestandalone或图像转换,提交前做一次干净构建,避免混入旧的缓存 PDF 或 PNG。
放进项目中的组织方式
在实际论文或技术文档中,把 standalone 文件当作图的源文件,并保持它能独立于正文检查,会很有力。例如主文件是 paper.tex,图放在 figures/ 下,正文只写 \input{figures/energy-flow}。这样修改图的人可以只编译 figures/energy-flow.tex 来确认,而主文档只管理标题、编号和引用。审阅时附上这个单独 PDF,安排一次“只看图”的检查,就能不等整篇稿件重建而提升图的质量。
paper.tex
figures/
energy-flow.tex
apparatus-layout.tex
timing-diagram.tex提交前的选择也要在这里说清楚。如果只是 \input 源文件,就不需要外部命令,普通 LaTeX 构建即可。如果使用 \includestandalone 单独构建图并作为图像包含,就把 -shell-escape 和生成文件的清理规则也写进构建设置。多人协作时,也应说明生成的 PDF 是否提交到仓库,以免旧图混进最终构建。