The lips LaTeX package

Chicago Manual text ellipses (Frankenstein’s lips)

          Matt Swift <swift@alum.mit.edu>

Version: 2.1 Date: 2001/08/31

Documentation revision: 2001/08/31

Abstract

The \lips command generates text ellipses that are closer to what Chicago Manual of Style suggests than what \dots produces. It does the right thing in most circumstances, and so is easy to use.

Contents

I Discussion 2

1 Text Ellipses 2 2 Line breaking considerations 2 3 Limitations 3

II Implementation 4

4 Version control 4 5 The macro 4

III Testing 9

6 Ante-\Lips 9 7 Post-\Lips 9

source  result

Hello\lips.␣And  Hello. . . . And
Hello␣\lips.␣And Hello. . . . And
Hello.\lips␣And  Hello. . . . And
Hello.␣\lips␣And Hello. . . . And
one,\lips,␣three one, . . . , three
one,␣\lips,␣three one, . . . , three
Hello\lips␣and  Hello . . . and
Hello␣\lips␣and  Hello . . . and
Hello!\lips␣And  Hello! . . . And
Hello!␣\lips␣And Hello! . . . And

Figure 1: Examples of correct usage of \lips.

Part I

Discussion

1 Text Ellipses

\lips The macro \lips should be used for all text ellipses, that is, ellipses not part of

a mathematical expression.

Chicago Manual does not acknowledge different spacings after different marks of punctuation, distinguish interword from intersentence space, or give rules about where to break a line near an ellipsis. Given a context where such spaces do vary and rules for linebreaks can be given, I arrived at the following rules for handling them around ellipses.

1. Pre-, post-, and intra-ellipsis space is normal intra-word space, which should be 3-to-em. In L^{A}TEX there is also some glue (it’s a “rubber space”).

2. When non-period punctuation p follows \lips, p is followed by the space that normally follows p.

3. A period following \lips is treated as if the period preceded \lips. Conceptually, an ellipsis never precedes a period, so conceptually there is only one case; but it is convenient to be able to type either \lips. or .\lips.

4. Lines are a tiny bit breakable before ellipses and a tiny bit breakable after ellipses that are not followed by punctuation.

In figure 1 are examples of correct usage and in figure 2 is a comparison of \lips to \dots. You can substitute any of the characters !"()*+,-/:;=?@[]' `|<>~{} for the exclamation point in the examples. There can be additional contiguous spaces after \lips, just like after any command name. There can also be contiguous spaces before \lips.

2 Line breaking considerations

\LPNobreakList When \lips is followed by certain punctuation (,:;?!)']}/ by default), we never

source  result

Hello\dots.␣And  Hello. . . . And
Hello\lips.␣And  Hello. . . . And
Hello␣\dots.␣And Hello . . . . And
Hello␣\lips.␣And Hello. . . . And
Hello.\dots␣And  Hello.. . . And
Hello.\lips␣And  Hello. . . . And
Hello.␣\dots␣And Hello. . . . And
Hello.␣\lips␣And Hello. . . . And
one,\dots,␣three one,. . . , three
one,\lips,␣three one, . . . , three
one,␣\dots,␣three one, . . . , three
one,␣\lips,␣three one, . . . , three

Hello\dots␣and     Hello. . . and

Hello\lips␣and  Hello . . . and

Hello␣\dots␣and    Hello . . . and

Hello␣\lips␣and  Hello . . . and
Hello!\dots␣And  Hello!. . . And
Hello!\lips␣And  Hello! . . . And
Hello!␣\dots␣And Hello! . . . And
Hello!␣\lips␣And Hello! . . . And

Figure 2: Comparison of \lips with \dots.

want to break a line after the ellipsis and before that punctuation. For the other punctuation, such as open parenthesis and open quote, we want normally breakable space following the ellipsis. \LPNobreakList is a list of those characters before which \lips should never break a line. To force unbreakable space following \lips, follow \lips with a tie (~).

3 Limitations

\lips does the right thing after \par, but after \indent or \noindent there is an extra preceding space (see the final section on testing for an example). Suggestions on how to handle this problem are welcome.

Part II

Implementation

4 Version control

