10

I want to typeset the number for the section in the margin. Here's an MWE of what I'm starting from.

%  --- Fonts ------------------------------------------------
\font\0="Roboto Condensed Light" at 12pt\0
\font\ssa="Roboto Condensed Bold" at 24pt

%  --- Layout ------------------------------------------------
\raggedright
\parindent=0pt
\parskip=1em

%  --- Structure ---------------------------------------------
\newcount\SectionNumber

\def\Section #1\par{%
\vskip 40pt
\advance \SectionNumber by 1
{\ssa\the\SectionNumber. #1}
\vskip 8pt
}

% Start Text
\Section Project One

\input knuth

\bye

example-before-margin

I'm looking at this answer and trying to adapt it here, so I came up with this:

\def\inmargin#1{\strut\vadjust{\kern-\dp\strutbox\smash{\llap{#1}}\kern\dp\strutbox}}

\def\Section #1\par{%
\vskip 40pt
\advance \SectionNumber by 1
{\ssa\inmargin{\the\SectionNumber. }#1}
\vskip 8pt
}

This is close, but when the section header has descenders it seems to be incorrectly aligned. See:

badly-aligned

As you can see, the 1. is a little below where it should be. The problem doesn't occur if I omit the descender:

enter image description here

I tried various contortions creating my own box and moving it around, and also trying to just kern the whole section heading negatively into the margin. I don't really care what approach is taken, I'd just like to understand what I'm missing. I suspect it has something to do with the height and depth of the section heading text.

6
  • Playing with the TeXbook, eh? Also, I'm no Plain user, but can't you put the number in a box, hskip -\wd\thebox, and then set the title on the same baseline? Jun 13, 2015 at 4:50
  • @SeanAllred You are the Kwisatz Haderach! Jun 13, 2015 at 5:20
  • I have no idea what that means, but I'll take that as a good thing :) l3coffins (texdoc xcoffins) has taught me everything I know ;) Jun 13, 2015 at 5:31
  • @SeanAllred it's a compliment, it's from Dune. I'll have to check out xcoffins, thanks! Jun 13, 2015 at 5:57
  • @seanallred do you mind putting the code from your comment as an answer?
    – jarnosz
    Jun 13, 2015 at 6:01

2 Answers 2

9

Let's see what happens with your \inmargin macro:

\def\inmargin#1{%
  \strut
  \vadjust{
    \kern-\dp\strutbox
    \smash{\llap{#1}}%
    \kern\dp\strutbox
  }%
}

You emit a \strut that starts horizontal mode, because it does \unhcopy\strutbox. However, you should be aware of the fact that Plain does

\setbox\strutbox=\hbox{\vrule height8.5pt depth3.5pt width0pt}

which is quite small, compared to \ssa which is a font at 24pt. Then you tell TeX that, after the paragraph has been typeset, after the first line of the paragraph (which is just the section title), a vertical kern of -\dp\strutbox (which is -3.5pt), a smashed box containing the section number and another kern (of 3.5pt) will be inserted. Now, if the section title has a descender it will be way more than 3.5pt, because it uses a large font.

The macro you are trying to modify is for adding something in the left margin without knowing the point where this addition is made. In your case you do know when the object in the margin must be announced: at the \Section command. So no trick is necessary: just \llap it.

However, \llap does \hbox, which is not a horizontal command, so you need to start it in some way. The correct way is to issue \noindent, that works independently of your setting to \parindent.

\def\Section#1\par{%
  % be in vertical mode
  \par
  % step the section number
  \global\advance\SectionNumber by 1
  % don't bother to add vertical space if there's already
  \ifdim\lastskip<40pt \removelastskip\penalty-400 \vskip40pt\fi
  % start horizontal mode without indent
  \noindent
  % print the section number
  \llap{\ssa\the\SectionNumber. }%
  % print the section title
  {\ssa\baselineskip=32pt \interlinepenalty=10000 #1\par}%
  % no page break
  \nobreak
  % some vertical space
  \vskip 8pt
}

Full example

%  --- Fonts ------------------------------------------------
\font\roboto="Roboto Condensed Light" at 12pt
\roboto
\font\ssa="Roboto Condensed Bold" at 24pt

%  --- Layout ------------------------------------------------
\raggedright
\parindent=0pt
\parskip=1em

%  --- Structure ---------------------------------------------
\newcount\SectionNumber

\def\Section#1\par{%
  % be in vertical mode
  \par
  % step the section number
  \global\advance\SectionNumber by 1
  % don't bother to add vertical space if there's already
  \ifdim\lastskip<40pt \removelastskip\penalty-400 \vskip40pt\fi
  % start horizontal mode without indent
  \noindent
  % print the section number
  \llap{\ssa\the\SectionNumber. }%
  % print the section title
  {\ssa\baselineskip=32pt \interlinepenalty=10000 #1\par}%
  % no page break
  \nobreak
  % some vertical space
  \vskip 8pt
}

% Start Text
\Section Project One

\input knuth

\Section Project Two

\input knuth

\bye

enter image description here

1
  • Thanks for the in-depth explanation of the code! This is really helping me understand TeX. Jun 14, 2015 at 5:29
6

You should be in horizontal mode when setting the sectional title. The following should work just fine:

\def\Section #1\par{%
\vskip 40pt
\advance \SectionNumber by 1
{\leavevmode\ssa\llap{\the\SectionNumber. }#1}
\vskip 8pt
}

Note the use of \leavevmode to enter horizontal mode.

2
  • Did the \vskip put me in vertical mode? Is \llap not sufficient to put me in horizontal mode? Jun 13, 2015 at 5:55
  • @DanielLyons: Correct, \llap is insufficient dit getting into horizontal mode. In your example you're in vertical mode, yes. Although typically one would execute an explicit \par to achieve this under all circumstances.
    – Werner
    Jun 13, 2015 at 6:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .