summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/mdwtools/at.dtx
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/mdwtools/at.dtx
Initial commit
Diffstat (limited to 'macros/latex/contrib/mdwtools/at.dtx')
-rw-r--r--macros/latex/contrib/mdwtools/at.dtx750
1 files changed, 750 insertions, 0 deletions
diff --git a/macros/latex/contrib/mdwtools/at.dtx b/macros/latex/contrib/mdwtools/at.dtx
new file mode 100644
index 0000000000..ea72376c88
--- /dev/null
+++ b/macros/latex/contrib/mdwtools/at.dtx
@@ -0,0 +1,750 @@
+% \begin{meta-comment}
+%
+% $Id: at.dtx,v 1.3 1996/11/19 20:46:55 mdw Exp $
+%
+% Allow @-commands
+%
+% (c) 1995 Mark Wooding
+%
+%----- Revision history -----------------------------------------------------
+%
+% $Log: at.dtx,v $
+% Revision 1.3 1996/11/19 20:46:55 mdw
+% Entered into RCS
+%
+%
+% \end{meta-comment}
+%
+% \begin{meta-comment} <general public licence>
+%%
+%% at package -- support for `@' commands'
+%% Copyright (c) 1996 Mark Wooding
+%%
+%% 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.
+%%
+% \end{meta-comment}
+%
+% \begin{meta-comment} <Package preamble>
+%<+package>\NeedsTeXFormat{LaTeX2e}
+%<+package>\ProvidesPackage{at}
+%<+package> [1996/05/02 1.3 @-command support (MDW)]
+% \end{meta-comment}
+%
+% \CheckSum{355}
+%% \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 \~}
+%%
+%
+% \begin{meta-comment} <driver>
+%
+%<*driver>
+\input{mdwtools}
+\describespackage{at}
+\aton
+\atlet p=\package
+\atdef at{\package{at}}
+\atdef={\mbox{-}}
+\atdef-{@@@=}
+\atlet.=\syntax
+\mdwdoc
+%</driver>
+%
+% \end{meta-comment}
+%
+% \section{User guide}
+%
+% The @at\ package is an attempt to remove a lot of tedious typing that
+% ends up in \LaTeX\ documents, by expanding the number of short command
+% names available. The new command names begin with the `|@|' character,
+% rather than the conventional `|\|', so you can tell them apart.
+%
+% The package provides some general commands for defining @-commands, and
+% then uses them to define some fairly simple ones which will be useful to
+% most people.
+%
+% The rules for @-command names aren't terribly complex:
+% \begin{itemize}
+% \item If the first character of the name is a letter, then the command name
+% consists of all characters up to, but not including, the first
+% nonletter. Spaces following the command name are ignored.
+% \item If the first character of the name is a backslash, then the @-command
+% name consists of the control sequence introduced by the backslash.
+% \item Otherwise, the command name consists only of that first character.
+% Spaces following the name are not ignored, unless that character
+% was itself a space character.
+% \end{itemize}
+%
+% Usually, digits are not considered to be letters. However, the
+% \package{at} package will consider digits to be letters if you give it the
+% \textsf{digits} option in the |\usepackage| command. (Note that this
+% only affects the \package{at} package; it won't change the characters
+% allowed in normal command names.)
+%
+% \DescribeMacro{\atallowdigits}
+% \DescribeMacro{\atdisallowdigits}
+% You can enable and disable digits being considered as letters dynamically.
+% The |\atallowdigits| command allows digits to be used as letters;
+% |\atdisallowdigits| prevents this. Both declarations follow \LaTeX's
+% usual scoping rules. Both of these commands have corresponding
+% environments with the same names (without the leading `|\|', obviously).
+%
+% \subsection{Defining @-commands}
+%
+% \DescribeMacro{\newatcommand}
+% \DescribeMacro{\renewatcommand}
+% The |\newatcommand| command will define a new @-command using a syntax
+% similar to |\newcommand|. For example, you could define
+% \begin{listing}
+%\newatcommand c[1]{\chapter{#1}}
+% \end{listing}
+% to make @.{"@c{"<name>"}"} equivalent to @.{"\\chapter{"<name>"}"}.
+%
+% A |\renewatcommand| is also provided to redefine existing commands, should
+% the need arise.
+%
+% \DescribeMacro{\atdef}
+% For \TeX\ hackers, the |\atdef| command defines @-commands using a syntax
+% similar to \TeX's built-in |\def|.
+%
+% As an example, the following command makes @.{"@/"<text>"/"} write its
+% argument \<text> in italics:
+% \begin{listing}
+%\atdef/#1/{\textit{#1}}
+% \end{listing}
+% The real implementation of the |@/|\dots|/| command is a bit more
+% complex, and is given in the next section.
+%
+% You can use all of \TeX's features for defining the syntax of your
+% command. (See chapter~20 of @/The \TeX book/ for more details.)
+%
+% \DescribeMacro{\atlet}
+% Since |\atdef| is provided to behave similarly to |\def|, @at\ provides
+% |\atlet| which works similarly to |\let|. For example you can say
+% \begin{listing}
+%\atlet!=\index
+% \end{listing}
+% to allow the short |@!| to behave exactly like |\index|.
+%
+% Note that all commands defined using these commands are robust even if you
+% use fragile commands in their definitions. Unless you start doing very
+% strange things, @-commands never need |\protect|ing.
+%
+% \subsection{Predefined @-commands}
+%
+% A small number of hopefully useful commands are provided by default.
+% These are described in the table below:
+%
+% \bigskip \begin{center} \begin{tabular}{lp{3in}} \hline
+% \bf Command & \bf Meaning \\ \hline
+% @.{"@@"} & Typesets an `@@' character. \\
+% @.{"@/"<text>"/"} & In text (LR or paragraph) mode, typesets its
+% argument emphasised. In maths mode, it
+% always chooses italics. \\
+% @.{"@*"<text>"*"} & Typesets its argument \<text> in bold. \\
+% @.{"@i{"<text>"}"} & Equivalent to `@.{"\\index{"<text>"}"}'. \\
+% @.{"@I{"<text>"}"} & As for |@i|, but also writes its argument
+% to the document. \\ \hline
+% \end{tabular} \end{center} \bigskip
+%
+% Package writers should not rely on any predefined @-commands -- they're
+% provided for users, and users should be able to redefine them without
+% fear of messing anything up. (This includes the `standard' commands
+% provided by the @at\ package, by the way. They're provided in the vague
+% hope that they might be useful, and as examples.)
+%
+% \implementation
+%
+% \section{Implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \subsection{Options handling}
+%
+% We need a switch to say whether digits should be allowed. Since this
+% is a user thing, I'll avoid |\newif| and just define the thing by hand.
+%
+% \begin{macrocode}
+\def\atallowdigits{\let\ifat@digits\iftrue}
+\def\atdisallowdigits{\let\ifat@digits\iffalse}
+% \end{macrocode}
+%
+% Now define the options.
+%
+% \begin{macrocode}
+\DeclareOption{digits}{\atallowdigits}
+\DeclareOption{nodigits}{\atdisallowdigits}
+\ExecuteOptions{nodigits}
+\ProcessOptions
+% \end{macrocode}
+%
+% \subsection{How the commands work}
+%
+% Obviously we make the `@@' character active. It inspects the next
+% character (or argument, actually -- it can be enclosed in braces for
+% longer commands, although this is a bit futile), and builds the command
+% name from that.
+%
+% The |\at| command is equivalent to the active `@@' character always.
+%
+%
+% \subsection{Converting command names}
+%
+% We need to be able to read an @-command name, and convert it to a normal
+% \TeX\ control sequence. First, we declare some control sequences for
+% braces, which we need later.
+%
+% \begin{macrocode}
+\begingroup
+\catcode`\<1
+\catcode`\>2
+\catcode`\{12
+\catcode`\}12
+\gdef\at@lb<{>
+\gdef\at@rb<}>
+\gdef\at@spc< >
+\endgroup
+% \end{macrocode}
+%
+% I'll set up some helper routines now, to help me read the command
+% names. The way this works is that we |\futurelet| the token into
+% |\@let@token|. These routines will then sort out what to do next.
+%
+% \begin{macro}{\at@test}
+%
+% Given an |\if|\dots\ test, does its first or second argument.
+%
+% \begin{macrocode}
+\def\at@test#1\then{%
+ #1\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\at@ifcat}
+%
+% Checks the category code of the current character. If it matches the
+% argument, it does its second argument, otherwise it does the third.
+%
+% \begin{macrocode}
+\def\at@ifcat#1{\at@test\ifcat#1\noexpand\@let@token\then}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\at@ifletter}
+%
+% This routine tests the token to see if it's a letter, and if so adds
+% it to the token list and does the first argument; otherwise it does the
+% second argument. It accepts digits as letters if the switch is turned
+% on.
+%
+% There's some fun later, so I'll describe this slowly. First, we compare
+% the category code to a letter, and if we have a match, we know we're done;
+% we need to pick up the letter as an argument. If the catcode is `other',
+% we must compare with numbers to see if it's in range.
+%
+% \begin{macrocode}
+\def\at@ifletter#1#2{%
+ \at@ifcat x%
+ {\at@ifletter@ii{#1}}%
+ {\at@ifcat 0%
+ {\at@ifletter@i{#1}{#2}}%
+ {#2}%
+ }%
+}
+% \end{macrocode}
+%
+% Right. It's `other' (so it's safe to handle as a macro argument) and we
+% need to know if it's a digit. This is a little tricky: I use |\if| to
+% compare two characters. The first character is~`1' or~`0' depending on the
+% `digit' switch; the second is~`1' or~`x' depending on whether it's actually
+% a digit. They'll only match if everything's worked out OK.
+%
+% \begin{macrocode}
+\def\at@ifletter@i#1#2#3{%
+ \at@test\if%
+ \ifat@digits1\else0\fi%
+ \ifnum`#3<`0x\else\ifnum`#3>`9x\else1\fi\fi%
+ \then%
+ {\at@ifletter@ii{#1}{#3}}%
+ {#2#3}%
+}
+% \end{macrocode}
+%
+% Right; we have the character, so add it to the list and carry on.
+%
+% \begin{macrocode}
+\def\at@ifletter@ii#1#2{\toks@\expandafter{\the\toks@#2}#1}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% Now we define the command name reading routines. We have @/almost/ the
+% same behaviour as \TeX, although we can't support `|%|' characters for
+% reasons to do with \TeX's tokenising algorithm.
+%
+% \begin{macro}{\at@read@name}
+%
+% The routine which actually reads the command name works as follows:
+% \begin{enumerate}
+% \item Have a peek at the next character. If it's a left or right brace,
+% then use the appropriate character.
+% \item If the character is not a letter, just use the character (or whole
+% control sequence.
+% \item Finally, if it's a letter, keep reading letters until we find one
+% that wasn't.
+% \end{enumerate}
+%
+% First, we do some setting up and read the first character
+%
+% \begin{macrocode}
+\def\at@read@name#1{%
+ \let\at@next=#1%
+ \toks@{}%
+ \futurelet\@let@token\at@rn@i%
+}
+% \end{macrocode}
+%
+% Next, sort out what to do, based on the category code.
+%
+% \begin{macrocode}
+\def\at@rn@i{%
+ \def\@tempa{\afterassignment\at@rn@iv\let\@let@token= }%
+ \at@ifletter%
+ {\futurelet\@let@token\at@rn@iii}%
+ {\at@ifcat\bgroup%
+ {\toks@\expandafter{\at@lb}\@tempa}%
+ {\at@ifcat\egroup%
+ {\toks@\expandafter{\at@rb}\@tempa}%
+ {\at@ifcat\at@spc%
+ {\toks@{ }\@tempa}%
+ {\at@rn@ii}%
+ }%
+ }%
+ }%
+}
+% \end{macrocode}
+%
+% Most types of tokens can be fiddled using |\string|.
+%
+% \begin{macrocode}
+\def\at@rn@ii#1{%
+ \toks@\expandafter{\string#1}%
+ \at@rn@iv%
+}
+% \end{macrocode}
+%
+% We've found a letter, so we should check for another one.
+%
+% \begin{macrocode}
+\def\at@rn@iii{%
+ \at@ifletter%
+ {\futurelet\@let@token\at@rn@iii}%
+ {\@ifnextchar.\at@rn@iv\at@rn@iv}%
+}
+% \end{macrocode}
+%
+% Finally, we need to pass the real string, as an argument, to the
+% macro. We make |\@let@token| relax, since it might be something which will
+% upset \TeX\ later, e.g., a |#| character.
+%
+% \begin{macrocode}
+\def\at@rn@iv{%
+ \let\@let@token\relax%
+ \expandafter\at@next\csname at.\the\toks@\endcsname%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\at@cmdname}
+%
+% Given a control sequence, work out which @-command it came from.
+%
+% \begin{macrocode}
+\def\at@cmdname#1{\expandafter\at@cmdname@i\string#1\@@foo}
+% \end{macrocode}
+%
+% Now extract the trailing bits.
+%
+% \begin{macrocode}
+\def\at@cmdname@i#1.#2\@@foo{#2}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\at@decode}
+%
+% The |\at@decode| macro takes an extracted @-command name, and tries to
+% execute the correct control sequence derived from it.
+%
+% \begin{macrocode}
+\def\at@decode#1{%
+ \at@test\ifx#1\relax\then{%
+ \PackageError{at}{Unknown @-command `@\at@cmdname#1'}{%
+ The @-command you typed wasn't recognised, so I've ignored it.
+ }%
+ }{%
+ #1%
+ }%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\@at}
+%
+% We'd like a measure of compatibility with @p{amsmath}. The @-commands
+% provided by @p{amsmath} work only in maths mode, so this gives us a way of
+% distinguishing. If the control sequence |\Iat| is defined, and we're in
+% maths mode, we'll call that instead of doing our own thing.
+%
+% \begin{macrocode}
+\def\@at{%
+ \def\@tempa{\at@read@name\at@decode}%
+ \ifmmode\ifx\Iat\not@@defined\else%
+ \let\@tempa\Iat%
+ \fi\fi%
+ \@tempa%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+%
+% \subsection{Defining new commands}
+%
+% \begin{macro}{\at@buildcmd}
+%
+% First, we define a command to build these other commands:
+%
+% \begin{macrocode}
+\def\at@buildcmd#1#2{%
+ \expandafter\def\csname\expandafter
+ \@gobble\string#1@decode\endcsname##1{#2##1}%
+ \edef#1{%
+ \noexpand\at@read@name%
+ \expandafter\noexpand%
+ \csname\expandafter\@gobble\string#1@decode\endcsname%
+ }%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\newatcommand}
+% \begin{macro}{\renewatcommand}
+% \begin{macro}{\provideatcommand}
+% \begin{macro}{\atdef}
+% \begin{macro}{\atshow}
+%
+% Now we define the various operations on @-commands.
+%
+% \begin{macrocode}
+\at@buildcmd\newatcommand\newcommand
+\at@buildcmd\renewatcommand\renewcommand
+\at@buildcmd\provideatcommand\providecommand
+\at@buildcmd\atdef\def
+\at@buildcmd\atshow\show
+% \end{macrocode}
+%
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\atlet}
+%
+% |\atlet| is rather harder than the others, because we want to allow people
+% to say things like @.{"\\atlet"<name>"=@"<name>}. The following hacking
+% does the trick. I'm trying very hard to duplicate |\let|'s behaviour with
+% respect to space tokens here, to avoid any surprises, although there
+% probably will be some differences. In particular, |\afterassignment|
+% won't work in any sensible way.
+%
+% First, we read the name of the @-command we're defining. We also open
+% a group, to stop messing other people up, and make `@@' into an `other'
+% token, so that it doesn't irritatingly look like its meaning as a control
+% sequence.
+%
+% \begin{macrocode}
+\def\atlet{%
+ \begingroup%
+ \@makeother\@%
+ \at@read@name\atlet@i%
+}
+% \end{macrocode}
+%
+% Put the name into a scratch macro for later use. Now see if there's an
+% equals sign up ahead. If not, this will gobble any spaces in between the
+% @-command name and the argument.
+%
+% \begin{macrocode}
+\def\atlet@i#1{%
+ \def\at@temp{#1}%
+ \@ifnextchar=\atlet@ii{\atlet@ii=}%
+}
+% \end{macrocode}
+%
+% Now we gobble the equals sign (whatever catcode it is), and peek at the
+% next token up ahead using |\let| with no following space.
+%
+% \begin{macrocode}
+\def\atlet@ii#1{\afterassignment\atlet@iii\global\let\at@gnext=}
+% \end{macrocode}
+%
+% The control sequence |\at@gnext| is now |\let| to be whatever we want the
+% @-command to be, unless it's picked up an `@@' sign. If it has, we've
+% eaten the |@| token, so just read the name and pass it on. Otherwise,
+% we can |\let| the @-command directly to |\at@gnext|. There's some
+% nastiness here to make |\the\toks@| expand before we close the group and
+% restore its previous definition.
+%
+% \begin{macrocode}
+\def\atlet@iii{%
+ \if @\noexpand\at@gnext%
+ \expandafter\at@read@name\expandafter\atlet@iv%
+ \else%
+ \expandafter\endgroup%
+ \expandafter\let\at@temp= \at@gnext%
+ \fi%
+}
+% \end{macrocode}
+%
+% We've read the source @-command name, so just copy the definitions over.
+%
+% \begin{macrocode}
+\def\atlet@iv#1{%
+ \expandafter\endgroup%
+ \expandafter\let\at@temp=#1%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+%
+% \subsection{Robustness of @-commands}
+%
+% We want all @-commands to be robust. We could leave them all being
+% fragile, although making robust @-commands would then be almost impossible.
+% There are two problems which we must face:
+%
+% \begin{itemize}
+%
+% \item The `|\@at|' command which scans the @-command name is (very)
+% fragile. I could have used |\DeclareRobustCommand| for it (and in
+% fact I did in an earlier version), but that doesn't help the other
+% problem at all.
+%
+% \item The `name' of the @-command may contain active characters or control
+% sequences, which will be expanded at the wrong time unless we do
+% something about it now.
+%
+% \end{itemize}
+%
+% We must also be careful not to introduce extra space characters into any
+% files written, because spaces are significant in @-commands. Finally,
+% we have a minor problem in that most auxiliary files are read in with
+% the `@@' character set to be a letter.
+%
+% \begin{macro}{\at}
+%
+% Following the example of \LaTeX's `short' command handling, we'll define
+% |\at| to decide what to do depending on what |\protect| looks like. If
+% we're typesetting, we just call |\@at| (above) and expect it to cope.
+% Otherwise we call |\at@protect|, which scoops up the |\fi| and the |\@at|,
+% and inserts other magic.
+%
+% \begin{macrocode}
+\def\at{\ifx\protect\@typeset@protect\else\at@protect\fi\@at}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\at@protect}
+%
+% Since we gobbled the |\fi| from the above, we must put that back. We then
+% need to do things which are more complicated. If |\protect| is behaving
+% like |\string|, then we do one sort of protection. Otherwise, we assume
+% that |\protect| is being like |\noexpand|.
+%
+% \begin{macrocode}
+\def\at@protect\fi#1{%
+ \fi%
+ \ifx\protect\string%
+ \expandafter\at@protect@string%
+ \else%
+ \expandafter\at@protect@noexpand%
+ \fi%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\at@protect@string}
+%
+% When |\protect| is |\string|, we don't need to be able to recover the
+% original text particularly accurately -- it's for the user to look at.
+% Therefore, we just output a $|@|_{11}$ and use |\string| on the next
+% token. This must be sufficient, since we only allow multi-token command
+% names if the first token is a letter (code~11).
+%
+% \begin{macrocode}
+\def\at@protect@string{@\string}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\at@protect@noexpand}
+%
+% This is a little more complex, since we're still expecting to be executed
+% properly at some stage. However, there's a cheeky dodge we can employ
+% since the |\at| command is thoroughly robustified (or at least it will be
+% by the time we've finished this). All |\@unexpandable@protect| does
+% is confer repeated robustness on a fragile command. Since our command
+% is robust, we don't need this and we can get away with just using a
+% single |\noexpand|, both for the |\@at@| command and the following token
+% (which we must robustify, because no-one else can do it for us -- if
+% anyone tries, they end up using the |@\protect| command which is rather
+% embarassing).
+%
+% I'll give the definition, and then examine how this expands in various
+% cases.
+%
+% \begin{macrocode}
+\def\at@protect@noexpand{\noexpand\@at@ @\noexpand}
+\def\@at@#1{\at}
+% \end{macrocode}
+%
+% A few points, before we go into the main examination of the protection.
+% I've inserted a $|@|_{11}$ token, which is gobbled by |\@at@| when the
+% thing is finally expanded fully. This prevents following space tokens
+% in an |\input| file from being swallowed because they follow a control
+% sequence. (I can't use the normal $|@|_{13}$ token, because when files
+% like the |.aux| file are read in, |@| is given code~11 by
+% |\makeatletter|.)
+%
+% \setbox0\hbox{|@at@|}
+% Now for a description of why this works. When |\at| is expanded, it works
+% out that |\protect| is either |\noexpand| or |\@unexpandable@protect|, and
+% becomes |\at@protect@noexpand|. Because of the |\noexpand| tokens, this
+% stops being expanded once it reaches $\fbox{\box0}\,|@|_{11}\,x$ (where
+% $x$ is the token immediately following the $|@|_{13}$ character). If this
+% is expanded again, for example in another |\edef|, or in a |\write| or a
+% |\mark|, the |\@at@| wakes up, gobbles the following |@| (whatever catcode
+% it is -- there may be intervening |\write| and |\input| commands) and
+% becomes |\at|, and the whole thing can start over again.
+%
+% \end{macro}
+%
+%
+% \subsection{Enabling and disabling @-commands}
+%
+% \begin{macro}{\aton}
+%
+% We define the |\aton| command to enable all of our magic. We store
+% the old catcode in the |\atoff| command, make `@@' active, and make it
+% do the stuff.
+%
+% \begin{macrocode}
+\def\aton{%
+ \ifnum\catcode`\@=\active\else%
+ \edef\atoff{\catcode`\noexpand\@\the\catcode`\@}%
+ \catcode`\@\active%
+ \lccode`\~`\@%
+ \lowercase{\let~\at}%
+ \fi%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\atoff}
+%
+% The |\atoff| command makes `@@' do the stuff it's meant to. We remember
+% the old catcode and revert to it. This is largely unnecessary.
+%
+% \begin{macrocode}
+\def\atoff{\catcode`\@12}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\makeatother}
+%
+% Now we make our active `@@' the default outside of package files.
+%
+% \begin{macrocode}
+\let\makeatother\aton
+% \end{macrocode}
+%
+% \end{macro}
+%
+% And we must make sure that the user can use all of our nice commands.
+% Once the document starts, we allow @-commands.
+%
+% \begin{macrocode}
+\AtBeginDocument{\aton}
+% \end{macrocode}
+%
+% \begin{macro}{\dospecials}
+% \begin{macro}{\@sanitize}
+%
+% We must add the `@@' character to the various specials lists.
+%
+% \begin{macrocode}
+\expandafter\def\expandafter\dospecials\expandafter{\dospecials\do\@}
+\expandafter\def\expandafter\@sanitize\expandafter{%
+ \@sanitize\@makeother\@}
+% \end{macrocode}
+%
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Default @-commands}
+%
+% We define some trivial examples to get the user going.
+%
+% \begin{macrocode}
+\expandafter\chardef\csname at.@\endcsname=`\@
+\atdef*#1*{\ifmmode\mathbf{#1}\else\textbf{#1}\fi}
+\atdef/#1/{\ifmmode\mathit{#1}\else\emph{#1}\fi}
+\atlet i=\index
+\atdef I#1{#1\index{#1}}
+%</package>
+% \end{macrocode}
+%
+% \hfill Mark Wooding, \today
+%
+% \Finale
+%
+\endinput