在 LaTeX 中实现缩印效果

https://liam.page/

近日大概重拾了一点对 LaTeX 的兴趣,遇见这样一个问题:如何在 LaTeX 中实现缩印效果(即,将两页或更多页排版在一页纸上),并且实现水印效果的页码?

缩印

以朴素的办法实现缩印效果并不困难。例如,可以先以 LaTeX 正常输出文档,再以 pdfpages 宏包将生成的文档载入进来排版。不过,这样的做法扩展性太差,并且需要至少编译两份文档——一份是原始文档,一份是缩印框架文档。

更有技巧的办法,需要深入到 TeX 构建页面输出的过程中去。基本上来说,我们需要让 TeX 按往常一样去构建页面,但是在 TeX 准备将页面输出(shipout)时我们需要插入一个钩子。这个钩子做两件事情:

  • 打断输出过程;
  • 将整个页面内容保存在一个盒子中备用。

我们将保存在盒子里的页面称为逻辑页面(logic pages)。而后,当保存的页面足够多时,或没有更多页面需要保存时,将这些盒子的内容成比例缩小并列印在页面上。我们将最终输出的页面称之为物理页面。

pgfpages 就是这样做的。它是 PGF 宏集的一部分,因而使用 texdoc pgf 可以看到它的文档(Section 89)。

首先我们从一个简单的例子开始,其效果见这里。

demo-2on1-landscape.tex
12345678
documentclass{article}usepackage{pgfpages}pgfpagesuselayout{2 on 1}[a4paper, landscape, border shrink = 5mm]begin{document}This text is shown on the left.clearpageThis text is shown on the right.end{document}

这里,pgfpagesuselayout 命令是实现缩印效果的核心命令。参数 2 on 1 的含义不言自明。其后的可选参数:a4paper 表示物理页的尺寸是标准 A4 纸;landscape 表示要将物理页横过来——毕竟是二合一缩印,这很合理;border shink = 5mm 表示被缩印的逻辑页会被继续缩小,并在每个逻辑页的上下左右四周保留宽度为 5mm 的边框。

类似地,你也可以缩印 beamer 幻灯片。不过,由于 beamer 幻灯片的逻辑页本就是横着的,所以此处不需要在加 landscape 参数了。

相应的,4 on 1 需要加,6 on 18 on 1 不需要加,以及 16 on 1 又需要加。——32 on 1 是不存在的……

demo-2on1.tex
1234567891011
documentclass{beamer}usepackage{pgfpages}pgfpagesuselayout{2 on 1}[a4paper, border shrink=5mm]begin{document}begin{frame}This text is shown at the top.end{frame}begin{frame}This text is shown at the bottom.end{frame}end{document}

页码

在当前问题中,TeX 默认的页码机制实际上是作用在各个逻辑页上的。但显然,我们可能会想要为物理页编上页码。这里有两个问题需要解决:

  • 物理页的页码如何确定?
  • 缩印排版,有效内容字体很小且密集,如何保证物理页页码可见且不影响有效内容的阅读?

对于第一个问题,有两种思路。

一是读取逻辑页页码 page 计数器,然后按 x on 1 的比例做除法,得出物理页的页码。不过,这种方式是有前提的。具体来说,它要求 TeX 的逻辑页页码功能不在缩印的情况下失效,并且它要求 TeX 能正确计算整数除法(向上取整)。总得来说,这是一种快而脏的解法,不推荐。

如果十年以后,你以快而脏的方式做什么事的时候,能想象我在你的肩后看着,然后对自己说:「Dijkstra 不会希望这样的。」那么对我来说,这就和永生一样了。
—— Edsger Wybe Dijkstra

另一种思路则更加直接。既然页码本质是由计数器实现的,这一计数器随页面输出而自增,而 pgfpages 影响的正是 TeX 页面输出的逻辑,那么 pgfpages 内必然有什么地方可以下钩子来自增该计数器。

123456789
newcommandpgfshipoutphysicalpage{%  [email protected]>0relax%    [email protected]%    [email protected]%    [email protected]%    globalpgfphysicalpageemptytrue%    [email protected]%  fi%}

通过翻阅 pgfpages.sty 的源码,我们不难发现有以上代码和物理页输出有关。可以说,PGF 宏集的代码风格相当好,一眼就能看明白代码在做什么。显然,[email protected] 是在输出物理页,而它之前的 [email protected] 就是将逻辑页构建成物理页的过程了。因此,我们需要在 [email protected] 当中下钩子;此时我们又要用到老朋友 etoolbox 当中的 patchcmd 了。

1234567891011

newcounter{physicalpage}makeatletterpatchcmd{[email protected]}{%  [email protected]}{%  [email protected]  stepcounter{physicalpage}%}{}{}makeatother

第二个问题可能有多种解决思路。我偏好于在页面中央以水印的形式加一个大大的页码。四年多以前,我利用 TikZ 实现了水印功能。TikZ 也是 PGF 宏集的一部分,用在这里正好。于是,我们的代码变为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
大专栏  在 LaTeX 中实现缩印效果pan class="line">17

