From 86f6a31e4b41acb71ba37f3838a9ce75f7743330 Mon Sep 17 00:00:00 2001 From: mdw Date: Sun, 3 Feb 2002 20:49:03 +0000 Subject: [PATCH] Checkin for new build system. --- .cvsignore | 21 + .links | 5 + .skelrc | 9 + Makefile.m4 | 92 + at.dtx | 753 ++++++++ cmtt.dtx | 523 ++++++ configure.in | 57 + crypto.dtx | 461 +++++ doafter.dtx | 519 ++++++ doafter.tex | 113 ++ exercise.dtx | 555 ++++++ footnote.dtx | 702 ++++++++ mdwlist.dtx | 759 ++++++++ mdwmath.dtx | 1224 +++++++++++++ mdwtab.dtx | 5525 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ mdwthm.dtx | 303 ++++ mdwtools.ins | 87 + mdwtools.tex | 1215 +++++++++++++ poetry.dtx | 1242 +++++++++++++ sverb.dtx | 1189 +++++++++++++ syntax.dtx | 2940 +++++++++++++++++++++++++++++++ 21 files changed, 18294 insertions(+) create mode 100644 .cvsignore create mode 100644 .links create mode 100644 .skelrc create mode 100644 Makefile.m4 create mode 100644 at.dtx create mode 100644 cmtt.dtx create mode 100644 configure.in create mode 100644 crypto.dtx create mode 100644 doafter.dtx create mode 100644 doafter.tex create mode 100644 exercise.dtx create mode 100644 footnote.dtx create mode 100644 mdwlist.dtx create mode 100644 mdwmath.dtx create mode 100644 mdwtab.dtx create mode 100644 mdwthm.dtx create mode 100644 mdwtools.ins create mode 100644 mdwtools.tex create mode 100644 poetry.dtx create mode 100644 sverb.dtx create mode 100644 syntax.dtx 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{"