\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}