\fileinfo \DoXUsepackagE \HaveECitationS \fileversion \filedate \docdate \PPOptArg These definitions must be the first ones in the file.
 1 \def\fileinfo{Chicago Manual text ellipses (Frankenstein's lips)}
 2 \def\DoXPackageS {}
 3 \def\initelyHavECitationS {}
 4 \def\fileversion{v2.1}
 5 \def\filedate{2001/08/31}
 6 \def\docdate{2001/08/31}
 7 \edef\PPOptArg {%
 8 \filedate\space \fileversion\space \fileinfo
 9 }

If we’re loading this file from a \ProcessDTXFile command (see the compsci package), then \JusTLoaDInformatioN will be defined; othewise we assume it is not (that’s why the FunkY NamE).

If we’re loading from \ProcessDTXFile, we want to load the packages listed in \DoXPackageS (needed to typeset the documentation for this file) and then bail out. Otherwise, we’re using this file in a normal way as a package, so do nothing. \DoXPackageS, if there are any, are declared in the dtx file, and, if you’re reading the typeset documentation of this package, would appear just above. (It’s OK to call \usepackage with an empty argument or \relax, by the way.)

10 \makeatletter% A special comment to help create bst files.  Don't change!
11 \@ifundefined{JusTLoaDInformatioN} {%
12 }{% ELSE (we know the compsci package is already loaded, too)
13 \UndefineCS\JusTLoaDInformatioN
14 \SaveDoXVarS
15 \eExpand\csname DoXPackageS\endcsname\In {%use \csname in case it's undefined
16  \usepackage{#1}%
17 }%
18 \RestoreDoXVarS
19 \makeatother
20 \endinput
21 }% A special comment to help create bst files.  Don't change!

Now we check for L^{A}TEX2e and declare the LaTeX package.

22 \NeedsTeXFormat{LaTeX2e}
23 \ProvidesPackage{lips}[\PPOptArg]

5 The macro

\Lips \BracketedLips \lips \olips If we’re in math mode, raise an error. If we’re in vertical mode, leave it and do an

ellipsis not breakable at the end. If we’re in horizontal mode, call \lp@lips@hmode.

Normally I would use \NewRobustCommand, but this seems not enough reason to require the moredefs package. We reserve the name \lips by hand. In the future, this package may require moredefs.

24 \newcommand*\Lips {}

25 \let\Lips\relax
26 \DeclareRobustCommand\Lips {%
27 \ifmmode
28  \def\sc@t@a {%
29  \PackageError{lips}
30  {Don't use \protect\lips \space in math mode; use \protect\dots.}\@ehc
31  }%
32 \else
33  \ifvmode
34  \def\sc@t@a {%
35  \leavevmode
36  .\nobreak\ .\nobreak\ .\nobreak\ %
37  }%
38  \else
39  \let\sc@t@a\lp@lips@hmode
40  \fi
41 \fi
42 \sc@t@a

43 }

44 \newcommand*\BracketedLips {}
45 \let\BracketedLips\relax
46 \DeclareRobustCommand\BracketedLips {%
47 \ifmmode
48  \def\sc@t@a {%
49  \PackageError{lips}
50  {Don't use \protect\lips \space in math mode; use \protect\dots.}\@ehc
51  }%
52 \else
53  \ifvmode
54  \def\sc@t@a {%
55  \leavevmode
56  [.\nobreak\ .\nobreak\ .]\nobreak\ %
57  }%
58  \else
59  \let\sc@t@a\lp@blips@hmode
60  \fi
61 \fi
62 \sc@t@a

63 }

To do: need the relax to avoid mistaking as optarg in some contexts?

In MLA style, that is, with the mla option, \lips gives you brackets, meaning you To get no brackets, use \olips for “original lips,” that is, ellipses in the original document.

To do: Better dox here. Are options case sensitive? If so, make MLA=mla.

64 \newlet\lips\Lips
65 \newlet\olips\lips
66 \DeclareOption{mla} {%
67 \let\lips\BracketedLips

68 }

69 \ProcessOptions

\lp@lips@hmode \lp@blips@hmode \GobbleIgnoreSpaces The horizontal mode case. Then we remove the last skip on the horizontal list. If the next character is a period, we want to act as if the period preceded \lips, so we plonk down a period, a minimally-breakable space, then an ellipsis ending with normally-breakable space. This keeps the ellipsis on the same line as the sentence it follows if at all possible, but allows it to spill onto the next line if there’s no other way to avoid an overfull line. Then we want to gobble up the period that’s about to come, and ignore any spaces after it, since we’ve already inserted proper space.

If the next character is not a period, we output a minimally-breakable space and an ellipsis. To decide whether to follow it with unbreakable or normallybreakable space, we need to know more about the next character than just that it is not a period, so we \let it to scratch a and call \lp@lips@check@punct.

To do: document different logic with bracketed lips; how the heck to handle greater inter-sentence space?

70 \newcommand\lp@lips@hmode {%
71 \unskip
72 \@ifnextchar . {%
73  .\penalty9999\ .\nobreak\ .\nobreak\ .\ %
74  \GobbleIgnoreSpaces
75  }{% ELSE
76  \penalty9999\ .\nobreak\ .\nobreak\ .%
77  \futurelet\sc@t@a\lp@lips@check@punct
78 }%

79 }

80 % hmm, have to keep the check for period i guess because i don't want it in
81 % nobreaklist?  because the break/nobreak is different?  because it's more efficient?
82 \newcommand\lp@blips@hmode {%
83 \unskip
84 \@ifnextchar . {%
85  \penalty9999\ [.\nobreak\ .\nobreak\ .]%
86  }{% ELSE
87  \penalty9999\ [.\nobreak\ .\nobreak\ .]%
88  \futurelet\sc@t@a\lp@lips@check@punct
89 }%

90 }

91 \newcommand\GobbleIgnoreSpaces [1] {%
92 \ignorespaces

93 }

\LPNobreakList \lp@<punctuation> We’d like to use \ifcat.\sc@t@a for this, but that won’t work when we get a command sequence in scratch a. Bummer. Do I really need to define all this punctuation now? It protects against something becoming an active char or otherwise changing catcodes after the lips package is loaded.

94 \newcommand*\lp@bang {}
95 \newcommand*\lp@rparen {}
96 \newcommand*\lp@comma {}
97 \newcommand*\lp@slash {}
98 \newcommand*\lp@colon {}
99 \newcommand*\lp@semic {}
100 \newcommand*\lp@q {}
101 \newcommand*\lp@rbrack {}
102 \newcommand*\lp@rquote {}
103 \newcommand*\lp@tilde {}

104

105 \let\lp@bang=!
106 \let\lp@rparen=)
107 \let\lp@comma=,
108 \let\lp@slash=/
109 \let\lp@colon=:
110 \let\lp@semic=;
111 \let\lp@q=?
112 \let\lp@rbrack=]
113 \let\lp@rquote='
114 \let\lp@tilde=~

115

116 % \egroup

117

I’m making an attempt to put these in order of expected frequency. A doublequote could be at the beginning or end of a quotation, so half the time you’ll have to correct by adding {}, so let’s leave it out so there’s one less to check.

118 \newcommand \LPNobreakList {%
119 \lp@comma \lp@colon  \lp@semic
120 \lp@q \lp@bang
121 \lp@rparen \lp@rquote \lp@rbrack \egroup
122 \lp@slash

123 }

\lp@lips@check@punct Add nonbreakable space if scratch a is in \LPNobreakList; add normally-breakable space otherwise. Add no space at all if scratch a is a tie—the tie will add nonbreakable space. We use just the guts of \@tfor for efficiency.

124 \newcommand\lp@lips@check@punct {%
125 \ifx\sc@t@a\lp@tilde
126 \else
127  \@tempswatrue
128  \let\@fortmp\PunctList
129  \expandafter\@tforloop\LPNobreakList\@nil\@nil\@@\reserved@a {%
130  \ifx\sc@t@a\reserved@a
131 \@tempswafalse
132 \@break@tfor
133  \fi

134 }%

135  \if@tempswa

136 \ %

137  \else
138  \nobreak\ %
139  \fi
140 \fi

141 }

You might want to compare the L^{A}TEX version (as of 95/12/01). \fontdimen3 is the interword stretchability, not interword space.

  \DeclareTextCommandDefault{\textellipsis}{%
    .\kern\fontdimen3\font
    .\kern\fontdimen3\font
    .\kern\fontdimen3\font
  }

\def\mathellipsis{\mathinner{\ldotp\ldotp\ldotp}}
\DeclareRobustCommand{\dots}{%
  \ifmmode\mathellipsis\else\textellipsis\fi
}
\let\ldots\dots

Part III

Testing

6 Ante-\lips

This is some testing. We need some text here as the first paragraph after the

\section.

:…. : … text. : …) ;…. ; … text. ; …) !…. ! … text. ! …) t. … t … text. t …) T. … T … text. T …) ,…. , … text. , …)

