# Ensuring a paragraph uses at least a given height?

I'm making a custom document class based on memoir, and I don't know how to implement the chapter precis so that it does what I want (the chapter precis is a small optional paragraph that follows chapter headings).

I'd like the actual first paragraph of the chapter to start at a fixed vertical position below the chapter heading, unless the precis is very long, in which case it should push the first paragraph down. Here's what it currently looks like:

I have \setlength{\afterchapskip}{4\baselineskip} (distance from chapter heading to 1st paragraph), and \setlength{\prechapterprecisshift}{-3\baselineskip} (taken out of \afterchapskip if there is a precis). If I don't find a solution, I'll arrange for the spacing after the precis to be 2\baselineskip so one-line precis won't move the 1st paragraph. However, I'd like two-lines precis to still not push the 1st paragraph down.

Given the way memoir defines \chapterprecis and offers \prechapterprecis and \postchapterprecis hooks, I'm not sure how I can measure the height of the precis. I've also thought making about some sort of paragraph-level strut, but I don't know how (inserting a normal zero-width rule at the beginning of the precis text changes the height of its first line, not of the precis as a whole).

## Edit — my current solution

I've slightly adapted @Gonzalo's approach to simplify the height comparison. The minibox also needed its [t] argument:

\newlength{\postchapterprecisskip}
\setlength{\prechapterprecisshift}{3\baselineskip}
\setlength{\postchapterprecisskip}{\baselineskip}
\renewcommand\prechapterprecis{\vspace*{-\prechapterprecisshift}}
\renewcommand\postchapterprecis{\vspace*{\postchapterprecisskip}}
\newsavebox\sba@precisbox
\newlength\sba@precisboxht
\newlength\sba@precisboxdp
\renewcommand\chapterprecishere[1]{%
\begin{lrbox}{\sba@precisbox}%
\begin{minipage}[t]{\linewidth}%
\prechapterprecis
\flushright
\begin{balanced}{\linewidth}%
\precisfont\strut##1\strut%
\end{balanced}%
\postchapterprecis
\end{minipage}%
\end{lrbox}%
\settoheight\sba@precisboxht{\usebox\sba@precisbox}%
\settoheight\sba@precisboxdp{\usebox\sba@precisbox}%
\usebox{\sba@precisbox}\par\unskip%
\ifnum\sba@precisboxht<0pt
\vspace*{-\sba@precisboxht}
\fi}


For chapters with a precis it works nicely, with a consistent vertical position of the first chapter that gets pushed down as soon as the precis takes more than 2 lines.

However, there is a slight shift compared to the first paragraph without a precis (slightly lower. That shift is influenced by adding \hrule so I'm guessing it's an issue with \par or \parskip… any idea?

### Edit — Accepted solution

I haven't had much time to adopt one particular solution in my code; I've accepted David's answer because it uses an original technique, but Gonzalo's is probably a bit more general, with some tweaking of the surrounding whitespace.

-
 What about putting the precis in a box and measuring its height? (I don't know how memoir handles it, though, so it might not be an easy option.) – mbork Mar 16 at 20:38 Yes… the behavior I want is similar to list labels or hanging paragraph titles, and they go the box-and-measure-it way too… But the precis is typeset by a macro defined as \prechapterprecis #1\postchapterprecis, so it's tricky; in the end, I think I will have to forget about those hooks and redefine the whole macro, but I wonder if there is a nicer solution. – Damien Pollet Mar 16 at 20:59

As an alternative to boxing, this just uses \prevgraf to see how many lines were in the previous paragraph and adds \baselineskip spacing if it is less than a certain amount (3) in this example, which means that 1,2 or 3 line paragraphs take the same space but a 4 line one pushes the following text down.

Please note you should always provide a full working document in the question: as you didn't I have borrowed one from Gonzalo's answer.

\documentclass[openany]{memoir}% option openany just for the example
\usepackage{lipsum}

\renewcommand\chapterprecishere[1]{%
\prevgraf0
\prechapterprecis #1\postchapterprecis
{\count0 \numexpr3-\prevgraf\relax
\precisfont% just needed in case this did a size change so get right baselien
\ifnum\count0 >0 \vspace{\count0 \baselineskip}\fi}}

\begin{document}

\chapter{Test Chapter One}
\chapterprecishere{Test test test test test test test test test test test test test
test test test test test test test test test test test test test test test test}
\lipsum[4]
\chapter{Test Chapter Two}
\chapterprecishere{Test test test test test}
\lipsum[4]
\chapter{Test Chapter Three}
\chapterprecishere{Test test test test test test test test test test test test test test
test test test test test test test test test test test test test test test test test test test
test test test test test test test}
\lipsum[4]
\chapter{Test Chapter Four}
\chapterprecishere{Test test test test test test test test test test test test test test
test test test test test test test test test test test test test test test test test test test
test test test test test test test test test test test test test test test test test test}
\lipsum[4]
\chapter{Test Chapter Five}
\chapterprecishere{} % need this or need to hook the measuring code elsewhere
\lipsum[4]
\chapter{Test Chapter Six}
\chapterprecishere{Test test}
\lipsum[4]

\end{document}


If \postchapterprecis might use some decoration such as a (latex) rule or other decoration that resets \prevgraf a more general version would save \prevgraf and \baselineskip inside the precis, and then use them outside to adjust the spacing, so

\renewcommand\chapterprecishere[1]{%
\prevgraf0
\prechapterprecis #1%
\par
\xdef\precistmp{\noexpand\precisskip{\the\prevgraf}{\the\baselineskip}}%
\postchapterprecis
\precistmp}


so \precistmp will expand to something like

 \precisskip{3}{25pt}


so you need to define that command to do whatever you want to do if there was a 3 line paragraph on 25pt baseline. Say:

\def\precisskip#1#2{{%
\count0 \numexpr3-#1\relax
\dimen0=#2 %
\ifnum >0 \vspace{\count0 \dimen0}\fi}}

