The abbrevs package

abbreviation macros (Frankenstein’s briefs)

             Matt Swift <swift@bu.edu>

Version: v1.0 Documentation revision: 1996/03/21

Abstract

This package facilitates the definition of abbreviation macros which expand to text and insert the proper following space depending on context. These macros can be abbreviations in a second sense also, expanding to one thing the first time they are used and another thing on subsequent invocations. This facilitates the automatic spelling-out of abbreviations or acronyms at their first use. The initial and subsequent expansions of an abbreviation macro are available at any time via explicit commands. Abbreviation macros are grouped into categories; there are hooks applicable to each category. Categories can be reset so that subsequent abbreviation macros in that category behave as if used for the first time again.

A generic facility is also provided for suffixes like 1900 b.c. and 6:00 p.m., which correctly handles following periods.

Part I

Discussion

1 General

\nospacelist An abbreviation macro \foo that expands to ⟨text⟩ is robust; \foo can be used in place of ⟨text⟩ almost anywhere. A space is inserted following an abbreviation macro when the first non-white character following it is not in the set

\nospacelist, whose default value is ,.':;?-~!)]{}.

When an abbreviation macro has different initial and subsequent expansions, either may be explicitly requested by adding a suffix to the abbreviation macro. The commands \⟨command⟩short and \⟨command⟩long are also defined whenever an abbreviation macro \⟨command⟩ is defined.

All abbreviation macros are assigned categories, identified by a string. Four categories are defined by the package, and it is easy to add more.

2 Usage

Examples of how to define abbreviation macros:

\newbook\worst{Worstward Ho}
\newbook\fall{All That Fall}
\newbook\nacht{Nacht und Tr\"aume}
\newbook\csp{Collected Shorter Plays \emph{(}CSP\emph{)}}[CSP]
\newname\joyce{James Joyce}[Joyce]
\newname\nixon{Richard Milhous Nixon}[Nixon]
\newname\ww{Wordsworth}
\newname\beckett{Samuel Beckett}[Beckett]
\newwork\godot{Waiting for Godot}[Godot]
\newbook\prelude{The Prelude}
\newtextmacro\ART{American Repetrory Theater (ART)}[ART]

Examples of how to use the macros, and how they are typeset:

%␣   The manuscripts of \ww's \prelude
differ. . . .  Before he began
\prelude, \ww wrote. . . .

LOOKS LIKE:

The manuscripts of Wordsworth’s The Prelude differ. … Before he began The Prelude, Wordsworth wrote. …

%␣   \nixon was the 37st American
President. . . .  Many Americans
like my uncle Norm voted for \nixon
enthusiastically in both 1968 and
1972.

LOOKS LIKE:

Richard Milhous Nixon was the 37st American President. … Many Americans like my uncle Norm voted for Nixon enthusiastically in both 1968 and 1972.

%␣   \beckett gained international
noteriety with the play \godot in
the early 1950s.  \beckett wrote
\godot, he said, as a diversion from
the novels he was then writing.  I
have seen this play at the \ART in
Cambridge, Massachusetts.  The \ART
is often disappointing, but I liked
their production of \godot.

LOOKS LIKE:

Samuel Beckett gained international noteriety with the play Waiting for Godot in the early 1950s. Beckett wrote Godot, he said, as a diversion from the novels he was then writing. I have seen this play at the American Repetrory Theater (ART) in Cambridge, Massachusetts. The ART is often disappointing, but I liked their production of Godot.

\newtextmacro \newtextmacro {⟨“command⟩}{⟨initial⟩}[⟨subsequent⟩] defines an abbrevia-

tion macro ⟨“command⟩ of category Generic.

\newname \newname {⟨“command⟩}{⟨initial⟩}[⟨subsequent⟩] defines an abbreviation

macro ⟨“command⟩ of category Name.

\newbook \newbook {⟨“command⟩}{⟨initial⟩}[⟨subsequent⟩] defines an abbreviation

macro ⟨“command⟩ of category Book.

\newwork \newwork{⟨“command⟩}{⟨bibliography key⟩}{⟨initial⟩}[⟨subsequent⟩] defines an abbreviation macro ⟨“command⟩ of category Work. Works can be distinguished from books by being listed in a separate bibliography, e.g., of primary works referred to by short titles in the main text. The defining command therefore requires a BibTEX key as an argument. The first use of the work serves as a citation to that bibliography, and all uses of the work generate an index entry.

Warning: Works are not yet fully implemented. Presently they are the same as Books.

3 Date Marks

\PM These variants of abbreviation macros correctly handle following periods.

\AM
\BC
\AD

%␣␣␣     She left for work before 6\AM, but
     did not arrive until 12\PM.  The
     interval 5\BC--5\AD is one year
     shorter than the interval
     95\AD--105\AD.

LOOKS LIKE:

She left for work before 6 a.m., but did not arrive until 12 p.m. The interval 5 b.c.–5 a.d. is one year shorter than the interval 95 a.d.–105 a.d.

4 Programmers’ interface

\TMNewCategory \ResetAbbrevs {⟨category list⟩} resets all abbreviation macros of the listed cat-

\ResetAbbrevs
\TMFont<category>
\TMHook<category>
\TMReset<category>

egories. The list is comma-separated, and the category All is a shorthand for all defined categories. For each category catin the list, it simply calls the command \TMReset cat. When abbreviation macros are reset, their next invocation will expand to the initial text. Subsequent occurrences will expand to the subsequent text again. For exmaple, using \ResetAbbrevs {Name} at the beginning of chapters will cause the full name to be used only for the first occurrence in each chapter.

\AbbrevLongSuffix The suffixes “short” and “long” may be changed by changing the definitions

\AbbrevShortSuffix of \AbbrevShortSuffix and \AbbrevLongSuffix. The change should be made

after the package is loaded but before any abbreviation macros have been defined.

\DateMark Abbreviation macros like \PM are defined as \DateMarks, like this, without the final period:

     \newcommand\PM {%
       \DateMark{p.m}%
     }
\ifTMInhibitSwitching  When \ifTMInhibitSwitching is true, first occurrences of an abbreviation
\TMInhibitSwitchingfalse
\TMInhibitSwitchingtrue
\ifTMAlwaysLong
\TMAlwaysLongtrue
\TMAlwaysLongfalse

3 macro will expand to the initial expansion as usual, but they will not trigger the change to subsequent expansions. Example: inhibit switching inside footnotes, and abbreviations will not be spelled out for the first and only time in a footnote. That is, if their first appearance is in a footnote, their first appearance in the main text will also expand to the long version.

When \TMAlwaysLong is true, every abbreviation macro expands to its initial expansion.

Part II

Implementation

5 Version control

\fileinfo \fileversion \filedate \docdate \PPOptArg These definitions must be the first ones in the file.
 1 \def\fileinfo{abbreviation macros (Frankenstein's briefs)}
 2 \def\DoXNeeDME{}
 3 \def\fileversion{v1.0}
 4 \def\filedate{1996/03/21}
 5 \def\docdate{1996/03/21}
 6 \edef\PPOptArg {%
 7 \filedate\space \fileversion\space \fileinfo
 8 }

Stop right here if we’re just loading the file’s information, and don’t want to load this code for typesetting its documentation (only makes sense for certain packages). The JuStLaAdInFoRmAtIoN flag will be set by the documentation driver; the DoXNeeDME flag will be set in the dtx file, and will appear above if it’s set.

 9 \makeatletter
10 \@ifundefined{JuStLoAdInFoRmAtIoN} {%
11 }{%
12 \@ifundefined{DoXNeeDME} {%
13  }{%
14  \usepackage{abbrevs}%

15 }

16 \makeatother
17 \endinput

18 }

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

19 \NeedsTeXFormat{LaTeX2e}
20 \ProvidesPackage{abbrevs}[\PPOptArg]

6 Requirements

21 \NeedsTeXFormat{LaTeX2e}[1995/12/01]
22 \RequirePackage{moredefs}

7 Basics

Let’s begin with the tricky part of inserting space based on context. The strategy is: first, if the following character is not in \nocorr and the current font is not slanted, insert an italic correction with \sw@slant; second, if the following character is not in \nospacelist, insert a space.

Again, in pseudocode:

 LET T = the next token
 IF (slanted font is current AND T NOT IN \nocorrlist)
   \sw@slant
 FI
 IF T NOT IN \nospacelist
   \space
 FI

\nospacelist Put these in the order of their frequency. Anything in \nocorrlist should also be in here, most likely.

23 \newcommand\nospacelist {%
24 ,.':;?-~!)]\bgroup\egroup

25 }

\maybe@ic@space \maybe@ic@space@ \maybe@ic@space checks the next character and inserts an italic correction and space as appropriate.

26 \newcommand\maybe@ic@space {%
27 \futurelet\@let@token\maybe@ic@space@

28 }

We first call the kernel’s \maybe@ic@, then our own \maybe@space@.

29 \newcommand\maybe@ic@space@ {%
30 \maybe@ic@
31 \maybe@space@

32 }

\maybe@space \maybe@space@  \maybe@space and \maybe@space@ are very similar to the kernel’s analogs
\maybe@ic and \maybe@ic@, but they check \nospacelist instead of \nocorr.
\t@st@ic sets \@tempswa false if \@let@token is in \nospacelist.
33 \newcommand\maybe@space {%
34 \futurelet\@let@token\maybe@space@

35 }

36 \newcommand\maybe@space@ {%
37 \@tempswatrue
38 \expandafter   \@tfor
39  \expandafter \reserved@a
40  \expandafter :%
41  \expandafter =%
42  \nospacelist
43  \do \t@st@ic
44 \if@tempswa
45  \space
46 \fi

47 }

8 Categories

\ResetAbbrevs \TMNewCategory \TMResetAll \TMHookAll Each time an abbreviation of category C is defined, some tokens are added to the contents of \TMReset⟨C ⟩.

48 \ReserveCS\TMResetAll
49 \ReserveCS\TMHookAll

50

51 \newcommand\TMNewCategory [1] {% args:  category
52 \expandafter\ReserveCS\csname TMReset#1\endcsname
53 \expandafter\ReserveCS\csname TMFont#1\endcsname
54 \expandafter\ReserveCS\csname TMHook#1\endcsname
55 \expandafter\g@addto@macro
56  \expandafter\TMResetAll\csname TMReset#1\endcsname

57 }

58 \newcommand\ResetAbbrevs [1] {% args: category-list
59 \@for\sc@t@a:=#1\do {%
60  \@ifundefined{TMReset\sc@t@a} {%
61  \MonsterWarning{abbrevs}{The abbreviation category \sc@t@a\space
62  is not defined!}%
63  }{% ELSE
64  \@nameuse{TMReset\sc@t@a}%
65  }%
66 }%

67 }

9 Suffixes

\TMLongSuffix \TMShortSuffix When a text macro is created, two additional commands with these suffixes are also created. For example, \foo, foolong, and fooshort.

68 \newcommand\TMLongSuffix {%
69 long%

70 }

71 \newcommand\TMShortSuffix {%
72 short%

73 }

10 Plain abbreviations

The checking that \sw@slant does for skips and penalties on the list is going to be superfluous for the applications I imagine. But we trade that for a more flexible macro.

We don’t check for \nocorr or an empty body; maybe we should when it’s first defined; but I ran into really hairy expansion troubles trying to do that and

use \DeclareRobustCommand. FIX.

\TMNewAbbrevPlain Things are easy when the abbreviation doesn’t switch between initial and subsequent expansions.

74 \newcommand\TMNewAbbrevPlain [3] {% args: \csname category body
75 \@ifdefinable #1 {%
76  \DeclareRobustCommand #1 {%
77  \@bsphack

78  \@nameuse{TMHook#2}%
79  \@esphack
80  \ifmmode
81  \def\sc@t@a {%
82  \nfss@text{\@nameuse{TMFont#2}#3}%
83  }%
84  \else
85  \def\sc@t@a {%
86  \leavevmode
87  \begingroup

We can skip the check for emptiness and containing just a space, since those won’t occur with abbreviation macros except by accident, I think. We proceed straight to a check for \nocorrs.

88  \tm@check@nocorr #3\nocorr\@nil
89  \@nameuse{TMFont#2}%
90  \tm@check@left
91  #3%
92  \tm@check@right
93  \endgroup
94  }%
95  \fi
96  \sc@t@a
97  }%
98 }%

99 }

\tm@check@nocorr This corresponds to the kernel’s \check@nocorr@. We simply substitute \maybe@

ic@space and \maybe@space in where necessary. We also use \tm@check@left
and \tm@check@right instead of \check@icl and \check@icr.
100 \NewName{tm@check@nocorr} {#1#2\nocorr#3\@nil} {%
101 \let\tm@check@left\maybe@ic
102 \def\tm@check@right {\aftergroup\maybe@ic@space}%
103 \def\reserved@a {\nocorr}%
104 \def\reserved@b {#1}%
105 \def\reserved@c {#3}%
106 \ifx\reserved@a\reserved@b
107  \ifx\reserved@c\@empty
108  \let\check@icl\@empty
109  \else
110  \let\check@icl\@empty
111  \def\check@icr {\aftergroup\maybe@space}%
112  \fi
113 \else
114  \ifx\reserved@c\@empty\else
115  \def\tm@check@right {\aftergroup\maybe@space}%
116  \fi
117 \fi

118 }

11 Control booleans

\ifTMInhibitSwitching \TMInhibitSwitchingtrue \TMInhibitSwitchingfalse \ifTMAlwaysLong \TMAlwaysLongtrue \TMAlwaysLongfalse Control booleans.

119 \newboolean{TMInhibitSwitching} % initially false
120 \newboolean{TMAlwaysLong}       % initially false

12 Switching abbreviations

\TMNewAbbrevSwitcher Here is the main abbreviation macro definer. It works by defining two macros one for the initial text and one for the subsequent text, and setting up a third user command to choose between the two as appropriate. (The first two are made available to the user by explicit call as well.) The function used to define the two macros is passed as the first argument to this function. Supplied definers

are \TMNewAbbrevPlain (I will write \NewAbbrevWork and \NewAbbrevDotclose

soon FIX). The second argument is the category—each definer takes at least three arguments: a command name, a category, and the content. The third argument is the user macro name to be created, and the fourth and fifth arguments are the initial and subsequent expansion texts.

The first part sets three token variables to the three command sequences that this macro is going to define—the user, initial, and subsequent commands. The user command checks its associated boolean variable to see whether it has been called before. If so, it calls the “subsequent” macro; if not, the “initial” macro.

121 \newcommand\TMNewAbbrevSwitcher [5] {% args: maker category csname initial subseq.
122 \expandafter#1\csname #3\TMLongSuffix\endcsname{#2}{#4}
123 \expandafter#1\csname #3\TMShortSuffix\endcsname{#2}{#5}
124 \newboolean{@#3@mentioned}
125 \expandafter\g@addto@macro\csname TMReset#2\endcsname {%
126  \global\csname @#3@mentionedfalse\endcsname

127 }

We’ve created the initial and subsequent macros, and the boolean. Now we define the user macro. This definition is tricky. In pseudocode, it looks like this:

 if #3 definable then
   #3 := { if (#3-mentioned AND NOT TMAlwaysLong) then
             #3-short
           else
             if NOT TMInhibitSwitching then #3-mentioned := (global) true
             #3-long
           fi }
 fi

I’m not sure this is any more readable than a sea of \expandafter \noexpands.

128 \expandafter\@ifdefinable\csname #3\endcsname {%
129 %                is ##1 below:
130  \EExpand\csname #3\endcsname\In {%
131 %                   ####1:
132  \EExpand\csname if@#3@mentioned\endcsname\In {%
133 %                   ########1:
134  \EExpand\csname #3\TMShortSuffix\endcsname\In {%
135 %                   ################1:
136  \EExpand\csname @#3@mentionedtrue\endcsname\In {%
137 %                   ################################1:

138  \EExpand\csname #3\TMLongSuffix\endcsname\In {%
139 %     \gdef\<csname>{%
140  \gdef##1{%  must be NO SPACE before `{' !
141  \@tempswafalse
142 %       \if@<csname>mentioned
143  ####1%
144  \ifTMAlwaysLong\else
145  \@tempswatrue
146  \fi
147  \fi
148  \if@tempswa
149 %         \def\sc@t@a {\<csname>short}%
150  \def\sc@t@a {########1}%
151  \else
152  \ifTMInhibitSwitching\else
153 %           \global\@<csname>@mentionedtrue
154  \global ################1%
155  \fi
156 %         \def\sc@t@a {\<csname>long}%
157  \def\sc@t@a {################################1}%
158  \fi
159  \sc@t@a
160  }%   close \gdef
161  }}}}}% close \EExpand...\In's
162 }%       close \@ifdefinable

163 }

Warning: The \csnames (e.g., either \foolong or \fooshort) must be the very last thing to occur in the definitions, or the \futurelet that checks following spacing in \TMNewTextMacro will break. This is why we use the construction with \sc@t@a. No space must sneak into the macros, either!

The hard work is done. Now we define some macros to help create new categories.

13 Defining commands

\TMDefineAbbrevPlain \tm@defineabbrevplain  \TMDefineAbbrevPlain is the basic ⟨definer⟩ that makes the choice between defin-

ing and abbreviation and a text macro, depending on whether the user supplies a subsequent expansion.

164 \newcommand\TMDefineAbbrevPlain [3] {% args: category \csname
165  %       initial [subsequent]
166 \@ifnextchar [ {%
167  \tm@defineabbrevplain{#1}{#2}{#3}%
168  }{% ELSE
169  \TMNewAbbrevPlain{#2}{#1}{#3}%

170 }% 171 }

172 \NewName{tm@defineabbrevplain} {#1#2#3[#4]} {% args: category \csname
173  %       initial subsequent
174 \eExpand\expandafter\Gobble\string#2\In {%
175  \TMNewAbbrevSwitcher\TMNewAbbrevPlain{#1}{##1}{#3}{#4}%

176 }%

\NewUserAbbrevDefiner \tm@newuserabbrevdefiner  \NewUserAbbrevDefiner{⟨defining command⟩}{⟨category⟩}[⟨definer⟩] defines a

user command ⟨defining command⟩ which takes the arguments {⟨abbrev command⟩} {⟨initial⟩}[⟨subsequent⟩] and defines ⟨abbrev command⟩ to be a plain or switching abbreviation macro as appropriate. The argument ⟨definer⟩ should be a macro name which takes arguments {⟨category⟩}{⟨cs⟩}{⟨initial⟩}[⟨subsequent⟩] and defines {⟨cs⟩} appropriately.

178 \newcommand\NewUserAbbrevDefiner [2] {% args: \csname category [definer]
179 \@ifnextchar [ {%
180  \tm@newuserabbrevdefiner{#1}{#2}%
181  }{% ELSE
182  \tm@newuserabbrevdefiner{#1}{#2}[\TMDefineAbbrevPlain]%

183 }% 184 }

185 \NewName{tm@newuserabbrevdefiner}{#1#2[#3]} {% args: \csname category definer
186 \newcommand #1 {%
187  #3{#2}%

188 }% 189 }

14 Date marks

\DateMark \DateMarkSize I make \DateMarkSize a variable mainly because I like to use \smaller but I

don’t want this package to require it.

190 \newcommand\DateMark [1] {%
191 \hspace{.2em}{\DateMarkSize\scshape #1}%
192 \@ifnextchar. {%
193  \spacefactor\@m
194  }{% ELSE
195  .\maybe@ic@space

196 }% 197 }

198 \newlet\DateMarkSize\small

15 Configuration

We’ve built up the groundwork and leave the definitions of useful things to the configuration file.

199 \InputIfFileExists{abbrevs.cfg}{}{}

The contents of the distributed configuration file are below.

200 \def\fileinfo{Abbrevs package configuration}
201 \def\fileversion{v1.0}
202 \def\filedate{1996/03/21}
203 \def\docdate{1996/03/21}
204 \ProvidesFile{abbrevs.cfg}
\TMResetGeneric \TMResetName \TMResetBook \TMResetWork \TMHookGeneric \TMHookName \TMHookBook \TMHookWork \TMFontGeneric \TMFontName \TMFontBook \TMFontWork \newtextmacro \newname \newbook \newwork Right now, the Book and Work categories are separate but equal. A future revision

will distinguish them by keeping track of more information about Works, with the idea of using them to generate a separate bibliography and index in a long document that refers to a certain list of books by short titles. E.g., my thesis is on Samuel Beckett, and I want to refer to his works by short titles, and automatically generate a Beckett bibliography of only the ones I use, listed by title.

205 \TMNewCategory{Generic}
206 \TMNewCategory{Name}
207 \TMNewCategory{Book}
208 \TMNewCategory{Work}
209 \NewUserAbbrevDefiner\newtextmacro{Generic}
210 \NewUserAbbrevDefiner\newname{Name}
211 \NewUserAbbrevDefiner\newbook{Book}
212 \NewUserAbbrevDefiner\newwork{Work}

213

214 \RequirePackage{slemph}
215 \def\TMFontBook {%
216 \itswitch

217 }

218 \let\TMFontWork\TMFontBook

\PM \AM \BC \AD \DateMarkSize Some common time abbreviations.

219 \newcommand\PM {%
220 \DateMark{p.m}%

221 }

222 \newcommand\AM {%
223 \DateMark{a.m}%

224 }

225 \newcommand\BC {%
226 \DateMark{b.c}%

227 }

228 \newcommand\AD {%
229 \DateMark{a.d}%

230 }

231 \RequirePackage{relsize}
232 \def\DateMarkSize {%
233 \relsize{-1}%

234 }

16 Testing

I’m presently writing a dissertation on Samuel Beckett. Although there is comparatively little biographical material available, it is well known that he spent several years under the wing of James Joyce, another of the great writers in English this century. Both Joyce and Beckett, it is curious, like other great writers, both had trouble with their vision, and were exiles in some sense. One of my favorite pieces by Beckett is Worstward Ho, a short work written in the 1980’s not long before his death: “Fail again. Fail better.” Worstward Ho is lyric and exalting to me. A work I feel is underrated is the radio play All That Fall (all but his three long plays are collected in Collected Shorter Plays (CSP)). It’s extremely funny, and very touchingly compassionate. Because it is a radio play, it looses less from performance to reading. I would recommend All That Fall to anyone. His later plays (and fiction) are famously enigmatic, but with a little practice, it is not hard to see the same lyric beauty and compassion. Take the brief television play Nacht und Träume (in CSP of course), which has no dialogue, only a few murmured bars of the Schubert song, also brief, and also called Nacht und Träume—it’s one of the most hauntingly beautiful few minutes of music I’ve ever heard, and I particularly recommend Cheryl Studer’s recording on Deutsche Grammophone. Every other recording I’ve heard plays too fast.

Joyce is short for James Joyce, not Joyce Smith.

Now some more rigious and boring testing. Each pair should be identical. initial hello initial hello subsequent hello subsequent hello subsequent tie subsequent tie. subsequent regular text subsequent regular text subsequent: colon subsequent: colon subsequent; semicolon subsequent; semicolon subsequent. Period. subsequent. Period. subsequent! Exclamation point. subsequent! Exclamation point. subsequent? Question mark. subsequent? Question mark. subsequent-hyphen. subsequent-hyphen. subsequent texttt subsequent texttt subsequent (leftparen) subsequent (leftparen) (subsequent) rightparen (subsequent) rightparen subsequent, comma subsequent, comma. subsequent tmacro subsequent tmacro subsequent’s face subsequent’s face subsequent “quote” subsequent “quote” subsequent [leftbracket] subsequent [leftbracket] [subsequent] rightbracket [subsequent] rightbracket subsequentopen group subsequentopengroup subsequent close group subsequent close group subsequent {realbrace} subsequent {realbrace} subsequent 666 number subsequent 666 number subsequent x = y^{2} math subsequent x = y^{2} math subsequent $realdollar subsequent $realdollar subsequent #numbersign subsequent #numbersign