. . . and (\par \lips and)
and (\par and)
 . . . (\par\indent \lips and)
and (\par\indent and)
. . . and (\par\noindent \lips and)
and (\par\noindent and)

And. …

(And.\lips \par)

And.

(And. \par)

7 Post-\lips

\lips before a tie: One two three. … tiedtolips (I doubt you’d want to do this.) \lips before ), e.g., punctuation transparent to spacefactors: (One two three. …) This follows the ) with interword space, to compare. (One two three. …) This should follow the ) with intersentence space. (One two three. …) This should follow the ) with intersentence space.

\lips before shortverb: . . . shortverb verbatim stuff

\lips before \textsf: … sansserif

\lips before \\: … second line of a center environment \lips before \#: … # \lips before <: … ¡ \lips before an abbrev: … Frankenstein \lips before \cite: … (University of Chicago Press 1993) \lips before $: … f = ma

\lips before &: … second column of a tabular

References

University of Chicago Press. 1993. The Chicago Manual of Style. 14th ed. Chicago: University of Chicago Press.

Index

Numbers written in italic refer to the page where the corresponding entry is described; numbers underlined refer to the code line of the definition; numbers in roman refer to the code lines where the entry is used.

Symbols

\@@ . . . . . . . . . . . . . 129

\@break@tfor . . . . . . 132

