在 LaTeX 中实现缩印效果
https://liam.page/
近日大概重拾了一点对 LaTeX 的兴趣,遇见这样一个问题:如何在 LaTeX 中实现缩印效果(即,将两页或更多页排版在一页纸上),并且实现水印效果的页码?
缩印
以朴素的办法实现缩印效果并不困难。例如,可以先以 LaTeX 正常输出文档,再以 pdfpages 宏包将生成的文档载入进来排版。不过,这样的做法扩展性太差,并且需要至少编译两份文档——一份是原始文档,一份是缩印框架文档。
更有技巧的办法,需要深入到 TeX 构建页面输出的过程中去。基本上来说,我们需要让 TeX 按往常一样去构建页面,但是在 TeX 准备将页面输出(shipout)时我们需要插入一个钩子。这个钩子做两件事情:
- 打断输出过程;
- 将整个页面内容保存在一个盒子中备用。
我们将保存在盒子里的页面称为逻辑页面(logic pages)。而后,当保存的页面足够多时,或没有更多页面需要保存时,将这些盒子的内容成比例缩小并列印在页面上。我们将最终输出的页面称之为物理页面。
pgfpages 就是这样做的。它是 PGF 宏集的一部分,因而使用 texdoc pgf 可以看到它的文档(Section 89)。
首先我们从一个简单的例子开始,其效果见这里。
1 |
documentclass{article}
|
这里,pgfpagesuselayout 命令是实现缩印效果的核心命令。参数 2 on 1 的含义不言自明。其后的可选参数:a4paper 表示物理页的尺寸是标准 A4 纸;landscape 表示要将物理页横过来——毕竟是二合一缩印,这很合理;border shink = 5mm 表示被缩印的逻辑页会被继续缩小,并在每个逻辑页的上下左右四周保留宽度为 5mm 的边框。
类似地,你也可以缩印 beamer 幻灯片。不过,由于 beamer 幻灯片的逻辑页本就是横着的,所以此处不需要在加 landscape 参数了。
相应的,
4 on 1需要加,6 on 1和8 on 1不需要加,以及16 on 1又需要加。——32 on 1是不存在的……
1 |
documentclass{beamer}
|
页码
在当前问题中,TeX 默认的页码机制实际上是作用在各个逻辑页上的。但显然,我们可能会想要为物理页编上页码。这里有两个问题需要解决:
- 物理页的页码如何确定?
- 缩印排版,有效内容字体很小且密集,如何保证物理页页码可见且不影响有效内容的阅读?
对于第一个问题,有两种思路。
一是读取逻辑页页码 page 计数器,然后按 x on 1 的比例做除法,得出物理页的页码。不过,这种方式是有前提的。具体来说,它要求 TeX 的逻辑页页码功能不在缩印的情况下失效,并且它要求 TeX 能正确计算整数除法(向上取整)。总得来说,这是一种快而脏的解法,不推荐。
如果十年以后,你以快而脏的方式做什么事的时候,能想象我在你的肩后看着,然后对自己说:「Dijkstra 不会希望这样的。」那么对我来说,这就和永生一样了。
—— Edsger Wybe Dijkstra
另一种思路则更加直接。既然页码本质是由计数器实现的,这一计数器随页面输出而自增,而 pgfpages 影响的正是 TeX 页面输出的逻辑,那么 pgfpages 内必然有什么地方可以下钩子来自增该计数器。
1 |
newcommandpgfshipoutphysicalpage{%
|
通过翻阅 pgfpages.sty 的源码,我们不难发现有以上代码和物理页输出有关。可以说,PGF 宏集的代码风格相当好,一眼就能看明白代码在做什么。显然,pgfpages@shipoutshipoutbox 是在输出物理页,而它之前的 pgfpages@buildshipoutbox 就是将逻辑页构建成物理页的过程了。因此,我们需要在 pgfpages@buildshipoutbox 当中下钩子;此时我们又要用到老朋友 etoolbox 当中的 patchcmd 了。
1 |
newcounter{physicalpage}
|
第二个问题可能有多种解决思路。我偏好于在页面中央以水印的形式加一个大大的页码。四年多以前,我利用 TikZ 实现了水印功能。TikZ 也是 PGF 宏集的一部分,用在这里正好。于是,我们的代码变为
1 |
% require packages: pgfpages, etoolbox, xcolor, tikz |
实际效果
将以上代码综合起来,我做了一个简单的 demo。
1 |
documentclass[12pt]{article}
|

在 LaTeX 中实现缩印效果的更多相关文章
- 如何在latex 中插入EPS格式图片
如何在latex 中插入EPS格式图片 第一步:生成.eps格式的图片 1.利用visio画图,另存为pdf格式的图片 利用Adobe Acrobat裁边,使图片大小合适 另存为.eps格式,如下图所 ...
- Latex中画出函数文件的调用关系拓扑图
流程图,思维导图,拓扑图通常能把我们遇到的一些复杂的关系结构用图形的方式展现出来.在Latex中要想画这样的拓扑图,有一个很好用的绘图工具包 pgf/tikz . 1.pgf/tikz的安装:pgf/ ...
- Latex中插入C语言代码
Latex是一个文本排版的语言,能排版出各种我们想要的效果.而且用代码排版的优点是易于修改板式,因此在文本内容的排版时,Latex应用十分广泛. 当我们需要在Latex中插入代码时,就需要用到 \us ...
- Latex中cls和sty文件有何区别?
Latex中cls和sty文件有何区别? 资源 本文对 LaTeX 中 .cls 和 .sty 文件进行介绍,主要参考了 What are .cls and .sty files?How are th ...
- 在LaTeX中配置西夏文字体与环境
目录 1 配置字族 2 粗体.斜体设定 3 文本编辑器的字体设定(以Sublime Text为例) 4 附录:一些字体的下载源 警告:这篇文章的部分内容需要西夏文字体才能正常显示.若您需要安装,可参考 ...
- LaTeX 中插入图片使其紧跟插入的文字之后
LaTeX 中插入图片使其不跑到每页的开头而紧跟插入的文字之后. 此次建模过程中,遇到的一个比较棘手的问题是: 当插入图片时,图片的位置总是会自动跑到当页(或下一页)的最上方,而不是紧跟在其对应的说明 ...
- 一个LaTeX 中文文档的简单而实用的模板
网上找的一个latex中文模板,感觉很简单,在我机器上有点小问题,完善记录一下. %要运行该模板,LaTex需要安装CJK库以支持汉字. %字体大小为12像素,文档类型为article %如果你要写论 ...
- LaTex 中圆圈序号及一些特殊字符的输入
众所周知,LATEX 提供了 \textcircled 命令用以给字符加圈,但效果却不怎么好: 实际上,加圈并不是一个平凡的变换,它会涉及到圈内字符形状的微调,而这是几乎无法在 TEX 宏层面解决的. ...
- m.jd.com首页中的js效果
m.jd.com中的部分js效果 昨天把m.jd.com的首页布局写好了,今天写一下首页中部分js效果.头部背景色透明度的改变,焦点图轮播,京东快报的小轮播,以及秒杀倒计时.这里html,css样式就 ...
随机推荐
- msgfmt - 翻译汉化
说明 目前大部分自由软件实现国际化使用的是gettext. 国际化就是让程序可以使用多国语言来显示程序里的字符串. 程序里一般都有很多字符串,菜单名也好,错误信息也好,都是字符串.假设字符串为stri ...
- 吴裕雄--天生自然 PYTHON3开发学习:输入和输出
str = input("请输入:"); print ("你输入的内容是: ", str) # 打开一个文件 f = open("/tmp/foo.t ...
- set theory
set theory Apart from classical logic, we assume the usual informal concept of sets. The reader (onl ...
- flask学习笔记1.21
先新建一个文件夹 templates from flask import Flask #创建Flask应用程序实例 #需要传入__name__,作用是为了确定资源所在的路径 app = Flask( ...
- [ZJOI2019]开关(生成函数+背包DP)
注:以下p[i]均表示概率 设F(x)为按i次开关后到达终止状态方案数的EGF,显然F(x)=π(ep[i]x/p+(-1)s[i]e-p[i]x/p)/2,然而方案包含一些多次到达合法方案的状态,需 ...
- S5P4418开发板android源码下uboot和内核缺省文件的配置
uboot 需要配置缺省文件,进入解压的源码目录 android,然后进入 u-boot 目录,如下图所示.如上图所示,如果是 1G 核心板,则使用“cp nsih-1G16b-4418.txt ns ...
- 25)PHP,数据库定义
(1)数据库定义语句: create database [if not exists ] 数据库名 [charset 字符集] [collate 字符排序规则]: 说明: ,if not exists ...
- Educational Codeforces Round 48 (Rated for Div. 2)异或思维
题:https://codeforces.com/contest/1016/problem/D 题意:有一个 n * m 的矩阵, 现在给你 n 个数, 第 i 个数 a[ i ] 代表 i 这一行所 ...
- openfire配置好文
http://www.th7.cn/db/mysql/201406/59838.shtml 下载地址:Openfire 3.8.2 Release
- 系统学习Javaweb6----JavaScript2
感想:感觉自己还是只是学到皮毛,仍需继续努力,明天开始需要学习Android和阅读感想的书写. 学习笔记: 2.3.运算符 JavaScript运算符与java运算符基本一致. 这里我们来寻找不同点进 ...