1

My goal is to typeset a short, centered text in a way that the difference in line lengths is minimal. Or, to put it differently: In a way that the width of the block is minimal without increasing its height.

I am currently doing so by manual experimentation, but that doesn't scale.

\documentclass{article}

\usepackage{xltxtra}
\usepackage[paperheight=98mm,paperwidth=65mm,top=3mm,left=3mm,right=3mm,bottom=3mm,showframe]{geometry}
\setlength{\parskip}{5mm}
\newcommand{\shortlipsum}{Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit, vestibulum ut, placerat ac, adipiscing.}

\begin{document}
\begin{center}

\shortlipsum

\parbox{48mm}{\centering\shortlipsum}

\parbox{44mm}{\centering\shortlipsum}

\parbox{43mm}{\centering\shortlipsum}

\end{center}
\end{document}

rendered version of previous code block

The first paragraph is in default center formatting, I then try to fit it in an ever smaller box until the number of lines increases in the fourth paragraph. So the third one would be the desired formatting here (missing extra points for not trying a higher resolution than 1mm for me).

I found out that measuring height isn't that easy because the height might change slightly depending on the depth of the last line, for example. I would like to accept those height changes. I tried to count the number of lines (Count Lines in a Block of Text) but I did not even come close to a solution that way.

I am currently using XeLaTeX to get system fonts, but might switch to LuaLaTeX as well if that would make any difference in finding a good solution here.

0

enter image description here

\documentclass{article}

% just use fontspec, not this \usepackage{xltxtra}
\usepackage[paperheight=98mm,paperwidth=65mm,top=3mm,left=3mm,right=3mm,bottom=3mm,showframe]{geometry}
\setlength{\parskip}{5mm}
\newcommand{\shortlipsum}{Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit, vestibulum ut, placerat ac, adipiscing.}

\long\def\zzz#1#2{%
\dimen0=#1\relax
\sbox0{\parbox{\dimen0}{\centering#2\par\global\count1=\prevgraf}}%
\loop
\advance\dimen0 -1mm\relax
\sbox2{\parbox{\dimen0}{\centering#2\par\global\count3=\prevgraf}}%
\ifnum\count3<2\relax\count3=2\relax\fi
\ifnum\count3=\count1\relax
\setbox0\box2\relax
\repeat
\usebox0\relax
}

\begin{document}
\begin{center}

\shortlipsum


\zzz
{48mm}% initial guess
{\shortlipsum} % text

\end{center}
\end{document}
| improve this answer | |
  • Wow, thanks for the quick solution. Do you have a hint where to start reading to learn to understand it? :-) I'd like to do similar things on my own in the future. I bet there is a better place to start compared to looking up each of the commands in a reference. – olsn May 27 at 14:53
  • the \loop and \advance parts are plain tex and tex primitives, so the TeXBook is the canonical reference – David Carlisle May 27 at 18:22
  • I just discovered a problem with your solution and I fail to figure out why it is breaking: When I add more formatting in the parbox (for demonstration: a linebreak), your loop is going one step too far: \newcommand{\shortlipsum}{Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit, vestibulum ut, placerat ac,\\\hspace{20mm}adipiscing.} Expected: should still shrink to 44mm width, but is shrinking further, increasing total height. – olsn May 31 at 21:00
  • \\ starts a new paragraph under \centering so \prevgraf is always going to be 1 and it's going to be very confused. If you need multiple paragraphs you need another measure. As you are boxing teh trial anyway you can probably test \ht0 the height of thetest box at each loop – David Carlisle May 31 at 21:39
  • Just in case anybody comes across this later: I learned a bit and could now add a line \ifnum\count3<2\relax\count3=2\relax\fi before the original \ifnum. This avoids a loop when less than 2 words are in the argument. – olsn Jun 8 at 18:23

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.