summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/doc/latex/mdwtools/mdwtools.tex
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/doc/latex/mdwtools/mdwtools.tex')
-rw-r--r--Master/texmf-dist/doc/latex/mdwtools/mdwtools.tex1212
1 files changed, 1212 insertions, 0 deletions
diff --git a/Master/texmf-dist/doc/latex/mdwtools/mdwtools.tex b/Master/texmf-dist/doc/latex/mdwtools/mdwtools.tex
new file mode 100644
index 00000000000..63abfc4acf4
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/mdwtools/mdwtools.tex
@@ -0,0 +1,1212 @@
+% \begin{meta-comment}
+%
+% $Id: mdwtools.tex,v 1.4 1996/11/19 20:55:55 mdw Exp $
+%
+% Common declarations for mdwtools.dtx files
+%
+% (c) 1996 Mark Wooding
+%
+%----- Revision history -----------------------------------------------------
+%
+% $Log: mdwtools.tex,v $
+% Revision 1.4 1996/11/19 20:55:55 mdw
+% Entered into RCS
+%
+%
+% \end{meta-comment}
+%
+% \begin{meta-comment} <general public licence>
+%%
+%% mdwtools common declarations
+%% 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} <file preamble>
+%<*mdwtools>
+\ProvidesFile{mdwtools.tex}
+ [1996/05/10 1.4 Shared definitions for mdwtools .dtx files]
+%</mdwtools>
+% \end{meta-comment}
+%
+% \CheckSum{668}
+%% \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 \~}
+%%
+%
+% \section{Introduction and user guide}
+%
+% This file is really rather strange; it gets |\input| by other package
+% documentation files to set up most of the environmental gubbins for them.
+% It handles almost everything, like loading a document class, finding any
+% packages, and building and formatting the title.
+%
+% It also offers an opportunity for users to customise my nice documentation,
+% by using a |mdwtools.cfg| file (not included).
+%
+%
+% \subsection{Declarations}
+%
+% A typical documentation file contains something like
+% \begin{listinglist} \listingsize \obeylines
+% |\input{mdwtools}|
+% \<declarations>
+% |\mdwdoc|
+% \end{listinglist}
+% The initial |\input| reads in this file and sets up the various commands
+% which may be needed. The final |\mdwdoc| actually starts the document,
+% inserting a title (which is automatically generated), a table of
+% contents etc., and reads the documentation file in (using the |\DocInput|
+% command from the \package{doc} package.
+%
+% \subsubsection{Describing packages}
+%
+% \DescribeMacro{\describespackage}
+% \DescribeMacro{\describesclass}
+% \DescribeMacro{\describesfile}
+% \DescribeMacro{\describesfile*}
+% The most important declarations are those which declare what the
+% documentation describes. Saying \syntax{"\\describespackage{<package>}"}
+% loads the \<package> (if necessary) and adds it to the auto-generated
+% title, along with a footnote containing version information. Similarly,
+% |\describesclass| adds a document class name to the title (without loading
+% it -- the document itself must do this, with the |\documentclass| command).
+% For files which aren't packages or classes, use the |\describesfile| or
+% |\describesfile*| command (the $*$-version won't |\input| the file, which
+% is handy for files like |mdwtools.tex|, which are already input).
+%
+% \DescribeMacro{\author}
+% \DescribeMacro{\date}
+% \DescribeMacro{\title}
+% The |\author|, |\date| and |\title| declarations work slightly differently
+% to normal -- they ensure that only the \emph{first} declaration has an
+% effect. (Don't you play with |\author|, please, unless you're using this
+% program to document your own packages.) Using |\title| suppresses the
+% automatic title generation.
+%
+% \DescribeMacro{\docdate}
+% The default date is worked out from the version string of the package or
+% document class whose name is the same as that of the documentation file.
+% You can choose a different `main' file by saying
+% \syntax{"\\docdate{"<file>"}"}.
+%
+% \subsubsection{Contents handling}
+%
+% \DescribeMacro{\addcontents}
+% A documentation file always has a table of contents. Other
+% contents-like lists can be added by saying
+% \syntax{"\\addcontents{"<extension>"}{"<command>"}"}. The \<extension>
+% is the file extension of the contents file (e.g., \lit{lot} for the
+% list of tables); the \<command> is the command to actually typeset the
+% contents file (e.g., |\listoftables|).
+%
+% \subsubsection{Other declarations}
+%
+% \DescribeMacro{\implementation}
+% The \package{doc} package wants you to say
+% \syntax{"\\StopEventually{"<stuff>"}"}' before describing the package
+% implementation. Using |mdwtools.tex|, you just say |\implementation|, and
+% everything works. It will automatically read in the licence text (from
+% |gpl.tex|, and wraps some other things up.
+%
+%
+% \subsection{Other commands}
+%
+% The |mdwtools.tex| file includes the \package{syntax} and \package{sverb}
+% packages so that they can be used in documentation files. It also defines
+% some trivial commands of its own.
+%
+% \DescribeMacro{\<}
+% Saying \syntax{"\\<"<text>">" is the same as "\\synt{"<text>"}"}; this
+% is a simple abbreviation.
+%
+% \DescribeMacro{\smallf}
+% Saying \syntax{"\\smallf" <number>"/"<number>} typesets a little fraction,
+% like this: \smallf 3/4. It's useful when you want to say that the default
+% value of a length is 2 \smallf 1/2\,pt, or something like that.
+%
+%
+% \subsection{Customisation}
+%
+% You can customise the way that the package documentation looks by writing
+% a file called |mdwtools.cfg|. You can redefine various commands (before
+% they're defined here, even; |mdwtools.tex| checks most of the commands that
+% it defines to make sure they haven't been defined already.
+%
+% \DescribeMacro{\indexing}
+% If you don't want the prompt about whether to generate index files, you
+% can define the |\indexing| command to either \lit{y} or \lit{n}. I'd
+% recommend that you use |\providecommand| for this, to allow further
+% customisation from the command line.
+%
+% \DescribeMacro{\mdwdateformat}
+% If you don't like my date format (maybe you're American or something),
+% you can redefine the |\mdwdateformat| command. It takes three arguments:
+% the year, month and date, as numbers; it should expand to something which
+% typesets the date nicely. The default format gives something like
+% `10 May 1996'. You can produce something rather more exotic, like
+% `10\textsuperscript{th} May \textsc{\romannumeral 1996}' by saying
+%\begin{listing}
+%\newcommand{\mdwdateformat}[3]{%
+% \number#3\textsuperscript{\numsuffix{#3}}\ %
+% \monthname{#2}\ %
+% \textsc{\romannumeral #1}%
+%}
+%\end{listing}
+% \DescribeMacro{\monthname}
+% \DescribeMacro{\numsuffix}
+% Saying \syntax{"\\monthname{"<number>"}"} expands to the name of the
+% numbered month (which can be useful when doing date formats). Saying
+% \syntax{"\\numsuffix{"<number>"}"} will expand to the appropriate suffix
+% (`th' or `rd' or whatever) for the \<number>. You'll have to superscript
+% it yourself, if this is what you want to do. Putting the year number
+% in roman numerals is just pretentious |;-)|.
+%
+% \DescribeMacro{\mdwhook}
+% After all the declarations in |mdwtools.tex|, the command |\mdwhook| is
+% executed, if it exists. This can be set up by the configuration file
+% to do whatever you want.
+%
+% There are lots of other things you can play with; you should look at the
+% implementation section to see what's possible.
+%
+% \implementation
+%
+% \section{Implementation}
+%
+% \begin{macrocode}
+%<*mdwtools>
+% \end{macrocode}
+%
+% The first thing is that I'm not a \LaTeX\ package or anything official
+% like that, so I must enable `|@|' as a letter by hand.
+%
+% \begin{macrocode}
+\makeatletter
+% \end{macrocode}
+%
+% Now input the user's configuration file, if it exists. This is fairly
+% simple stuff.
+%
+% \begin{macrocode}
+\@input{mdwtools.cfg}
+% \end{macrocode}
+%
+% Well, that's the easy bit done.
+%
+%
+% \subsection{Initialisation}
+%
+% Obviously the first thing to do is to obtain a document class. Obviously,
+% it would be silly to do this if a document class has already been loaded,
+% either by the package documentation or by the configuration file.
+%
+% The only way I can think of for finding out if a document class is already
+% loaded is by seeing if the |\documentclass| command has been redefined
+% to raise an error. This isn't too hard, really.
+%
+% \begin{macrocode}
+\ifx\documentclass\@twoclasseserror\else
+ \documentclass[a4paper]{ltxdoc}
+ \ifx\doneclasses\mdw@undefined\else\doneclasses\fi
+\fi
+% \end{macrocode}
+%
+% As part of my standard environment, I'll load some of my more useful
+% packages. If they're already loaded (possibly with different options),
+% I'll not try to load them again.
+%
+% \begin{macrocode}
+\@ifpackageloaded{doc}{}{\usepackage{doc}}
+\@ifpackageloaded{syntax}{}{\usepackage[rounded]{syntax}}
+\@ifpackageloaded{sverb}{}{\usepackage{sverb}}
+% \end{macrocode}
+%
+%
+% \subsection{Some macros for interaction}
+%
+% I like the \LaTeX\ star-boxes, although it's a pain having to cope with
+% \TeX's space-handling rules. I'll define a new typing-out macro which
+% makes spaces more significant, and has a $*$-version which doesn't put
+% a newline on the end, and interacts prettily with |\read|.
+%
+% First of all, I need to make spaces active, so I can define things about
+% active spaces.
+%
+% \begin{macrocode}
+\begingroup\obeyspaces
+% \end{macrocode}
+%
+% Now to define the main macro. This is easy stuff. Spaces must be
+% carefully rationed here, though.
+%
+% I'll start a group, make spaces active, and make spaces expand to ordinary
+% space-like spaces. Then I'll look for a star, and pass either |\message|
+% (which doesn't start a newline, and interacts with |\read| well) or
+% |\immediate\write 16| which does a normal write well.
+%
+% \begin{macrocode}
+\gdef\mdwtype{%
+\begingroup\catcode`\ \active\let \space%
+\@ifstar{\mdwtype@i{\message}}{\mdwtype@i{\immediate\write\sixt@@n}}%
+}
+\endgroup
+% \end{macrocode}
+%
+% Now for the easy bit. I have the thing to do, and the thing to do it to,
+% so do that and end the group.
+%
+% \begin{macrocode}
+\def\mdwtype@i#1#2{#1{#2}\endgroup}
+% \end{macrocode}
+%
+%
+% \subsection{Decide on indexing}
+%
+% A configuration file can decide on indexing by defining the |\indexing|
+% macro to either \lit{y} or \lit{n}. If it's not set, then I'll prompt
+% the user.
+%
+% First of all, I want a switch to say whether I'm indexing.
+%
+% \begin{macrocode}
+\newif\ifcreateindex
+% \end{macrocode}
+%
+% Right: now I need to decide how to make progress. If the macro's not set,
+% then I want to set it, and start a row of stars.
+%
+% \begin{macrocode}
+\ifx\indexing\@@undefined
+ \mdwtype{*****************************}
+ \def\indexing{?}
+\fi
+% \end{macrocode}
+%
+% Now enter a loop, asking the user whether to do indexing, until I get
+% a sensible answer.
+%
+% \begin{macrocode}
+\loop
+ \@tempswafalse
+ \if y\indexing\@tempswatrue\createindextrue\fi
+ \if Y\indexing\@tempswatrue\createindextrue\fi
+ \if n\indexing\@tempswatrue\createindexfalse\fi
+ \if N\indexing\@tempswatrue\createindexfalse\fi
+ \if@tempswa\else
+ \mdwtype*{* Create index files? (y/n) *}
+ \read\sixt@@n to\indexing%
+\repeat
+% \end{macrocode}
+%
+% Now, based on the results of that, display a message about the indexing.
+%
+% \begin{macrocode}
+\mdwtype{*****************************}
+\ifcreateindex
+ \mdwtype{* Creating index files *}
+ \mdwtype{* This may take some time *}
+\else
+ \mdwtype{* Not creating index files *}
+\fi
+\mdwtype{*****************************}
+% \end{macrocode}
+%
+% Now I can play with the indexing commands of the \package{doc} package
+% to do whatever it is that the user wants.
+%
+% \begin{macrocode}
+\ifcreateindex
+ \CodelineIndex
+ \EnableCrossrefs
+\else
+ \CodelineNumbered
+ \DisableCrossrefs
+\fi
+% \end{macrocode}
+%
+% And register lots of plain \TeX\ things which shouldn't be indexed.
+% This contains lots of |\if|\dots\ things which don't fit nicely in
+% conditionals, which is a shame. Still, it doesn't matter that much,
+% really.
+%
+% \begin{macrocode}
+\DoNotIndex{\def,\long,\edef,\xdef,\gdef,\let,\global}
+\DoNotIndex{\if,\ifnum,\ifdim,\ifcat,\ifmmode,\ifvmode,\ifhmode,%
+ \iftrue,\iffalse,\ifvoid,\ifx,\ifeof,\ifcase,\else,\or,\fi}
+\DoNotIndex{\box,\copy,\setbox,\unvbox,\unhbox,\hbox,%
+ \vbox,\vtop,\vcenter}
+\DoNotIndex{\@empty,\immediate,\write}
+\DoNotIndex{\egroup,\bgroup,\expandafter,\begingroup,\endgroup}
+\DoNotIndex{\divide,\advance,\multiply,\count,\dimen}
+\DoNotIndex{\relax,\space,\string}
+\DoNotIndex{\csname,\endcsname,\@spaces,\openin,\openout,%
+ \closein,\closeout}
+\DoNotIndex{\catcode,\endinput}
+\DoNotIndex{\jobname,\message,\read,\the,\m@ne,\noexpand}
+\DoNotIndex{\hsize,\vsize,\hskip,\vskip,\kern,\hfil,\hfill,\hss}
+\DoNotIndex{\m@ne,\z@,\z@skip,\@ne,\tw@,\p@}
+\DoNotIndex{\dp,\wd,\ht,\vss,\unskip}
+% \end{macrocode}
+%
+% Last bit of indexing stuff, for now: I'll typeset the index in two columns
+% (the default is three, which makes them too narrow for my tastes).
+%
+% \begin{macrocode}
+\setcounter{IndexColumns}{2}
+% \end{macrocode}
+%
+%
+% \subsection{Selectively defining things}
+%
+% I don't want to tread on anyone's toes if they redefine any of these
+% commands and things in a configuration file. The following definitions
+% are fairly evil, but should do the job OK.
+%
+% \begin{macro}{\@gobbledef}
+%
+% This macro eats the following |\def|inition, leaving not a trace behind.
+%
+% \begin{macrocode}
+\def\@gobbledef#1#{\@gobble}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\tdef}
+% \begin{macro}{\tlet}
+%
+% The |\tdef| command is a sort of `tentative' definition -- it's like
+% |\def| if the control sequence named doesn't already have a definition.
+% |\tlet| does the same thing with |\let|.
+%
+% \begin{macrocode}
+\def\tdef#1{
+ \ifx#1\@@undefined%
+ \expandafter\def\expandafter#1%
+ \else%
+ \expandafter\@gobbledef%
+ \fi%
+}
+\def\tlet#1#2{\ifx#1\@@undefined\let#1=#2\fi}
+% \end{macrocode}
+%
+% \end{macro}
+% \end{macro}
+%
+%
+% \subsection{General markup things}
+%
+% Now for some really simple things. I'll define how to typeset package
+% names and environment names (both in the sans serif font, for now).
+%
+% \begin{macrocode}
+\tlet\package\textsf
+\tlet\env\textsf
+% \end{macrocode}
+%
+% I'll define the |\<|\dots|>| shortcut for syntax items suggested in the
+% \package{syntax} package.
+%
+% \begin{macrocode}
+\tdef\<#1>{\synt{#1}}
+% \end{macrocode}
+%
+% And because it's used in a few places (mainly for typesetting lengths),
+% here's a command for typesetting fractions in text.
+%
+% \begin{macrocode}
+\tdef\smallf#1/#2{\ensuremath{^{#1}\!/\!_{#2}}}
+% \end{macrocode}
+%
+%
+% \subsection{A table environment}
+%
+% \begin{environment}{tab}
+%
+% Most of the packages don't use the (obviously perfect) \package{mdwtab}
+% package, because it's big, and takes a while to load. Here's an
+% environment for typesetting centred tables. The first (optional) argument
+% is some declarations to perform. The mandatory argument is the table
+% preamble (obviously).
+%
+% \begin{macrocode}
+\@ifundefined{tab}{%
+ \newenvironment{tab}[2][\relax]{%
+ \par\vskip2ex%
+ \centering%
+ #1%
+ \begin{tabular}{#2}%
+ }{%
+ \end{tabular}%
+ \par\vskip2ex%
+ }
+}{}
+% \end{macrocode}
+%
+% \end{environment}
+%
+%
+% \subsection{Commenting out of stuff}
+%
+% \begin{environment}{meta-comment}
+%
+% Using |\iffalse|\dots|\fi| isn't much fun. I'll define a gobbling
+% environment using the \package{sverb} stuff.
+%
+% \begin{macrocode}
+\ignoreenv{meta-comment}
+% \end{macrocode}
+%
+% \end{environment}
+%
+%
+% \subsection{Float handling}
+%
+% This gubbins will try to avoid float pages as much as possible, and (with
+% any luck) encourage floats to be put on the same pages as text.
+%
+% \begin{macrocode}
+\def\textfraction{0.1}
+\def\topfraction{0.9}
+\def\bottomfraction{0.9}
+\def\floatpagefraction{0.7}
+% \end{macrocode}
+%
+% Now redefine the default float-placement parameters to allow `here' floats.
+%
+% \begin{macrocode}
+\def\fps@figure{htbp}
+\def\fps@table{htbp}
+% \end{macrocode}
+%
+%
+% \subsection{Other bits of parameter tweaking}
+%
+% Make \env{grammar} environments look pretty, by indenting the left hand
+% sides by a large amount.
+%
+% \begin{macrocode}
+\grammarindent1in
+% \end{macrocode}
+%
+% I don't like being told by \TeX\ that my paragraphs are hard to linebreak:
+% I know this already. This lot should shut \TeX\ up about most problems.
+%
+% \begin{macrocode}
+\sloppy
+\hbadness\@M
+\hfuzz10\p@
+% \end{macrocode}
+%
+% Also make \TeX\ shut up in the index. The \package{multicol} package
+% irritatingly plays with |\hbadness|. This is the best hook I could find
+% for playing with this setting.
+%
+% \begin{macrocode}
+\expandafter\def\expandafter\IndexParms\expandafter{%
+ \IndexParms%
+ \hbadness\@M%
+}
+% \end{macrocode}
+%
+% The other thing I really don't like is `Marginpar moved' warnings. This
+% will get rid of them, and lots of other \LaTeX\ warnings at the same time.
+%
+% \begin{macrocode}
+\let\@latex@warning@no@line\@gobble
+% \end{macrocode}
+%
+% Put some extra space between table rows, please.
+%
+% \begin{macrocode}
+\def\arraystretch{1.2}
+% \end{macrocode}
+%
+% Most of the code is at guard level one, so typeset that in upright text.
+%
+% \begin{macrocode}
+\setcounter{StandardModuleDepth}{1}
+% \end{macrocode}
+%
+%
+% \subsection{Contents handling}
+%
+% I use at least one contents file (the main table of contents) although
+% I may want more. I'll keep a list of contents files which I need to
+% handle.
+%
+% There are two things I need to do to contents files here:
+% \begin{itemize}
+% \item I must typeset the table of contents at the beginning of the
+% document; and
+% \item I want to typeset tables of contents in two columns (using the
+% \package{multicol} package).
+% \end{itemize}
+%
+% The list consists of items of the form
+% \syntax{"\\do{"<extension>"}{"<command>"}"}, where \<extension> is the
+% file extension of the contents file, and \<command> is the command to
+% typeset it.
+%
+% \begin{macro}{\docontents}
+%
+% This is where I keep the list of contents files. I'll initialise it to
+% just do the standard contents table.
+%
+% \begin{macrocode}
+\def\docontents{\do{toc}{\tableofcontents}}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\addcontents}
+%
+% By saying \syntax{"\\addcontents{"<extension>"}{"<command>"}"}, a document
+% can register a new table of contents which gets given the two-column
+% treatment properly. This is really easy to implement.
+%
+% \begin{macrocode}
+\def\addcontents#1#2{%
+ \toks@\expandafter{\docontents\do{#1}{#2}}%
+ \edef\docontents{\the\toks@}%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+%
+% \subsection{Finishing it all off}
+%
+% \begin{macro}{\finalstuff}
+%
+% The |\finalstuff| macro is a hook for doing things at the end of the
+% document. Currently, it inputs the licence agreement as an appendix.
+%
+% \begin{macrocode}
+\tdef\finalstuff{\appendix\part*{Appendix}\input{gpl}}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\implementation}
+%
+% The |\implementation| macro starts typesetting the implementation of
+% the package(s). If we're not doing the implementation, it just does
+% this lot and ends the input file.
+%
+% I define a macro with arguments inside the |\StopEventually|, which causes
+% problems, since the code gets put through an extra level of |\def|fing
+% depending on whether the implementation stuff gets typeset or not. I'll
+% store the code I want to do in a separate macro.
+%
+% \begin{macrocode}
+\def\implementation{\StopEventually{\attheend}}
+% \end{macrocode}
+%
+% Now for the actual activity. First, I'll do the |\finalstuff|. Then, if
+% \package{doc}'s managed to find the \package{multicol} package, I'll add
+% the end of the environment to the end of each contents file in the list.
+% Finally, I'll read the index in from its formatted |.ind| file.
+%
+% \begin{macrocode}
+\tdef\attheend{%
+ \finalstuff%
+ \ifhave@multicol%
+ \def\do##1##2{\addtocontents{##1}{\protect\end{multicols}}}%
+ \docontents%
+ \fi%
+ \PrintIndex%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+%
+% \subsection{File version information}
+%
+% \begin{macro}{\mdwpkginfo}
+%
+% For setting up the automatic titles, I'll need to be able to work out
+% file versions and things. This macro will, given a file name, extract
+% from \LaTeX\ the version information and format it into a sensible string.
+%
+% First of all, I'll put the original string (direct from the
+% |\Provides|\dots\ command). Then I'll pass it to another macro which can
+% parse up the string into its various bits, along with the original
+% filename.
+%
+% \begin{macrocode}
+\def\mdwpkginfo#1{%
+ \edef\@tempa{\csname ver@#1\endcsname}%
+ \expandafter\mdwpkginfo@i\@tempa\@@#1\@@%
+}
+% \end{macrocode}
+%
+% Now for the real business. I'll store the string I build in macros called
+% \syntax{"\\"<filename>"date", "\\"<filename>"version" and
+% "\\"<filename>"info"}, which store the file's date, version and
+% `information string' respectively. (Note that the file extension isn't
+% included in the name.)
+%
+% This is mainly just tedious playing with |\expandafter|. The date format
+% is defined by a separate macro, which can be modified from the
+% configuration file.
+%
+% \begin{macrocode}
+\def\mdwpkginfo@i#1/#2/#3 #4 #5\@@#6.#7\@@{%
+ \expandafter\def\csname #6date\endcsname%
+ {\protect\mdwdateformat{#1}{#2}{#3}}%
+ \expandafter\def\csname #6version\endcsname{#4}%
+ \expandafter\def\csname #6info\endcsname{#5}%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\mdwdateformat}
+%
+% Given three arguments, a year, a month and a date (all numeric), build a
+% pretty date string. This is fairly simple really.
+%
+% \begin{macrocode}
+\tdef\mdwdateformat#1#2#3{\number#3\ \monthname{#2}\ \number#1}
+\def\monthname#1{%
+ \ifcase#1\or%
+ January\or February\or March\or April\or May\or June\or%
+ July\or August\or September\or October\or November\or December%
+ \fi%
+}
+\def\numsuffix#1{%
+ \ifnum#1=1 st\else%
+ \ifnum#1=2 nd\else%
+ \ifnum#1=3 rd\else%
+ \ifnum#1=21 st\else%
+ \ifnum#1=22 nd\else%
+ \ifnum#1=23 rd\else%
+ \ifnum#1=31 st\else%
+ th%
+ \fi\fi\fi\fi\fi\fi\fi%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\mdwfileinfo}
+%
+% Saying \syntax{"\\mdwfileinfo{"<file-name>"}{"<info>"}"} extracts the
+% wanted item of \<info> from the version information for file \<file-name>.
+%
+% \begin{macrocode}
+\def\mdwfileinfo#1#2{\mdwfileinfo@i{#2}#1.\@@}
+\def\mdwfileinfo@i#1#2.#3\@@{\csname#2#1\endcsname}
+% \end{macrocode}
+%
+% \end{macro}
+%
+%
+% \subsection{List handling}
+%
+% There are several other lists I need to build. These macros will do
+% the necessary stuff.
+%
+% \begin{macro}{\mdw@ifitem}
+%
+% The macro \syntax{"\\mdw@ifitem"<item>"\\in"<list>"{"<true-text>"}"^^A
+% "{"<false-text>"}"} does \<true-text> if the \<item> matches any item in
+% the \<list>; otherwise it does \<false-text>.
+%
+% \begin{macrocode}
+\def\mdw@ifitem#1\in#2{%
+ \@tempswafalse%
+ \def\@tempa{#1}%
+ \def\do##1{\def\@tempb{##1}\ifx\@tempa\@tempb\@tempswatrue\fi}%
+ #2%
+ \if@tempswa\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\mdw@append}
+%
+% Saying \syntax{"\\mdw@append"<item>"\\to"<list>} adds the given \<item>
+% to the end of the given \<list>.
+%
+% \begin{macrocode}
+\def\mdw@append#1\to#2{%
+ \toks@{\do{#1}}%
+ \toks\tw@\expandafter{#2}%
+ \edef#2{\the\toks\tw@\the\toks@}%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\mdw@prepend}
+%
+% Saying \syntax{"\\mdw@prepend"<item>"\\to"<list>} adds the \<item> to the
+% beginning of the \<list>.
+%
+% \begin{macrocode}
+\def\mdw@prepend#1\to#2{%
+ \toks@{\do{#1}}%
+ \toks\tw@\expandafter{#2}%
+ \edef#2{\the\toks@\the\toks\tw@}%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\mdw@add}
+%
+% Finally, saying \syntax{"\\mdw@add"<item>"\\to"<list>} adds the \<item>
+% to the list only if it isn't there already.
+%
+% \begin{macrocode}
+\def\mdw@add#1\to#2{\mdw@ifitem#1\in#2{}{\mdw@append#1\to#2}}
+% \end{macrocode}
+%
+% \end{macro}
+%
+%
+% \subsection{Described file handling}
+%
+% I'l maintain lists of packages, document classes, and other files
+% described by the current documentation file.
+%
+% First of all, I'll declare the various list macros.
+%
+% \begin{macrocode}
+\def\dopackages{}
+\def\doclasses{}
+\def\dootherfiles{}
+% \end{macrocode}
+%
+% \begin{macro}{\describespackage}
+%
+% A document file can declare that it describes a package by saying
+% \syntax{"\\describespackage{"<package-name>"}"}. I add the package to
+% my list, read the package into memory (so that the documentation can
+% offer demonstrations of it) and read the version information.
+%
+% \begin{macrocode}
+\def\describespackage#1{%
+ \mdw@ifitem#1\in\dopackages{}{%
+ \mdw@append#1\to\dopackages%
+ \usepackage{#1}%
+ \mdwpkginfo{#1.sty}%
+ }%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\describesclass}
+%
+% By saying \syntax{"\\describesclass{"<class-name>"}"}, a document file
+% can declare that it describes a document class. I'll assume that the
+% document class is already loaded, because it's much too late to load
+% it now.
+%
+% \begin{macrocode}
+\def\describesclass#1{\mdw@add#1\to\doclasses\mdwpkginfo{#1.cls}}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\describesfile}
+%
+% Finally, other `random' files, which don't have the status of real \LaTeX\
+% packages or document classes, can be described by saying \syntax{^^A
+% "\\describesfile{"<file-name>"}" or "\\describesfile*{"<file-name>"}"}.
+% The difference is that the starred version will not |\input| the file.
+%
+% \begin{macrocode}
+\def\describesfile{%
+ \@ifstar{\describesfile@i\@gobble}{\describesfile@i\input}%
+}
+\def\describesfile@i#1#2{%
+ \mdw@ifitem#2\in\dootherfiles{}{%
+ \mdw@add#2\to\dootherfiles%
+ #1{#2}%
+ \mdwpkginfo{#2}%
+ }%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+%
+% \subsection{Author and title handling}
+%
+% I'll redefine the |\author| and |\title| commands so that I get told
+% whether I need to do it myself.
+%
+% \begin{macro}{\author}
+%
+% This is easy: I'll save the old meaning, and then redefine |\author| to
+% do the old thing and redefine itself to then do nothing.
+%
+% \begin{macrocode}
+\let\mdw@author\author
+\def\author{\let\author\@gobble\mdw@author}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\title}
+%
+% And oddly enough, I'll do exactly the same thing for the title, except
+% that I'll also disable the |\mdw@buildtitle| command, which constructs
+% the title automatically.
+%
+% \begin{macrocode}
+\let\mdw@title\title
+\def\title{\let\title\@gobble\let\mdw@buildtitle\relax\mdw@title}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\date}
+%
+% This works in a very similar sort of way.
+%
+% \begin{macrocode}
+\def\date#1{\let\date\@gobble\def\today{#1}}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\datefrom}
+%
+% Saying \syntax{"\\datefrom{"<file-name>"}"} sets the document date from
+% the given filename.
+%
+% \begin{macrocode}
+\def\datefrom#1{%
+ \protected@edef\@tempa{\noexpand\date{\csname #1date\endcsname}}%
+ \@tempa%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\docfile}
+%
+% Saying \syntax{"\\docfile{"<file-name>"}"} sets up the file name from which
+% documentation will be read.
+%
+% \begin{macrocode}
+\def\docfile#1{%
+ \def\@tempa##1.##2\@@{\def\@basefile{##1.##2}\def\@basename{##1}}%
+ \edef\@tempb{\noexpand\@tempa#1\noexpand\@@}%
+ \@tempb%
+}
+% \end{macrocode}
+%
+% I'll set up a default value as well.
+%
+% \begin{macrocode}
+\docfile{\jobname.dtx}
+% \end{macrocode}
+%
+% \end{macro}
+%
+%
+% \subsection{Building title strings}
+%
+% This is rather tricky. For each list, I need to build a legible looking
+% string.
+%
+% \begin{macro}{\mdw@addtotitle}
+%
+% By saying
+%\syntax{"\\mdw@addtotitle{"<list>"}{"<command>"}{"<singular>"}{"<plural>"}"}
+% I can add the contents of a list to the current title string in the
+% |\mdw@title| macro.
+%
+% \begin{macrocode}
+\tdef\mdw@addtotitle#1#2#3#4{%
+% \end{macrocode}
+%
+% Now to get to work. I need to keep one `lookahead' list item, and a count
+% of the number of items read so far. I'll keep the lookahead item in
+% |\@nextitem| and the counter in |\count@|.
+%
+% \begin{macrocode}
+ \count@\z@%
+% \end{macrocode}
+%
+% Now I'll define what to do for each list item. The |\protect| command is
+% already set up appropriately for playing with |\edef| commands.
+%
+% \begin{macrocode}
+ \def\do##1{%
+% \end{macrocode}
+%
+% The first job is to add the previous item to the title string. If this
+% is the first item, though, I'll just add the appropriate \lit{The } or
+% \lit{ and the } string to the title (this is stored in the |\@prefix|
+% macro).
+%
+% \begin{macrocode}
+ \edef\mdw@title{%
+ \mdw@title%
+ \ifcase\count@\@prefix%
+ \or\@nextitem%
+ \else, \@nextitem%
+ \fi%
+ }%
+% \end{macrocode}
+%
+% That was rather easy. Now I'll set up the |\@nextitem| macro for the
+% next time around the loop.
+%
+% \begin{macrocode}
+ \edef\@nextitem{%
+ \protect#2{##1}%
+ \protect\footnote{%
+ The \protect#2{##1} #3 is currently at version %
+ \mdwfileinfo{##1}{version}, dated \mdwfileinfo{##1}{date}.%
+ }\space%
+ }%
+% \end{macrocode}
+%
+% Finally, I need to increment the counter.
+%
+% \begin{macrocode}
+ \advance\count@\@ne%
+ }%
+% \end{macrocode}
+%
+% Now execute the list.
+%
+% \begin{macrocode}
+ #1%
+% \end{macrocode}
+%
+% I still have one item left over, unless the list was empty. I'll add
+% that now.
+%
+% \begin{macrocode}
+ \edef\mdw@title{%
+ \mdw@title%
+ \ifcase\count@%
+ \or\@nextitem\space#3%
+ \or\ and \@nextitem\space#4%
+ \fi%
+ }%
+% \end{macrocode}
+%
+% Finally, if $|\count@| \ne 0$, I must set |\@prefix| to \lit{ and the }.
+%
+% \begin{macrocode}
+ \ifnum\count@>\z@\def\@prefix{ and the }\fi%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\mdw@buildtitle}
+%
+% This macro will actually do the job of building the title string.
+%
+% \begin{macrocode}
+\tdef\mdw@buildtitle{%
+% \end{macrocode}
+%
+% First of all, I'll open a group to avoid polluting the namespace with
+% my gubbins (although the code is now much tidier than it has been in
+% earlier releases).
+%
+% \begin{macrocode}
+ \begingroup%
+% \end{macrocode}
+%
+% The title building stuff makes extensive use of |\edef|. I'll set
+% |\protect| appropriately. (For those not in the know,
+% |\@unexpandable@protect| expands to `|\noexpand\protect\noexpand|',
+% which prevents expansion of the following macro, and inserts a |\protect|
+% in front of it ready for the next |\edef|.)
+%
+% \begin{macrocode}
+ \let\@@protect\protect\let\protect\@unexpandable@protect%
+% \end{macrocode}
+%
+% Set up some simple macros ready for the main code.
+%
+% \begin{macrocode}
+ \def\mdw@title{}%
+ \def\@prefix{The }%
+% \end{macrocode}
+%
+% Now build the title. This is fun.
+%
+% \begin{macrocode}
+ \mdw@addtotitle\dopackages\package{package}{packages}%
+ \mdw@addtotitle\doclasses\package{document class}{document classes}%
+ \mdw@addtotitle\dootherfiles\texttt{file}{files}%
+% \end{macrocode}
+%
+% Now I want to end the group and set the title from my string. The
+% following hacking will do this.
+%
+% \begin{macrocode}
+ \edef\next{\endgroup\noexpand\title{\mdw@title}}%
+ \next%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+%
+% \subsection{Starting the main document}
+%
+% \begin{macro}{\mdwdoc}
+%
+% Once the document preamble has done all of its stuff, it calls the
+% |\mdwdoc| command, which takes over and really starts the documentation
+% going.
+%
+% \begin{macrocode}
+\def\mdwdoc{%
+% \end{macrocode}
+%
+% First, I'll construct the title string.
+%
+% \begin{macrocode}
+ \mdw@buildtitle%
+ \author{Mark Wooding}%
+% \end{macrocode}
+%
+% Set up the date string based on the date of the package which shares
+% the same name as the current file.
+%
+% \begin{macrocode}
+ \datefrom\@basename%
+% \end{macrocode}
+%
+% Set up verbatim characters after all the packages have started.
+%
+% \begin{macrocode}
+ \shortverb\|%
+ \shortverb\"%
+% \end{macrocode}
+%
+% Start the document, and put the title in.
+%
+% \begin{macrocode}
+ \begin{document}
+ \maketitle%
+% \end{macrocode}
+%
+% This is nasty. It makes maths displays work properly in demo environments.
+% \emph{The \LaTeX\ Companion} exhibits the bug which this hack fixes. So
+% ner.
+%
+% \begin{macrocode}
+ \abovedisplayskip\z@%
+% \end{macrocode}
+%
+% Now start the contents tables. After starting each one, I'll make it
+% be multicolumnar.
+%
+% \begin{macrocode}
+ \def\do##1##2{%
+ ##2%
+ \ifhave@multicol\addtocontents{##1}{%
+ \protect\begin{multicols}{2}%
+ \hbadness\@M%
+ }\fi%
+ }%
+ \docontents%
+% \end{macrocode}
+%
+% Input the main file now.
+%
+% \begin{macrocode}
+ \DocInput{\@basefile}%
+% \end{macrocode}
+%
+% That's it. I'm done.
+%
+% \begin{macrocode}
+ \end{document}
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+%
+% \subsection{And finally\dots}
+%
+% Right at the end I'll put a hook for the configuration file.
+%
+% \begin{macrocode}
+\ifx\mdwhook\@@undefined\else\expandafter\mdwhook\fi
+% \end{macrocode}
+%
+% That's all the code done now. I'll change back to `user' mode, where
+% all the magic control sequences aren't allowed any more.
+%
+% \begin{macrocode}
+\makeatother
+%</mdwtools>
+% \end{macrocode}
+%
+% Oh, wait! What if I want to typeset this documentation? Aha. I'll cope
+% with that by comparing |\jobname| with my filename |mdwtools|. However,
+% there's some fun here, because |\jobname| contains category-12 letters,
+% while my letters are category-11. Time to play with |\string| in a messy
+% way.
+%
+% \begin{macrocode}
+%<*driver>
+\makeatletter
+\edef\@tempa{\expandafter\@gobble\string\mdwtools}
+\edef\@tempb{\jobname}
+\ifx\@tempa\@tempb
+ \describesfile*{mdwtools.tex}
+ \docfile{mdwtools.tex}
+ \makeatother
+ \expandafter\mdwdoc
+\fi
+\makeatother
+%</driver>
+% \end{macrocode}
+%
+% That's it. Done!
+%
+% \hfill Mark Wooding, \today
+%
+% \Finale
+%
+\endinput