时间: 2024-10-12 15:29:38

在 LaTeX 中实现缩印效果的相关文章

如何在latex 中插入EPS格式图片

如何在latex 中插入EPS格式图片 第一步:生成.eps格式的图片 1.利用visio画图,另存为pdf格式的图片 利用Adobe Acrobat裁边,使图片大小合适 另存为.eps格式,如下图所示: 注:这一步必须按照图示方式另存为,不能直接强行改后缀名,否则插入后无法显示. 2.利用matlab画图,直接另存为eps格式即可 第二步:插入代码 1.添加宏包   \usepackage{graphicx}     \usepackage{epstopdf} 2.将.eps图片和.tex文件

Latex中插入C语言代码

Latex是一个文本排版的语言,能排版出各种我们想要的效果.而且用代码排版的优点是易于修改板式,因此在文本内容的排版时,Latex应用十分广泛. 当我们需要在Latex中插入代码时,就需要用到 \usepackage{listings} 宏包.例如插入一个简单的C语言代码 #include <stdio.h> int main(int argc, char ** argv) { printf("Hello, world!\n"); return 0; } 要将上面 Hell

在LaTeX中利用preview宏包和tikz宏包生成单图pdf

有时候我们利用tikz宏包画出的图片后,只想生成一个单图pdf,而且pdf的页面大小与图片相同,以便于以后再次用latex插入. 可以与preview宏包进行搭配,页面大小由图像大小决定,可以通过改变\PreviewBorder的值来改变页边界的空白大小. 效果如下: 代码如下: 1 \documentclass{beamer} 2 \usepackage{tikz} 3 \usetikzlibrary{arrows,snakes,backgrounds} 4 \usepackage[activ

LaTeX 中列表环境的使用

列表就是将所要表达的内容分为若干个条目并按一定的顺序排列,达到简明.直观的效果.在论文的写作中会经常使用到列表.LaTeX 中常见的列表环境有 enumerate.itemize 和 description.这三种列表环境的主要区别是列表项标签的不同: 1. enumerate 是有序的列表.例如: 1 \begin{enumerate} 2 \item This is the first item 3 \item This is the second item 4 \item This is

在LaTeX中配置西夏文字体与环境

警告:这篇文章的部分内容需要西夏文字体才能正常显示.若您需要安装,可参考本文的第四部分. 赖云帆已经在他的博客里发布了在LaTeX中排印西夏文的基本方法.这里多说一点. 1 配置字族 我的做法是:直接占用sans字族,将其用于打印西夏文.对于中国的研究者,排西夏文的时候肯定是和汉文混排,所以还是建议直接上xeCJK宏包(或ctex宏包),免得麻烦多: \usepackage{xeCJK} \setCJKmainfont{华文仿宋} % 景永时字体比较接近于仿宋的字形,搭配效果较好 \setCJK

HTML和CSS中的居中效果(1)

HTML和CSS中的居中效果 单行上下左右居中 Html: <div class="container"></div> CSS: .container{ width: 600px; height: 300px; text-align: center; line-height: 300px; border: 1px solid green; } 固定高宽上下左右居中 Html: <div class="container"><

The usage method of reference with bibtex in Latex【latex中参考文献的使用方法】

如何在latex中以Bibtex文件方式引用参考文献? 以IEEEtran模板为例: 1.制作bibtex参考文献库.方法如下: ①建立myreference.bib文件: ②在Google scholar上找到某一篇文献的bibtex格式,如下图: ③复制该内容到myreference.bib文件中,类似的操作,直至制作好参考文献库. 2.在需要生成参考文献的地方插入“引用样式”和“文件名称”的代码 \bibliographystyle{IEEEtran} \bibliography{myre

气泡图在开源监控工具中的应用效果

气泡图在开源监控工具中的应用 Bubble Chart(气泡图),使用气泡图便于在行.列两个方向同时进行比较.气泡图也清晰地告诉哪里大哪里小,图1~图5为你展示几款开源监控工具在使用气泡图时的应用场景. 图1 气泡图直观感受 图2 气泡图在NTOP中的应用效果 图3 气泡图在OSSIM中的应用效果 图4  气泡图在日志分析工具Gltail中的应用效果 图5 气泡图在日志分析工工具Gource中的应用效果 以上就是气泡图的一些基本应用,当然在监控工具中除了气泡图还有饼图.柱状图.雷达图.波浪图等多

Latex使用:在latex中添加算法模块

在Miktex下有三个latex algorithm包,分别为:algorithm,algorithmic,algorithm2e三个,其中algorithm,algorithmic经常成套使用: latex中algorithm模板为: latex文件中顶端加入的package: \usepackage{algorithm} \usepackage{algorithmic} \usepackage{setspace} 算法块代码: \begin{algorithm}[htb] \setstret