5

This one has me stumped. The idea is to pack boxes (in this case, \rule) together tightly while allowing them to break at the end of a line. It works without geometry, but not with.

Another package (which I haven't isolated yet) causes gaps between the boxes.

\documentclass{article}
\usepackage{geometry}% works when commented out

\newcommand{\block}{\rule{0.5\textwidth}{1pt}\allowbreak}
\parindent=0pt

\begin{document}
\block
\block
\block
\block
\end{document}
7

geometry changes the page size unless you use options to prevent that,

\documentclass{article}
\showthe\textwidth
\usepackage{geometry}% works when commented out
\showthe\textwidth

\newcommand{\block}{\rule{0.5\textwidth}{1pt}\allowbreak}
\parindent=0pt

\begin{document}
\block
\block
\block
\block
\end{document}

You see the same without geometry but with the same page width

\documentclass{article}

\textwidth=430.00462pt

\newcommand{\block}{\rule{0.5\textwidth}{1pt}\allowbreak}
\parindent=0pt

\begin{document}
\block
\block
\block
\block
\end{document}

In either case, due to rounding errors, you can't fit two blocks exactly filling a line.....

  • Ah, yes, rounding errors... So, a tiny-tiny bit of stretchable and shrinkable glue should be enough in all cases, right? – frougon May 28 at 21:48
  • So why does it try to cram 3 in where even two won't fit? Aha, I need some glue! – John Kormylo May 28 at 21:49
  • I guess: when the rounding errors say that two aren't enough, there we are: let's take a third one... – frougon May 28 at 21:50
  • 1
    @frougon yes in this case two blocks are 1sp short of a line but there is no flexibility so tex tries to stuff another block into that 1sp of space..... – David Carlisle May 28 at 21:51
  • BTW, \hspace{0pt plus 1pt minus 1pt} fixes the problem. – John Kormylo May 28 at 22:03
6

According to TeX, 0.5\textwidth+0.5\textwidth may not be equal to \textwidth.

When geometry sets the text width to 430.00462pt, this is precisely what happens. The sum of the widths of two rules falls 1sp short of the textwidth and TeX tries to stick another rule in the first line, having no stretchability available.

However, you can do more accurate computations:

\documentclass{article}
\usepackage{geometry}% works when commented out
\usepackage{xfp}

\newcommand{\block}{\rule{\fpeval{0.5\textwidth}pt}{1pt}\allowbreak}
\parindent=0pt

\begin{document}
\block
\block
\block
\block\unpenalty % to avoid the spurious underfull box message

\bigskip

\begin{tabular}[t]{llll}
Method & half & half + half & text width\\
\hline
\TeX & \the\dimexpr 0.5\textwidth\relax & \the\dimexpr 0.5\textwidth + 0.5\textwidth\relax &
\the\textwidth \\
l3fp & \fpeval{0.5\textwidth}pt & \fpeval{0.5\textwidth+0.5\textwidth}pt
\end{tabular}

\end{document}

enter image description here

The length 0.5\textwidth, according to TeX is 14090391sp, whereas the text width is 28180783.

You can solve the issue by defining the rule differenly:

\documentclass{article}
\usepackage{geometry}% works when commented out

\newcommand{\block}{\rule{0.5\textwidth}{1pt}\allowbreak\hspace{0pt plus 1sp}}
\parindent=0pt

\begin{document}
\block
\block
\block
\block

\end{document}

Another famous case: if you try

\setbox0=\hbox to 2in{\hskip 1in \hskip 1in}

you'll get Underfull \hbox (badness 10000) because two one inch skips fall 1sp short of two inches.

  • Thanks for the insight! In such operations, are the rounding errors (by TeX) always towards zero, always towards $-\infty$, or is it variable? (in the last case, unless I'm mistaken, your \hspace{0pt plus 1sp} solution would rely on a large enough value of \hfuzz—like David Carlisle's \raggedright, BTW) – frougon May 28 at 22:41
  • 1
    @frougon Always truncation, so \hfuzz is not really relevant, because it is about slight overfull, rather than underfull. – egreg May 28 at 23:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.