How to get headings to be an integral number of lines high (using the memoir class)?

I use the memoir class and the \checkandfixthelayout command to calculate the \textheight so that an integral number of lines will fit. This works very well:

But now I want to add a few section headings. Unfortunately, the height of my section headings destroys the nice relationship between \textheight and the height of normal lines, causing stretching between paragraphs (I use \flushbottom):

The solution seems obvious; I only need to ensure that the height of my section headings + any preceding and following space is also an integral number of normal lines high. This seems simple in theory, but in practice I’m not able to figure out how to calculate the various parameters to achieve this.

I want the section headings to be about twice the size of normal text (i.e., about 22 points). Then adding, for example, 1.5 lines of preceding space and .5 lines of following space should do the trick (or perhaps 2 + 1 lines, since the preceding space may disappear when a section heading appears at the top of a page). But I’ve tried both redefining \huge and setting \setbeforesecskip and \setaftersecskip to ‘sensible’ values, i.e., based on \onelineskip or \baselineskip, and it still doesn’t work. I have to manually select precise point sizes by trial and error, which isn’t a very reliable method, and causes much work if I decide to change some values later.

So, is it possible to get the headings to automatically be an integral number of lines high (based on some input values, such as the required font size)? Note that I’m using \setSingleSpace to increase the leading, which may also complicate things (the values of \baselineskip and \onelineskip are not identical).

Here’s an example document, used to create the above images (and yes, I do realise that widows and orphans, or section headings at the bottom of pages, may cause stretching even if the headings are an integral number of lines high – ignore this for now):

\documentclass[a4paper,11pt,twoside]{memoir}

\RequirePackage[utf8]{inputenc}
\RequirePackage[T1]{fontenc}

\usepackage[osf,sc]{mathpazo}

\setSingleSpace{1.05}
\SingleSpacing

\setulmarginsandblock{1.8cm}{2.8cm}{*}
\checkandfixthelayout[nearest]

\usepackage{lipsum}

\begin{document}

\section*{Hello}

\noindent\lipsum[1]\par\lipsum*[2-7]

\end{document}

-
You need to remove all glue, in order to achieve what you want, for example \parskip should be set to 14.28pt not 14.28pt plus 1 pt. This you must do for all parameters. See the grid.sty at ctan. There is also quite a bit of info there for what you trying to achieve and the difficulties. –  Yiannis Lazarides Nov 27 '11 at 7:39
@YiannisLazarides Why do I need to remove the glue? (I have read the ‘grid.sty’ documentation.) If all sizes and skips are set to (or add up to) an integral number of lines, shouldn’t it not matter if there are extra stretchability, as the stretchability isn’t used? –  Karl Ove Hufthammer Nov 27 '11 at 8:52
There are many other parameters that all contribute to TeX's calculation. In addition there can be round off errors. If everything fits exactly, then any glue you specified will be discarded. –  Yiannis Lazarides Nov 27 '11 at 9:12

If your question still holds, here is an attempted answer to the problem of grid typesetting using the memoir class. These are mainly hints, as a complete, foolproof, solution would require a lot more work.

Regarding the size of headings, and hence your question proper, you should have a look at the .clo file and write down the leading of each font size. With 11pt, for instance, \normalsize has a baselineskip of 13.6pt, and \huge of 25pt. You can then calculate: 2*13.6-25=2.2pt, which is the correction you must apply to your heading.

Alternatively, you can redefine the font size by using:

(Note: there are other ways of doing it, but this one has worked for me.)

\renewcommand*{\huge}{\fontsize{<size>}{<leading>}\selectfont}


Then you can write:

\newdimen\addtohuge
\setlength{\aftersecskip}{\baselineskip}


(See @egreg's answer to my question, which explains it.)

Be sure to redefine both \beforeXskip and \afterXskip in all cases, as memoir by default puts some glue in all headings. Note that it will not work for multiline (or directly successive) headings – if you need them, you can either adjust vertical spaces manually, or follow the advice in this question by setting the leading to a multiple of the baseline.

Other issues that may be of interest to you:

• I don't know about setSpacing and friends, but using \renewcommand{\baselineskip}, I have found it better practice to write \selectfont just afterwards when trying to obtain vertical alignment. Make sure to define it before the layout modifications, as you did.

• You should remove the glue between paragraphs through: \setlength{\parskip}{0pt} (or the baselineskip).

• If you need footnotes, it is advisable to write something like \setfootnoterule[\vfill]{\baselineskip}{0pt}{0pt} so as to make them flushbottom (see the memoir documentation).

You will also need to use \setlength{\footnotesep}{.7\baselineskip}, which will vertically align the footnotes (for an explanation, see this post).

• And you will need to redefine all floats and all lists so as to squeeze vertical space. List environments should all be redefined by setting the vertical lengths to z@ or a multiple of baselineskip. For minipages, this may be useful to you. Figures and tables are very painful to get right, but you can get inspiration from grid.sty. I have never found a solution to the \marginpar problem, though you can always use \marginnote, \sidebar, etc.

• The best way to check and debug vertical alignment issues is to use twocolumns(even if it looks ugly with your font size) or to make the pdf viewer display two pages side by side so that you can compare them.

-

You can cure the difference between \baselineskip and \onelineskip by saying

\setlength{\onelineskip}{\baselineskip}


just after declaring \SingleSpacing.

The space before a section title should be an integral multiple of \onelineskip (modified) and the spacing after it must be computed. If you put a \strut in the section title you'll be sure about its height and depth.

Now it's just a matter of computations:

{\Huge\showthe\ht\strutbox}


will show the height of a strut in \Huge size (it's 17.49992pt, if the main font size is 10pt). Thus we need at least two lines: the space after the title should be

2\baselineskip-17.49992pt


(or 3, take your pick). But there's another catch: one has to say \prevdepth=0pt between the section title and the first paragraph, in order that TeX inserts the correct interlineskip for ensuring "grid" typesetting.

-