\@ehc . . . . . . . . . . 30, 50 \@fortmp . . . . . . . . . 128

\@ifnextchar . . . . 72, 84
\@ifundefined . . . . . 11

\@nil . . . . . . . . . . . . 129

\@tempswafalse . . . . 131
\@tempswatrue . . . . . 127
\@tforloop . . . . . . . 129

\␣ . . . . . . 36, 56, 73, 76, 85, 87, 136, 138

B

\BracketedLips . . . . \underline{24}

C

\csname . . . . . . . . . . 15

D

\DeclareOption . . . . 66
\DeclareRobustCommand

. . . . . . . . . 26, 46 \def . . 1–6, 28, 34, 48, 54 \docdate . . . . . . . . . . \underline{1} \dots . . . . . . . . . . 30, 50

\DoXPackageS . . . . . . . 2
\DoXUsepackagE . . . . . \underline{1}

E

\edef . . . . . . . . . . . . . 7 \eExpand . . . . . . . . . 15 \egroup . . . . . . 116, 121 \else . . . . . . . . . 32,

38, 52, 58, 126, 137

\endcsname . . . . . . . 15

\endinput . . . . . . . . 20

\expandafter . . . . . . 129

F

\fi . . . . . . . . 40, 41, 60, 61, 133, 139, 140 \filedate . . . . . . . . . \underline{1} \fileinfo . . . . . . . . . \underline{1}

\fileversion . . . . . . . \underline{1}
\futurelet . . . . . 77, 88

G

\GobbleIgnoreSpaces   \underline{70}

H

\HaveECitationS . . . . \underline{1}

I

\if@tempswa . . . . . . . 135

\ifmmode . . . . . . . 27, 47 \ifvmode . . . . . . . 33, 53 \ifx . . . . . . . . . 125, 130

\ignorespaces . . . . . 92

\In . . . . . . . . . . . . . 15

\initelyHavECitationS

. . . . . . . . . . . . . 3

J

\JusTLoaDInformatioN 13

L

\leavevmode . . . . . 35, 55

\let . . . . . 25, 39, 45,

59, 67, 105–114, 128 \Lips . . . . . . . . . . . . \underline{24} \lips . . . . . . . . . . . 2, \underline{24} \lp@bang . . 94, 105, 120

\lp@blips@hmode . 59, \underline{70}

\lp@colon . 98, 109, 119 \lp@comma . 96, 107, 119

\lp@lips@check@punct

. . . . . . 77, 88, \underline{124}

\lp@lips@hmode . . 39, \underline{70}

\lp@q . . . . . 100, 111, 120 \lp@rbrack 101, 112, 121

\lp@rparen 95, 106, 121

\lp@rquote 102, 113, 121 \lp@semic . 99, 110, 119 \lp@slash . 97, 108, 122 \lp@tilde . 103, 114, 125

                          \LPNobreakList 2, \underline{94}, 129

M

                          \makeatletter . . . . . 10
                          \makeatother . . . . . . 19

N

                          \NeedsTeXFormat . . . 22
                          \newcommand . . . . . . .

. 24, 44, 70, 82, 91, 94–103, 118, 124

\newlet . . . . . . . . 64, 65 \nobreak …. 36, 56,

73, 76, 85, 87, 138

O \olips . . . . . . . . . . . \underline{24}

P

                          \PackageError . . . 29, 49

\penalty . 73, 76, 85, 87 \PPOptArg . . . . . . . \underline{1}, 23

                          \ProcessOptions . . . 69

\protect . . . . . . . 30, 50

                          \ProvidesPackage . . 23
                          \PunctList . . . . . . . 128

R \relax . . . . . . . . . 25, 45

                          \reserved@a . . . 129, 130
                          \RestoreDoXVarS . . . 18

S

                          \SaveDoXVarS . . . . . . 14

\sc@t@a . . 28, 34, 39, 42, 48, 54, 59, 62, 77, 88, 125, 130

\space . . . . . . . 8, 30, 50

U

                          \UndefineCS . . . . . . . 13

\unskip . . . . . . . . 71, 83

                          \usepackage . . . . . . . 16