测量一个非常大的 \vbox

测量一个非常大的 \vbox

我想测量\vbox大于的盒子的总高度\maxdimen。如果代码只正确计算小盒子的总高度就足够了。对于非常大的盒子,“非常大”声明就足够了。

我按照以下回答中的建议去做了 mdframed 中的长帧 并制作了以下测试代码,该代码能够\vbox正确测量总高度高达 4 倍的程度\maxdimen

\documentclass{article}

\usepackage{blindtext}

\begin{document}

\newbox\largebox
\newdimen\measuredHeight

\newcommand*{\measureBox}[1]{%
  \chardef\previousinteractionmode=\interactionmode%
  \batchmode%
  \measuredHeight=\dimexpr\ht#1+\dp#1\relax%
  \ifdim\measuredHeight<0pt\relax%
    \measuredHeight=\maxdimen%
  \else\ifdim\measuredHeight=0pt\relax%
    \ifdim\ht#1>0pt\relax%
      \measuredHeight=\maxdimen%
  \fi\fi\fi%
  \interactionmode\previousinteractionmode%
}

\newcommand*{\blindtexttest}[1]{%
  Blindtext[#1]:
  \setbox\largebox\vbox{\blindtext[#1]}%
  \measureBox{\largebox}%
  total height
  \ifdim\measuredHeight<\maxdimen\relax
    \the\measuredHeight%
  \else%
    \the\maxdimen\ or larger%
  \fi%
  \par%
}

\newcount\mytest
\mytest=0
\loop
  \advance\mytest by 1
  \blindtexttest{\the\mytest}
\ifnum\mytest<550\repeat

\end{document}

在此处输入图片描述

...

在此处输入图片描述

缺点是,此代码在日志文件中生成了大量消息。这些消息是正确的,但很烦人! Arithmetic overflow! Dimension too large

因此,我的第一个问题是:我该如何隐藏这些信息?我该如何让命令\measureBox尽可能安静?

我的问题是:您能给我一个更好的代码吗\measureBox?此宏将一个框寄存器作为参数,并将计算或猜测的总高度保存到中\measuredHeight

更好的代码会给出更少的烦人的消息,并且如果可能的话,会测量大于 4 倍的盒子\maxdimen

答案1

TeX 中允许的尺寸范围是 (-2 30 +1) sp 到 (2 30 -1) sp,后者是\maxdimen(16383.99998 pt)。但是,如果将尺寸用作数字,TeX 将尺寸寄存器存储为 32 位数字,并且不会检查允许的尺寸范围。

如果大框的高度不为负数,那么我们可以测量从 0pt 到 65535.99998 pt 的框的高度,即 4 * \maxdimen+ 3 sp = (2 32 - 1) sp。如果框的高度更大,那么我们只能获得高度的最低 32 位,因为 TeX 将高度存储为 32 位数字。因此,不知道该值是否正确,或者是否必须添加 2 32 sp的整数倍,并且可以添加短语“或更大”全部值。

以下示例定义了\DefPositiveDimenValue。它将 dimen 值作为第二个参数(盒子的高度/深度/宽度,dimen 寄存器,...)并将单位为 pt 的值存储在宏中,作为第一个参数给出。大于的值\maxdimen通过包计算fp

\documentclass{article}

\usepackage{blindtext}
\newbox\largebox

\usepackage{fp,fp-snap}
\makeatletter

\newcommand*{\DefPositiveDimenValue}[2]{%
  \ifnum#2<0 %
    \begingroup
      \FPmessagesfalse
      \count@=#2\relax
      \advance\count@ by 2147483647\relax
      \advance\count@ by 1\relax
      \ifnum\count@<\maxdimen
        \FPadd#1{\strip@pt\dimexpr\count@ sp}{32768}%
      \else
        \advance\count@ by -1073741824\relax
        \FPadd#1{\strip@pt\dimexpr\count@ sp}{49152}%
      \fi
      \FPclip#1#1%
      \edef\x{\endgroup
        \edef\noexpand#1{#1pt}%
      }%
    \x  
  \else
    \edef#1{\the#2}%
  \fi
}
\makeatother

\newcommand*{\blindtexttest}[1]{%
  Blindtext[#1]:
  \setbox\largebox\vbox{\blindtext[#1]}%
  \DefPositiveDimenValue\TotalHeight{\ht\largebox}%
  total height \TotalHeight\par
}

\begin{document}

\newcount\mytest
\mytest=0
\loop
  \advance\mytest by 1
  \blindtexttest{\the\mytest}
\ifnum\mytest<550\repeat

\end{document}

末尾且超出支持范围的值:

结果

相关内容