%^^A* copyright % \iffalse % % This program is part of the Frankenstein bundle for LaTeX2e. % % Copyright (C) 1995 Matt Swift % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; if not, write to the Free Software % Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. % %^^A* to do % %^^A NOTE: \DocInput will start reading after this \fi. % \fi % %^^A* checks % %^^A NOTE: The character table, with two %'s, will get written to all files. %% \CharacterTable %% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z %% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z %% Digits \0\1\2\3\4\5\6\7\8\9 %% Exclamation \! Double quote \" Hash (number) \# %% Dollar \$ Percent \% Ampersand \& %% Acute accent \' Left paren \( Right paren \) %% Asterisk \* Plus \+ Comma \, %% Minus \- Point \. Solidus \/ %% Colon \: Semicolon \; Less than \< %% Equals \= Greater than \> Question mark \? %% Commercial at \@ Left bracket \[ Backslash \\ %% Right bracket \] Circumflex \^ Underscore \_ %% Grave accent \` Left brace \{ Vertical bar \| %% Right brace \} Tilde \~} % % \CheckSum{266} % % \begin{abstract} % This package facilitates the definition of \term{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\BC and 6:00\PM, % which correctly handles following periods. % \end{abstract} % % \part{Discussion} % % \section{General} % % \DescribeMacro{\nospacelist} % An abbreviation macro \cs\foo that expands to \meta{text} is robust; % \cs\foo can be used in place of \meta{text} almost anywhere. A space is % inserted following an abbreviation macro when the first non-white character % following it is \emph{not} in the set \cs\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 |\|\meta{command}|short| and |\|\meta{command}|long| % are also defined whenever an abbreviation macro |\|\meta{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. % % \section{Usage} % % \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] %^^A FIX -- reduce, move % Examples of how to define abbreviation macros: % \begin{codeexample} % \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] % \end{codeexample} % % Examples of how to use the macros, and how they are typeset: % \begin{bothexample} % The manuscripts of \ww's \prelude % differ. . . . Before he began % \prelude, \ww wrote. . . . % \end{bothexample} % \begin{bothexample} % \nixon was the 37st American % President. . . . Many Americans % like my uncle Norm voted for \nixon % enthusiastically in both 1968 and % 1972. % \end{bothexample} % \begin{bothexample} % \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. % \end{bothexample} % % \DescribeMacro{\newtextmacro} % \cs\newtextmacro\marg{\\command}\marg{initial}\oarg{subsequent} defines an % abbreviation macro \meta{\\command} of category \cat{Generic}. % % \DescribeMacro{\newname} % \cs\newname\marg{\\command}\marg{initial}\oarg{subsequent} defines an % abbreviation macro \meta{\\command} of category \cat{Name}. % % \DescribeMacro{\newbook} % \cs\newbook\marg{\\command}\marg{initial}\oarg{subsequent} defines an % abbreviation macro \meta{\\command} of category \word{Book}. % % \DescribeMacro{\newwork} % \cs\newwork\marg{\\command}\marg{bibliography % key}\marg{initial}\oarg{subsequent} defines an abbreviation macro % \meta{\\command} of category \word{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. % % \caveat{\cat{Work}s are not yet fully implemented. Presently they are the same as \cat{Book}s.} % % \section{Date Marks} % \DescribeMacro{\PM} % \DescribeMacro{\AM} % \DescribeMacro{\BC} % \DescribeMacro{\AD} % These variants of abbreviation macros correctly handle following periods. % \begin{bothexample} % 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. % \end{bothexample} % % \section{Programmers' interface} % % \DescribeMacro{\TMNewCategory} % \DescribeMacro{\ResetAbbrevs} % \DescribeMacro{\TMFont} % \DescribeMacro{\TMHook} % \DescribeMacro{\TMReset} % \cs\ResetAbbrevs\marg{category list} resets all abbreviation macros of the % listed categories. The list is comma-separated, and the category \cat{All} % is a shorthand for all defined categories. For each category \cat{cat}in % the list, it simply calls the command \cs\TMReset\cat{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 \cs\ResetAbbrevs|{Name}| at the beginning of % chapters will cause the full name to be used only for the first occurrence % in each chapter. % % \DescribeMacro{\AbbrevLongSuffix} % \DescribeMacro{\AbbrevShortSuffix} % The suffixes ``short'' and ``long'' may be changed by changing the % definitions of \cs\AbbrevShortSuffix and \cs\AbbrevLongSuffix. The change % should be made after the package is loaded but before any abbreviation % macros have been defined. % % \DescribeMacro{\DateMark} % Abbreviation macros like \cs\PM are defined as \cs\DateMark{}s, like this, % without the final period: % \begin{codeexample} % \newcommand\PM {% % \DateMark{p.m}% % } % \end{codeexample} % % \DescribeMacro{\ifTMInhibitSwitching} % \DescribeMacro{\TMInhibitSwitchingfalse} % \DescribeMacro{\TMInhibitSwitchingtrue} % \DescribeMacro{\ifTMAlwaysLong} % \DescribeMacro{\TMAlwaysLongtrue} % \DescribeMacro{\TMAlwaysLongfalse} % When \cname{ifTMInhibitSwitching} is true, first occurrences of an % abbreviation 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 \cs\TMAlwaysLong is true, every abbreviation macro expands to its % initial expansion. % % \StopEventually{} % % \part{Implementation} % % \section{Version control} % % \begin{macro}{\fileinfo} % \begin{macro}{\fileversion} % \begin{macro}{\filedate} % \begin{macro}{\docdate} % \begin{macro}{\PPOptArg} % These definitions must be the first ones in the file. % \begin{macrocode} \def\fileinfo{abbreviation macros (Frankenstein's briefs)} \def\DoXNeeDME{} \def\fileversion{v1.0} \def\filedate{1996/03/21} \def\docdate{1996/03/21} \edef\PPOptArg {% \filedate\space \fileversion\space \fileinfo } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % 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 % \ext{dtx} file, and will appear above if it's set. % \begin{macrocode} \makeatletter \@ifundefined{JuStLoAdInFoRmAtIoN} {% }{% \@ifundefined{DoXNeeDME} {% }{% \usepackage{abbrevs}% } \makeatother \endinput } % \end{macrocode} % % Now we check for \LaTeX2e and declare the package. % \begin{macrocode} \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{abbrevs}[\PPOptArg] % \end{macrocode} % % ^^A NOTE: We have to compensate for the above backslashes, which are not % ^^A actually in the doctex file I work on. %% % \AddToCheckSum{24} % % \makeatletter % \@ifundefined{DoXNeeDME} {} {\AddToCheckSum{2}} % \makeatother % % % \section{Requirements} % % \begin{macrocode} \NeedsTeXFormat{LaTeX2e}[1995/12/01] \RequirePackage{moredefs} % \end{macrocode} % % \section{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 \cs\nocorr and the % current font is not slanted, insert an italic correction with % \cname{sw@slant}; second, if the following character is not in % \cs\nospacelist, insert a space. % % Again, in pseudocode: % \begin{codeexample} % 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 % \end{codeexample} % % \begin{macro}{\nospacelist} % Put these in the order of their frequency. Anything in \cs\nocorrlist % should also be in here, most likely. % \begin{macrocode} \newcommand\nospacelist {% ,.':;?-~!)]\bgroup\egroup } % \end{macrocode} % \end{macro} % % \begin{macro}{\maybe@ic@space} % \begin{macro}{\maybe@ic@space@} % \cname{maybe@ic@space} checks the next character and inserts an italic % correction and space as appropriate. % \begin{macrocode} \newcommand\maybe@ic@space {% \futurelet\@let@token\maybe@ic@space@ } % \end{macrocode} % We first call the kernel's \cname{maybe@ic@}, then our own \cname{maybe@space@}. % \begin{macrocode} \newcommand\maybe@ic@space@ {% \maybe@ic@ \maybe@space@ } % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\maybe@space} % \begin{macro}{\maybe@space@} % \cname{maybe@space} and \cname{maybe@space@} are very similar to the % kernel's analogs \cname{maybe@ic} and \cname{maybe@ic@}, but they check % % \cs\nospacelist instead of \cs\nocorr. \cname{t@st@ic} sets % \cname{@tempswa} false if \cname{@let@token} is in \cs\nospacelist. % \begin{macrocode} \newcommand\maybe@space {% \futurelet\@let@token\maybe@space@ } \newcommand\maybe@space@ {% \@tempswatrue \expandafter \@tfor \expandafter \reserved@a \expandafter :% \expandafter =% \nospacelist \do \t@st@ic \if@tempswa \space \fi } % \end{macrocode} % \end{macro} % \end{macro} % % \section{Categories} % % \begin{macro}{\ResetAbbrevs} % \begin{macro}{\TMNewCategory} % \begin{macro}{\TMResetAll} % \begin{macro}{\TMHookAll} % Each time an abbreviation of category \cat{C} is defined, some tokens are % added to the contents of |\TMReset|\meta{C}. % \begin{macrocode} \ReserveCS\TMResetAll \ReserveCS\TMHookAll \newcommand\TMNewCategory [1] {% args: category \expandafter\ReserveCS\csname TMReset#1\endcsname \expandafter\ReserveCS\csname TMFont#1\endcsname \expandafter\ReserveCS\csname TMHook#1\endcsname \expandafter\g@addto@macro \expandafter\TMResetAll\csname TMReset#1\endcsname } \newcommand\ResetAbbrevs [1] {% args: category-list \@for\sc@t@a:=#1\do {% \@ifundefined{TMReset\sc@t@a} {% \MonsterWarning{abbrevs}{The abbreviation category \sc@t@a\space is not defined!}% }{% ELSE \@nameuse{TMReset\sc@t@a}% }% }% } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \section{Suffixes} % % \begin{macro}{\TMLongSuffix} % \begin{macro}{\TMShortSuffix} % When a text macro is created, two additional commands with these suffixes % are also created. For example, |\foo|, |foolong|, and |fooshort|. % \begin{macrocode} \newcommand\TMLongSuffix {% long% } \newcommand\TMShortSuffix {% short% } % \end{macrocode} % \end{macro} % \end{macro} % % \section{Plain abbreviations} % % The checking that \cname{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 \cs\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 \cs\DeclareRobustCommand. FIX. % % \begin{macro}{\TMNewAbbrevPlain} % Things are easy when the abbreviation doesn't switch between initial and % subsequent expansions. % \begin{macrocode} \newcommand\TMNewAbbrevPlain [3] {% args: \csname category body \@ifdefinable #1 {% \DeclareRobustCommand #1 {% \@bsphack \@nameuse{TMHook#2}% \@esphack \ifmmode \def\sc@t@a {% \nfss@text{\@nameuse{TMFont#2}#3}% }% \else \def\sc@t@a {% \leavevmode \begingroup % \end{macrocode} % 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 \cs\nocorr{}s. % \begin{macrocode} \tm@check@nocorr #3\nocorr\@nil \@nameuse{TMFont#2}% \tm@check@left #3% \tm@check@right \endgroup }% \fi \sc@t@a }% }% } % \end{macrocode} % \end{macro} % % \begin{macro}{\tm@check@nocorr} % This corresponds to the kernel's \cname{check@nocorr@}. We simply % substitute \cname{maybe@ic@space} and \cname{maybe@space} in where % necessary. We also use \cname{tm@check@left} and \cname{tm@check@right} % instead of \cname{check@icl} and \cname{check@icr}. % \begin{macrocode} \NewName{tm@check@nocorr} {#1#2\nocorr#3\@nil} {% \let\tm@check@left\maybe@ic \def\tm@check@right {\aftergroup\maybe@ic@space}% \def\reserved@a {\nocorr}% \def\reserved@b {#1}% \def\reserved@c {#3}% \ifx\reserved@a\reserved@b \ifx\reserved@c\@empty \let\check@icl\@empty \else \let\check@icl\@empty \def\check@icr {\aftergroup\maybe@space}% \fi \else \ifx\reserved@c\@empty\else \def\tm@check@right {\aftergroup\maybe@space}% \fi \fi } % \end{macrocode} % \end{macro} % % \section{Control booleans} % % \begin{macro}{\ifTMInhibitSwitching} % \begin{macro}{\TMInhibitSwitchingtrue} % \begin{macro}{\TMInhibitSwitchingfalse} % \begin{macro}{\ifTMAlwaysLong} % \begin{macro}{\TMAlwaysLongtrue} % \begin{macro}{\TMAlwaysLongfalse} % Control booleans. % \begin{macrocode} \newboolean{TMInhibitSwitching} % initially false \newboolean{TMAlwaysLong} % initially false % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \section{Switching abbreviations} % % \vspace{7ex}^^A kludge to handle all those macro names % \begin{macro}{\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 \cs\TMNewAbbrevPlain (I will write % \cs\NewAbbrevWork and \cs\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. % % \begin{macrocode} \newcommand\TMNewAbbrevSwitcher [5] {% args: maker category csname initial subseq. \expandafter#1\csname #3\TMLongSuffix\endcsname{#2}{#4} \expandafter#1\csname #3\TMShortSuffix\endcsname{#2}{#5} \newboolean{@#3@mentioned} \expandafter\g@addto@macro\csname TMReset#2\endcsname {% \global\csname @#3@mentionedfalse\endcsname } % \end{macrocode} % 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: % \begin{codeexample} % 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 % \end{codeexample} % I'm not sure this is any more readable than a sea of % \cs\expandafter\cs\noexpand{}s. % \begin{macrocode} \expandafter\@ifdefinable\csname #3\endcsname {% % is ##1 below: \EExpand\csname #3\endcsname\In {% % ####1: \EExpand\csname if@#3@mentioned\endcsname\In {% % ########1: \EExpand\csname #3\TMShortSuffix\endcsname\In {% % ################1: \EExpand\csname @#3@mentionedtrue\endcsname\In {% % ################################1: \EExpand\csname #3\TMLongSuffix\endcsname\In {% % \gdef\{% \gdef##1{% must be NO SPACE before `{' ! \@tempswafalse % \if@mentioned ####1% \ifTMAlwaysLong\else \@tempswatrue \fi \fi \if@tempswa % \def\sc@t@a {\short}% \def\sc@t@a {########1}% \else \ifTMInhibitSwitching\else % \global\@@mentionedtrue \global ################1% \fi % \def\sc@t@a {\long}% \def\sc@t@a {################################1}% \fi \sc@t@a }% close \gdef }}}}}% close \EExpand...\In's }% close \@ifdefinable } % \end{macrocode} % \caveat{The \cs\csname{}s (e.g., either \cs\foolong or \cs\fooshort) % \emph{must} be the very last thing to occur in the definitions, or the % \cs\futurelet that checks following spacing in \cs\TMNewTextMacro will break. % This is why we use the construction with \cname{sc@t@a}. No space must sneak % into the macros, either!} % \end{macro} % % The hard work is done. Now we define some macros to help create new % categories. % % \section{Defining commands} % % \begin{macro}{\TMDefineAbbrevPlain} % \begin{macro}{\tm@defineabbrevplain} % \cs\TMDefineAbbrevPlain is the basic \meta{definer} that makes the choice % between defining and abbreviation and a text macro, depending on whether the % user supplies a subsequent expansion. % \begin{macrocode} \newcommand\TMDefineAbbrevPlain [3] {% args: category \csname % initial [subsequent] \@ifnextchar [ {% \tm@defineabbrevplain{#1}{#2}{#3}% }{% ELSE \TMNewAbbrevPlain{#2}{#1}{#3}% }% } \NewName{tm@defineabbrevplain} {#1#2#3[#4]} {% args: category \csname % initial subsequent \eExpand\expandafter\Gobble\string#2\In {% \TMNewAbbrevSwitcher\TMNewAbbrevPlain{#1}{##1}{#3}{#4}% }% } % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\NewUserAbbrevDefiner} % \begin{macro}{\tm@newuserabbrevdefiner} % \cs\NewUserAbbrevDefiner\marg{defining command}\marg{category}\oarg{definer} % defines a user command \meta{defining command} which takes the arguments % \marg{abbrev command}\marg{initial}\oarg{subsequent} and defines \meta{abbrev % command} to be a plain or switching abbreviation macro as appropriate. The % argument \meta{definer} should be a macro name which takes arguments % \marg{category}\marg{cs}\marg{initial}\oarg{subsequent} and defines \marg{cs} % appropriately. % \begin{macrocode} \newcommand\NewUserAbbrevDefiner [2] {% args: \csname category [definer] \@ifnextchar [ {% \tm@newuserabbrevdefiner{#1}{#2}% }{% ELSE \tm@newuserabbrevdefiner{#1}{#2}[\TMDefineAbbrevPlain]% }% } \NewName{tm@newuserabbrevdefiner}{#1#2[#3]} {% args: \csname category definer \newcommand #1 {% #3{#2}% }% } % \end{macrocode} % \end{macro} % \end{macro} % % \section{Date marks} % % \begin{macro}{\DateMark} % \begin{macro}{\DateMarkSize} % I make \cs\DateMarkSize a variable mainly because I like to use \cs\smaller % but I don't want this package to require it. % \begin{macrocode} \newcommand\DateMark [1] {% \hspace{.2em}{\DateMarkSize\scshape #1}% \@ifnextchar. {% \spacefactor\@m }{% ELSE .\maybe@ic@space }% } \newlet\DateMarkSize\small % \end{macrocode} % \end{macro} % \end{macro} % % \section{Configuration} % % We've built up the groundwork and leave the definitions of useful things to % the configuration file. % \begin{macrocode} \InputIfFileExists{abbrevs.cfg}{}{} % \end{macrocode} % % The contents of the distributed configuration file are below. % % \InputIfFileExists{abbrevs.cfg}{}{} % % \Finale