13

When imitating \dotfill, I ran into \kern\z@. Why would I want to kern zero points off the end of \dotfill (or my version)? Why is this smart? What practical reasons does it serve?

\dotfill:

enter image description here

Code

\documentclass{article}
\usepackage{fontspec} % xelatex

\makeatletter
\def\plusfill{\leavevmode\cleaders\hbox to 1em{\hss+\hss}\hfill\kern\z@}
\def\title#1{\noindent\plusfill#1\plusfill}
\makeatother

\begin{document}
\title{Test}

\meaning\dotfill

\end{document}

Generic \charfill

Throwing this in the question for keepsakes. It is a generic character fill command. It features the ability to use any character. Could be improved by detecting a bottom-dwelling character as in: . _. Automatically (dynamically) applies vertical centering to bottom-dwelling characters (according to middle of the upper case letter A)

\def\charfill#1{\leavevmode\leaders\hbox to 1em{\hss\raisebox{\dimexpr-\height+\fontcharht\font`A}{#1}\hss}\hfill\kern\z@}

Related

4
  • 2
    One thing that comes to my mind is protecting against \unskip.
    – Skillmon
    Feb 25, 2018 at 19:04
  • In any case, you should insert \noindent before \title.
    – Mico
    Feb 25, 2018 at 19:15
  • @Mico True, thanks for your attention to detail. I forgot that while being a minimalist, but that is definitely needed in a real def. I'll adjust my code accordingly. Feb 25, 2018 at 19:19
  • 1
    Similarly, \hspace* ends with \hskip\z@skip so this is removed by \par or \unskip instead of the main one.
    – egreg
    Feb 25, 2018 at 22:40

3 Answers 3

15

There are some places in TeX/LaTeX, where horizontal glue is removed, e.g.:

  • At the end of a paragraph an ending space is removed by \unskip.
  • Table cells are surrounded by \ignorespaces and \unskip to remove leading spaces and a trailing space.

However, \unskip is not specific to spaces, it removes glue, which a space is. \hfill is another kind of glue, it is also removed. The additional \kern at the end prevents \unskip from seeing the glue before the \kern and the \dotfill stays.

1
  • Regarding Heiko's answer, \unskip wouldn't exactly remove an \hfill glue item in the absence of the \kern\z@. Rather, it would remove the leaders of which \hfill gives the extent. I've detailed this here.
    – frougon
    May 19, 2019 at 20:19
12

If you invoke texdoc source2e (to look at the listing for the source code for the LaTeX kernel), and search for \dotfill, it says:

LaTeX change: \kern\z@ added to end of \hrulefill and \dotfill to make them work in ‘tabular’ and ‘array’ environments. (Change made 24 July 1987).

image

2

I'm shamelessly borrowing the start of this answer from Heiko Oberdiek's answer, fixing a little detail, adapting the wording to my taste and completing with code examples (if I were to add so much when editing Heiko's answer, my edit would likely be rejected). In case Heiko wants to incorporate my answer into his, that's fine with me and I'll delete this one.

There are some places in TeX where horizontal glue, typically contributed by spaces in the input, is automatically removed. For instance:

  • At the end of a paragraph, there is always an implicit \unskip command that removes the last item from the current horizontal list, if that item is of type glue.
  • Table cells are implicitly surrounded by \ignorespaces and \unskip commands in order to cancel the effect of leading and trailing spaces.

Note that \unskip is not specific to spaces: it removes any kind of glue, regardless of whether it was contributed by a space or by more complicated commands. \hfill is another kind of glue, and so are leaders; thus, both can be removed by \unskip. The additional \kern at the end of \dotfill's definition prevents a potential \unskip from seeing the last glue item before the \kern, so that the dots don't get removed.

Note: in this case, the glue item that is “protected” this way from \unskip1 is not \hfill, but a glue item that produces leaders: precisely, the one that \cleaders \hb@xt@ .44em{\hss.\hss}\hfill contributes to the current horizontal list (cf. TeXbook p. 280 about \unskip2). This can be verified using TeX's introspection capabilities. The following document:

\documentclass{article}

\makeatletter
\newcommand*{\myTest}{%
  \leavevmode \cleaders \hb@xt@ .44em{\hss.\hss}\hfill \kern\z@\unskip
  \showboxbreadth=10\showboxdepth=2\showlists
}
\makeatother

\begin{document}
\myTest
\end{document}

shows this in the log file (among others):

### horizontal mode entered at line 11
\hbox(0.0+0.0)x15.0
\cleaders 0.0 plus 1.0fill
.\hbox(1.05554+0.0)x4.40002, glue set 0.81113fil
..\glue 0.0 plus 1.0fil minus 1.0fil
..\OT1/cmr/m/n/10 .
..\glue 0.0 plus 1.0fil minus 1.0fil
\kern 0.0
spacefactor 1000
### vertical mode entered at line 0

whereas the same example without the \kern\z@ gives this:

### horizontal mode entered at line 11
\hbox(0.0+0.0)x15.0
spacefactor 1000
### vertical mode entered at line 0

(the \hbox(0.0+0.0)x15.0 is the indentation box that \noindent would have suppressed had we used it).


Footnotes

  1. This is in the general sense of the word “protected”, and has nothing to do with either \protect or \protected.

  2. Among the commands that operate in essentially the same way, regardless of the mode, except that they deal with different sorts of lists (horizontal list, vertical list, math list):

    \unpenalty, \unkern, \unskip. If the last item on the current list is respectively of type penalty, kern, or glue (possibly including leaders), that item is removed from the list.

You must log in to answer this question.

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