-
 \prechapterprecis might change the font size and the baseline skip, so probably the code should go before \postchapterprecis (assuming it only does \par and doesn't add to the paragraph). – egreg Mar 17 at 17:36 @egreg using knowledge about the class is cheating. I suppose I'll delete then, shame, prevgraf doesn't get many chances to come out of the dark:-) – David Carlisle Mar 17 at 17:38 actually I'll undelete, if the fontsize in the precis is changed then the same font should be used inside the calculation group so the right value of \baselineskip is used. – David Carlisle Mar 18 at 22:38 Sorry about the MWE… for reference, the actual code is on github. I'm curious, what are the limitations of your solution, besides changing \baselineskip inside the precis text? E.g what if \postchapterprecis is a \hrule? – Damien Pollet Mar 19 at 13:52 @DamienPollet Example added at end of answer – David Carlisle Mar 19 at 14:41

If I understand correctly your question, you can box the precis, measure its total height (height+depth) and conditionally decide (depending on the calculated box height) whether to add or not some vertical spacing using a redefinition of \postchapterprecis; all this is done inside an appropriate redefinition of \chapterprecishere; something along these lines:

\documentclass[openany]{memoir}% option openany just for the example
\usepackage{lipsum}

% this is just for drawing a green rule on every page and test the code
% it can be safely deleted
\usepackage[contents={},angle=0,scale=1]{background}
\usetikzlibrary{calc}
\backgroundsetup{contents={%
\begin{tikzpicture}[overlay]
\draw[green,ultra thick] ( $(current page.west) + (0,3.02cm)$ )-- ++(2\textwidth,0);
\end{tikzpicture}}}
% end of the code drawing the line

\newsavebox\mybox
\newlength\myboxht
\newlength\myboxdp

\setlength\afterchapskip{4\baselineskip}
\renewcommand\chapterprecishere[1]{%
\begin{lrbox}{\mybox}
\begin{minipage}{\dimexpr\linewidth-\leftmargin-25pt\relax}
\precisfont #1
\end{minipage}%
\end{lrbox}%
\settoheight\myboxht{\usebox\mybox}%
\settoheight\myboxdp{\usebox\mybox}%
\ifnum\myboxht>\dimexpr\baselineskip\relax
\renewcommand\postchapterprecis{\end{quote}}
\else
\renewcommand\postchapterprecis{\end{quote}\vskip\baselineskip}
\fi%
\vskip\dimexpr-\baselineskip+2pt\relax
\prechapterprecis #1\postchapterprecis}

\begin{document}

\chapter{Test Chapter One}
\chapterprecishere{Test test test test test test test test test test test test test
test test test test test test test test test test test test test test test test}
\lipsum[4]
\chapter{Test Chapter Two}
\chapterprecishere{Test test test test test}
\lipsum[4]
\chapter{Test Chapter Three}
\chapterprecishere{Test test test test test test test test test test test test test test
test test test test test test test test test test test test test test test test test test test
test test test test test test test}
\lipsum[4]
\chapter{Test Chapter Four}
\chapterprecishere{Test test test test test test test test test test test test test test
test test test test test test test test test test test test test test test test test test test
test test test test test test test test test test test test test test test test test test}
\lipsum[4]
\chapter{Test Chapter Five}
\lipsum[4]
\chapter{Test Chapter Six}
\chapterprecishere{Test test}
\lipsum[4]

\end{document}


With the help of the background package I draw a horizontal green rule as a visual guide.

An image of the first page of chapters one and two, showing the same distance for one and two line precises:

If the precis has three or more lines, the distance will increase, as shown here in an image of the first page of chapters three and four:

If there's no precis, the distance will be the same as in the case of a one or two line precis, as shown here in an image of the first page of chapters five and six:

Depending on your actual settings, you might need to adjust the width of the minipage used.

-
 very nice, I will test that when I get a chance ! – Damien Pollet Mar 17 at 1:40 @DamienPollet in my first answer there was a case missing: the case of no precis; now I updated my answer to also cover this case. – Gonzalo Medina Mar 17 at 2:12 +1 hope you don't mind but I borrowed your example for testing an alternative implementation. – David Carlisle Mar 17 at 17:33 @GonzaloMedina where does the \vskip\dimexpr-\baselineskip+2pt\relax come from? – Damien Pollet Mar 17 at 18:00 @DamienPollet the 2pt accounts for the difference in \baselineskip between \small in the precis and \normalfont in regular text; depending on your actual setting you might need to adjust this value also. – Gonzalo Medina Mar 17 at 20:56