%^^A* legal notices % \iffalse % % This program is part of the Frankenstein bundle for LaTeX. % % Copyright 1995-2001 Matt Swift . % % This file contains both the code and documentation for the % abbrevs LaTeX package. It will work ONLY if it is placed in a % proper directory. Files called README, INSTALL, abbrevs.tex % and abbrevs.ins should have also been distributed to you % with this file. See them for more information on how to typeset % the documentation with LaTeX and how to generate a version of this % file that will work faster than this one. % % This program is free software; you may redistribute it and/or % modify it under the conditions of the LaTeX Project Public % License, either version 1.2 or (at your option) any later version. % The latest version of this license is in % http://www.latex-project.org/lppl.txt, and version 1.2 or later is % part of all distributions of LaTeX version 1999/12/01 or later. % % 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 % LaTeX Project Public License for more details. % % \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{683} % % \begin{abstract} % ``Abbreviation macros'' expand to defined text and insert following space % intelligently, based on context. They can also expand to one thing the first % time they are used and another thing on subsequent invocations. Thus they % can be abbreviations in two senses, in the source and in the document. % Useful applications include the abstraction of textual elements such as names % without fussing over spacing and the automatic expansion of abbreviations and % 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} % \tableofcontents % % \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 \verb*|,.':;?-/~!)]{}\ \/\@xobeysp|. % % 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. Using the |\|\meta{command}|long| command does not affect what % the next abbreviation macros expands to. % % All abbreviation macros are assigned categories, identified by a string. % Four categories are defined by the package, and it is easy to add more. % Categories facilitate handling different groups of abbreviation macros in % different ways. % % \caveat{Regarding CJK macros and probably other 8-bit input. If you use % the \package{abbrevs} package with the CJK macros for typesetting Chinese, % Japanese, and Korean text, you must define your abbreviations within the % CJK environment. I believe that the CJK macros work by interpreting 8-bit % input in the source file. But this input is only interpreted properly % within the CJK environment. If you define the abbrevs outside, such as in % the preamble, you will just get a bunch of numbers when your abbreviation % expands.} % % I would use capital letters for the name of this macro, since it doesn't % seem like a user command to me, but I'm modelling after the kernel's % \cs\nocorrlist. % % \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} % \newabbrev\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} % \newabbrev\ART{American Repetrory Theater (ART)}[ART] % \end{codeexample} % % \todo{Give example of using |short| or |long|.} % % Examples of how to use the macros, and how they are typeset:\relax % \footnote{\cs\lips is defined in the \package{lips} package, part of the % \Frankenstein bundle.} % \begin{bothexample} % The manuscripts of \ww's \prelude differ. \lips Before he began \prelude, % \ww wrote \lips % \end{bothexample} % \begin{bothexample} % \nixon was the 37st American President. \lips 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{\newabbrev} % \cs\newabbrev\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 \cat{Book}. % % \DescribeMacro{\newwork} % \cs\newwork\marg{\\command}\marg{bibliography % key}\marg{initial}\oarg{subsequent} defines an abbreviation macro % \meta{\\command} of category \cat{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. % % \todo{\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{Emulation of \package{acromake}} % We emulate the \package{acromake} package by Paul A.~Thompson (version of % 1995/7/16 at \url{CTAN:/macros/latex/contrib/other/misc/acromake.sty}). % \package{Abbrevs} will issue an informative warning when it guesses it is % about to fail because \package{acromake} is already loaded (we cannot know % for certain if it is). I will add an option so that \package{abbrevs} and % \package{acromake} can both be loaded if anyone persuades me it will be % useful. % % One reason to emulate \package{acromake} with \package{abbrevs} is that it % can be done easily and by doing so we can avoid keeping two packages around % when one will do. Another is that \package{abbrevs} is a more general and % powerful package which adds value to \package{acromake} functionality. % \package{Abbrevs} should be a drop-in replacement for \package{acromake}, but % you can also take advantage of features of \package{abbrevs}: acromake-style % abbreviations obey \cs\TMInhibitSwitching, and they are defined as their own % category of abbreviations, \cat{Acromake}, so that \package{acromake}-style % abbreviations can be manipulated with the general mechanisms available to any % category. % % The following three \package{acromake} user commands are implemented in % \package{abbrevs}. % % \DescribeMacro{\acromake} % \cs\acromake \marg{csname}\marg{initial text}\marg{final text} FIX dox % % \DescribeMacro{\ACRcnta} % The macro \cs\ACRcnta contains the number of times (default 1) the initial % text (full text) is given. Use \cs\renewcommand to redefine it. % % \DescribeMacro{\ACRcntb} % The macro \cs\ACRcntb contains the number of iterations (default 2) before % the final text is given. The intermediate text (final text plus page % reference) is therefore given $\mbox{|ACRcntb|} - \mbox{|ACRcnta|}$ times. % % \DescribeMacro{\AcromakePageref} % Define the macro \cs\AcromakePageref to contain the text that expresses the % page reference. \package{Abbrevs} will replace the string |##1| in the % definition of this macro with the page number where the abbreviation was % first used (more precisely, with |\pageref{|\meta{label}|}|). The default % value is |(see Page ##1)| for compatibility with \package{acromake}. The % styles I am familiar with would call for a lowercase ``page.'' % % \caveat{\cs\AcromakePageref not implemented yet} % % \subsection{Possible discrepancies} % The counter |util| and the macros \cs\pv and \cs\addtomacro are used % internally by \package{acromake} and are not defined in \package{abbrevs}. % (If you managed to find some use for \cs\addtomacro, you will probably see % easily how to redefine it in this context---and if not, write me.) % % The emulation may behave slightly differently due to the difference beteween % the way the \package{xspace} package handles following punctuation and space % and the way \package{abbrevs} does. I think \package{abbrevs} is very % likely to be as good or better than \package{xspace} at making these % decisions. Let me know if you think otherwise. % % \section{Programmers' interface} % % \DescribeMacro{\ResetAbbrevs} % 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. \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. Example: % \begin{codeexample} % \SaveCS\chapter % \renewcommand\chapter {% % \ResetAbbrevs{All}% % \MDSavedchapter % } % \end{codeexample} % % \DescribeMacro{\NewAbbrevCategory} % \DescribeMacro{\TMFontAll} % \DescribeMacro{\TMHookAll} % \DescribeMacro{\TMResetAll} % \DescribeMacro{\TMFont} % \DescribeMacro{\TMHook} % \DescribeMacro{\TMReset} % To create new categories of abbreviation, use % \cs\NewAbbrevCategory\marg{category name}. Macros % \cs\TMFont\meta{category}, \cs\TMHook\meta{category}, and % \cs\TMReset{}\meta{category} are all reserved. The hook and font slots % start empty. The virtual category \cat{All} is predefined and refers to % all defined categories. \cs\TMHookAll and \cs\TMFontAll are called % \emph{before} the respective category-specific commands. % % \DescribeMacro{\NewUserAbbrevDefiner} % \cs\NewUserAbbrevDefiner\marg{defining % command}\marg{category}\oarg{definer} defines a user command \meta{defining % command}. With the default \meta{definer}, \cs\TMDefineAbbrevStandard, % the \meta{defining command} will take the arguments \marg{abbrev % command}\marg{initial text}\oarg{subsequent text} and defines % \meta{abbrev command} to be a plain or switching abbreviation macro as % appropriate. If given, the optional argument \meta{definer} should be a % macro name, which will be first be passed a \marg{category}, then will % read user arguments (e.g., in the case of \cs\TMDefineAbbrevStandard, % \marg{cs}\marg{initial}\oarg{subsequent}). The \meta{definer} is % expected of course to do something like define \marg{cs}. % % \DescribeMacro{\TMInitialSuffix} % \DescribeMacro{\TMSubsequentSuffix} % The factory default suffixes ``short'' and ``long'' may be changed by % changing the definitions of \cs\TMSubsequentSuffix and % \cs\TMInitialSuffix. 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. See the configuration file for how to do this. % % When \cs\TMAlwaysLong is true, every abbreviation macro expands to its % initial expansion. % % \StopEventually{} % % \part{Implementation} % % \section{Version control} % % \begin{macro}{\fileinfo} % \begin{macro}{\DoXUsepackagE} % \begin{macro}{\HaveECitationS} % \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\DoXPackageS {abbrevs} \def\fileversion{v1.4} \def\filedate{2001/09/08} \def\docdate{2001/09/08} \edef\PPOptArg {% \filedate\space \fileversion\space \fileinfo } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % If we're loading this file from a \cs\ProcessDTXFile command (see the % \package{compsci} package), then \cs\JusTLoaDInformatioN will be defined; % othewise we assume it is not (that's why the FunkY NamE). % % If we're loading from \cs\ProcessDTXFile, we want to load the packages listed % in \cs\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. \cs\DoXPackageS, if there are any, are declared in % the \ext{dtx} file, and, if you're reading the typeset documentation of this % package, would appear just above. (It's OK to call \cs\usepackage with an % empty argument or \cs\relax, by the way.) % \begin{macrocode} \makeatletter% A special comment to help create bst files. Don't change! \@ifundefined{JusTLoaDInformatioN} {% }{% ELSE (we know the compsci package is already loaded, too) \UndefineCS\JusTLoaDInformatioN \SaveDoXVarS \eExpand\csname DoXPackageS\endcsname\In {%use \csname in case it's undefined \usepackage{#1}% }% \RestoreDoXVarS \makeatother \endinput }% A special comment to help create bst files. Don't change! % \end{macrocode} % % Now we check for \LaTeX2e and declare the LaTeX package. % \begin{macrocode} \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{abbrevs}[\PPOptArg] % \end{macrocode}^^A special comment to help create bst files. Don't change! % % ^^A NOTE: We have to compensate for the above backslashes, which are not % ^^A actually in the .dtx file the author works on, by adding to the % ^^A CheckSum. %% % \AddToCheckSum{17}^^A `dtx-update-checksum' automatically handles this. % \AddToCheckSum{7}^^A The half a macrocode env. at the top is missed, however... % \AddToCheckSum{10}^^A ... and so are the 5 \defs from the .dtx file % ^^A that precede it. % \IfCitations {% % \AddToCheckSum{2}^^A When \initelyHavECitationS is defined in % } ^^A the .dtx file, we need 2 more in the CheckSum. % % % \section{Requirements} % % \begin{macrocode} \NeedsTeXFormat{LaTeX2e}[1995/12/01] \RequirePackage{moredefs,slemph} % \end{macrocode} % % \caveat{These docs could be much improved. There are far too many things % called ``definers.'' Cleaning up the basic code concepts wouldn't hurt either.} % % \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. I'm putting in \cname{@xobeysp} % because it's in the \package{xspace} package, but I can't tell you when it % would come up. % \begin{macrocode} \requirecommand\nospacelist {% ,.':;?-/\slash~!)]\bgroup\egroup\@sptoken\ \space\/\@xobeysp } % \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 % \DTypeout{In maybe@space@ my lettoken is [\meaning\@let@token]}% \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}{\NewAbbrevCategory} % \begin{macro}{\TMResetAll} % \begin{macro}{\TMHookAll} % \begin{macro}{\TMFontAll} % 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 \ReserveCS\TMFontAll \newcommand\NewAbbrevCategory [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} {% \FrankenWarning{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} % \end{macro} % % \section{Suffixes} % % \begin{macro}{\TMInitialSuffix} % \begin{macro}{\TMSubsequentSuffix} % When an abbreviation macro is created, two additional commands with these % suffixes are also created. For example, \cs\foo, \cs\foolong, and % \cs\fooshort. When abbrevs are used in such a way that ``long'' and % ``short'' don't make sense, it would make sense to change these to % something more descriptive. % \begin{macrocode} \newcommand\TMInitialSuffix {% long% } \newcommand{\TMSubsequentSuffix} {% 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. % \todo{pass root and suffix instead of \code{\csname} so that we don't have to parse % it out again later from tmcurrentmacro} % \begin{macrocode} \ReserveCS\TMCurrentMacro \newcommand\TMNewAbbrevPlain [3] {% args: \csname category body \NewRobustCommand #1 {% % \xdef\TMCurrentMacro {\expandafter\Gobble\string#1}% \@bsphack \TMHookAll \@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 \TMFontAll \@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\TMNewAbbrevWork and \cs\TMNewAbbrevDotclose 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: definer category csname % % initial subseq. \expandafter#1\csname #3\TMInitialSuffix\endcsname{#2}{#4} \expandafter#1\csname #3\TMSubsequentSuffix\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} % Hmm, I'm not sure this is any more readable than a sea of % \cs\expandafter\cs\noexpand{}s. % % Notice that in a switching abbrev, the -mentioned boolean is set to true % \emph{before} calling the macro itself, so that the hook can check and % possibly alter the value. The \package{acromake} emulation takes advantage % of this. % \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\TMSubsequentSuffix\endcsname\In {% % ################1: \EExpand\csname @#3@mentionedtrue\endcsname\In {% % ################################1: \EExpand\csname #3\TMInitialSuffix\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 {\\TMSubsequentSuffix}% \def\sc@t@a {########1}% \else \ifTMInhibitSwitching\else % \global\@@mentionedtrue \global ################1% \fi % \def\sc@t@a {\\TMInitialSuffix}% \def\sc@t@a {################################1}% \fi % \expandafter \gdef % \expandafter\TMCurrentMacro % \expandafter{\sc@t@a}% \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, e.g., \cs\TMNewAbbrevPlain % 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} % % A \meta{definer} is always called with a category as a first argument. The % only definers in this version of this package are this one and the one that % emulates the \package{acromake} package. More later! % % \begin{macro}{\TMDefineAbbrevStandard} % \begin{macro}{\tm@defineabbrevstandard} % \cs\TMDefineAbbrevStandard is the standard \meta{definer} that makes the % choice between defining an switching or a plain abbreviation, depending on % whether the user supplies a subsequent text. % \begin{macrocode} \newcommand\TMDefineAbbrevStandard [3] {% args: category \csname % initial [subsequent] \@ifnextchar [ {% \tm@defineabbrevstandard{#1}{#2}{#3}% }{% ELSE \TMNewAbbrevPlain{#2}{#1}{#3}% }% } \NewName{tm@defineabbrevstandard} {#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} % \mbox{} % \begin{macrocode} \newcommand\NewUserAbbrevDefiner [2] {% args: \csname category [definer] \@ifnextchar [ {% \tm@newuserabbrevdefiner{#1}{#2}% }{% ELSE \tm@newuserabbrevdefiner{#1}{#2}[\TMDefineAbbrevStandard]% }% } \NewName{tm@newuserabbrevdefiner}{#1#2[#3]} {% args: \csname category definer \newcommand #1 {% #3{#2}% }% } % \end{macrocode} % \end{macro} % \end{macro} % % \section{Basic categories} % % \begin{macro}{\TMResetGeneric} % \begin{macro}{\TMResetName} % \begin{macro}{\TMResetBook} % \begin{macro}{\TMResetWork} % \begin{macro}{\TMHookGeneric} % \begin{macro}{\TMHookName} % \begin{macro}{\TMHookBook} % \begin{macro}{\TMHookWork} % \begin{macro}{\TMFontGeneric} % \begin{macro}{\TMFontName} % \begin{macro}{\TMFontBook} % \begin{macro}{\TMFontWork} % \begin{macro}{\newabbrev} % \begin{macro}{\newname} % \begin{macro}{\newbook} % \begin{macro}{\newwork} % Right now, the \cat{Book} and \cat{Work} categories are separate but % equal. A future revision will distinguish them by keeping track of more % information about \cat{Work}s, 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. % \begin{macrocode} \NewAbbrevCategory{Generic} \NewAbbrevCategory{Name} \NewAbbrevCategory{Book} \NewAbbrevCategory{Work} \NewUserAbbrevDefiner{\newabbrev}{Generic} \NewUserAbbrevDefiner{\newname}{Name} \NewUserAbbrevDefiner{\newbook}{Book} \NewUserAbbrevDefiner{\newwork}{Work} \def\TMFontBook {% \itswitch } \def\TMFontWork {% \itswitch } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \section{Date marks} % % \begin{macro}{\DateMark} % \begin{macro}{\DateMarkSize} % \mbox{} % \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} % % \begin{macro}{\PM} % \begin{macro}{\AM} % \begin{macro}{\BC} % \begin{macro}{\AD} % Some common time abbreviations. % \begin{macrocode} \newcommand{\PM} {% \DateMark{p.m}% } \newcommand{\AM} {% \DateMark{a.m}% } \newcommand{\BC} {% \DateMark{b.c}% } \newcommand{\AD} {% \DateMark{a.d}% } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \section{Emulation of \package{Acromake}} % % \caveat{This code is a \emph{mess!} Consider all but the user functions % ``internal.'' I will reimplement it all another time. Meanwhile it works, % and the user interface is \package{acromake}'s anyway, so it won't change.} % % \begin{macro}{\TMResetAcromake} % \begin{macro}{\TMFontAcromake} % \begin{macro}{\TMHookAcromake} % \begin{macro}{\TMHookAcromakeHook} % \begin{macro}{\TMAcromakeSecondarySuffix} % \begin{macro}{\acromake} % \begin{macro}{\tm@acromake@pageref} % Define the category \cat{Acromake} and declare its user defining % command to be \cs\acromake. Create a suffix \TMAcromakeSecondarySuffix % analogous to \cs\TMInitialSuffix and \cs\TMSubsequentSuffix. % % Instead of building more generality into \package{abbrevs}, I emulate % \package{acromake} with a few hacks, since I don't see a \emph{general} need % for more than two expansions. Counting iterations, on the other hand, is % something I would like to do for all abbrevs. Doing so is tantamount to % replacing the present |-mentioned| booleans with ``counter'' macros. % % The emulation is done in the following way. Let's call the three expansions % of an \package{acromake} macro the \meta{am-initial}, \meta{am-secondary}, % and \meta{am-subsequent} expansions, in order. These must be mapped onto the % \package{abbrevs} concepts of \term{inital} and \term{subsequent} expansions. % The \cs\acromake command as I define it here defines a switching abbrev whose % initial text contains \meta{am-initial} and subsequent text contains % \meta{am-subsequent}. It also defines a plain abbrev with a suffix % \cs\TMAcroSecondarySuffix (analogous to \cs\TMInitialSuffix and % \cs\TMSubsequentSuffix) that expands to \meta{am-secondary}. In a switching % abbrev, the associated |-mentioned| boolean is set to |true| \emph{before} % calling the macro itself (and therefore its hook). The hook can therefore % reset the boolean to |false|, and I do this in \cs\TMHookAcromake until it is % time to go from the \meta{am-initial} to the \meta{am-secondary} expansions. % \cs\TMInhibitSwitching affects the \cat{Acromake} category like all others, % and \cs\TMResetAcromake behaves as expected. % % \begin{macrocode} \@ifpackageloaded{acromake}{% \FrankenWarning{abbrevs}{LaTeX is about to fail because \protect\acromake is already defined.\MessageBreak Probably you have loaded acromake.sty, and if so,\MessageBreak you should simply not load it, since abbrevs.sty emulates\MessageBreak acromake.sty.} }{%ELSE } \NewAbbrevCategory{Acromake} \NewUserAbbrevDefiner{\acromake}{Acromake}[\TMAcromakeDefiner] \newcommand\TMAcromakeSecondarySuffix {secondary} \ReserveCS\tm@acromake@pageref % \end{macrocode} % We're going to use the main hook, so provide another free one. % \begin{macrocode} \ReserveCS\TMHookAcromakeHook % \end{macrocode} % I'm not sure why \package{acromake} does this check for odd values of % \cs\ACRcnta. I use logic below that I think does reasonable things with odd % values. % % I think \package{acromake} tried to inhibit using \meta{am-secondary} when it % appeared on the same page as the (first!)\ \meta{am-initial} instance, but I % also think there was a spurious $0$ in the source that broke this feature. % I've emulated the working feature. % \begin{macrocode} % consider these acromake functions internal for now! % differs from regular version in passing args to definer \newcommand\TMNewAbbrevSwitcherAcromake [5] {% args: definer category csname % % initial subseq. #1{#3}{\TMInitialSuffix}{#2}{#4} #1{#3}{\TMSubsequentSuffix}{#2}{#5} \newboolean{@#3@mentioned} \expandafter\g@addto@macro\csname TMReset#2\endcsname {% \global\csname @#3@mentionedfalse\endcsname } \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\TMSubsequentSuffix\endcsname\In {% % ################1: \EExpand\csname @#3@mentionedtrue\endcsname\In {% % ################################1: \EExpand\csname #3\TMInitialSuffix\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 {\\TMSubsequentSuffix}% \def\sc@t@a {########1}% \else \ifTMInhibitSwitching\else % \global\@@mentionedtrue \global ################1% \fi % \def\sc@t@a {\\TMInitialSuffix}% \def\sc@t@a {################################1}% \fi % \expandafter \gdef % \expandafter\TMCurrentMacro % \expandafter{\sc@t@a}% \sc@t@a }% close \gdef }}}}}% close \EExpand...\In's }% close \@ifdefinable } \newcommand\TMAcromakeDefiner [4] {% args: category csname acronym fulltext \ifnum \ACRcnta < 1\relax \def\ACRcnta {1}% \fi% % \end{macrocode} % \package{Acromake} uses a suffix of |z| here, which IMHO is a bad idea, so % I use something a user will not put in a source file: a prefix of |tm@acromake@|. % See below for why we start at $-1$. % \begin{macrocode} \Global\NewName{tm@acromake@#2}{} {-1}% macro for counting occurrences % \end{macrocode} % Define an abbrev that switches from \meta{am-initial} to % \meta{am-subsequent}. Hack the resetting macro to reset the count as well as % the |-mentioned| boolean. Reset to $0$ not $-1$ so that we only label once! % Is this an argument for having the ``mentioned'' boolean switch at the % transition from \meta{am-secondary} to \meta{am-subsequent}? (so that % resetting goes back to \meta{am-secondary} instead of \meta{am-initial}.) I % think so; or, better, define a \emph{new} label each time we reset. % \begin{macrocode} \TMNewAbbrevSwitcherAcromake\TMNewAbbrevAcromake{#1}{#2}{#4 (#3)}{#3}% \expandafter\g@addto@macro\csname TMReset#1\endcsname {% \global\DefName{tm@acromake@#2}{} {-1}% }% % \end{macrocode} % Define an additional abbrev that expands to \meta{am-secondary}. In the code % below, Fred replaces the |#1| with something else with |#1| in it; Ethel % replaces the new |#1| with the contents of \cname{sc@toks@a}. (The |#| is % quoted with more |#|'s below.) Hmm, this expansion business could probably % be simplified by thinking it through from the beginning. % \begin{macrocode} % \def\tm@acromake@pageref {% % \sc@toks@a={\noexpand\pageref{TMacromake:#2}}% % \EExpand\AcromakePageref\In {% ``Fred'' % \EExpand\sc@toks@a\In {% ``Ethel'' % ####1% % }% % }% % }% % \eExpand\tm@acromake@pageref\In {% \TMNewAbbrevAcromake{#2}{\TMAcromakeSecondarySuffix} {Acromake} {#3\ (see Page \pageref{TMacromake:#2})}% % {#3\ ##1}% % }% } % \end{macrocode} % Now define \cs\TMHookAcromake. % Arg, first have to define an alternative of \cs\TMNewAbbrevPlain because of % the odd problem described above. Same as \cs\TMNewAbbrevPlain except takes % first argument in two parts and defines \TMCurrentMacroRootname, which will % be used in the hook. % \begin{macrocode} \ReserveCS\TMCurrentMacroRootname % plain's args: csname category body \newcommand\TMNewAbbrevAcromake [4] {% args: csname-root csname-suffix category body \expandafter\NewRobustCommand\csname #1#2\endcsname {% \gdef\TMCurrentMacroRootname {#1}% \@bsphack \TMHookAll \@nameuse{TMHook#3}% \@esphack \ifmmode \def\sc@t@a {% \nfss@text{\@nameuse{TMFont#3}#4}% }% \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 #4\nocorr\@nil \TMFontAll \@nameuse{TMFont#3}% \tm@check@left #4% \tm@check@right \endgroup }% \fi \sc@t@a }% } %\def\tm@chop#1 {#1}% %\def\tm@choplong#1long{#1} \ReserveCS\tm@t % temp \def\TMHookAcromake {% % \end{macrocode} % We handle inhibition of switching as follows. If the count is $-1$, this is % the first iteration, so make the \cs\label, increment the count to $0$, and % proceed. If switching is not inhibited, increment the counter. Then proceed % with choosing the right expansion based on the counter. A first iteration in % the normal case will therefore increment the counter twice from $-1$ to $1$. % A first iteration in the case that switching is inhibited will advance the % counter once to $0$, where it will stay until switching is permitted. % % I need to extract the root name from the three suffixed names -- why can't I % do that?! % \begin{codeexample} % \documentclass{minimal} % \begin{document} % \def\gobble#1{} % \def\one{j} % \edef\two{\expandafter\gobble\string\j} % %\edef\two{\two} % doesn't help % \edef\three{\two} % \typeout{one: [\meaning\one]} % \typeout{two: [\meaning\two]} % [\one] [\two] % \typeout{\ifx\one\two ifx same\else ifx different -- WHY?!\fi} % \typeout{\if\one\two if same\else if different\fi} % \end{codeexample} % % % \begin{macrocode} % \edef\tm@t{\expandafter\strip@prefix\meaning\TMCurrentMacro}% % \edef\tm@t{\E@cdr\tm@t\@nil}% % \edef\tm@t{\expandafter\tm@choplong\TMCurrentMacro}% \edef\tm@t{\TMCurrentMacroRootname}% \ifnum\csname tm@acromake@\tm@t\endcsname = -1\relax \eExpand\tm@t\In{% % \typeout{initial: labeling ##1}% \label{TMacromake:##1}% }% \tm@incmacro{\tm@t}% \fi \ifTMInhibitSwitching\else \tm@incmacro{\tm@t}% \fi % \typeout{BEGIN: count is \csname tm@acromake@\tm@t\endcsname}% % \end{macrocode} % When the count is $< \mbox{|ACRcnta|}$, reset the |-mentioned| boolean so % that the expansion will be the initial text i.e., \meta{am-initial}, again % the next time. % \begin{macrocode} % doesn't work: % \ifnum\csname tm@acromake@\tm@t\endcsname < \ACRcnta% % doesn't work: % \ifnum\csname tm@acromake@\tm@t\endcsname < \ACRcnta % % works: I have no clue why... \ifnum\csname tm@acromake@\tm@t\endcsname < \ACRcnta\relax % \typeout{use before cnta}% \expandafter\global\csname @\tm@t@mentionedfalse\endcsname \else % \end{macrocode} % When the count is $= \mbox{|ACRcnta|}$, use the initial text (i.e., % \meta{am-initial}) one last time and switch to using \meta{am secondary} next % time. We allow the |-mentioned| boolean to become |true| by refraining from % resetting it. We save the existing subsequent macro (which expands to % \meta{am-subsequent}) and substitute the abbrev that expands to % \meta{am-secondary}. The bounds check on \cs\ACRcnta at the beginning % guarantees that we execute this clause once. % \begin{macrocode} \ifnum\csname tm@acromake@\tm@t\endcsname = \ACRcnta\relax \ifTMInhibitSwitching\else % \typeout{use at cnta A}% \SaveName{\tm@t\TMSubsequentSuffix}% % \typeout{use at cnta B}% \global\EElet\csname \tm@t\TMSubsequentSuffix\endcsname \csname \tm@t\TMAcromakeSecondarySuffix\endcsname % \typeout{use at cnta C}% \fi \fi % \end{macrocode} % When the count is $> \mbox{|ACRcnta|}$ and $<= \mbox{|ACRcntb|}$, % the expansion is \meta{am-secondary}, we only check whether we are currently % on the page of the original use of the \meta{am-initial} text and in this % case use \meta{am-subsequent}. % \begin{macrocode} % \@tempswafalse % \ifnum\csname tm@acromake@\tm@t\endcsname < \ACRcntb\relax % \ifnum\csname tm@acromake@\tm@t\endcsname > \ACRcnta\relax % \@tempswatrue % \fi % \else % \ifnum\csname tm@acromake@\tm@t\endcsname = \ACRcntb\relax % \@tempswatrue % \fi % \fi % % ie cnta < count <= cntb % \if@tempswa % % \typeout{use between cnta and cntb}% % \eExpand\tm@t\In{% % \typeout{page [\thepage] ref [\r@TMacromake:##1]}% % \expandafter\ifnum\expandafter\thepage\expandafter=\csname r@TMacromake:##1\endcsname\relax % % \typeout{this instance should be subsequent instead of secondary}% % % insert a * to signal where: % % *% % % FIX how to do it?? I leave it broken for now, as it is broken in acromake % % itself, % \fi % }% % \fi % \end{macrocode} % When the count is $= \mbox{|ACRcntb|}$, we want to restore the definition of % the subsequent macro. This test is not in an \cs\else clause to handle the % case where $\mbox{|ACRcnta|} = \mbox{|ACRcntb|}$. % \begin{macrocode} % \ifnum\csname tm@acromake@\tm@t\endcsname < \ACRcntb\relax % \ifnum\csname tm@acromake@\tm@t\endcsname > \ACRcnta\relax % \typeout{use between cnta and cntb}% % \fi % \fi \ifnum\csname tm@acromake@\tm@t\endcsname = \ACRcntb\relax % \typeout{use at cntb}% \RestoreName{\tm@t\TMSubsequentSuffix}% \fi \fi \TMHookAcromakeHook } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\tm@incmacro} % \begin{macro}{\c@tm@util} % This is Paul's trick for using a macro like a counter. I reduce the command % to its essential function in this context. It looks like Paul wanted a more % general command. I think if you define such a command (or set of commands % that emulate counters with macros) they do not belong here but in % \package{moredefs} or their own package. I also % \begin{macrocode} \newcounter{tm@util} \newcommand{\tm@incmacro} [1] {% arg: acroabbrev \eExpand\csname tm@acromake@#1\endcsname\In {% \setcounter{tm@util}{##1}% }% \stepcounter{tm@util}% \expandafter\xdef\csname tm@acromake@#1\endcsname {\thetm@util}% } % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\ACRcnta} % \mbox{} % \begin{macrocode} \newcommand\ACRcnta {1} \newcommand\ACRcntb {2} % \end{macrocode} % \end{macro} % % \begin{macro}{\AcromakePageref} % The string |#1| will make it into the macro, which will in another % context be replaced with a \cs\pageref. % \begin{macrocode} \newcommand\AcromakePageref {(see Page ##1)} % suggestion: % \renewcommand\AcromakePageref {(see page ##1)} % \end{macrocode} % \end{macro} % % \part{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