5

I am trying to use a two-column layout in plain TeX (pdftex, to be precise), where the lines of text in the two columns are vertically aligned. Here is what I've got so far (code is below):

example of the (broken) two-column layout

Normal rows should take up 12pt of vertical space, headings (A and B) should take up 36 points when they are in the middle of a column, or 24 points when they are at the top of a column. My aim is for lines on the left and on the right to have the same vertical position, like line 1a and 7g currently do.

My questions:

  1. Section heading A consists of a vskip of 12pt, followed by a vbox of height 24pt. I hoped that it would take up the same space as three rows do. The picture shows, that the heading takes up slightly too much space, pushing line 6f down a bit. How can I make the section heading A take up exactly three rows of space?

  2. For heading B I had hoped that the vskip is discarded (because of the page break), leaving only the vbox of height 24pt. The picture shows that heading B takes up much more than 2 rows of vertical space. How can I remove the extra space so that rows 15o and 21u align vertically?

Here is my code:

% !TEX TS-program = pdftex

% tiny pages for testing
\pdfpageheight 92pt\voffset -62.27pt\vsize72pt
\pdfpagewidth 120pt\hoffset -62.27pt\hsize50pt
\parindent0pt\parskip0pt\topskip0pt

% a very simple two-column layout
\newbox\leftcol
\newif\ifleftcol\leftcoltrue
\def\xout{\ifleftcol
\global\setbox\leftcol\box255
\global\leftcolfalse
\else
\shipout\vbox to 72pt{\hbox to 100pt{\box\leftcol \box255}}%
\global\leftcoltrue
\fi}
\output{\xout}

% section headings (2 lines on top of column, 3 line otherwise)
\font\bigfont=ecbx2488
\def\section#1{\vskip1\baselineskip\vbox to24pt{\vss\noindent\bigfont#1}}

% visually mark the baselines for testing
\everypar{\hbox to0pt{\vrule height.1pt depth.1pt width50pt\hss}}
\obeylines

1a
2b
\section{A}
6f
7g
8h
9i
10j
11k
12l
\section{B}
15o
16p
17q
18r
19s
20t
21u
22v
23w
24x

\bye
  • 1
    In my experiment, changing \pdfpageheight 92pt\voffset -62.27pt\vsize72pt to \pdfpageheight132pt\voffset -62.27pt\vsize120pt leads to unexpected result: The baselines are not aligned at all! Note even one pair of them! – Ruixi Zhang Jul 26 '18 at 1:35
  • The paracol package comes to mind, but I'm not if the baselines or tops are aligned when switching columns (which can only be done between paragraphs). See also tex.stackexchange.com/questions/401778/… – John Kormylo Jul 26 '18 at 4:07
  • @RuixiZhang Thanks for pointing this out. Experimenting a bit more, it seems that my \topskip0pt was a bad idea. Changing this to \topskip10pt makes the first lines of your larger pages align properly. Things are still out of alignment after the headings, though. – jochen Jul 26 '18 at 10:18
2

The general advice:

When you stack boxes be careful with occurrences of \lineskip. Use \nointerlineskip or \offinterlineskip and apply a \strut to know the height and depth of lines.

The details for your example:

1) \topskip is used to have first lines at the same position. TeX calculates the width (topskip - height of first line) and put this difference as glue at the beginning of the page. So \topskip=0pt means that the baselines of a line with 'a' and a line with 'h' have different distances from the top of the print area. This is not what you want.

2) \topskip=10pt is sufficient for cmr10. The \vsize shall be set then as (number of lines - 1)baselineskip + topskip. Here \topskip=\baselineskip is useful for box B on the second page.

Therefore set \topskip=12pt and keep \vsize=72pt.

3) Similar to the process in 1) the glue needed between lines is calculated from the depth of one line and the height of the next to get the distance \baselineskip. This glue is called interline glue. If the interline glue gets smaller than \lineskiplimit TeX sets \lineskip glue between the lines. The boxes of the big letters are larger than \baselineskip so \lineskip is applied. It is set to 1pt and that makes the lines for A and 6f 1pt lower than the lines on the right side. (Use \tracingoutput=1 and \showboxdepth=100, \showboxbreadth=100 to see the page contents and search for \lineskip.)

Therefore use \nointerlineskip in the definition of your \section.

4) Your rules add the depth 0.1pt. So the section for A changes the baseline by a little bit more than 36pt after 2b. The \vskip does not care about the depth of the previous line. (Better use a \strut in the line then you know its depth, i.e., all lines have the same depth; the \vskip can be changed so that exactly \baselineskip is left above the box.)

Therefore instead of \vskip1\baselineskip use \vskip11.9pt in this example for a perfect alignment after a line with depth zero.

This fixes both pages with your input:

\topskip12pt
\def\section#1{\vskip11.9pt\nointerlineskip
   \vbox to24pt{\vss\noindent\bigfont#1}}

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.