From: mdw Date: Sun, 3 Feb 2002 20:49:03 +0000 (+0000) Subject: Checkin for new build system. X-Git-Tag: 1.6.0~8 X-Git-Url: https://git.distorted.org.uk/~mdw/mdwtools/commitdiff_plain/86f6a31e4b41acb71ba37f3838a9ce75f7743330 Checkin for new build system. --- 86f6a31e4b41acb71ba37f3838a9ce75f7743330 diff --git a/.cvsignore b/.cvsignore new file mode 100644 index 0000000..e0ed709 --- /dev/null +++ b/.cvsignore @@ -0,0 +1,21 @@ +*.ans +*.aux +*.def +*.dvi +*.fd +*.idx +*.ilg +*.ind +*.log +*.lot +*.sty +*.thm +*.tmp +*.toc +Makefile +Makefile.am +Makefile.in +aclocal.m4 +config.cache +config.status +configure diff --git a/.links b/.links new file mode 100644 index 0000000..b091697 --- /dev/null +++ b/.links @@ -0,0 +1,5 @@ +missing +mkinstalldirs +install-sh +COPYING +gpl.tex diff --git a/.skelrc b/.skelrc new file mode 100644 index 0000000..efff991 --- /dev/null +++ b/.skelrc @@ -0,0 +1,9 @@ +;;; -*-emacs-lisp-*- + +(setq skel-alist + (append + '((author . "Mark Wooding") + (full-title . "the mdwtools LaTeX package collection") + (Program . "mdwtools") + (program . "mdwtools")) + skel-alist)) diff --git a/Makefile.m4 b/Makefile.m4 new file mode 100644 index 0000000..380b5a0 --- /dev/null +++ b/Makefile.m4 @@ -0,0 +1,92 @@ +## -*-makefile-*- +## +## $Id: Makefile.m4,v 1.1 2002/02/03 20:49:02 mdw Exp $ +## +## Build system for mdwtools +## +## (c) 2002 Mark Wooding +## + +##----- Licensing notice ---------------------------------------------------- +## +## This file is part of the mdwtools LaTeX package collection. +## +## mdwtools 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. +## +## mdwtools 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 mdwtools; if not, write to the Free Software Foundation, +## Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +##----- Revision history ---------------------------------------------------- +## +## $Log: Makefile.m4,v $ +## Revision 1.1 2002/02/03 20:49:02 mdw +## Checkin for new build system. +## + +AUTOMAKE_OPTIONS = foreign + +texmfdir = @texmfdir@ +pkglatexdir = ${texmfdir}/tex/latex/${PACKAGE} +pkgdocdir = ${texmfdir}/doc/latex/${PACKAGE} + +define(`addsuffix', `patsubst(`$1', `\>', `.$2')') +define(`BASE', `\ + at cmtt crypto doafter exercise footnote \ + mdwlist mdwmath mdwtab mdwthm poetry sverb syntax') + +SRC = addsuffix(BASE, `dtx') +DVI = addsuffix(BASE, `dvi') mdwtools.dvi +OBJ = \ + at.sty \ + cmtt.sty mTTcmtt.fd mTTenc.def \ + crypto.sty \ + doafter.sty \ + doafter.tex \ + exercise.sty \ + footnote.sty \ + mdwlist.sty \ + mdwmath.sty \ + mdwtab.sty mathenv.sty \ + mdwthm.sty mdwmargin.thm \ + poetry.sty \ + sverb.sty \ + syntax.sty + +pkglatex_DATA = $(OBJ) +pkgdoc_DATA = $(DVI) + +SUFFIXES = .dtx .tex .dvi +define(`run_latex', `latex "\def\indexing{n} \nonstopmode \input $<" + latex "\def\indexing{y} \nonstopmode \input $<" + makeindex -s gind.ist $`'*.idx + latex "\def\indexing{n} \nonstopmode \input $<"') + +.dtx.dvi: gpl.tex mdwtools.tex + run_latex +.tex.dvi: gpl.tex + run_latex + +all: $(OBJ) +dvi: $(DVI) + +$(OBJ): $(SRC) mdwtools.ins + tex mdwtools.ins + +MAINTAINERCLEANFILES = $(OBJ) $(DVI) +CLEANFILES = *.tmp *.aux *.idx *.ilg *.log *.toc *.ind *.lot *.ans + +Makefile.am: Makefile.m4 + cd $(srcdir) && m4 Makefile.m4 >Makefile.am + +.PHONY: dvi + +##----- That's all, folks --------------------------------------------------- diff --git a/at.dtx b/at.dtx new file mode 100644 index 0000000..753a475 --- /dev/null +++ b/at.dtx @@ -0,0 +1,753 @@ +% \begin{meta-comment} +% +% $Id: at.dtx,v 1.1 2002/02/03 20:49:02 mdw Exp $ +% +% Allow @-commands +% +% (c) 1995 Mark Wooding +% +%----- Revision history ----------------------------------------------------- +% +% $Log: at.dtx,v $ +% Revision 1.1 2002/02/03 20:49:02 mdw +% Checkin for new build system. +% +% Revision 1.3 1996/11/19 20:46:55 mdw +% Entered into RCS +% +% +% \end{meta-comment} +% +% \begin{meta-comment} +%% +%% 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>\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> +\input{mdwtools} +\describespackage{at} +\aton +\atlet p=\package +\atdef at{\package{at}} +\atdef={\mbox{-}} +\atdef-{@@@=} +\atlet.=\syntax +\mdwdoc +% +% +% \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{""}"} equivalent to @.{"\\chapter{""}"}. +% +% 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 @.{"@/""/"} write its +% argument \ 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. \\ +% @.{"@/""/"} & In text (LR or paragraph) mode, typesets its +% argument emphasised. In maths mode, it +% always chooses italics. \\ +% @.{"@*""*"} & Typesets its argument \ in bold. \\ +% @.{"@i{""}"} & Equivalent to `@.{"\\index{""}"}'. \\ +% @.{"@I{""}"} & 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""=@"}. 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}} +% +% \end{macrocode} +% +% \hfill Mark Wooding, \today +% +% \Finale +% +\endinput diff --git a/cmtt.dtx b/cmtt.dtx new file mode 100644 index 0000000..95d284f --- /dev/null +++ b/cmtt.dtx @@ -0,0 +1,523 @@ +% \begin{meta-comment} +% +% $Id: cmtt.dtx,v 1.1 2002/02/03 20:49:02 mdw Exp $ +% +% Nicer handling of the Computer Modern Typewriter font +% +% (c) 1996 Mark Wooding +% +%----- Revision history ----------------------------------------------------- +% +% $Log: cmtt.dtx,v $ +% Revision 1.1 2002/02/03 20:49:02 mdw +% Checkin for new build system. +% +% Revision 1.1 1996/11/19 20:47:55 mdw +% Initial revision +% +% +% \end{meta-comment} +% +% \begin{meta-comment} +%% +%% mdwlist package -- various list-related things +%% 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} +%<+sty>\NeedsTeXFormat{LaTeX2e} +%<+sty>\ProvidesPackage{cmtt} +%<+fd>\ProvidesFile{mTTcmtt.fd} +%<+def>\ProvidesFile{mTTcmtt.def} +%<+sty|fd|def> [1996/05/25 1.1 Handing of the cmtt font] +% \end{meta-comment} +% +% ^^A \CheckSum{174} +%% \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> +\input{mdwtools} +\describespackage{cmtt} +\mdwdoc +% +% +% \end{meta-comment} +% +%^^A------------------------------------------------------------------------- +% \section{Introductory note} +% +% \LaTeX\ has a rather cunning encoding handling system, which makes funny +% commands like accents work properly independent of the current font's +% actual layout. While this works rather well most of the time, the standard +% \mtt{tt} font has been rather left out of things. \LaTeX\ assumes that +% the Computer Modern Typewriter fonts have exactly the same layout as the +% more normal Computer Modern Roman family (i.e., that both conform to the +% \mtt{OT1} encoding). This plainly isn't true, since the Typewriter font +% contains a bunch of standard ASCII characters which are omitted from the +% standard Computer Modern fonts, such as curly braces \mtt{\{} and \mtt{\}}, +% and the backslash \mtt{\\}; these are usually dug up from the maths fonts, +% which looks fine in normal text, but looks really odd in monospace text. +% Compare `\texttt{\textbackslash begin\{document\}}' to +% `\mtt{\\begin\{document\}}', for example. +% +% There are two possibilities for dealing with this problem. One is to use +% the \mtt{\\verb} command, which works since all the extra characters in +% the Typewriter font are in the correct places, or use the DC~fonts, which +% have a proper encoding set up which contains all of these special +% characters anyway. +% +% Neither of these solutions is perfect. Using \mtt{\\verb} causes all +% manner of little niggly problems: you can't use it in footnotes or +% section headings, for example. (There are of course workarounds for this +% sort of thing: the author's \package{footnote} package provides a +% \env{footnote} environment which will allow verbatim text, and verbatim +% text in section headings can be achieved if one is sufficiently +% \TeX nical.) Using the DC~fonts is fine, although you actually lose a +% glyph or two. As far as the author is aware, the character \mtt{\'} (an +% `unsexed' single quote) is not present in the \mtt{T1}-encoded version of +% Computer Modern Typewriter, although it is hidden away in the original +% version. The author has found a need for this character in computer +% listings, and was horrified to discover that it was replaced by a German +% single quote character (\mtt{\\quotesinglbase}). +% +% This package defines a special encoding for the Computer Modern Typewriter +% font, so that documents can take advantage of its ASCII characters without +% resorting to verbatim text. (The main advantage of the DC~fonts, that +% words containing accents can be hyohenated, doesn't really apply to the +% Typewriter font, since it doesn't allow hyphenation by default anyway.) +% +% There are several files you'll need to create: +% \begin{description} \def\makelabel#1{\hskip\labelsep\mttfamily#1\hfil} +% +% \item [cmtt.sty] tells \LaTeX\ that there's a new encoding. It also +% provides some options for customising some aspects of the +% encoding, and defines some useful commands. +% +% \item [mTTenc.def] describes the encoding to \LaTeX: it sets up all the +% appropriate text commands so that they produce beautiful results. +% +% \item [mTTcmtt.fd] describes the re-encoded version of the font. This +% is more or less a copy of the file \mtt{OT1cmtt.fd}. +% +% \end{description} +% +% The package accepts some options which may be useful: +% \begin{description} \def\makelabel#1{\hskip\labelsep\sffamily#1\hfil} +% +% \item [override] overrides the meaning of the \mtt{\\ttfamily} command +% (and therefore also the \mtt{\\texttt} command too), making it the +% same as the new \mtt{\\mttfamily} command. This isn't the default +% just in case the change breaks something in an unexpected way. +% +% \item [t1] informs the package that you're using the \mtt{T1} encoding, +% and therefore can borrow some accented characters from the DC~version +% of Computer Modern Typewriter. This will probably be unnecessary, +% since the package attempts to work out what to do all by itself. +% +% \item [ot1] forces the package \emph{not} to use the DC~version of the +% Computer Modern Typewriter font for funny accents. Only use this +% option if the package thinks it should use the DC~Typewriter font +% when it shouldn't. +% +% \end{description} +% +% \DescribeMacro{\mttfamily} +% The command \mtt{\\mttfamily} selects the properly-encoded Typewriter +% font. It's a declaration which works just like the \mtt{\\ttfamily} +% command, except that comamnds like \mtt{\\\}} and \mtt{\\\_} use the +% characters from the font rather than choosing odd-looking versions from +% the maths fonts. All of the accent commands still work properly. In fact, +% some accent commands which didn't work before have been fixed. For +% example, saying `\mtt{\\texttt\{P\\'al Erd\\H os\}}' would produce +% something truly appalling like `\texttt{P\'al Erd\H os}', which is +% obviously ghastly. The new encoding handles this properly, and produces +% `\textmtt{P\'al Erd\H os}'.\footnote{ +% This isn't quite perfect. The accent, which isn't actually present in +% the Typewriter font, is taken from the Computer Modern bold font, but +% it doesn't look too bad. However, if you pass the option \textsf{t1} +% to the \package{cmtt} package when you load it, the accent will be taken +% from the DC~Typewriter font, and it will look totally wonderful.} +% +% \DescribeMacro{\textmtt} +% Font changing commands are much more convenient than th declarations, +% so a command \mtt{\\textmtt} is provided: it just typesets its argument +% in the re-encoded Typewriter font. +% +% \DescribeMacro{\mtt} +% Rather more excitingly, the \mtt{\\mtt} command allows you to generate +% almost-verbatim text very easily, without any of the restrictions of +% the \mtt{\\verb} command. This command was inspired by something which +% David Carlisle said to me in an email correspondence regarding the +% overuse of verbatim commands. +% +% \mtt{\\mtt} redefines several `short' commands to typeset the obvious +% characters. The complete list is shown below: there are some oddities, +% so watch out. +% +% ^^A This is an evil table. See if I care. (This is based on lots of +% ^^A hacking I did in glyphs.tex, but a good deal less horrible.) +% +% \medskip +% \hbox to \hsize\bgroup +% \hfil\vbox\bgroup +% \def\ex#1#2{\strut +% \enskip +% \mtt{\\\char`#2}\quad\hfil% +% \mtt{#2}\enskip} +% \def\h{\noalign{\hrule}} +% \def\v{height2pt&\omit&&\omit&&\omit&&\omit&&\omit&\cr} +% \let~\relax +% \offinterlineskip +% \ialign\bgroup&\vrule#&\ex#\cr \h\v +% &~\\&&~\{&&~\}&&~\_&&~\^&\cr \v\h\v +% &~\$&&~\%&&~\&&&~\#&&~\~&\cr \v\h\v +% &~\"&&~\'&&~\ &&~\|&&\omit\hfil&\cr \v\h +% \egroup\egroup +% \hfil\egroup +% \medskip +% +% As well as redefining these commands, \mtt{\\mtt} will endeavour to make +% single special characters display themselves in a verbatim-like way. This +% only works on `active' characters (like \mtt{~}), and \mtt{\\mtt} makes +% no attempt to change the category codes of any characters. +% +% Among other things, you'll probably noticed that several accent-making +% commands have been redefined. You can still use these accents through +% the \mtt{\\a} command, by saying \mtt{\\a'}, \mtt{\\a\^} and so on, +% as in the \env{tabbing} environment. +% +% There are also some oddities in the table: \mtt{\|} and \mtt{\"} can be +% accessed easily without playing with silly commands. Well, that's almost +% the case: these two characters are both often used as `short' verbatim +% commands, so they are forced back to their normal meanings so you can +% type them. +% +% Finally, a word on spacing. The \mtt{\\\ } command has been hijacked +% to produce a funny `visible space' character. You can still produce +% multiple spaces by saying something like `\mtt{\ \{\}\ \{\}}\dots\mtt{\ }', +% which is a bit contrived, but that's tough. Also, \mtt{~} has been stolen +% so that you can type \mtt{~} characters (e.g., in URLs), so the only +% way you can tpye a nonbreaking space is by using the \mtt{\\nobreakspace} +% command, which is a bit of a mouthful. There's an abbreviation, though: +% \mtt{\\nbsp} now means exactly the same thing. +% +% Was that not all supremely useful? Oh, just a note: this document doesn't +% use a single verbatim command or environment (except in the listings, +% where it's unavoidable) -- it's all done with \mtt{\\mtt}. +% +% \implementation +% +% \section{Implementation} +% +% \subsection{The package} +% +% \begin{macrocode} +%<*sty> +% \end{macrocode} +% +% I'll start with some options handling. +% +% \begin{macrocode} +\newif\ifcmtt@override +\newif\ifcmtt@dcfonts +\def\@tempa{T1}\ifx\encodingdefault\@tempa + \cmtt@dcfontstrue +\fi +\DeclareOption{override}{\cmtt@overridetrue} +\DeclareOption{t1}{\cmtt@dcfontstrue} +\DeclareOption{ot1}{\cmtt@dcfontsfalse} +\ProcessOptions +% \end{macrocode} +% +% This bit is really trivial. I'll just declare the font encoding. Oh, that +% was easy. +% +% \begin{macrocode} +\DeclareFontEncoding{mTT}{}{} +% \end{macrocode} +% +% Wait: there's a problem. \LaTeX\ will now complain bitterly that it can't +% find the font \mtt{mTT/cmr/m/n}, which is readonable, since I haven't +% declared any such font. The following line should sort this out, +% +% \begin{macrocode} +\DeclareFontSubstitution{mTT}{cmtt}{m}{n} +% \end{macrocode} +% +% Now I'd better load all the text commands I'll need when in this funny +% font variant. +% +% \begin{macrocode} +\input{mTTenc.def} +% \end{macrocode} +% +% \begin{macro}{\mttfamily} +% \begin{macro}{\textmtt} +% +% Finally, I'll need to define a command which switches to this funny font, +% and a \mtt{\\text}\dots\ command for it. +% +% \begin{macrocode} +\DeclareRobustCommand{\mttfamily}{% + \fontencoding{mTT}\fontfamily{\ttdefault}\selectfont% +} +\DeclareTextFontCommand{\textmtt}{\mttfamily} +% \end{macrocode} +% +% \end{macro} +% \end{macro} +% +% If an override was requested, make \mtt{\\ttfamily} the same as +% \mtt{\\mttfamily}. +% +% \begin{macrocode} +\ifcmtt@override + \let\ttfamily\mttfamily +\fi +% \end{macrocode} +% +% Well, that's all that's needed for the font definition. Here's a command +% which will typeset its argument in the typewriter font, allowing easy +% access to all the funny characters, and printing them properly in the +% correct font (which \mtt{\\\{} doesn't do, for example). +% +% \begin{macro}{\mtt@setchar} +% +% This macro assigns the given meaning to the given control sequence. Also, +% if the character named in the control sequence is currently set active, +% it will set the active meaning of the character to the same value. +% +% \begin{macrocode} +\def\mtt@setchar#1#2{% + \ifx#1#2\chardef#1`#1\else\let#1#2\fi% + \ifnum\catcode`#1=13% + \begingroup% + \lccode`\~=`#1% + \lowercase{\endgroup\let~#1}% + \fi% +} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\mtt@chars} +% +% This macro lists the various control sequences which should be set up, +% so that they can be easily added to. +% +% \begin{macrocode} +\def\mtt@chars{% + \do\#\#% + \do\%\%% + \do\&\&% + \do\^\^% + \do\~\~% + \do\'\textquotesingl% + \do\"\textquotedbl% + \do\|\textbar% + \do\$\textdollar% + \do\_\textunderscore% + \do\{\textbraceleft% + \do\}\textbraceright% + \do\\\textbackslash% + \do\ \textvisiblespace% +} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\mtt@do} +% +% This just sets up all the special characters listed above. It's a simple +% abbreviation, really. +% +% \begin{macrocode} +\def\mtt@do{\let\do\mtt@setchar\mtt@chars} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\mtt} +% +% And finally, the macro itself. Ta-da! +% +% \begin{macrocode} +\DeclareRobustCommand\mtt[1]{\textmtt{\mtt@do#1}} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\@tabacckludge} +% +% The otherwise almost totally perfect \mtt{\\@tabacckludge} gets very +% upset when its argument is an active character. (If you're wondering, +% this is the command which is responsible for the behaviour of the \mtt{\\a} +% command.) Adding a \mtt{\\string} makes everything work perfectly. +% +% \begin{macrocode} +\def\@tabacckludge#1{% + \expandafter\@changed@cmd\csname\string#1\endcsname\relax% +} +\let\a\@tabacckludge +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\nbsp} +% +% Make an abbreviation for \mtt{\\nobreakspace}. +% +% \begin{macrocode} +\let\nbsp\nobreakspace +% \end{macrocode} +% +% \end{macro} +% +% I think that's all that I have to do for the package. If there's any +% more to do, I'll add it later. +% +% \begin{macrocode} +% +% \end{macrocode} +% +% +% \subsection{The font definition file} +% +% This is obviously copied almost verbatim from the file \mtt{OT1cmtt.fd}. +% +% \begin{macrocode} +%<*fd> +\DeclareFontFamily{mTT}{cmtt}{\hyphenchar\font\m@ne} +\DeclareFontShape{mTT}{cmtt}{m}{n}{ + <5> <6> <7> <8> cmtt8 + <9> cmtt9 + <10> <10.95> cmtt10 + <12> <14.4> <17.28> <20.74> <24.88> cmtt12 +}{} +\DeclareFontShape{mTT}{cmtt}{m}{it}{ + <5> <6> <7> <8> <9> <10> <10.95> <12> <14.4> <17.28> <20.74> <24.88> + cmitt10 +}{} +\DeclareFontShape{mTT}{cmtt}{m}{sl}{ + <5> <6> <7> <8> <9> <10> <10.95> <12> <14.4> <17.28> <20.74> <24.88> + cmsltt10 +}{} +\DeclareFontShape{mTT}{cmtt}{m}{sc}{ + <5> <6> <7> <8> <9> <10> <10.95> <12> <14.4> <17.28> <20.74> <24.88> + cmtcsc10 +}{} +\DeclareFontShape{mTT}{cmtt}{m}{ui} {<->sub * cmtt/m/it} {} +\DeclareFontShape{mTT}{cmtt}{bx}{n} {<->sub * cmtt/m/n} {} +\DeclareFontShape{mTT}{cmtt}{bx}{it} {<->sub * cmtt/m/it} {} +\DeclareFontShape{mTT}{cmtt}{bx}{ui} {<->sub * cmtt/m/it} {} +% +% \end{macrocode} +% +% +% \subsection{The encoding definitions file} +% +% I've saved the trickiest bit until last. This file defines the mappings +% from text commands to glyphs in the font. +% +% \begin{macrocode} +%<*def> +% \end{macrocode} +% +% First for some fun with accents. The |cmtt| font doesn't contain all of +% the accents which the other Computer Modern fonts do, because those slots +% contain the standard ASCII characters which usually have to be `borrowed' +% from the maths fonts. +% +% Anyway, there's a load which don't need any special treatment. These are +% chosen from the \mtt{OT1} encoding by default anyway, so I needn't +% bother unless I'm really bothered about speed. I'm not, so I'll save +% the memory. +% +% Following the example of the \TeX book, I'll use the bold roman font +% for accents, so that they don't look really spindly. This is actually +% remarkably difficult to do, because the \textsf{NFSS} keeps getting in +% the way. I'll look after the old font name in a macro (it's handy that +% \textsf{NFSS} maintains this for me) and change to a known font, do the +% accent, change font back again, do the argument to the accent, and then +% close the group I did all of this in, so that no-one else notices what a +% naughty chap I am, really. This is startlingly evil. +% +% \begin{macrocode} +\def\cmtt@accent#1#2{{% + \let\@old@font\font@name% + \ifcmtt@dcfonts% + \fontencoding{T1}\selectfont% + \else% + \usefont{OT1}{cmr}{bx}{n}% + \fi% + #1{\@old@font#2}% +}} +% \end{macrocode} +% +% And now for the actual offending accents. +% +% \begin{macrocode} +\DeclareTextCommand{\H}{mTT}{\cmtt@accent\H} +\DeclareTextCommand{\.}{mTT}{\cmtt@accent\.} +% \end{macrocode} +% +% The `under' accents are all OK, so I shan't bother to define them either. +% Similarly, lots of the text symbol commands are fine as they are by +% default and I don't need to try and define them again. +% +% This, then, is the remaining commands which really need sorting out. +% (By the way, the only reason I've redefined \mtt{\\textellipsis} is +% because otherwise it will mess up the nice monospacing.) +% +% \begin{macrocode} +\DeclareTextSymbol{\textbackslash}{mTT}{92} +\DeclareTextSymbol{\textbar}{mTT}{124} +\DeclareTextSymbol{\textbraceleft}{mTT}{123} +\DeclareTextSymbol{\textbraceright}{mTT}{125} +\DeclareTextSymbol{\textless}{mTT}{60} +\DeclareTextSymbol{\textgreater}{mTT}{62} +\DeclareTextSymbol{\textunderscore}{mTT}{95} +\DeclareTextSymbol{\textvisiblespace}{mTT}{32} +\DeclareTextCommand{\textellipsis}{mTT}{...} +\DeclareTextSymbol{\textquotedbl}{mTT}{34} +\DeclareTextSymbol{\textquotesingl}{mTT}{13} +% \end{macrocode} +% +% That's all there is. Please return to your homes. +% +% \Finale +% +\endinput diff --git a/configure.in b/configure.in new file mode 100644 index 0000000..172c82d --- /dev/null +++ b/configure.in @@ -0,0 +1,57 @@ +dnl -*-fundamental-*- +dnl +dnl $Id: configure.in,v 1.1 2002/02/03 20:49:03 mdw Exp $ +dnl +dnl Configuration script for mdwtools +dnl +dnl (c) 2002 Mark Wooding +dnl + +dnl ----- Licensing notice -------------------------------------------------- +dnl +dnl This file is part of the mdwtools LaTeX package collection. +dnl +dnl mdwtools is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 2 of the License, or +dnl (at your option) any later version. +dnl +dnl mdwtools is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with mdwtools; if not, write to the Free Software Foundation, +dnl Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +dnl ----- Revision history -------------------------------------------------- +dnl +dnl $Log: configure.in,v $ +dnl Revision 1.1 2002/02/03 20:49:03 mdw +dnl Checkin for new build system. +dnl + +AC_INIT(mdwtools.ins) +AM_INIT_AUTOMAKE(mdwtools, 1.6.0) + +AC_ARG_WITH([texmfdir], +[ --with-texmfdir=DIR set the TeX install directory to DIR], +[texmfdir=$witharg], +[AC_MSG_CHECKING([where to put installed TeX files]) +mdw_DEFINE_PATHS([ +texmfdir='${datadir}/texmf' +for d in \ + '${datadir}/texmf' '${libdir}/texmf' '${prefix}/lib/texmf' \ + '${prefix}/texmf'; do + if test -d "mdw_PATH([$d])"; then + texmfdir=$d + break + fi +done +AC_MSG_RESULT([$texmfdir])])]) +AC_SUBST(texmfdir) + +AC_OUTPUT(Makefile) + +dnl ----- That's all, folks ------------------------------------------------- diff --git a/crypto.dtx b/crypto.dtx new file mode 100644 index 0000000..92f381c --- /dev/null +++ b/crypto.dtx @@ -0,0 +1,461 @@ +% \begin{meta-comment} +% +% $Id: crypto.dtx,v 1.1 2002/02/03 20:49:03 mdw Exp $ +% +% Typesetting crypto papers +% +% (c) 2001 Mark Wooding +% +%----- Revision history ----------------------------------------------------- +% +% $Log: crypto.dtx,v $ +% Revision 1.1 2002/02/03 20:49:03 mdw +% Checkin for new build system. +% +% +% \end{meta-comment} +% +% \begin{meta-comment} +%% +%% crypto package -- useful macros for typesetting crypto papers +%% Copyright (c) 2001 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +% \end{meta-comment} +% +% \begin{meta-comment} +%<+package>\NeedsTeXFormat{LaTeX2e} +%<+package>\ProvidesPackage{crypto} +%<+package> [2001/09/16 1.0 Crypto typesetting] +% \end{meta-comment} +% +% \CheckSum{215} +%% \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> +\input{mdwtools} +\describespackage{crypto} +\mdwdoc +% +% +% \end{meta-comment} +% +%^^A------------------------------------------------------------------------- +% \section{User guide} +% +% \subsection{Algorithm typesetting} +% +% A lot of provable-security papers need to be able to typeset algorithms +% describing adversaries, schemes, oracle behaviour, etc. There is a +% (relatively) standard format for doing this which we support. +% +% \DescribeEnv{program} +% The \env{program} environment provides handy notation for describing +% algorithms formally. It gives a \env{tabbing} environment, so that things +% can be laid out nicely, and allows fragments of algorithms to be laid out +% in columns or rows, with separating rules. +% +% \DescribeMacro\next +% Within the \env{program} environment, the |\next| command stops typesetting +% the current column, typesets a vertical separator rule, and starts a new +% column. Adjacent columns are spaced out evenly across the page, with equal +% space around the rules rules and at the current margins. This means that +% the rules don't line up, but it still seems to provide a pleasing effect. +% +% \DescribeMacro\newline +% The |\newline| macro begins a new row of algorithm typesetting. A page +% break is possible at a |\newline|. +% +% \DescribeMacro\kw +% A number of standard keywords are available, as shown in +% table~\ref{tab:kw}. The typsetting of these is done by the |\kw| command, +% which usually sets its argument in text bold face, but can be redefined. +% The standard definition uses |\xspace| so that you don't need to remember +% to say \verb*+\ *+ after a keyword command. +% \begin{table} +% \centering +% \def\row#1{\texttt{\string#1} & #1 \\} +% \begin{tabular}{ll} +% \textbf{Command} & \textbf{Keyword} \\ +% \row\RETURN +% \row\IF +% \row\THEN +% \row\ELSE +% \row\REPEAT +% \row\WHILE +% \row\UNTIL +% \row\FOREVER +% \row\DO +% \row\FOR +% \row\FOREACH +% \row\FROM +% \row\IN +% \row\TO +% \row\ABORT +% \row\PARSE +% \row\AS +% \end{tabular} +% \caption{Keywords available for algorithm typesetting} +% \label{tab:kw} +% \end{table} +% +% \DescribeMacro\gets +% \DescribeMacro\getsr +% \DescribeMacro\inr +% Assignment can be represented using the standard command |\gets|, which +% typesets a left-pointing arrow `$\gets$'. Random sampling -- the selection +% of a random element from a set or probability distribution -- can be +% represented using the new command |\getsr|, which typesets an arrow with a +% little `R' above it `$\getsr$'. Random membership -- showing that +% something is a random variable with some distribution -- can be represented +% using the |\inr| command, which just typesets an $\in$ sign with a +% subscript `R': `$\inr$'. +% +% \DescribeMacro\id +% Long identifiers can be typeset using the |\id| command. giving the +% identifier name as an argument. The |\id| command is only valid in maths +% mode. As currently set up, |\id| sets its argument in \emph{text} italics; +% this seems to look better in documents which use a PostScript body face and +% Computer Modern for maths. +% +% \DescribeMacro\Xid +% It's handy to be able to glue a bit of (possibly fancy) maths typesetting +% to an identifier, e.g., to construct $\Xid{H'}{list}$, or +% $\Xid{\mathcal{E}}{CTR$\$$}^F$. This is done using +% \syntax{"\\Xid{""}{""}"}. The two bits are joined by a text +% hyphen `-'. +% +% \DescribeMacro\cookie +% Sometimes textual names are used for special `symbols', which have meaning +% to algorithms, e.g., the symbols $\cookie{find}$ and $\cookie{guess}$ in +% the standard indistinguishability game. These can be typeset using the +% |\cookie| command. +% +% \subsection{Other stuff} +% +% \DescribeMacro\Thing +% In the quantifiable-security world, there are standard symbols for +% advantage, success probability, insecurity, etc. The generic `style hook' +% for these is \syntax{"\\Thing{""}{""}{"scheme"}"}, which +% typesets $\Thing{name}{notion}{scheme}$. It helps a lot if you have the +% \package{amstext} package loaded. +% +% \DescribeMacro\Succ +% \DescribeMacro\Adv +% \DescribeMacro\InSec +% \DescribeMacro\Expt +% \begin{synshorts} +% Some standard `things' are provided: "\\Succ{""}{""}", +% "\\Adv{""}{""}", "\\InSec{""}", and +% "\\Expt{""}{""}". +% \end{synshorts} +% +% \DescribeMacro\G +% In proofs which proceed by varying the rules of the game played by the +% adversary and bounding the probability of it noticing at each step, game +% names are usually typeset as $\G n$ for small numbers $n$. The command +% \syntax{"\\G{""}"} command does this typesetting. There's an optional +% argument, which is a symbol to write instead of `G'. +% +% \DescribeMacro\Func +% \DescribeMacro\Perm +% When dealing with finite PRFs and PRPs, we need to talk about the set of +% \emph{all} functions (or permutations) over particular sets, usually +% $n$-vectors of bits. The macros \syntax{"\\Func{""}{""}"} and +% \syntax{"\\Perm{""}"} typeset $\Func{l}{L}$ and $\Perm{L}$ respectively, +% and are intended to denote the sets of all functions $F\colon \{0, 1\}^l +% \to \{0, 1\}^L$ and all permutations $\Pi\colon \{0, 1\}^L \to \{0, 1\}^L$ +% respectively. +% +% \DescribeMacro\PKCS +% Finally, the |\PKCS| macro typesets `\PKCS{$n$}', allowing you to name RSA +% Security Inc.'s Public Key Cryptography Standards in a relatively nice way. +% +% \implementation +% +% +%^^A------------------------------------------------------------------------- +% \section{Implementation} +% +% We need David Carlisle's handy \package{xspace} package and the AMS |\text| +% command. +% +% \begin{macrocode} +%<*package> +\RequirePackage{amstext} +\RequirePackage{xspace} +% \end{macrocode} + +% \subsection{Algorithm typsetting} +% +% \begin{macro}{\cookie} +% \begin{macro}{\kw} +% \begin{macro}{\id} +% +% First, some style issues. Note the |\xspace| at the end of |\kw|. +% +% \begin{macrocode} +\def\cookie#1{\text{\normalfont\sffamily\/#1\/}} +\def\kw#1{\text{\normalfont\bfseries\/#1\/}\xspace} +\def\id#1{\text{\normalfont\itshape\/#1\/}} +% \end{macrocode} +% +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\getsr} +% \begin{macro}{\inr} +% +% The symbols for random selection and membership are fairly easy. The `R' +% over $\getsr$ is actually in scriptscript style, because that seems to look +% nicer. +% +% \begin{macrocode} +\def\inr{\mathrel{\in_R}} +\def\getsr{\mathrel{\mathop{\gets}\limits^{\scriptscriptstyle R}}} +% \end{macrocode} +% +% \end{macro} +% \end{macro} +% +% \begin{macro}{\Xid} +% +% The compound identifiers set by |\Xid| are easy. +% +% \begin{macrocode} +\def\Xid#1#2{\id{$#1$-#2}} +% \end{macrocode} +% +% \end{macro} +% +% Now for the various keywords. These are trivial, but useful. +% +% \begin{macrocode} +\def\RETURN{\kw{return}} +\def\IF{\kw{if}} +\def\THEN{\kw{then}} +\def\ELSE{\kw{else}} +\def\REPEAT{\kw{repeat}} +\def\WHILE{\kw{while}} +\def\UNTIL{\kw{until}} +\def\FOREVER{\kw{forever}} +\def\DO{\kw{do}} +\def\FOR{\kw{for}} +\def\FOREACH{\kw{for\,each}} +\def\FROM{\kw{from}} +\def\IN{\kw{in}} +\def\TO{\kw{in}} +\def\ABORT{\kw{abort}} +\def\PARSE{\kw{parse}} +\def\AS{\kw{as}} +% \end{macrocode} +% +% \begin{environment}{program} +% \begin{macro}{\next} +% \begin{macro}{\newline} +% +% Now for the \env{program} environment and its associated twiddling. This +% is actually a little fiddly. +% +% At the beginning, if we're in vertical mode -- i.e., there was a paragraph +% break before the start of the environment -- then remember this, because it +% affects the typesetting at the end. Set up |\next| and |\newline| in terms +% of the underlying machinery, and start a row of algorithm. +% +% \begin{macrocode} +\def\program{% + \normalfont% + \@tempswatrue\ifvmode\@tempswafalse\fi% + \def\next{\program@end\vrule\program@begin}% + \def\newline{\program@endline\medskip\program@startline}% + \begingroup\trivlist% + \advance\@topsep-\parskip\advance\@topsepadd-\parskip\item% + \program@startline% +} +% \end{macrocode} +% +% Ending the environment is easy-ish. We stop the current row and leave a +% gap, matching the one that |\poem@startline| adds automatically. If we +% were initially in horizontal mode, then don't indent the next paragraph, +% and ignore spaces after the |\end{program}| command. +% +% \begin{macrocode} +\def\endprogram{% + \program@endline\endtrivlist\endgroup% + \if@tempswa\noindent\fi\@ignoretrue% +} +% \end{macrocode} +% +% Now for the guts of all of this. First of all, we turn to the typesetting +% of a column, which is just hfil glue, a \env{minipage} with zero width and +% a \env{tabbing} environment. The first tab is already set 1\,em in from +% the margin. We use \env{minipage} to set up the list parameters correctly +% and manage the initial and final spacing. The zero width is OK because +% \env{tabbing} sets a list of hboxes rather than using outer horizontal +% mode, so the |\hsize| is irrelevant. +% +% \begin{macrocode} +\def\program@begin{% + \begingroup% + \hfil% + \minipage[t]\z@% + \topsep\z@% + \itemsep\z@% + \parskip\z@\parsep\z@% + \partopsep\z@% + \tabbing% +% \end{macrocode} +% +% This is rather messy. The |\item| from the \env{trivlist} messes up the +% spacing. We remove the box, and fix |\prevdepth| to ensure that there's no +% glue at the top. +% +% \begin{macrocode} + \quad\=dummy\\% + \@stopfield% + \begingroup% + \setbox\z@\lastbox\unskip\unskip\unskip\setbox\z@\lastbox\unskip% + \endgroup% + \prevdepth-\@m\p@% + \@startfield\strut% +} +% \end{macrocode} +% +% Ending a program has no discernable subtlety. +% +% \begin{macrocode} +\def\program@end{% + \endtabbing% + \endminipage% + \hfil% + \endgroup% +} +% \end{macrocode} +% +% Finally, the row setting is fairly easy. We have to ensure that we obey +% the prevailing list parameters. +% +% \begin{macrocode} +\def\program@startline{% + \moveright\@totalleftmargin% + \hb@xt@\linewidth\bgroup% + \program@begin% +} +\def\program@endline{% + \program@end% + \egroup% +} +% \end{macrocode} +% +% \end{macro} +% \end{macro} +% \end{environment} +% +% \subsection{Other stuff} +% +% \begin{macro}{\Thing} +% \begin{macro}{\Succ} +% \begin{macro}{\Adv} +% \begin{macro}{\InSec} +% \begin{macro}{\Expt} +% +% Typesetting |\Thing| is easy. This acts as a style hook for the rest of +% these things.. +% +% \begin{macrocode} +\def\Thing#1#2#3{\text{\normalfont\bfseries#1}^{\text{\normalfont#2}}_{#3}} +% \end{macrocode} +% +% And now here they are. +% +% \begin{macrocode} +\def\Succ{\Thing{Succ}} +\def\Adv{\Thing{Adv}} +\def\InSec#1{\Thing{InSec}{#1}{}} +\def\Expt{\Thing{Expt}} +% \end{macrocode} +% +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\G} +% +% The name of a game is typeset simply as +% +% \begin{macrocode} +\newcommand\G[2][G]{\mathbf{#1}_{#2}} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\Func} +% \begin{macro}{\Perm} +% +% The finite sets of functions and permutations are just a style choice. We +% choose to buck the standard trends and use caligraphic letters. +% +% \begin{macrocode} +\def\Func#1#2{\mathcal{F}^{#1,#2}} +\def\Perm#1{\mathcal{P}^{#1}} +% \end{macrocode} +% +% \end{macro} +% \end{macro} +% +% \begin{macro}{\PKCS} +% +% Finally, I find that \PKCS{$n$} looks best typeset like this: +% +% \begin{macrocode} +\def\PKCS#1{PKCS\,\##1} +% \end{macrocode} +% +% \end{macro} +% +% \vskip\parskip\vbox{ ^^A The best way I could find of keeping this lot +% ^^A together, I'm afraid. +% That's all there is. Byebye. +% +% \begin{macrocode} +% +% \end{macrocode} +% \nopagebreak +% +% \hfill Mark Wooding, \today +% } +% \Finale +% +\endinput diff --git a/doafter.dtx b/doafter.dtx new file mode 100644 index 0000000..f1ec3f2 --- /dev/null +++ b/doafter.dtx @@ -0,0 +1,519 @@ +% \begin{meta-comment} +% +% $Id: doafter.dtx,v 1.1 2002/02/03 20:49:03 mdw Exp $ +% +% Insert tokens to be read after a group has been processed +% +% (c) 1996 Peter Schmitt and Mark Wooding +% +%----- Revision history ----------------------------------------------------- +% +% $Log: doafter.dtx,v $ +% Revision 1.1 2002/02/03 20:49:03 mdw +% Checkin for new build system. +% +% Revision 1.2 1996/11/19 20:49:08 mdw +% Entered into RCS +% +% +% \end{meta-comment} +% +% \begin{meta-comment} +%% +%% doafter package -- insert a token really after a group +%% Copyright (c) 1996 Peter Schmitt and Mark Wooding +%<*package> +%% +%% 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} +%<+latex2e>\NeedsTeXFormat{LaTeX2e} +%<+latex2e>\ProvidesPackage{doafter} +%<+latex2e> [1996/05/08 1.2 Aftergroup hacking (PS/MDW)] +% \end{meta-comment} +% +% \CheckSum{259} +%\iffalse +%<*package> +%\fi +%% \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 \~} +%% +%\iffalse +% +%\fi +% +% \begin{meta-comment} +% +%<*driver> +\input{mdwtools} +\describespackage{doafter} +\author{Peter Schmitt\thanks{% + Peter came up with the basic implementation after I posed the problem + in the \texttt{comp.text.tex} newsgroup. I fixed some really piddly little + things, to improve it a bit, wrote the documentation, and turned the code + into a nice \package{doc}ced package. Then Peter gave me an updated + version, and I upgraded this from memory. Then he gave me some more tweaks + which I haven't incorporated.} + \and Mark Wooding} +\def\author#1{} +\mdwdoc +% +% +% \end{meta-comment} +% +% \section{Description} +% +% \subsection{What it's all about} +% +% \DescribeMacro{\doafter} +% It's common for the \TeX\ primitive |\aftergroup| to be used to `tidy up' +% after a group. For example, \LaTeX's colour handling uses this to insert +% appropriate |\special|s when the scope of a colour change ends. This +% causes several problems, though; for example, extra grouping must be added +% within boxes to ensure that the |\special|s don't `leak' out of their box +% and appear in odd places in the document. \LaTeX\ usually solves this +% problem by reading the box contents as an argument, although this isn't +% particularly desirable. The |\doafter| macro provided here will solve the +% problem in a different way, by allowing a macro to regain control after +% all the |\aftergroup| things have been processed. +% +% The macro works like this: +% \begin{grammar} +% ::= \[[ +% "\\doafter" +% \]] +% \end{grammar} +% The \ can be any token you like, except an explicit braces, since +% it's read as an undelimited macro argument. The \ is a normal +% \TeX\ group, surrounded by either implicit or explicit braces, or by +% |\begingroup| and |\endgroup| tokens. Once the final closing token of the +% \ is read, and any tokens saved up by |\aftergroup| have been +% processed, the \ is inserted and processed. Under normal +% circumstances, this will be a macro. +% +% There are some subtle problems with the current implementation, which you +% may need to be aware of: +% +% \begin{itemize} +% +% \item Since we're inserting things after all the |\aftergroup| tokens, +% those tokens might read something they're not expecting if they try +% to look ahead at the text after the group (e.g., with |\futurelet|). +% This is obviously totally unavoidable. +% +% \item Implicit braces (like |\bgroup| and |\egroup|) inserted using +% |\aftergroup| may be turned into \emph{explicit} $|{|_1$ and $|}|_2$ +% characters within a |\doafter| group. This can cause probems under +% very specialised circumstances. The names |\bgroup| and |\egroup| +% are treated specially, and they will work normally (remaining as +% implicit braces). This should minimise problems caused by this +% slight difference. (This only applies to the last |\aftergroup| +% token in a group.) +% +% \item To handle the |\aftergroup| tokens properly, |\doafter| has to insert +% some |\aftergroup| tokens of its own. It will then process the +% other tokens some more, and set them up to be read again. This does +% mean that after the group ends, some assignments and other `stomach +% operations' will be performed, which may cause problems in +% alignments and similar places. +% +% \end{itemize} +% +% +% \subsection{Package options} +% +% There are a fair few \textsf{docstrip} options provided by this packge: +% +% \begin{description} +% \item [driver] extracts the documentation driver. This isn't usually +% necessary. +% \item [package] extracts the code as a standalone package, formatted for +% either \LaTeXe\ or Plain~\TeX. +% \item [latex2e] inserts extra identification code for a \LaTeXe\ package. +% \item [plain] inserts some extra code for a Plain \TeX\ package. +% \item [macro] just extracts the raw code, for inclusion in another package. +% \item [test] extracts some code for testing the current implementation. +% \end{description} +% +% +% \implementation +% +% \section{Implementation} +% +% \subsection{The main macro} +% +% We start outputting code here. If this is a Plain~\TeX\ package, we must +% make \lit{@} into a letter. +% +% \begin{macrocode} +%<*macro|package> +%<+plain>\catcode`\@=11 +% \end{macrocode} +% +% \begin{macro}{\doafter} +% +% The idea is to say \syntax{"\\doafter" } and expect the +% \synt{token} to be processed after the group has finished its stuff, +% even if it contains |\aftergroup| things. My eternal gratitude goes to +% Peter Schmitt, who came up with most of the solution implemented here; +% I've just tidied up some very minor niggles and things later. +% +% Let's start with some preamble. I'll save the (hopefully) primitive +% |\aftergroup| in a different token. +% +% \begin{macrocode} +\let\@@aftergroup\aftergroup +% \end{macrocode} +% +% Now to define the `user' interface. It takes a normal undelimited +% argument, although this must be a single token; otherwise eveything will +% go wrong. It assumes that the token following is some kind of group +% opening thing (an explicit or implicit character with catcode~1, or +% a |\begingroup| token). To make this work, I'll save the token, +% together with an |\@@aftergroup| (to save an |\expandafter| later) in +% a temporary macro which no-one will mind me using, and then look ahead at +% the beginning-group token. +% +% \begin{macrocode} +\def\doafter#1{% + \def\@tempa{\@@aftergroup#1}% + \afterassignment\doafter@i\let\@let@token% +} +% \end{macrocode} +% +% I now have the token in |\@let@token|, so I'll put that in. I'll then +% make |\aftergroup| do my thing rather than the normal thing, and queue +% the tokens |\@prepare@after| and the |\doafter| argument for later use. +% +% \begin{macrocode} +\def\doafter@i{% + \@let@token% + \let\aftergroup\@my@aftergroup% + \@@aftergroup\@prepare@after\@tempa% +} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\@my@aftergroup} +% +% Now the cleverness begins. We keep two macros (Peter's original used +% count registers) which keep counts of the numbers of |\aftergroup|s, +% both locally and globally. Let's call the local counter~$n$ and the +% global one $N$. Every time we get a call to our |\aftergroup| hack, +% we set~$n := n+1$ and~$N := n$, and leave the token given to us for later +% processing. When we actually process an |\aftergroup| token properly, +% set~$N := N-1$ to indicate that it's been handled; when they're all done, +% we'll have $N=n$, which is exactly what we'd have if there weren't any +% to begin with. +% +% \begin{macrocode} +\def\ag@cnt@local{0 } +\let\ag@cnt@global\ag@cnt@local +% \end{macrocode} +% +% Now we come to the definition of my version of |\aftergroup|. I'll just +% add the token |\@after@token| before every |\aftergroup| token I find. +% This means there's two calls to |\aftergroup| for every one the user makes, +% but these things aren't all that common, so it's OK really. I'll also +% bump the local counter, and synchronise them. +% +% \begin{macrocode} +\def\@my@aftergroup{% + \begingroup% + \count@\ag@cnt@local% + \advance\count@\@ne% + \xdef\ag@cnt@global{\the\count@\space}% + \endgroup% + \let\ag@cnt@local\ag@cnt@global% + \@@aftergroup\@after@token\@@aftergroup% +} +% \end{macrocode} +% +% \end{macro} +% +% Now what does |\@after@token| we inserted above actually do? Well, this +% is more exciting. There are actually two different variants of the +% macro, which are used at different times. +% +% \begin{macro}{\@after@token} +% +% The default |\@after@token| starts a group, which will `catch' +% |\aftergroup| tokens which I throw at it. I put the two counters into +% some scratch count registers. (There's a slight problem here: Plain \TeX\ +% only gives us one. For the sake of evilness I'll use |\clubpenalty| as the +% other one. Eeeek.) I then redefine |\@after@token| to the second +% variant, and execute it. The |\@start@after@group| macro starts the +% group, because this code is shared with |\@prepare@after| below. +% +% \begin{macrocode} +\def\@after@token{% + \@start@after@group% + \@after@token% +} +\def\@start@after@group{% + \begingroup% + \count@\ag@cnt@global% + \clubpenalty\ag@cnt@local% + \let\@after@token\@after@token@i% +} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\@after@token@i} +% +% I have $|\count@| = N$ and $|\@tempcnta| = n$. I'll decrement~$N$, +% and if I have $N = n$, I know that this is the last token to do, so I +% must insert an |\@after@all| after the token. This will close the group, +% and maybe insert the original |\doafter| token if appropriate. +% +% \begin{macrocode} +\def\@after@token@i{% + \advance\count@\m@ne% + \ifnum\count@=\clubpenalty% + \global\let\ag@cnt@global\ag@cnt@local% + \expandafter\@after@aftertoken\expandafter\@after@all% + \else% + \expandafter\@@aftergroup% + \fi% +} +% \end{macrocode} +% +% Finally, establish a default meaning for |\@after@all|. +% +% \begin{macrocode} +\let\@after@all\endgroup +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\@prepare@after} +% +% If this group is handled by |\doafter|, then the first |\aftergroup| token +% isn't |\@after@token|; it's |\@prepare@after|. +% +% There are some extra cases to deal with: +% \begin{itemize} +% \item If $N=n$ then there were no |\aftergroup| tokens, so we have an easy +% job. I'll just let the token do its stuff directly. +% \item Otherwise, $N>n$, and there are |\aftergroup| tokens. I'll open +% the group, and let |\@after@token| do all the handling. +% \end{itemize} +% +% \begin{macrocode} +\def\@prepare@after{% + \ifx\ag@cnt@local\ag@cnt@global\else% + \expandafter\@prepare@after@i% + \fi% +} +\def\@prepare@after@i#1{% + \@start@after@group% + \def\@after@all{\@@aftergroup#1\endgroup}% +} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\@after@aftertoken} +% +% This is where all the difficulty lies. The next token in the stream is +% an |\aftergroup| one, which could be more or less anything. We have an +% argument, which is some code to do \emph{after} the token has been +% |\aftergroup|ed. +% +% If the token is anything other than a brace (i.e., an explicit character +% of category~1 or~2) then I have no problem; I can scoop up the token with +% an undelimited macro argument. But the only way I can decide if this token +% is a brace (nondestructively) is with |\futurelet|, which makes the token +% implicit, so I can't decide whether it's really dangerous. +% +% There is a possible way of doing this\footnote{Due to Peter Schmitt, +% again.} which relates to nobbling the offending token with |\string| and +% sifting through the results. The problem here involves scooping up all the +% tokens of a |\string|ed control sequence, which may turn out to be +% `|\csname\endcsname|' or something equally horrid. +% +% The solution I've used is much simpler: I'll change |\bgroup| and |\egroup| +% to stop them from being implicit braces before comparing. +% +% \begin{macrocode} +\def\@after@aftertoken#1{% + \let\bgroup\relax\let\egroup\relax% + \toks@{#1}% + \futurelet\@let@token\@after@aftertoken@i% +} +\def\@after@aftertoken@i{% + \ifcat\noexpand\@let@token{% + \@@aftergroup{% + \else\ifcat\noexpand\@let@token}% + \@@aftergroup}% + \else% + \def\@tempa##1{\@@aftergroup##1\the\toks@}% + \expandafter\expandafter\expandafter\@tempa% + \fi\fi% +} +% \end{macrocode} +% +% \end{macro} +% +% +% Phew! +% +% \begin{macrocode} +%<+plain>\catcode`\@=12 +% +% \end{macrocode} +% +% \subsection{Test code} +% +% The following code gives |\doafter| a bit of a testing. It's based on +% the test suite I gave to comp.text.tex, although it's been improved a +% little since then. +% +% The first thing to do is define a control sequence with an \lit{@} sign +% in its name, so we can test catcode changes. This also hides an +% |\aftergroup| within a macro, making life more difficult for prospective +% implementations. +% +% \begin{macrocode} +%<*test> +\catcode`\@=11 +\def\at@name{\aftergroup\saynine} +\def\saynine{\say{ix}} +\catcode`\@=12 +% \end{macrocode} +% +% Now define a command to write a string to the terminal. The name will +% probably be familiar to REXX hackers. +% +% \begin{macrocode} +\def\say{\immediate\write16} +% \end{macrocode} +% +% Test one: This is really easy; it just tests that the thing works at all. +% If your implementation fails this, it's time for a major rethink. +% +% \begin{macrocode} +\say{Test one... (1--2)} +\def\saytwo{\say{ii}} +\doafter\saytwo{\say{i}} +% \end{macrocode} +% +% Test two: Does |\aftergroup| work? +% +% \begin{macrocode} +\say{Test two... (1--4)} +\def\saythree{\say{iii}} +\def\sayfour{\say{iv}} +\doafter\sayfour{\say{i}\aftergroup\saythree\say{ii}} +% \end{macrocode} +% +% Test three: Test braces and |\iffalse| working as they should. Several +% proposed solutions based on |\write|ing the group to a file get upset by +% this test, although I forgot to include it in the torture test. It also +% tests whether literal braces can be |\aftergroup|ed properly. (Added a new +% test here, making sure that |\bgroup| is left as an implicit token.) +% +% \begin{macrocode} +\say{Test three... (1--4, `\string\bgroup', 5)} +\def\sayfive{\say{v}} +\doafter\sayfive{% + \say{i}% + \aftergroup\say% + \aftergroup{% + \aftergroup\romannumeral\aftergroup3% + \aftergroup}% + \iffalse}\fi% + \aftergroup\def% + \aftergroup\sayfouretc% + \aftergroup{% + \aftergroup\say% + \aftergroup{% + \aftergroup i% + \aftergroup v% + \aftergroup}% + \aftergroup\say% + \aftergroup{% + \aftergroup\string% + \aftergroup\bgroup% + \aftergroup}% + \aftergroup}% + \aftergroup\sayfouretc% + \say{ii}% +} +% \end{macrocode} +% +% Test four: Make sure the implementation isn't leaking things. This just +% makes sure that |\aftergroup| is its normal reasonable self. +% +% \begin{macrocode} +\say{Test four... (1--3)} +{\say{i}\aftergroup\saythree\say{ii}} +% \end{macrocode} +% +% Test five: Nesting, aftergroup, catcodes, grouping. This is the `torture' +% test I gave to comp.text.tex, slightly corrected (oops) and amended. It +% ensures that nested groups and |\doafter|s work properly (the latter is +% actually more likely than might be imagined). +% +% \begin{macrocode} +\say{Test five... (1--14)} +\def\sayten{\say{x}} +\def\saythirteen{\say{xiii}} +\def\sayfourteen{\say{xiv}} +\doafter\sayfourteen\begingroup% + \say{i}% + {\say{ii}\aftergroup\sayfour\say{iii}}% + \def\saynum{\say{viii}}% + \doafter\sayten{% + \say{v}% + \def\saynum{\say{vii}}% + \catcode`\@=11% + \aftergroup\saynum% + \say{vi}% + \at@name% + \saynum% + }% + \say{xi}% + \aftergroup\saythirteen% + \say{xii}% +\endgroup +\end +% +% \end{macrocode} +% +% That's it. All present and correct. +% +% \Finale +% +\endinput diff --git a/doafter.tex b/doafter.tex new file mode 100644 index 0000000..2e9cabb --- /dev/null +++ b/doafter.tex @@ -0,0 +1,113 @@ +%% +%% This is file `doafter.tex', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% doafter.dtx (with options: `package,plain') +%% +%% IMPORTANT NOTICE +%% +%% doafter package -- insert a token really after a group +%% Copyright (c) 1996 Peter Schmitt and 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. +%% +%% \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 \~} +%% +\catcode`\@=11 +\let\@@aftergroup\aftergroup +\def\doafter#1{% + \def\@tempa{\@@aftergroup#1}% + \afterassignment\doafter@i\let\@let@token% +} +\def\doafter@i{% + \@let@token% + \let\aftergroup\@my@aftergroup% + \@@aftergroup\@prepare@after\@tempa% +} +\def\ag@cnt@local{0 } +\let\ag@cnt@global\ag@cnt@local +\def\@my@aftergroup{% + \begingroup% + \count@\ag@cnt@local% + \advance\count@\@ne% + \xdef\ag@cnt@global{\the\count@\space}% + \endgroup% + \let\ag@cnt@local\ag@cnt@global% + \@@aftergroup\@after@token\@@aftergroup% +} +\def\@after@token{% + \@start@after@group% + \@after@token% +} +\def\@start@after@group{% + \begingroup% + \count@\ag@cnt@global% + \clubpenalty\ag@cnt@local% + \let\@after@token\@after@token@i% +} +\def\@after@token@i{% + \advance\count@\m@ne% + \ifnum\count@=\clubpenalty% + \global\let\ag@cnt@global\ag@cnt@local% + \expandafter\@after@aftertoken\expandafter\@after@all% + \else% + \expandafter\@@aftergroup% + \fi% +} +\let\@after@all\endgroup +\def\@prepare@after{% + \ifx\ag@cnt@local\ag@cnt@global\else% + \expandafter\@prepare@after@i% + \fi% +} +\def\@prepare@after@i#1{% + \@start@after@group% + \def\@after@all{\@@aftergroup#1\endgroup}% +} +\def\@after@aftertoken#1{% + \let\bgroup\relax\let\egroup\relax% + \toks@{#1}% + \futurelet\@let@token\@after@aftertoken@i% +} +\def\@after@aftertoken@i{% + \ifcat\noexpand\@let@token{% + \@@aftergroup{% + \else\ifcat\noexpand\@let@token}% + \@@aftergroup}% + \else% + \def\@tempa##1{\@@aftergroup##1\the\toks@}% + \expandafter\expandafter\expandafter\@tempa% + \fi\fi% +} +\catcode`\@=12 +\endinput +%% +%% End of file `doafter.tex'. diff --git a/exercise.dtx b/exercise.dtx new file mode 100644 index 0000000..5b01925 --- /dev/null +++ b/exercise.dtx @@ -0,0 +1,555 @@ +% \begin{meta-comment} +% +% $Id: exercise.dtx,v 1.1 2002/02/03 20:49:03 mdw Exp $ +% +% Exercises +% +% (c) 2001 Mark Wooding +% +%----- Revision history ----------------------------------------------------- +% +% $Log: exercise.dtx,v $ +% Revision 1.1 2002/02/03 20:49:03 mdw +% Checkin for new build system. +% +% +% \end{meta-comment} +% +% \begin{meta-comment} +%% +%% exercise package -- useful macros for setting exercises with answers +%% Copyright (c) 2001 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +% \end{meta-comment} +% +% \begin{meta-comment} +%<+package>\NeedsTeXFormat{LaTeX2e} +%<+package>\ProvidesPackage{exercise} +%<+package> [2001/09/21 1.0 Exercies with answers] +% \end{meta-comment} +% +% \CheckSum{236} +%% \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> +\input{mdwtools} +\describespackage{exercise} +\let\epsilon\varepsilon +\mdwdoc +% +% +% \end{meta-comment} +% +%^^A------------------------------------------------------------------------- +% \section{User guide} +% +% The \package{exercise} package allows you to typeset exercises and keep the +% answers together with the questions in your source (so they don't get +% lost) but typeset them all together at the end of your document. +% +% \subsection{Exercises and answers} +% +% \DescribeEnv{exercise} +% Exercises are typset in an \env{exercise} environment. This takes no +% arguments. There's a counter for exercises, named |exercise|, and you can +% cross-reference exercises in the usual way. +% +% \DescribeMacro\answer +% If you want to include an answer for your exercise, just say |\answer| +% followed by your answer. The rest of the text up to the end of the +% \env{exercise} environment is considered to be the answer, and is stored +% away until asked for. This material can contain anything you like. It +% \emph{isn't} a moving argument. +% +% \begin{figure} +%\begin{demo}[w]{The \env{exercise} environment} +%\begin{exercise} +%Show that if $F\colon \{0, 1\}^k \times \{0, 1\}^* \to \{0, 1\}^L$ +%is a $(t, q + 1, \epsilon)$-secure PRF, then $F$~is also a +%$(t, q, \epsilon + 2^{-L})$-secure MAC. +%\answer +%Let~$A$ be an adversary attacking~$F$ as a MAC. Consider the +%adversary~$B$ \ldots +%\end{exercise} +%\end{demo} +% \end{figure} +% +% \subsection{The answers file} +% +% \DescribeMacro\answrite +% Answers are accumulated into a file, to be read later. Additional material +% can be added to the file using the |\answrite| macro, which just writes its +% argument. Note that this is a \emph{moving} argument, so fragile commands +% need |\protect|ing. +% +% \DescribeMacro\exctrcheck +% It's common to divide up the answers by section. You can tell the package +% to check a collection of counters and perform actions if they've changed +% since last time, giving you a chance to write the correct decorations to +% the answers file. This is done by saying +% \syntax{"\\exctrcheck{""}{""}"}. Then, each |\answer| +% command checks to see if \ has changed since last time, and if it +% has, it does \, For example, +%\begin{verbatim} +%\exctrcheck{section} +% {\answrite{\protect\subsection*{Section \thesection}}} +%\end{verbatim} +% starts a new (unnumbered) subsection in the answers for each section in the +% main document. +% +% \subsection{Style tweaks} +% +% The \env{exercise} environment is very simple, and can be easily rewritten +% to fit in with your style preferences. If you like exercises to look like +% theorems, the easiest thing to do is say something like +%\begin{verbatim} +%\newtheorem{doexercise}[exercise]{\exercisename} +%\renewenvironment{exercise}{\exfix\doexercise}{\enddoexercise} +%\end{verbatim} +% This makes the environment use the existing exercise counter. If you don't +% want that, say +%\begin{verbatim} +%\newtheorem{doexercise}[othercounter]{\exercisename} +%\renewenvironment{exercise}{\exfix\doexercise}{\enddoexercise} +%\let\theexercise\theothercounter +%\end{verbatim} +% and all will be well. +% +% \DescribeEnv{doanswer} +% Answers are typeset in a \env{doanswer} environment, which is given one +% argument: the exercise number (as set by |\theexercise|). This can be +% modified to do whatever you like. +% +% \DescribeMacro\exfix +% The |\exfix| is a convenient hook which is run both in the \env{exercise} +% and \env{doanswer} environments by default. The current implementation +% just skips a level of \env{enumerate} depth, which usually means that +% \env{enumerate} lists will go (a), (b), (c), \ldots\ rather than 1, 2, 3, +% \ldots +% +% \subsection{Lists in paragraphs} +% +% \DescribeEnv{parenum} +% Answers to subparts tend to be compressed together into a single +% paragraph. It's nice, when you do this, not to have to worry about losing +% your numbering of subparts. The \env{parenum} environment provides an +% enumerated list in a paragraph. So, for example, you can say something +% like this. +%\begin{demo}[w]{Example of \env{parenum}} +%\begin{exercise} +%A PRG $g\colon \{0, 1\}^k \to \{0, 1\}^L$ is \emph{trivial} if +%$k \ge L$. +%\begin{enumerate} +%\item Show that trivial PRGs exist. +%\item Show that a non-trivial $(t, \epsilon)$-secure PRG is a +% $(t, \epsilon + 2^{k-L})$-secure one-way function. +%\end{enumerate} +%\answer +%\begin{parenum} +%\item The identity function is a trivial PRG: the real and random +% games are identically distributed. +%\item Let~$A$ be an adversary attempting to invert~$g$: then we +% can construct a distinguisher~$B$ as follows \ldots +%\end{parenum} +%\end{exercise} +%\end{demo} +% +% \subsection{And finally} +% +% \DescribeMacro\answers +% In order to extract your answers, say |\answers|. +%\begin{demo}[w]{The \texttt{\string\answers} command} +%\section*{Answers} +%\answers +%\end{demo} +% +% \implementation +% +% +%^^A------------------------------------------------------------------------- +% \section{Implementation} +% +% \begin{macrocode} +%<*package> +% \end{macrocode} +% +% \subsection{Initialization} +% +% The \textsf{within} option is handled by the \package{keyval} package. +% +% \begin{macrocode} +\RequirePackage{keyval} +% \end{macrocode} +% +% \begin{macro}{\ex@within} +% +% When the \textsf{within} option is seen, we set a command |\ex@within| to +% the correct code, to be executed later when we've made our minds up. +% +% \begin{macrocode} +\let\ex@within\relax +\define@key{ex}{within}{% + \def\ex@within{% + \@addtoreset{exercise}{#1}% + \toks@\expandafter{\csname the#1\expandafter\endcsname% + \expandafter.\theexercise}% + \edef\theexercise{\the\toks@}% + }% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\ex@opts} +% +% The |\ex@opts| macro just runs the \package{keyval} kit to parse an option +% string. +% +% \begin{macrocode} +\def\ex@opts{\setkeys{ex}} +% \end{macrocode} +% \end{macro} +% +% Now do the options thing. +% +% \begin{macrocode} +\DeclareOption*{\expandafter\ex@opts\expandafter{\CurrentOption}} +\ProcessOptions* +% \end{macrocode} +% +% Set up the |exercise| counter, and number it within some other sort of +% counter as appropriate. +% +% \begin{macrocode} +\newcounter{exercise}\ex@within +% \end{macrocode} +% +% We also need the \package{sverb} package in order to do the delaying of the +% answers. +% +% \begin{macrocode} +\RequirePackage{sverb} +% \end{macrocode} +% +% \subsection{Checking for counter changes} +% +% \begin{macro}{\ex@ctrcheck} +% +% The counter checking state is stored here. It's initially empty. +% +% \begin{macrocode} +\def\ex@ctrcheck{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\exctrcheck} +% +% Adding a counter to the check list is relatively easy. We expand the +% current list into a token register, add the new material to the end, and +% put the list back in our macro using |\edef|. The `last' value of the +% counter is set to |\relax|, to force out the change on the next |\answer|. +% +% \begin{macrocode} +\def\exctrcheck#1#2{% + \toks@\expandafter{\ex@ctrcheck\ex@ctrdo{#1}{#2}}% + \edef\ex@ctrcheck{\the\toks@}% + \global\expandafter\let\csname ex@ctrlast@#1\endcsname\relax% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\ex@ctrdo} +% +% Here we actually check to see whether a counter has changed and execute the +% appropriate code. +% +% \begin{macrocode} +\def\ex@ctrdo#1#2{% + \edef\@tempa{\csname the#1\endcsname}% + \expandafter\ifx\csname ex@ctrlast@#1\endcsname\@tempa\else% + #2% + \global\expandafter\let\csname ex@ctrlast@#1\endcsname\@tempa% + \fi% +} +% \end{macrocode} +% \end{macro} +% +% \subsection{The \env{exercise} environment} +% +% \begin{macro}{\exercisename} +% +% We store the string to print for each exercise in |\exercisename| as a +% half-hearted attempt at internationalization. +% +% \begin{macrocode} +\providecommand\exercisename{Exercise} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\exfix} +% +% This is a dumping ground for style fixing common to both exercises and +% answers. Here, we bump on the \env{enum} depth counter, so that it skips +% labelling with digits. +% +% \begin{macrocode} +\def\exfix{\advance\@enumdepth\@ne} +% \end{macrocode} +% \end{macro} +% +% \begin{environment}{exercise} +% +% This is pretty simple. The environment is list-based, with the number set +% in bold in a label. +% +% \begin{macrocode} +\def\exercise{% + \refstepcounter{exercise}% + \exfix% + \trivlist\advance\itemindent\labelsep% + \item[\textbf{\exercisename\ \theexercise}]% +} +\let\endexercise\endtrivlist +% \end{macrocode} +% \end{environment} +% +% \subsection{Answers} +% +% We need a file in which to store our answers. +% +% \begin{macrocode} +\newwrite\ex@ansfile +% \end{macrocode} +% +% \begin{macro}{\ex@ansfilename} +% +% In case anyone has a better idea for a filename than our default, we +% provide a hook. +% +% \begin{macrocode} +\def\ex@ansfilename{\jobname.ans} +% \end{macrocode} +% \end{macro} +% +% We open the file at the end of the preamble, to give the user a chance to +% say |\nofiles|, or change |\ex@ansfilename|. +% +% \begin{macrocode} +\AtBeginDocument{% + \if@filesw% + \immediate\openout\ex@ansfile=\ex@ansfilename\relax% + \answrite\relax% + \fi% +} +% \end{macrocode} +% +% \begin{macro}{\answrite} +% +% This writes stuff to the answers file. We make sure that it's +% appropriately protected, so that you can insert section headings and so on. +% +% \begin{macrocode} +\def\answrite#1{% + \if@filesw% + \begingroup% + \let\protect\@unexpandable@protect% + \immediate\write\ex@ansfile{#1}% + \endgroup% + \fi% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\answer} +% +% The |\answer| macro needs to read until the end of the enclosing +% \env{exercise} environment (or whatever). +% +% \begin{macrocode} +\def\answer{\sv@readenv\ex@answer} +% \end{macrocode} +% +% Now for the main guts. +% +% \begin{macrocode} +\def\ex@answer#1#2{% + \begingroup% + \@bsphack% +% \end{macrocode} +% +% First of all, check to see whether any counters have changed. +% +% \begin{macrocode} + \ex@ctrcheck% +% \end{macrocode} +% +% Start a \env{doanswer} environment in the file. +% +% \begin{macrocode} + \answrite{\noexpand\begin{doanswer}{\theexercise}}% +% \end{macrocode} +% +% Set catcodes to be strange, and read lines one-at-a-time, writing them to +% the file. When finished, continue at |\ex@endanswer|. +% +% \begin{macrocode} + \let\do\@makeother\dospecials% + \sv@safespc% + \sv@read{#1}\answrite{\ex@endanswer#2}% +} +% \end{macrocode} +% +% When that's done, we wind up here. +% +% \begin{macrocode} +\def\ex@endanswer{% + \@esphack% + \answrite{\noexpand\end{doanswer}}% + \endgroup% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\answers} +% +% The |\answers| macro closes the file, makes sure that future +% \env{exercise}s with answers cause an error, and reads in the file. +% +% \begin{macrocode} +\def\answers{% + \immediate\closeout\ex@ansfile% + \global\let\answrite\exerr@toolate% + \input{\ex@ansfilename}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{environment}{doanswer} +% +% A very simple environment. We set the exercise number in bold and then +% just write the text. +% +% \begin{macrocode} +\def\doanswer#1{% + \exfix% + \trivlist\advance\itemindent\labelsep% + \item[\textbf{#1}]% +} +\let\enddoanswer\endtrivlist +% \end{macrocode} +% \end{environment} +% +% \subsection{Lists inside paragraphs} +% +% \begin{environment}{parlist} +% +% The \env{parlist} environment is a trimmed-down version of a normal list. +% We todge the |\item| command, make |\list| and |\trivlist| make errors, and +% do various normal list things. +% +% \begin{macrocode} +\def\parlist#1#2{% + \let\@trivlist\exerr@parlist% + \def\@itemlabel{#1}% + \let\makelabel\relax% + \@nmbrlistfalse% + #2% + \let\item\pl@item% + \ignorespaces% +} +% \end{macrocode} +% \end{environment} +% +% \begin{macro}{\pl@item} +% +% This is the implementation of |\item| within a \env{parlist}. The main +% interesting point is the game with boxes, which has the objective of +% extracting the text of the item, together with any style changes set by +% |\makelabel|, but without any stupid bits of glue, or |\llap| or anything +% like that. +% +% \begin{macrocode} +\def\pl@item{\@ifnextchar[\pl@item@i{\pl@item@i[\@itemlabel]}} +\def\pl@item@i[#1]{% + \if@nmbrlist\refstepcounter{\@listctr}\fi% + \setbox\z@\hbox{\makelabel{\global\setbox\@ne\hbox{#1}}}% + \ifvmode\leavevmode\else\unskip\hskip1em\fi\box\@ne~\ignorespaces% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\useparlist} +% +% We just set the \env{list} environment to use \env{parlist}. +% +% \begin{macrocode} +\def\useparlist{\let\list\parlist\let\endlist\relax} +% \end{macrocode} +% \end{macro} +% +% \begin{environment}{parenum} +% +% Very simple, this. Note that we don't run |\endenumerate|, because that's +% |\let| to |\endlist|. +% +% \begin{macrocode} +\def\parenum{\useparlist\enumerate} +\let\endparenum\endparlist +% \end{macrocode} +% \end{environment} +% +% \subsection{Errors} +% +% \begin{macrocode} +\def\exerr@toolate{% + \PackageError{exercise}{Too late now for \string\answrite}{% + You can't write answers after you've read the file in. I've^^J% + ignored the text you attempted to write. This is why answers^^J% + go at the end of a book!% + }% +} +\def\exerr@parlist{% + \PackageError{exercise}{You can't nest a `list' inside a `parlist'.}{% + I've found a `list' or `trivlist' environment nested inside^^J% + a `parlist'. This isn't allowed.% + }% +} +% +% \end{macrocode} +% +% Done. +% +% \hfill Mark Wooding, \today +% +% \Finale +% +\endinput diff --git a/footnote.dtx b/footnote.dtx new file mode 100644 index 0000000..07dac84 --- /dev/null +++ b/footnote.dtx @@ -0,0 +1,702 @@ +% \begin{meta-comment} +% +% $Id: footnote.dtx,v 1.1 2002/02/03 20:49:03 mdw Exp $ +% +% Save footnotes around boxing environments and things +% +% (c) 1996 Mark Wooding +% +%----- Revision history ----------------------------------------------------- +% +% $Log: footnote.dtx,v $ +% Revision 1.1 2002/02/03 20:49:03 mdw +% Checkin for new build system. +% +% Revision 1.13 1997/01/28 19:45:16 mdw +% Fixed stupid bug in AMS environment handling which stops the thing from +% working properly if you haven't included amsmath. Doh. +% +% Revision 1.12 1997/01/18 00:45:37 mdw +% Fix problems with duplicated footnotes in broken AMS environments which +% typeset things multiple times. This is a nasty kludge. +% +% Revision 1.11 1996/11/19 20:50:05 mdw +% Entered into RCS +% +% +% \end{meta-comment} +% +% \begin{meta-comment} +%% +%% footnote package -- Save footnotes around boxing environments +%% Copyright (c) 1996 Mark Wooding +%<*package> +%% +%% 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>\NeedsTeXFormat{LaTeX2e} +%<+package>\ProvidesPackage{footnote} +%<+package> [1997/01/28 1.13 Save footnotes around boxes] +% \end{meta-comment} +% +% \CheckSum{327} +%\iffalse +%<*package> +%\fi +%% \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 \~} +%% +%\iffalse +% +%\fi +% +% \begin{meta-comment} +% +%<*driver> +\input{mdwtools} +\describespackage{footnote} +\mdwdoc +% +% +% \end{meta-comment} +% +% \section{User guide} +% +% This package provides some commands for handling footnotes slightly +% better than \LaTeX\ usually does; there are several commands and +% environments (notably |\parbox|, \env{minipage} and \env{tabular} +% \begin{footnote} +% The \package{mdwtab} package, provided in this distribution, handles +% footnotes correctly anyway; it uses an internal version of this package +% to do so. +% \end{footnote}) +% which `trap' footnotes so that they can't escape and appear at the bottom +% of the page. +% +% \DescribeEnv{savenotes} +% The \env{savenotes} environment saves up any footnotes encountered within +% it, and performs them all at the end. +% +% \DescribeMacro{\savenotes} +% \DescribeMacro{\spewnotes} +% If you're defining a command or environment, you can use the |\savenotes| +% command to start saving up footnotes, and the |\spewnotes| command to +% execute them all at the end. Note that |\savenotes| and |\spewnotes| +% enclose a group, so watch out. You can safely nest the commands and +% environments -- they work out if they're already working and behave +% appropriately. +% +% \DescribeEnv{minipage*} +% To help things along a bit, the package provides a $*$-version of the +% \env{minipage} environment, which doesn't trap footnotes for itself (and +% in fact sends any footnotes it contains to the bottom of the page, where +% they belong). +% +% \DescribeMacro{\makesavenoteenv} +% The new \env{minipage$*$} environment was created with a magic command +% called |\makesavenoteenv|. It has a fairly simple syntax: +% +% \begin{grammar} +% ::= \[[ +% "\\makesavenoteenv" +% \begin{stack} \\ "[" "]" \end{stack} +% "{" "}" +% \]] +% \end{grammar} +% +% Without the optional argument, it redefines the named environment so that +% it handles footnotes correctly. With the optional argument, it makes +% the new environment named by \ into a footnote-friendly +% version of the \ environment. +% +% \DescribeMacro{\parbox} +% The package also redefines the |\parbox| command so that it works properly +% with footnotes. +% +% \DescribeEnv{footnote} +% The other problem which people tend to experience with footnotes is that +% you can't put verbatim text (with the |\verb| comamnd or the \env{verbatim} +% environment) into the |\footnote| command's argument. This package +% provides a \env{footnote} \emph{environment}, which \emph{does} allow +% verbatim things. You use the environment just like you do the command. +% It's really easy. It even has an optional argument, which works the same +% way. +% +% \DescribeEnv{footnotetext} +% To go with the \env{footnote} environment, there's a \env{footnotetext} +% environment, which just puts the text in the bottom of the page, like +% |\footnotetext| does. +% +% There's a snag with these environments, though. Some other nonstandard +% environments, like \env{tabularx}, try to handle footnotes their own +% way, because they won't work otherwise. The way they do this is not +% compatible with the way that the \env{footnote} and \env{footnotetext} +% environments work, and you will get strange results if you try (there'll +% be odd vertical spacing, and the footnote text may well be incorrect). +% \begin{footnote} +% The solution to this problem is to send mail to David Carlisle persuading +% him to use this package to handle footnotes, rather than doing it his +% way. +% \end{footnote} +% +% \implementation +% +% \section{Implementation} +% +% Most implementations of footnote-saving (in particular, that used in +% the \package{tabularx} and \package{longtable} packages) use a token +% list register to store the footnote text, and then expand it when whatever +% was preventing footnotes (usually a vbox) stops. This is no good at all +% if the footnotes contain things which might not be there by the time the +% expansion occurs. For example, references to things in temporary boxes +% won't work. +% +% This implementation therefore stores the footnotes up in a box register. +% This must be just as valid as using tokens, because all I'm going to do +% at the end is unbox the box). +% +% \begin{macrocode} +%<*macro|package> +\ifx\fn@notes\@@undefined% + \newbox\fn@notes% +\fi +% \end{macrocode} +% +% I'll need a length to tell me how wide the footnotes should be at the +% moment. +% +% \begin{macrocode} +\newdimen\fn@width +% \end{macrocode} +% +% Of course, I can't set this up until I actually start saving footnotes. +% Until then I'll use |\columnwidth| (which works in \package{multicol} +% even though it doesn't have any right to). +% +% \begin{macrocode} +\let\fn@colwidth\columnwidth +% \end{macrocode} +% +% And now a switch to remember if we're already handling footnotes, +% +% \begin{macrocode} +\newif\if@savingnotes +% \end{macrocode} +% +% +% \subsection{Building footnote text} +% +% I need to emulate \LaTeX's footnote handling when I'm putting the notes +% into my box; this is also useful in the verbatim-in-footnotes stuff. +% +% \begin{macro}{\fn@startnote} +% +% Here's how a footnote gets started. Most of the code here is stolen +% from |\@footnotetext|. +% +% \begin{macrocode} +\def\fn@startnote{% + \hsize\fn@colwidth% + \interlinepenalty\interfootnotelinepenalty% + \reset@font\footnotesize% + \floatingpenalty\@MM% Is this right??? + \@parboxrestore% + \protected@edef\@currentlabel{\csname p@\@mpfn\endcsname\@thefnmark}% + \color@begingroup% +} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\fn@endnote} +% +% Footnotes are finished off by this macro. This is the easy bit. +% +% \begin{macrocode} +\let\fn@endnote\color@endgroup +% \end{macrocode} +% +% \end{macro} +% +% +% \subsection{Footnote saving} +% +% \begin{macro}{\fn@fntext} +% +% Now to define how to actually do footnotes. I'll just add the notes to +% the bottom of the footnote box I'm building. +% +% There's some hacking added here to handle the case that a footnote is +% in an |\intertext| command within a broken \package{amsmath} alignment +% environment -- otherwise the footnotes get duplicated due to the way that +% that package measures equations. +% \begin{footnote} +% The correct solution of course is to +% implement aligning environments in a sensible way, by building the table +% and leaving penalties describing the intended format, and then pick that +% apart in a postprocessing phase. If I get the time, I'll start working +% on this again. I have a design worked out and the beginnings of an +% implementation, but it's going to be a long time coming. +% \end{footnote} +% +% \begin{macrocode} +\def\fn@fntext#1{% + \ifx\ifmeasuring@\@@undefined% + \expandafter\@secondoftwo\else\expandafter\@iden% + \fi% + {\ifmeasuring@\expandafter\@gobble\else\expandafter\@iden\fi}% + {% + \global\setbox\fn@notes\vbox{% + \unvbox\fn@notes% + \fn@startnote% + \@makefntext{% + \rule\z@\footnotesep% + \ignorespaces% + #1% + \@finalstrut\strutbox% + }% + \fn@endnote% + }% + }% +} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\savenotes} +% +% The |\savenotes| declaration starts saving footnotes, to be spewed at a +% later date. We'll also remember which counter we're meant to use, and +% redefine the footnotes used by minipages. +% +% The idea here is that we'll gather up footnotes within the environment, +% and output them in whatever format they were being typeset outside the +% environment. +% +% I'll take this a bit at a time. The start is easy: we need a group in +% which to keep our local definitions. +% +% \begin{macrocode} +\def\savenotes{% + \begingroup% +% \end{macrocode} +% +% Now, if I'm already saving footnotes away, I won't bother doing anything +% here. Otherwise I need to start hacking, and set the switch. +% +% \begin{macrocode} + \if@savingnotes\else% + \@savingnotestrue% +% \end{macrocode} +% +% I redefine the |\@footnotetext| command, which is responsible for adding +% a footnote to the appropriate insert. I'll redefine both the current +% version, and \env{minipage}'s specific version, in case there's a nested +% minipage. +% +% \begin{macrocode} + \let\@footnotetext\fn@fntext% + \let\@mpfootnotetext\fn@fntext% +% \end{macrocode} +% +% I'd better make sure my box is empty before I start, and I must set up +% the column width so that later changes (e.g., in \env{minipage}) don't +% upset things too much. +% +% \begin{macrocode} + \fn@width\columnwidth% + \let\fn@colwidth\fn@width% + \global\setbox\fn@notes\box\voidb@x% +% \end{macrocode} +% +% Now for some yuckiness. I want to ensure that \env{minipage} doesn't +% change how footnotes are handled once I've taken charge. I'll store the +% current values of |\thempfn| (which typesets a footnote marker) and +% |\@mpfn| (which contains the name of the current footnote counter). +% +% \begin{macrocode} + \let\fn@thempfn\thempfn% + \let\fn@mpfn\@mpfn% +% \end{macrocode} +% +% The \env{minipage} environment provides a hook, called |\@minipagerestore|. +% Initially it's set to |\relax|, which is unfortunately unexpandable, so if +% I want to add code to it, I must check this possibility. I'll make it +% |\@empty| (which expands to nothing) if it's still |\relax|. Then I'll +% add my code to the hook, to override |\thempfn| and |\@mpfn| set up by +% \env{minipage}. +% +% Note that I can't just force the |mpfootnote| counter to be equal to +% the |footnote| one, because \env{minipage} clears |\c@mpfootnote| to zero +% when it starts. This method will ensure that even so, the current counter +% works OK. +% +% \begin{macrocode} + \ifx\@minipagerestore\relax\let\@minipagerestore\@empty\fi% + \expandafter\def\expandafter\@minipagerestore\expandafter{% + \@minipagerestore% + \let\thempfn\fn@thempfn% + \let\@mpfn\fn@mpfn% + }% + \fi% +} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\spewnotes} +% +% Now I can spew out the notes we saved. This is a bit messy, actually. +% Since the standard |\@footnotetext| implementation tries to insert funny +% struts and things, I must be a bit careful. I'll disable all this bits +% which start paragraphs prematurely. +% +% \begin{macrocode} +\def\spewnotes{% + \endgroup% + \if@savingnotes\else\ifvoid\fn@notes\else\begingroup% + \let\@makefntext\@empty% + \let\@finalstrut\@gobble% + \let\rule\@gobbletwo% + \@footnotetext{\unvbox\fn@notes}% + \endgroup\fi\fi% +} +% \end{macrocode} +% +% \end{macro} +% +% Now make an environment, for users. +% +% \begin{macrocode} +\let\endsavenotes\spewnotes +% \end{macrocode} +% +% That's all that needs to be in the shared code section. +% +% \begin{macrocode} +% +%<*package> +% \end{macrocode} +% +% +% \subsection{The \env{footnote} environment} +% +% Since |\footnote| is a command with an argument, things like \env{verbatim} +% are unwelcome in it. Every so often someone on |comp.text.tex| moans +% about it and I post a nasty hack to make it work. However, as a more +% permanent and `official' solution, here's an environment which does the +% job rather better. Lots of this is based on code from my latest attempt +% on the newsgroup. +% +% I'll work on this in a funny order, although I think it's easier to +% understand. First, I'll do some macros for reading the optional argument +% of footnote-related commands. +% +% \begin{macro}{\fn@getmark} +% +% Saying \syntax{"\\fn@getmark{""}{""}"} will read +% an optional argument giving a value for the footnote counter; if the +% argument isn't there, the \ is executed, and it's expected +% to set up the appropriate counter to the current value. The footnote +% marker text is stored in the macro |\@thefnmark|, as is conventional for +% \LaTeX's footnote handling macros. Once this is done properly, the +% \ is called to continue handling things. +% +% Since the handling of the optional argument plays with the footnote +% counter locally, I'll start a group right now to save some code. Then I'll +% decide what to do based on the presence of the argument. +% +% \begin{macrocode} +\def\fn@getmark#1#2{% + \begingroup% + \@ifnextchar[% + {\fn@getmark@i{#1}}% + {#1\fn@getmark@ii{#2}}% +} +% \end{macrocode} +% +% There's an optional argument, so I need to read it and assign it to the +% footnote counter. +% +% \begin{macrocode} +\def\fn@getmark@i#1[#2]{% + \csname c@\@mpfn\endcsname#2% + \fn@getmark@ii% +} +% \end{macrocode} +% +% Finally, set up the macro properly, and end the group. +% +% \begin{macrocode} +\def\fn@getmark@ii#1{% + \unrestored@protected@xdef\@thefnmark{\thempfn}% + \endgroup% + #1% +} +% \end{macrocode} +% +% \end{macro} +% +% From argument reading, I'll move on to footnote typesetting. +% +% \begin{macro}{\fn@startfntext} +% +% The |\fn@startfntext| macro sets everything up for building the footnote +% in a box register, ready for unboxing into the footnotes insert. The +% |\fn@prefntext| macro is a style hook I'll set up later. +% +% \begin{macrocode} +\def\fn@startfntext{% + \setbox\z@\vbox\bgroup% + \fn@startnote% + \fn@prefntext% + \rule\z@\footnotesep% + \ignorespaces% +} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\fn@endfntext} +% +% Now I'll end the vbox, and add it to the footnote insertion. Again, I +% must be careful to prevent |\@footnotetext| from adding horizontal mode +% things in bad places. +% +% \begin{macrocode} +\def\fn@endfntext{% + \@finalstrut\strutbox% + \fn@postfntext% + \egroup% + \begingroup% + \let\@makefntext\@empty% + \let\@finalstrut\@gobble% + \let\rule\@gobbletwo% + \@footnotetext{\unvbox\z@}% + \endgroup% +} +% \end{macrocode} +% +% \end{macro} +% +% \begin{environment}{footnote} +% +% I can now start on the environment proper. First I'll look for an +% optional argument. +% +% \begin{listing} +%\def\footnote{% +% \end{listing} +% +% Oh. I've already come up against the first problem: that name's already +% used. I'd better save the original version. +% +% \begin{macrocode} +\let\fn@latex@@footnote\footnote +% \end{macrocode} +% +% The best way I can think of for seeing if I'm in an environment is to +% look at |\@currenvir|. I'll need something to compare with, then. +% +% \begin{macrocode} +\def\fn@footnote{footnote} +% \end{macrocode} +% +% Now to start properly. |;-)| +% +% \begin{macrocode} +\def\footnote{% + \ifx\@currenvir\fn@footnote% + \expandafter\@firstoftwo% + \else% + \expandafter\@secondoftwo% + \fi% + {\fn@getmark{\stepcounter\@mpfn}% + {\leavevmode\unskip\@footnotemark\fn@startfntext}}% + {\fn@latex@@footnote}% +} +% \end{macrocode} +% +% Ending the environment is simple. +% +% \begin{macrocode} +\let\endfootnote\fn@endfntext +% \end{macrocode} +% +% \end{environment} +% +% \begin{environment}{footnotetext} +% +% I'll do the same magic as before for |\footnotetext|. +% +% \begin{macrocode} +\def\fn@footnotetext{footnotetext} +\let\fn@latex@@footnotetext\footnotetext +\def\footnotetext{% + \ifx\@currenvir\fn@footnotetext% + \expandafter\@firstoftwo% + \else% + \expandafter\@secondoftwo% + \fi% + {\fn@getmark{}\fn@startfntext}% + {\fn@latex@@footnotetext}% +} +\let\endfootnotetext\endfootnote +% \end{macrocode} +% +% \end{environment} +% +% \begin{macro}{\fn@prefntext} +% \begin{macro}{\fn@postfntext} +% +% Now for one final problem. The style hook for footnotes is the command +% |\@makefntext|, which takes the footnote text as its argument. Clearly +% this is utterly unsuitable, so I need to split it into two bits, where +% the argument is. This is very tricky, and doesn't deserve to work, +% although it appears to be a good deal more effective than it has any right +% to be. +% +% \begin{macrocode} +\long\def\@tempa#1\@@#2\@@@{\def\fn@prefntext{#1}\def\fn@postfntext{#2}} +\expandafter\@tempa\@makefntext\@@\@@@ +% \end{macrocode} +% +% \end{macro} +% \end{macro} +% +% +% \subsection{Hacking existing environments} +% +% Some existing \LaTeX\ environments ought to have footnote handling but +% don't. Now's our chance. +% +% \begin{macro}{\makesavenoteenv} +% +% The |\makesavenoteenv| command makes an environment save footnotes around +% itself. +% +% It would also be nice to make |\parbox| work with footnotes. I'll do this +% later. +% +% \begin{macrocode} +\def\makesavenoteenv{\@ifnextchar[\fn@msne@ii\fn@msne@i} +% \end{macrocode} +% +% We're meant to redefine the environment. We'll copy it (using |\let|) to +% a magic name, and then pass it on to stage~2. +% +% \begin{macrocode} +\def\fn@msne@i#1{% + \expandafter\let\csname msne$#1\expandafter\endcsname% + \csname #1\endcsname% + \expandafter\let\csname endmsne$#1\expandafter\endcsname% + \csname end#1\endcsname% + \fn@msne@ii[#1]{msne$#1}% +} +% \end{macrocode} +% +% Now we'll define the new environment. The start is really easy, since we +% just need to insert a |\savenotes|. The end is more complex, since we +% need to preserve the |\if@endpe| flag so that |\end| can pick it up. I +% reckon that proper hooks should be added to |\begin| and |\end| so that +% environments can define things to be done outside the main group as +% well as within it; still, we can't all have what we want, can we? +% +% \begin{macrocode} +\def\fn@msne@ii[#1]#2{% + \expandafter\edef\csname#1\endcsname{% + \noexpand\savenotes% + \expandafter\noexpand\csname#2\endcsname% + }% + \expandafter\edef\csname end#1\endcsname{% + \expandafter\noexpand\csname end#2\endcsname% + \noexpand\expandafter% + \noexpand\spewnotes% + \noexpand\if@endpe\noexpand\@endpetrue\noexpand\fi% + }% +} +% \end{macrocode} +% +% \end{macro} +% +% \begin{environment}{minipage*} +% +% Let's define a \env{minipage$*$} environment which handles footnotes +% nicely. Really easy: +% +% \begin{macrocode} +\makesavenoteenv[minipage*]{minipage} +% \end{macrocode} +% +% \end{environment} +% +% \begin{macro}{\parbox} +% +% Now to alter |\parbox| slightly, so that it handles footnotes properly. +% I'm going to do this fairly inefficiently, because I'm going to try and +% change it as little as possible. +% +% First, I'll save the old |\parbox| command. If I don't find a \lit{*}, +% I'll just call this command. +% +% \begin{macrocode} +\let\fn@parbox\parbox +% \end{macrocode} +% +% This is the clever bit: I don't know how many optional arguments +% Mr~Mittelbach and his chums will add to |\parbox|, so I'll handle any +% number. I'll store them all up in my first argument and call myself +% every time I find a new one. If I run out of optional arguments, +% I'll call the original |\parbox| command, surrounding it with |\savenotes| +% and |\spewnotes|. +% +% \begin{macrocode} +\def\parbox{\@ifnextchar[{\fn@parbox@i{}}{\fn@parbox@ii{}}} +\def\fn@parbox@i#1[#2]{% + \@ifnextchar[{\fn@parbox@i{#1[#2]}}{\fn@parbox@ii{#1[#2]}}% +} +\long\def\fn@parbox@ii#1#2#3{\savenotes\fn@parbox#1{#2}{#3}\spewnotes} +% \end{macrocode} +% +% \end{macro} +% +% Done! +% +% \begin{macrocode} +% +% \end{macrocode} +% +% \hfill Mark Wooding, \today +% +% \Finale +% +\endinput diff --git a/mdwlist.dtx b/mdwlist.dtx new file mode 100644 index 0000000..f93ef07 --- /dev/null +++ b/mdwlist.dtx @@ -0,0 +1,759 @@ +% \begin{meta-comment} +% +% $Id: mdwlist.dtx,v 1.1 2002/02/03 20:49:03 mdw Exp $ +% +% Various list-related things +% +% (c) 1996 Mark Wooding +% +%----- Revision history ----------------------------------------------------- +% +% $Log: mdwlist.dtx,v $ +% Revision 1.1 2002/02/03 20:49:03 mdw +% Checkin for new build system. +% +% Revision 1.1 1996/11/19 20:52:26 mdw +% Initial revision +% +% +% \end{meta-comment} +% +% \begin{meta-comment} +%% +%% mdwlist package -- various list-related things +%% 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>\NeedsTeXFormat{LaTeX2e} +%<+package>\ProvidesPackage{mdwlist} +%<+package> [1996/05/02 1.1 Various list-related things] +% \end{meta-comment} +% +% \CheckSum{179} +%% \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> +\input{mdwtools} +\describespackage{mdwlist} +\def\defaultdesc{% + \desclabelwidth{80pt}% + \desclabelstyle\nextlinelabel% + \def\makelabel{\bfseries}% +} +\newenvironment{cmdlist} + {\basedescript{\let\makelabel\cmd}} + {\endbasedescript} +\mdwdoc +% +% +% \end{meta-comment} +% +% \section{User guide} +% +% This package provides some vaguely useful list-related commands and +% environments: +% \begin{itemize*} +% \item A way of building \env{description}-like environments. +% \item Commands for making `compacted' versions of list environments +% \item A method for suspending and resuming enumerated lists. +% \end{itemize*} +% +% \subsection{Description list handling} +% +% Different sorts of description-type lists require different sorts of +% formatting: I think that's fairly obvious. There are essentially three +% different attributes which should be changable: +% \begin{itemize*} +% \item the indentation of the items being described, +% \item the handling of labels which don't fit properly, and +% \item the style used to typeset the label text. +% \end{itemize*} +% The first two items should usually be decided for all description-like +% lists in the document, to ensure consistency of appearance. The last +% depends much more on the content of the labels. +% +% \DescribeEnv{basedescript} +% The \env{basedescript} environment acts as a `skeleton' for description +% environments. It takes one argument, which contains declarations to +% be performed while constructing the list. I'd consider it unusual for +% the \env{basedescript} environment to be used in the main text: it's +% intended to be used to build other environments. +% +% The declarations which can be used to define description-type environments +% include all of those which are allowed when setting up a list (see the +% \LaTeX\ book for information here). Some others, which apply specifically +% to description lists, are also provided: +% +% \begin{itemize} +% +% \item \DescribeMacro{\desclabelwidth} +% The \syntax{"\\desclabelwidth{""}"} declaration sets labels +% to be left-aligned, with a standard width of \; the item +% text is indented by \ plus the value of |\labelsep|. +% +% \item \DescribeMacro{\desclabelstyle} +% The label style determines how overlong labels are typeset. A style +% may be set using the \syntax{"\\desclabelstyle{"