如何检查文本是否适合一页?

如何检查文本是否适合一页?


我正在尝试排版长度不定的页面。有时它比 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

相关内容