Gridding

Is there any way to get back on grid once you’re off? Or to have some text be off grid while you’re secretly keeping track of the grid in the background?

The first pages of my books are laid out like this:

MAIN TITLE
introductory outline (with \io markers)
\s
\p

The problem is caused by the \io section. I want the text and line spacing for that section to be smaller than normal, but if I do that then the \s and \p aren’t on grid. I can correct using a \vskip, but since each introduction has a different number of lines, the \vskip would need to be different for each book. (Now that I write that, if there’s no way to get back on grid maybe I can fix the problem by writing a change or a sethook for each book.)

Well… there is \parlines, which TeX uses to tell you how many lines there have been in a paragraph.
I guess the end of paragraph code could do some counting and some maths…

Argh. Sorry, two fairly major glitches in my reply earlier.

  1. \@parlines is part of the accounting we use to calculate dropped chapters, etc, I should probably have written \prevgraf
  2. \prevgraph gives you almost exactly what you want - multiply the off-griddedness by that and as long as there are no other skips, before/after space, etc. then you’ve got an ‘off by X pt’ you can then use to restore to the grid, after making sure that it’s positive and less than 1 gridline. This would all work on the first run of TeX. BUT there’s a huge caveat here:
    That is all fine as long as your preceding off-grid text doesn’t ever get split across a page. At that point, all careful calculations need discarding, because all text on the page starts on the 1st baseline. And without the @parlines type processing you don’t know how many lines of that paragraph somewhere in the middle of the text are on the new page.

So… having thought a bit more, I can’t think of a way to do this when it includes page breaks without the .parlocs file getting directly involved, and at that point it’s going to be easier to say ‘I want this paragraph (cursor currently at X,Y) to be on the grid’ and don’t bother to count any paragraphs at all. At least for the first transition.
That then would require a rerun of TeX, if it’s off-grid. The downside is that that might change page break points and figure/footnote placements, potentially at >= one rerun per transition! (eek, if you’re talking about a whole Bible!)

I think that this is a common-enough issue for a LOT of people, so we should probably automatically force the text back onto grid after the intro ends and when the 1st chapter begins. (Could we do that programmatically so that users don’t need to trouble themselves?)

My huge caveat applies, if we want this to work in every situation. Given that people might have multi-page introductions, I think we’d effectively need to (a) number every paragraph with a non-regular spacing, and also any after that for another page-full, (b) calculate which paragraph gets broken and how many lines into the paragraph the break was calculated to be. (c) remember that for the next run, when we get to ‘restore grid’.

The alternative, is what we do at the moment on a transition from single to double columns: the partially full page is typeset, becoming fixed, and other material gets added below. That causes different problems in 2 column mode, e.g… with balancing.

At any given point in time, does TeX not know where it is on the page? Does it only know it’s positive relative to the line above it? I don’t understand why there’s no way to say "the chapter number occurs at y-value of a, the next grid line is at y-value of b, and so we need to shift the chapter baseline down by b-a.

The alternative, is what we do at the moment on a transition from single to double columns: the partially full page is typeset, becoming fixed, and other material gets added below.

Actually, in the project that prompted this question both the intro and the main text are single column. Is that something I can do manually–close out the page and start a new one below?

TeX has the ‘galley’ (uninterrupted column of paragraphs and spacing) all prepared before it decides how it will chop it into pages. It always finishes a paragraph before it tests to see if everything in the galley adds up to make a page, and while it tries to make a reasonable guess about when to trigger the page-chopping, those guesses aren’t fully accurate: to get column balancing, footnotes, cross-references, figures and sidebars and consistent end-of pages, we often have to try shorter cut-lengths of galley. Thus a new page might have quite a pile of text, figures and footnotes waiting in it’s galley as it starts.

When a paragraph is started (the point in which you’d have to add extra space) the \pagegoal and \pagetotal are known, but really, they are only guesses, and the program doesn’t know e.g. what pictures might be added on top of the page, or if there will be any call to stretch anything that’s flexible.

Yes, it should be possible to make it close out the partial page, but probably not manually. There are also some side effects that might be a complete pain.
It has just occurred to me that one other option would be to use stretchable spacing, a bit like this:

Stretch to page height{
  {figures}
  Stretch to 35 normal lines{
    {Intro paragraph (13.4 normal lines)}
    {stretchy bit}
    {main text (21 lines)}
  }
  {stretchy bit}
  {footnotes}
}

(The new bit being the ‘Stretch to 35 lines’ for the middle section, and of course the ‘35 lines’ would need to be calculated based on what the un-stretched length of the text run is.)
@Martin_Hosken might want to comment about why this is a silly idea, though.

Offline David suggested \par\layoutstylebreak. That didn’t work, but looking at how it was used in other documents I ended up trying out \singlecolumn, and it works!!! Even though I’m switching from single column to single column that seems to be enough to reset the grid.


That solution raised another question:

My .sfm document now looks like

\io a bunch of introductory outline rows
\\p ~
\zgetbackongrid\*
\s The first section title

and my *mods.text file has this:

\sethook{end}{zgetbackongrid}{\singlecolumn}

But, I can’t get it to work without that \\p ~ line, which then adds in an extra blank line which I don’t want. I’m assuming the problem is that my milestone zgetbackongrid is still inside the \io paragraph, but I can’t figure out how to get out of that paragraph without adding the extra line. The \par that David originally suggested in conjunction with layoutstylebreak seems to not be allowed within a sethook.

If \zgetbackongrid\* is an otherwise empty milestone, you could go the whole hog and try to make it expand to do stuff inside (no guarantees, I’ve not tested this):

\expandafter\def\csname MS:zgetbackongrid\endcsname{\par\singlecolumn}

It might not work. The milestone code is expecting to be (at most) generating some character-level text, and has various complicated bits to ensure style settings etc. don’t escape.

Using your code didn’t cause an error from the \par, but it also didn’t seem to reset the grid like using a \p in the .sfm file did.

However, the following ended up working and so I think I can reset the grid without having an extra space:
Put \p ~ in the sfm file.
In the *mods.tex file, use this:
\sethook{end}{zgetbackongrid}{\vskip-1\baselineskip\singlecolumn}

Thank you for all your help.