summaryrefslogtreecommitdiff
path: root/systems/tex-extensions/clasen/margin/margin.tex
blob: 561ab8514f7b829e1e0e02524848c3b81112b363 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
\documentclass[preprint]{ltugboat}
\usepackage{shortvrb}
\usepackage{url}

\providecommand{\meta}[1]{\ensuremath{\langle\textit{#1}\rangle}}
\makeatletter
\providecommand{\eTeX}{$\m@th\varepsilon$-\TeX}
\makeatother
\hyphenation{pa-ra-me-ter}

\emergencystretch=4mm
\title{Hanging punctuation revisited}
\author{Matthias Clasen}
%\address{}
\netaddress{maclas@gmx.de}
\setcounter{page}{1}

\begin{document}
\maketitle
\MakeShortVerb{\|}

\section{Introduction}

In appendix D of the \TeX book~\cite{Knuth:86}, Knuth discusses a way to
implement hanging punctuation within \TeX. As noted by Frank
Mittelbach~\cite{Mittelbach:90}, this solution \textit{make[s] the ligature
  mechanism partly unusable, along with other side effects,}
and thus a better solution is needed. 

Since the problem obviously depends on the shape of the letters, it seems
natural to attack it at the font level. The basic idea is to associate
a |\marginchar| with each font. The kerning with the |\marginchar| (at the
appropriate side) is used to determine how far the first/last character on
a line should drop in the margin. This information is used in the calculation
of the length (and badness) of a ``candidate line'' during paragraph breaking.

Every font in \TeX\ has an associated |\margin|\-|char| parameter (analogous
to |\hyphenchar| and |\skewchar|) whose initial value is the value of
|\default|\-|margin|\-|char|. The |tfm| file doesn't have to know anything
about |\marginchar|s, it just has to contain appropriate kern values. It is
perfectly possible to have more than one |\marginchar| in a |tfm| file,
e.\,g.\ for  
\begin{itemize}
\item hanging punctuation,
\item hanging hyphenation,
\item optically correct margins,
\item various combinations thereof.
\end{itemize}

Imagine the |\marginchar| as a zero-width character which is automatically
inserted at the beginning and end of every line. It is fixed at the margin,
thus kerning against it will drag the first or last character in the margin.
This is of course a gross simplification of the actual algorithm which is
complicated by the need to deal properly with |\parindent| boxes, hanging
indentation, |\right-| and |\leftskip|s, discretionaries, and breakpoints which
are not taken. 

 
\section{Implementation}

The changes to \TeX{} the program sketched above are realized in the
change file |margin.ch|. The implementation is highly inefficient:
Lists are traversed more often than necessary and results are not cached. But
this implementation was possible without figuring out in detail how
|break_width| and |cur_active_width| have to be changed to incorporate 
the |\marginchar| kerning. This is what eventually should be done. 

\section{Installation}
 
 The change files are written for \TeX~3.1459. But it should need only
 cosmetic changes to get them to work with other versions of \TeX3.

 To make the change files for \TeX{} work, you have to apply the change file
 |pre.ch| first. I have only tried these files with |web2c|, and
 for that you need to surround the |web2c| change file with |pre-web2c.ch| and
 |post-web2c.ch|. You also need the additional change file 
 |margin-post-web2c.ch|. In the present form, |margin.ch| can only be
 applied \emph{after} the changes for variable letter width in |hz.ch|.

 All this boils down to the command line

\begin{verbatim}
mv tex.ch tex.ch.orig
tie -c tex.ch tex.web pre.ch hz.ch \
       margin.ch pre-web2c.ch \
       tex.ch.orig post-web2c.ch \
       hz-post-web2c.ch \
       margin-post-web2c.ch
\end{verbatim}

 \makesignature

 \bibliographystyle{plain}
 \bibliography{etex}

\end{document}