我正在尝试排版长度不定的页面。有时它比 A4 短,但有时它超过 A4 的长度。
我的问题是,如何检查文本是否适合一页,如果不适合,我希望尽可能多地放在一页上,然后添加类似“(缩短)“并隐藏其余文本,使其不会出现在第二页?
答案1
尝试在之前立即输入这个神奇的代码\begin{document}
\newbox\boxA
\newtoks\loutput
\loutput=\output
\let\lenddocument\enddocument
\makeatletter
\output={\outA}
\def\outA{\global\setbox\boxA=\box255 \global\output={\outB}}
\def\outB{\setbox2=\vbox{\unvbox255\vskip 0pt plus 1filll }
\global\output=\loutput
\setbox0=\vbox to\vsize{
\unvbox\boxA
\ifdim\ht2>\topskip
\vbox to0pt{
\vskip6pt
\hbox to\hsize{\hfil\small\itshape Shortened}
\vss
}\fi
}%
\unvbox0 \aftergroup\lenddocument}
这应该在最简单的情况下起作用,但引用和浮点数不(完全)受支持。
一些解释。最终页面是在 TeX 调用输出例程:它收集一页(不带页眉或页脚和脚注),将其组装到盒子寄存器编号 255 中,并执行标记列表中包含的操作\output
。在这里,我将 中的常用代码保存\output
在标记变量中,\loutput
并将其更改为\outA
。反过来\outA
意味着:将包含页面的盒子放入盒子寄存器\boxA
,然后更改输出例程以执行\outB
。由于输出例程是成组执行的,因此这里需要使用\global
。
会做什么\outB
?它将的内容发送\box255
到盒子寄存器 2 中,但“取消装箱”并添加无限粘连,因为 的正常高度\box255
是页面高度,所以我们将其缩小到其自然大小(除非有人在文档中使用了三阶无限粘连,但这种情况不太可能发生)。我们现在将输出例程恢复为 LaTeX 中的标准例程,并通过取消装箱盒子寄存器\boxA
(包含第一页)并在其后添加一个包含“缩短”指示的零高度盒子来构建一个新盒子,但前提是盒子寄存器 2 包含除 之外的内容\topskip
,因此是一些文本。
现在输出例程开始运行,因为我们拆箱寄存器 0,并在组结束时执行正常操作\end{document}
,因此不再读取纸张。
我没有进行非常广泛的测试,但看起来“正常”的论文应该可以被正确处理。
其他方法
(1)保留一堆盒子寄存器并改为\shipout
“将完成的页面放入盒子 n”并步进计数器;在工作结束时查看“盒子 2”是否为空;如果不是,则像以前一样向其中添加“缩短”标签;然后运出新的“盒子 1”。
(2)使用 pdfpages:编译论文,在辅助文件中写上页数,并编译一个仅包含第一页的新文档,如果页数>1,则添加“缩短”标签。
我的原始方法和方法 (1) 有一个缺点:对辅助文件的非立即写入会被扩展并仅在输出例程期间执行,因此我们会丢失第 1 页和第 2 页之后的所有引用。方法 (2) 不会出现这种情况,它可能是最好的方法。
环境方法
\documentclass[a4paper]{article}
\usepackage{lipsum}
\newsavebox{\shbox}\newlength{\shlen}
\newenvironment{shorten}[1][\textheight]
{\shlen=#1\relax\setbox\shbox=\vbox\bgroup}
{\egroup\doshorten}
\newcommand{\doshorten}{%
\ifdim\ht\shbox>\shlen
\edef\keepvb{\the\vbadness}\vbadness=10000 % avoid spurious messages
\setbox\shbox=\vsplit\shbox to\shlen
\vbadness=\keepvb % restore the \vbadness
\setbox\shbox=\vbox to\shlen{
\dimen0=\dp\shbox
\unvbox\shbox
\kern-\dimen0
\vbox to0pt{
\vskip12pt
\hbox to\hsize{\hfil\small\itshape Shortened}
\vss
}
\vfill
}
\fi
\begin{figure}[p]
\centering
\kern-3.4pt\hrule\kern3pt
\box\shbox
\kern3pt\hrule\kern-3.4pt
\end{figure}
}
\begin{document}
A\lipsum
\begin{shorten}
B\lipsum
\end{shorten}
\begin{shorten}[.5\textwidth]
C\lipsum
\end{shorten}
D\lipsum
\begin{shorten}
E\lipsum[2]
\end{shorten}
\end{document}
环境shorten
会将一些文本放入浮动环境(我选择了figure
);文本将被排版,并且只有适合一页的内容(或在可选参数指定的长度内)才会设置在页面浮动中。为了将此浮动与上下文区分开来,添加了前后规则。
将文本放入 中\vbox
。我们检查其高度,如果其高度小于所需高度,则不执行任何操作;否则,我们用 截去超出所需高度的部分\vsplit
,然后对框进行一些调整,添加\vfill
以解决可能出现的“未满”情况和“缩短”消息。最后,在环境中打印框,其前面和后面均有规则figure
。