chiark / gitweb /
Checkin for new build system.
[mdwtools] / mdwtools.tex
1 % \begin{meta-comment}
2 %
3 % $Id: mdwtools.tex,v 1.1 2002/02/03 20:49:03 mdw Exp $
4 %
5 % Common declarations for mdwtools.dtx files
6 %
7 % (c) 1996 Mark Wooding
8 %
9 %----- Revision history -----------------------------------------------------
10 %
11 % $Log: mdwtools.tex,v $
12 % Revision 1.1  2002/02/03 20:49:03  mdw
13 % Checkin for new build system.
14 %
15 % Revision 1.4  1996/11/19 20:55:55  mdw
16 % Entered into RCS
17 %
18 %
19 % \end{meta-comment}
20 %
21 % \begin{meta-comment} <general public licence>
22 %%
23 %% mdwtools common declarations
24 %% Copyright (c) 1996 Mark Wooding
25 %%
26 %% This program is free software; you can redistribute it and/or modify
27 %% it under the terms of the GNU General Public License as published by
28 %% the Free Software Foundation; either version 2 of the License, or
29 %% (at your option) any later version.
30 %%
31 %% This program is distributed in the hope that it will be useful,
32 %% but WITHOUT ANY WARRANTY; without even the implied warranty of
33 %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
34 %% GNU General Public License for more details.
35 %%
36 %% You should have received a copy of the GNU General Public License
37 %% along with this program; if not, write to the Free Software
38 %% Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
39 %%
40 % \end{meta-comment}
41 %
42 % \begin{meta-comment} <file preamble>
43 %<*mdwtools>
44 \ProvidesFile{mdwtools.tex}
45              [1996/05/10 1.4 Shared definitions for mdwtools .dtx files]
46 %</mdwtools>
47 % \end{meta-comment}
48 %
49 % \CheckSum{668}
50 %% \CharacterTable
51 %%  {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
52 %%   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
53 %%   Digits        \0\1\2\3\4\5\6\7\8\9
54 %%   Exclamation   \!     Double quote  \"     Hash (number) \#
55 %%   Dollar        \$     Percent       \%     Ampersand     \&
56 %%   Acute accent  \'     Left paren    \(     Right paren   \)
57 %%   Asterisk      \*     Plus          \+     Comma         \,
58 %%   Minus         \-     Point         \.     Solidus       \/
59 %%   Colon         \:     Semicolon     \;     Less than     \<
60 %%   Equals        \=     Greater than  \>     Question mark \?
61 %%   Commercial at \@     Left bracket  \[     Backslash     \\
62 %%   Right bracket \]     Circumflex    \^     Underscore    \_
63 %%   Grave accent  \`     Left brace    \{     Vertical bar  \|
64 %%   Right brace   \}     Tilde         \~}
65 %%
66 %
67 % \section{Introduction and user guide}
68 %
69 % This file is really rather strange; it gets |\input| by other package
70 % documentation files to set up most of the environmental gubbins for them.
71 % It handles almost everything, like loading a document class, finding any
72 % packages, and building and formatting the title.
73 %
74 % It also offers an opportunity for users to customise my nice documentation,
75 % by using a |mdwtools.cfg| file (not included).
76 %
77 %
78 % \subsection{Declarations}
79 %
80 % A typical documentation file contains something like
81 % \begin{listinglist} \listingsize \obeylines
82 % |\input{mdwtools}|
83 % \<declarations>
84 % |\mdwdoc|
85 % \end{listinglist}
86 % The initial |\input| reads in this file and sets up the various commands
87 % which may be needed.  The final |\mdwdoc| actually starts the document,
88 % inserting a title (which is automatically generated), a table of
89 % contents etc., and reads the documentation file in (using the |\DocInput|
90 % command from the \package{doc} package.
91 %
92 % \subsubsection{Describing packages}
93 %
94 % \DescribeMacro{\describespackage}
95 % \DescribeMacro{\describesclass}
96 % \DescribeMacro{\describesfile}
97 % \DescribeMacro{\describesfile*}
98 % The most important declarations are those which declare what the
99 % documentation describes.  Saying \syntax{"\\describespackage{<package>}"}
100 % loads the \<package> (if necessary) and adds it to the auto-generated
101 % title, along with a footnote containing version information.  Similarly,
102 % |\describesclass| adds a document class name to the title (without loading
103 % it -- the document itself must do this, with the |\documentclass| command).
104 % For files which aren't packages or classes, use the |\describesfile| or
105 % |\describesfile*| command (the $*$-version won't |\input| the file, which
106 % is handy for files like |mdwtools.tex|, which are already input).
107 %
108 % \DescribeMacro{\author}
109 % \DescribeMacro{\date}
110 % \DescribeMacro{\title}
111 % The |\author|, |\date| and |\title| declarations work slightly differently
112 % to normal -- they ensure that only the \emph{first} declaration has an
113 % effect.  (Don't you play with |\author|, please, unless you're using this
114 % program to document your own packages.)  Using |\title| suppresses the
115 % automatic title generation.
116 %
117 % \DescribeMacro{\docdate}
118 % The default date is worked out from the version string of the package or
119 % document class whose name is the same as that of the documentation file.
120 % You can choose a different `main' file by saying
121 % \syntax{"\\docdate{"<file>"}"}.
122 %
123 % \subsubsection{Contents handling}
124 %
125 % \DescribeMacro{\addcontents}
126 % A documentation file always has a table of contents.  Other
127 % contents-like lists can be added by saying
128 % \syntax{"\\addcontents{"<extension>"}{"<command>"}"}.  The \<extension>
129 % is the file extension of the contents file (e.g., \lit{lot} for the
130 % list of tables); the \<command> is the command to actually typeset the
131 % contents file (e.g., |\listoftables|).
132 %
133 % \subsubsection{Other declarations}
134 %
135 % \DescribeMacro{\implementation}
136 % The \package{doc} package wants you to say
137 % \syntax{"\\StopEventually{"<stuff>"}"}' before describing the package
138 % implementation.  Using |mdwtools.tex|, you just say |\implementation|, and
139 % everything works.  It will automatically read in the licence text (from
140 % |gpl.tex|, and wraps some other things up.
141 %
142
143 % \subsection{Other commands}
144 %
145 % The |mdwtools.tex| file includes the \package{syntax} and \package{sverb}
146 % packages so that they can be used in documentation files.  It also defines
147 % some trivial commands of its own.
148 %
149 % \DescribeMacro{\<}
150 % Saying \syntax{"\\<"<text>">" is the same as "\\synt{"<text>"}"}; this
151 % is a simple abbreviation.
152 %
153 % \DescribeMacro{\smallf}
154 % Saying \syntax{"\\smallf" <number>"/"<number>} typesets a little fraction,
155 % like this: \smallf 3/4.  It's useful when you want to say that the default
156 % value of a length is 2 \smallf 1/2\,pt, or something like that.
157 %
158 %
159 % \subsection{Customisation}
160 %
161 % You can customise the way that the package documentation looks by writing
162 % a file called |mdwtools.cfg|.  You can redefine various commands (before
163 % they're defined here, even; |mdwtools.tex| checks most of the commands that
164 % it defines to make sure they haven't been defined already.
165 %
166 % \DescribeMacro{\indexing}
167 % If you don't want the prompt about whether to generate index files, you
168 % can define the |\indexing| command to either \lit{y} or \lit{n}.  I'd
169 % recommend that you use |\providecommand| for this, to allow further
170 % customisation from the command line.
171 %
172 % \DescribeMacro{\mdwdateformat}
173 % If you don't like my date format (maybe you're American or something),
174 % you can redefine the |\mdwdateformat| command.  It takes three arguments:
175 % the year, month and date, as numbers; it should expand to something which
176 % typesets the date nicely.  The default format gives something like
177 % `10 May 1996'.  You can produce something rather more exotic, like
178 % `10\textsuperscript{th} May \textsc{\romannumeral 1996}' by saying
179 %\begin{listing}
180 %\newcommand{\mdwdateformat}[3]{%
181 %  \number#3\textsuperscript{\numsuffix{#3}}\ %
182 %  \monthname{#2}\ %
183 %  \textsc{\romannumeral #1}%
184 %}
185 %\end{listing}
186 % \DescribeMacro{\monthname}
187 % \DescribeMacro{\numsuffix}
188 % Saying \syntax{"\\monthname{"<number>"}"} expands to the name of the
189 % numbered month (which can be useful when doing date formats).  Saying
190 % \syntax{"\\numsuffix{"<number>"}"} will expand to the appropriate suffix
191 % (`th' or `rd' or whatever) for the \<number>.  You'll have to superscript
192 % it yourself, if this is what you want to do.  Putting the year number
193 % in roman numerals is just pretentious |;-)|.
194 %
195 % \DescribeMacro{\mdwhook}
196 % After all the declarations in |mdwtools.tex|, the command |\mdwhook| is
197 % executed, if it exists.  This can be set up by the configuration file
198 % to do whatever you want.
199 %
200 % There are lots of other things you can play with; you should look at the
201 % implementation section to see what's possible.
202 %
203 % \implementation
204 %
205 % \section{Implementation}
206 %
207 %    \begin{macrocode}
208 %<*mdwtools>
209 %    \end{macrocode}
210 %
211 % The first thing is that I'm not a \LaTeX\ package or anything official
212 % like that, so I must enable `|@|' as a letter by hand.
213 %
214 %    \begin{macrocode}
215 \makeatletter
216 %    \end{macrocode}
217 %
218 % Now input the user's configuration file, if it exists.  This is fairly
219 % simple stuff.
220 %
221 %    \begin{macrocode}
222 \@input{mdwtools.cfg}
223 %    \end{macrocode}
224 %
225 % Well, that's the easy bit done.
226 %
227 %
228 % \subsection{Initialisation}
229 %
230 % Obviously the first thing to do is to obtain a document class.  Obviously,
231 % it would be silly to do this if a document class has already been loaded,
232 % either by the package documentation or by the configuration file.
233 %
234 % The only way I can think of for finding out if a document class is already
235 % loaded is by seeing if the |\documentclass| command has been redefined
236 % to raise an error.  This isn't too hard, really.
237 %
238 %    \begin{macrocode}
239 \ifx\documentclass\@twoclasseserror\else
240   \documentclass[a4paper]{ltxdoc}
241   \ifx\doneclasses\mdw@undefined\else\doneclasses\fi
242 \fi
243 %    \end{macrocode}
244 %
245 % As part of my standard environment, I'll load some of my more useful
246 % packages.  If they're already loaded (possibly with different options),
247 % I'll not try to load them again.
248 %
249 %    \begin{macrocode}
250 \@ifpackageloaded{doc}{}{\usepackage{doc}}
251 \@ifpackageloaded{syntax}{}{\usepackage[rounded]{syntax}}
252 \@ifpackageloaded{sverb}{}{\usepackage{sverb}}
253 %    \end{macrocode}
254 %
255 %
256 % \subsection{Some macros for interaction}
257 %
258 % I like the \LaTeX\ star-boxes, although it's a pain having to cope with
259 % \TeX's space-handling rules.  I'll define a new typing-out macro which
260 % makes spaces more significant, and has a $*$-version which doesn't put
261 % a newline on the end, and interacts prettily with |\read|.
262 %
263 % First of all, I need to make spaces active, so I can define things about
264 % active spaces.
265 %
266 %    \begin{macrocode}
267 \begingroup\obeyspaces
268 %    \end{macrocode}
269 %
270 % Now to define the main macro.  This is easy stuff.  Spaces must be
271 % carefully rationed here, though.
272 %
273 % I'll start a group, make spaces active, and make spaces expand to ordinary
274 % space-like spaces.  Then I'll look for a star, and pass either |\message|
275 % (which doesn't start a newline, and interacts with |\read| well) or
276 % |\immediate\write 16| which does a normal write well.
277 %
278 %    \begin{macrocode}
279 \gdef\mdwtype{%
280 \begingroup\catcode`\ \active\let \space%
281 \@ifstar{\mdwtype@i{\message}}{\mdwtype@i{\immediate\write\sixt@@n}}%
282 }
283 \endgroup
284 %    \end{macrocode}
285 %
286 % Now for the easy bit.  I have the thing to do, and the thing to do it to,
287 % so do that and end the group.
288 %
289 %    \begin{macrocode}
290 \def\mdwtype@i#1#2{#1{#2}\endgroup}
291 %    \end{macrocode}
292 %
293 %
294 % \subsection{Decide on indexing}
295 %
296 % A configuration file can decide on indexing by defining the |\indexing|
297 % macro to either \lit{y} or \lit{n}.  If it's not set, then I'll prompt
298 % the user.
299 %
300 % First of all, I want a switch to say whether I'm indexing.
301 %
302 %    \begin{macrocode}
303 \newif\ifcreateindex
304 %    \end{macrocode}
305 %
306 % Right: now I need to decide how to make progress.  If the macro's not set,
307 % then I want to set it, and start a row of stars.
308 %
309 %    \begin{macrocode}
310 \ifx\indexing\@@undefined
311   \mdwtype{*****************************}
312   \def\indexing{?}
313 \fi
314 %    \end{macrocode}
315 %
316 % Now enter a loop, asking the user whether to do indexing, until I get
317 % a sensible answer.
318 %
319 %    \begin{macrocode}
320 \loop
321   \@tempswafalse
322   \if y\indexing\@tempswatrue\createindextrue\fi
323   \if Y\indexing\@tempswatrue\createindextrue\fi
324   \if n\indexing\@tempswatrue\createindexfalse\fi
325   \if N\indexing\@tempswatrue\createindexfalse\fi
326   \if@tempswa\else
327   \mdwtype*{* Create index files? (y/n) *}
328   \read\sixt@@n to\indexing%
329 \repeat
330 %    \end{macrocode}
331 %
332 % Now, based on the results of that, display a message about the indexing.
333 %
334 %    \begin{macrocode}
335 \mdwtype{*****************************}
336 \ifcreateindex
337   \mdwtype{* Creating index files      *}
338   \mdwtype{* This may take some time   *}
339 \else
340   \mdwtype{* Not creating index files  *}
341 \fi
342 \mdwtype{*****************************}
343 %    \end{macrocode}
344 %
345 % Now I can play with the indexing commands of the \package{doc} package
346 % to do whatever it is that the user wants.
347 %
348 %    \begin{macrocode}
349 \ifcreateindex
350   \CodelineIndex
351   \EnableCrossrefs
352 \else
353   \CodelineNumbered
354   \DisableCrossrefs
355 \fi
356 %    \end{macrocode}
357 %
358 % And register lots of plain \TeX\ things which shouldn't be indexed.
359 % This contains lots of |\if|\dots\ things which don't fit nicely in
360 % conditionals, which is a shame.  Still, it doesn't matter that much,
361 % really.
362 %
363 %    \begin{macrocode}
364 \DoNotIndex{\def,\long,\edef,\xdef,\gdef,\let,\global}
365 \DoNotIndex{\if,\ifnum,\ifdim,\ifcat,\ifmmode,\ifvmode,\ifhmode,%
366             \iftrue,\iffalse,\ifvoid,\ifx,\ifeof,\ifcase,\else,\or,\fi}
367 \DoNotIndex{\box,\copy,\setbox,\unvbox,\unhbox,\hbox,%
368             \vbox,\vtop,\vcenter}
369 \DoNotIndex{\@empty,\immediate,\write}
370 \DoNotIndex{\egroup,\bgroup,\expandafter,\begingroup,\endgroup}
371 \DoNotIndex{\divide,\advance,\multiply,\count,\dimen}
372 \DoNotIndex{\relax,\space,\string}
373 \DoNotIndex{\csname,\endcsname,\@spaces,\openin,\openout,%
374             \closein,\closeout}
375 \DoNotIndex{\catcode,\endinput}
376 \DoNotIndex{\jobname,\message,\read,\the,\m@ne,\noexpand}
377 \DoNotIndex{\hsize,\vsize,\hskip,\vskip,\kern,\hfil,\hfill,\hss}
378 \DoNotIndex{\m@ne,\z@,\z@skip,\@ne,\tw@,\p@}
379 \DoNotIndex{\dp,\wd,\ht,\vss,\unskip}
380 %    \end{macrocode}
381 %
382 % Last bit of indexing stuff, for now: I'll typeset the index in two columns
383 % (the default is three, which makes them too narrow for my tastes).
384 %
385 %    \begin{macrocode}
386 \setcounter{IndexColumns}{2}
387 %    \end{macrocode}
388 %
389 %
390 % \subsection{Selectively defining things}
391 %
392 % I don't want to tread on anyone's toes if they redefine any of these
393 % commands and things in a configuration file.  The following definitions
394 % are fairly evil, but should do the job OK.
395 %
396 % \begin{macro}{\@gobbledef}
397 %
398 % This macro eats the following |\def|inition, leaving not a trace behind.
399 %
400 %    \begin{macrocode}
401 \def\@gobbledef#1#{\@gobble}
402 %    \end{macrocode}
403 %
404 % \end{macro}
405 %
406 % \begin{macro}{\tdef}
407 % \begin{macro}{\tlet}
408 %
409 % The |\tdef| command is a sort of `tentative' definition -- it's like
410 % |\def| if the control sequence named doesn't already have a definition.
411 % |\tlet| does the same thing with |\let|.
412 %
413 %    \begin{macrocode}
414 \def\tdef#1{
415   \ifx#1\@@undefined%
416     \expandafter\def\expandafter#1%
417   \else%
418     \expandafter\@gobbledef%
419   \fi%
420 }
421 \def\tlet#1#2{\ifx#1\@@undefined\let#1=#2\fi}
422 %    \end{macrocode}
423 %
424 % \end{macro}
425 % \end{macro}
426 %
427 %
428 % \subsection{General markup things}
429 %
430 % Now for some really simple things.  I'll define how to typeset package
431 % names and environment names (both in the sans serif font, for now).
432 %
433 %    \begin{macrocode}
434 \tlet\package\textsf
435 \tlet\env\textsf
436 %    \end{macrocode}
437 %
438 % I'll define the |\<|\dots|>| shortcut for syntax items suggested in the
439 % \package{syntax} package.
440 %
441 %    \begin{macrocode}
442 \tdef\<#1>{\synt{#1}}
443 %    \end{macrocode}
444 %
445 % And because it's used in a few places (mainly for typesetting lengths),
446 % here's a command for typesetting fractions in text.
447 %
448 %    \begin{macrocode}
449 \tdef\smallf#1/#2{\ensuremath{^{#1}\!/\!_{#2}}}
450 %    \end{macrocode}
451 %
452 %
453 % \subsection{A table environment}
454 %
455 % \begin{environment}{tab}
456 %
457 % Most of the packages don't use the (obviously perfect) \package{mdwtab}
458 % package, because it's big, and takes a while to load.  Here's an
459 % environment for typesetting centred tables.  The first (optional) argument
460 % is some declarations to perform.  The mandatory argument is the table
461 % preamble (obviously).
462 %
463 %    \begin{macrocode}
464 \@ifundefined{tab}{%
465   \newenvironment{tab}[2][\relax]{%
466     \par\vskip2ex%
467     \centering%
468     #1%
469     \begin{tabular}{#2}%
470   }{%
471     \end{tabular}%
472     \par\vskip2ex%
473   }
474 }{}
475 %    \end{macrocode}
476 %
477 % \end{environment}
478 %
479 %
480 % \subsection{Commenting out of stuff}
481 %
482 % \begin{environment}{meta-comment}
483 %
484 % Using |\iffalse|\dots|\fi| isn't much fun.  I'll define a gobbling
485 % environment using the \package{sverb} stuff.
486 %
487 %    \begin{macrocode}
488 \ignoreenv{meta-comment}
489 %    \end{macrocode}
490 %
491 % \end{environment}
492 %
493 %
494 % \subsection{Float handling}
495 %
496 % This gubbins will try to avoid float pages as much as possible, and (with
497 % any luck) encourage floats to be put on the same pages as text.
498 %
499 %    \begin{macrocode}
500 \def\textfraction{0.1}
501 \def\topfraction{0.9}
502 \def\bottomfraction{0.9}
503 \def\floatpagefraction{0.7}
504 %    \end{macrocode}
505 %
506 % Now redefine the default float-placement parameters to allow `here' floats.
507 %
508 %    \begin{macrocode}
509 \def\fps@figure{htbp}
510 \def\fps@table{htbp}
511 %    \end{macrocode}
512 %
513 %
514 % \subsection{Other bits of parameter tweaking}
515 %
516 % Make \env{grammar} environments look pretty, by indenting the left hand
517 % sides by a large amount.
518 %
519 %    \begin{macrocode}
520 \grammarindent1in
521 %    \end{macrocode}
522 %
523 % I don't like being told by \TeX\ that my paragraphs are hard to linebreak:
524 % I know this already.  This lot should shut \TeX\ up about most problems.
525 %
526 %    \begin{macrocode}
527 \sloppy
528 \hbadness\@M
529 \hfuzz10\p@
530 %    \end{macrocode}
531 %
532 % Also make \TeX\ shut up in the index.  The \package{multicol} package
533 % irritatingly plays with |\hbadness|.  This is the best hook I could find
534 % for playing with this setting.
535 %
536 %    \begin{macrocode}
537 \expandafter\def\expandafter\IndexParms\expandafter{%
538   \IndexParms%
539   \hbadness\@M%
540 }
541 %    \end{macrocode}
542 %
543 % The other thing I really don't like is `Marginpar moved' warnings.  This
544 % will get rid of them, and lots of other \LaTeX\ warnings at the same time.
545 %
546 %    \begin{macrocode}
547 \let\@latex@warning@no@line\@gobble
548 %    \end{macrocode}
549 %
550 % Put some extra space between table rows, please.
551 %
552 %    \begin{macrocode}
553 \def\arraystretch{1.2}
554 %    \end{macrocode}
555 %
556 % Most of the code is at guard level one, so typeset that in upright text.
557 %
558 %    \begin{macrocode}
559 \setcounter{StandardModuleDepth}{1}
560 %    \end{macrocode}
561 %
562 %
563 % \subsection{Contents handling}
564 %
565 % I use at least one contents file (the main table of contents) although
566 % I may want more.  I'll keep a list of contents files which I need to
567 % handle.
568 %
569 % There are two things I need to do to contents files here:
570 % \begin{itemize}
571 % \item I must typeset the table of contents at the beginning of the
572 %       document; and
573 % \item I want to typeset tables of contents in two columns (using the
574 %       \package{multicol} package).
575 % \end{itemize}
576 %
577 % The list consists of items of the form
578 % \syntax{"\\do{"<extension>"}{"<command>"}"}, where \<extension> is the
579 % file extension of the contents file, and \<command> is the command to
580 % typeset it.
581 %
582 % \begin{macro}{\docontents}
583 %
584 % This is where I keep the list of contents files.  I'll initialise it to
585 % just do the standard contents table.
586 %
587 %    \begin{macrocode}
588 \def\docontents{\do{toc}{\tableofcontents}}
589 %    \end{macrocode}
590 %
591 % \end{macro}
592 %
593 % \begin{macro}{\addcontents}
594 %
595 % By saying \syntax{"\\addcontents{"<extension>"}{"<command>"}"}, a document
596 % can register a new table of contents which gets given the two-column
597 % treatment properly.  This is really easy to implement.
598 %
599 %    \begin{macrocode}
600 \def\addcontents#1#2{%
601   \toks@\expandafter{\docontents\do{#1}{#2}}%
602   \edef\docontents{\the\toks@}%
603 }
604 %    \end{macrocode}
605 %
606 % \end{macro}
607 %
608 %
609 % \subsection{Finishing it all off}
610 %
611 % \begin{macro}{\finalstuff}
612 %
613 % The |\finalstuff| macro is a hook for doing things at the end of the
614 % document.  Currently, it inputs the licence agreement as an appendix.
615 %
616 %    \begin{macrocode}
617 \tdef\finalstuff{\appendix\part*{Appendix}\input{gpl}}
618 %    \end{macrocode}
619 %
620 % \end{macro}
621 %
622 % \begin{macro}{\implementation}
623 %
624 % The |\implementation| macro starts typesetting the implementation of
625 % the package(s).  If we're not doing the implementation, it just does
626 % this lot and ends the input file.
627 %
628 % I define a macro with arguments inside the |\StopEventually|, which causes
629 % problems, since the code gets put through an extra level of |\def|fing
630 % depending on whether the implementation stuff gets typeset or not.  I'll
631 % store the code I want to do in a separate macro.
632 %
633 %    \begin{macrocode}
634 \def\implementation{\StopEventually{\attheend}}
635 %    \end{macrocode}
636 %
637 % Now for the actual activity.  First, I'll do the |\finalstuff|.  Then, if
638 % \package{doc}'s managed to find the \package{multicol} package, I'll add
639 % the end of the environment to the end of each contents file in the list.
640 % Finally, I'll read the index in from its formatted |.ind| file.
641 %
642 %    \begin{macrocode}
643 \tdef\attheend{%
644   \finalstuff%
645   \ifhave@multicol%
646     \def\do##1##2{\addtocontents{##1}{\protect\end{multicols}}}%
647     \docontents%
648   \fi%
649   \PrintIndex%
650 }
651 %    \end{macrocode}
652 %
653 % \end{macro}
654 %
655 %
656 % \subsection{File version information}
657 %
658 % \begin{macro}{\mdwpkginfo}
659 %
660 % For setting up the automatic titles, I'll need to be able to work out
661 % file versions and things.  This macro will, given a file name, extract
662 % from \LaTeX\ the version information and format it into a sensible string.
663 %
664 % First of all, I'll put the original string (direct from the
665 % |\Provides|\dots\ command).  Then I'll pass it to another macro which can
666 % parse up the string into its various bits, along with the original
667 % filename.
668 %
669 %    \begin{macrocode}
670 \def\mdwpkginfo#1{%
671   \edef\@tempa{\csname ver@#1\endcsname}%
672   \expandafter\mdwpkginfo@i\@tempa\@@#1\@@%
673 }
674 %    \end{macrocode}
675 %
676 % Now for the real business.  I'll store the string I build in macros called
677 % \syntax{"\\"<filename>"date", "\\"<filename>"version" and
678 % "\\"<filename>"info"}, which store the file's date, version and
679 % `information string' respectively.  (Note that the file extension isn't
680 % included in the name.)
681 %
682 % This is mainly just tedious playing with |\expandafter|.  The date format
683 % is defined by a separate macro, which can be modified from the
684 % configuration file.
685 %
686 %    \begin{macrocode}
687 \def\mdwpkginfo@i#1/#2/#3 #4 #5\@@#6.#7\@@{%
688   \expandafter\def\csname #6date\endcsname%
689     {\protect\mdwdateformat{#1}{#2}{#3}}%
690   \expandafter\def\csname #6version\endcsname{#4}%
691   \expandafter\def\csname #6info\endcsname{#5}%
692 }
693 %    \end{macrocode}
694 %
695 % \end{macro}
696 %
697 % \begin{macro}{\mdwdateformat}
698 %
699 % Given three arguments, a year, a month and a date (all numeric), build a
700 % pretty date string.  This is fairly simple really.
701 %
702 %    \begin{macrocode}
703 \tdef\mdwdateformat#1#2#3{\number#3\ \monthname{#2}\ \number#1}
704 \def\monthname#1{%
705   \ifcase#1\or%
706      January\or February\or March\or April\or May\or June\or%
707      July\or August\or September\or October\or November\or December%
708   \fi%
709 }
710 \def\numsuffix#1{%
711   \ifnum#1=1 st\else%
712   \ifnum#1=2 nd\else%
713   \ifnum#1=3 rd\else%
714   \ifnum#1=21 st\else%
715   \ifnum#1=22 nd\else%
716   \ifnum#1=23 rd\else%
717   \ifnum#1=31 st\else%
718   th%
719   \fi\fi\fi\fi\fi\fi\fi%
720 }
721 %    \end{macrocode}
722 %
723 % \end{macro}
724 %
725 % \begin{macro}{\mdwfileinfo}
726 %
727 % Saying \syntax{"\\mdwfileinfo{"<file-name>"}{"<info>"}"} extracts the
728 % wanted item of \<info> from the version information for file \<file-name>.
729 %
730 %    \begin{macrocode}
731 \def\mdwfileinfo#1#2{\mdwfileinfo@i{#2}#1.\@@}
732 \def\mdwfileinfo@i#1#2.#3\@@{\csname#2#1\endcsname}
733 %    \end{macrocode}
734 %
735 % \end{macro}
736 %
737 %
738 % \subsection{List handling}
739 %
740 % There are several other lists I need to build.  These macros will do
741 % the necessary stuff.
742 %
743 % \begin{macro}{\mdw@ifitem}
744 %
745 % The macro \syntax{"\\mdw@ifitem"<item>"\\in"<list>"{"<true-text>"}"^^A
746 % "{"<false-text>"}"} does \<true-text> if the \<item> matches any item in
747 % the \<list>; otherwise it does \<false-text>.
748 %
749 %    \begin{macrocode}
750 \def\mdw@ifitem#1\in#2{%
751   \@tempswafalse%
752   \def\@tempa{#1}%
753   \def\do##1{\def\@tempb{##1}\ifx\@tempa\@tempb\@tempswatrue\fi}%
754   #2%
755   \if@tempswa\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi%
756 }
757 %    \end{macrocode}
758 %
759 % \end{macro}
760 %
761 % \begin{macro}{\mdw@append}
762 %
763 % Saying \syntax{"\\mdw@append"<item>"\\to"<list>} adds the given \<item>
764 % to the end of the given \<list>.
765 %
766 %    \begin{macrocode}
767 \def\mdw@append#1\to#2{%
768   \toks@{\do{#1}}%
769   \toks\tw@\expandafter{#2}%
770   \edef#2{\the\toks\tw@\the\toks@}%
771 }
772 %    \end{macrocode}
773 %
774 % \end{macro}
775 %
776 % \begin{macro}{\mdw@prepend}
777 %
778 % Saying \syntax{"\\mdw@prepend"<item>"\\to"<list>} adds the \<item> to the
779 % beginning of the \<list>.
780 %
781 %    \begin{macrocode}
782 \def\mdw@prepend#1\to#2{%
783   \toks@{\do{#1}}%
784   \toks\tw@\expandafter{#2}%
785   \edef#2{\the\toks@\the\toks\tw@}%
786 }
787 %    \end{macrocode}
788 %
789 % \end{macro}
790 %
791 % \begin{macro}{\mdw@add}
792 %
793 % Finally, saying \syntax{"\\mdw@add"<item>"\\to"<list>} adds the \<item>
794 % to the list only if it isn't there already.
795 %
796 %    \begin{macrocode}
797 \def\mdw@add#1\to#2{\mdw@ifitem#1\in#2{}{\mdw@append#1\to#2}}
798 %    \end{macrocode}
799 %
800 % \end{macro}
801 %
802 %
803 % \subsection{Described file handling}
804 %
805 % I'l maintain lists of packages, document classes, and other files
806 % described by the current documentation file.
807 %
808 % First of all, I'll declare the various list macros.
809 %
810 %    \begin{macrocode}
811 \def\dopackages{}
812 \def\doclasses{}
813 \def\dootherfiles{}
814 %    \end{macrocode}
815 %
816 % \begin{macro}{\describespackage}
817 %
818 % A document file can declare that it describes a package by saying
819 % \syntax{"\\describespackage{"<package-name>"}"}.  I add the package to
820 % my list, read the package into memory (so that the documentation can
821 % offer demonstrations of it) and read the version information.
822 %
823 %    \begin{macrocode}
824 \def\describespackage#1{%
825   \mdw@ifitem#1\in\dopackages{}{%
826     \mdw@append#1\to\dopackages%
827     \usepackage{#1}%
828     \mdwpkginfo{#1.sty}%
829   }%
830 }
831 %    \end{macrocode}
832 %
833 % \end{macro}
834 %
835 % \begin{macro}{\describesclass}
836 %
837 % By saying \syntax{"\\describesclass{"<class-name>"}"}, a document file
838 % can declare that it describes a document class.  I'll assume that the
839 % document class is already loaded, because it's much too late to load
840 % it now.
841 %
842 %    \begin{macrocode}
843 \def\describesclass#1{\mdw@add#1\to\doclasses\mdwpkginfo{#1.cls}}
844 %    \end{macrocode}
845 %
846 % \end{macro}
847 %
848 % \begin{macro}{\describesfile}
849 %
850 % Finally, other `random' files, which don't have the status of real \LaTeX\
851 % packages or document classes, can be described by saying \syntax{^^A
852 % "\\describesfile{"<file-name>"}" or "\\describesfile*{"<file-name>"}"}.
853 % The difference is that the starred version will not |\input| the file.
854 %
855 %    \begin{macrocode}
856 \def\describesfile{%
857   \@ifstar{\describesfile@i\@gobble}{\describesfile@i\input}%
858 }
859 \def\describesfile@i#1#2{%
860   \mdw@ifitem#2\in\dootherfiles{}{%
861     \mdw@add#2\to\dootherfiles%
862     #1{#2}%
863     \mdwpkginfo{#2}%
864   }%
865 }
866 %    \end{macrocode}
867 %
868 % \end{macro}
869 %
870 %
871 % \subsection{Author and title handling}
872 %
873 % I'll redefine the |\author| and |\title| commands so that I get told
874 % whether I need to do it myself.
875 %
876 % \begin{macro}{\author}
877 %
878 % This is easy: I'll save the old meaning, and then redefine |\author| to
879 % do the old thing and redefine itself to then do nothing.
880 %
881 %    \begin{macrocode}
882 \let\mdw@author\author
883 \def\author{\let\author\@gobble\mdw@author}
884 %    \end{macrocode}
885 %
886 % \end{macro}
887 %
888 % \begin{macro}{\title}
889 %
890 % And oddly enough, I'll do exactly the same thing for the title, except
891 % that I'll also disable the |\mdw@buildtitle| command, which constructs
892 % the title automatically.
893 %
894 %    \begin{macrocode}
895 \let\mdw@title\title
896 \def\title{\let\title\@gobble\let\mdw@buildtitle\relax\mdw@title}
897 %    \end{macrocode}
898 %
899 % \end{macro}
900 %
901 % \begin{macro}{\date}
902 %
903 % This works in a very similar sort of way.
904 %
905 %    \begin{macrocode}
906 \def\date#1{\let\date\@gobble\def\today{#1}}
907 %    \end{macrocode}
908 %
909 % \end{macro}
910 %
911 % \begin{macro}{\datefrom}
912 %
913 % Saying \syntax{"\\datefrom{"<file-name>"}"} sets the document date from
914 % the given filename.
915 %
916 %    \begin{macrocode}
917 \def\datefrom#1{%
918   \protected@edef\@tempa{\noexpand\date{\csname #1date\endcsname}}%
919   \@tempa%
920 }
921 %    \end{macrocode}
922 %
923 % \end{macro}
924 %
925 % \begin{macro}{\docfile}
926 %
927 % Saying \syntax{"\\docfile{"<file-name>"}"} sets up the file name from which
928 % documentation will be read.
929 %
930 %    \begin{macrocode}
931 \def\docfile#1{%
932   \def\@tempa##1.##2\@@{\def\@basefile{##1.##2}\def\@basename{##1}}%
933   \edef\@tempb{\noexpand\@tempa#1\noexpand\@@}%
934   \@tempb%
935 }
936 %    \end{macrocode}
937 %
938 % I'll set up a default value as well.
939 %
940 %    \begin{macrocode}
941 \docfile{\jobname.dtx}
942 %    \end{macrocode}
943 %
944 % \end{macro}
945 %
946 %
947 % \subsection{Building title strings}
948 %
949 % This is rather tricky.  For each list, I need to build a legible looking
950 % string.
951 %
952 % \begin{macro}{\mdw@addtotitle}
953 %
954 % By saying
955 %\syntax{"\\mdw@addtotitle{"<list>"}{"<command>"}{"<singular>"}{"<plural>"}"}
956 % I can add the contents of a list to the current title string in the
957 % |\mdw@title| macro.
958 %
959 %    \begin{macrocode}
960 \tdef\mdw@addtotitle#1#2#3#4{%
961 %    \end{macrocode}
962 %
963 % Now to get to work.  I need to keep one `lookahead' list item, and a count
964 % of the number of items read so far.  I'll keep the lookahead item in
965 % |\@nextitem| and the counter in |\count@|.
966 %
967 %    \begin{macrocode}
968   \count@\z@%
969 %    \end{macrocode}
970 %
971 % Now I'll define what to do for each list item.  The |\protect| command is
972 % already set up appropriately for playing with |\edef| commands.
973 %
974 %    \begin{macrocode}
975   \def\do##1{%
976 %    \end{macrocode}
977 %
978 % The first job is to add the previous item to the title string.  If this
979 % is the first item, though, I'll just add the appropriate \lit{The } or
980 % \lit{ and the } string to the title (this is stored in the |\@prefix|
981 % macro).
982 %
983 %    \begin{macrocode}
984     \edef\mdw@title{%
985       \mdw@title%
986       \ifcase\count@\@prefix%
987       \or\@nextitem%
988       \else, \@nextitem%
989       \fi%
990     }%
991 %    \end{macrocode}
992 %
993 % That was rather easy.  Now I'll set up the |\@nextitem| macro for the
994 % next time around the loop.
995 %
996 %    \begin{macrocode}
997     \edef\@nextitem{%
998       \protect#2{##1}%
999       \protect\footnote{%
1000         The \protect#2{##1} #3 is currently at version %
1001         \mdwfileinfo{##1}{version}, dated \mdwfileinfo{##1}{date}.%
1002       }\space%
1003     }%
1004 %    \end{macrocode}
1005 %
1006 % Finally, I need to increment the counter.
1007 %
1008 %    \begin{macrocode}
1009     \advance\count@\@ne%
1010   }%
1011 %    \end{macrocode}
1012 %
1013 % Now execute the list.
1014 %
1015 %    \begin{macrocode}
1016   #1%
1017 %    \end{macrocode}
1018 %
1019 % I still have one item left over, unless the list was empty.  I'll add
1020 % that now.
1021 %
1022 %    \begin{macrocode}
1023   \edef\mdw@title{%
1024     \mdw@title%
1025     \ifcase\count@%
1026     \or\@nextitem\space#3%
1027     \or\ and \@nextitem\space#4%
1028     \fi%
1029   }%
1030 %    \end{macrocode}
1031 %
1032 % Finally, if $|\count@| \ne 0$, I must set |\@prefix| to \lit{ and the }.
1033 %
1034 %    \begin{macrocode}
1035   \ifnum\count@>\z@\def\@prefix{ and the }\fi%
1036 }
1037 %    \end{macrocode}
1038 %
1039 % \end{macro}
1040 %
1041 % \begin{macro}{\mdw@buildtitle}
1042 %
1043 % This macro will actually do the job of building the title string.
1044 %
1045 %    \begin{macrocode}
1046 \tdef\mdw@buildtitle{%
1047 %    \end{macrocode}
1048 %
1049 % First of all, I'll open a group to avoid polluting the namespace with
1050 % my gubbins (although the code is now much tidier than it has been in
1051 % earlier releases).
1052 %
1053 %    \begin{macrocode}
1054   \begingroup%
1055 %    \end{macrocode}
1056 %
1057 % The title building stuff makes extensive use of |\edef|.  I'll set
1058 % |\protect| appropriately.  (For those not in the know,
1059 % |\@unexpandable@protect| expands to `|\noexpand\protect\noexpand|',
1060 % which prevents expansion of the following macro, and inserts a |\protect|
1061 % in front of it ready for the next |\edef|.)
1062 %
1063 %    \begin{macrocode}
1064   \let\@@protect\protect\let\protect\@unexpandable@protect%
1065 %    \end{macrocode}
1066 %
1067 % Set up some simple macros ready for the main code.
1068 %
1069 %    \begin{macrocode}
1070   \def\mdw@title{}%
1071   \def\@prefix{The }%
1072 %    \end{macrocode}
1073 %
1074 % Now build the title.  This is fun.
1075 %
1076 %    \begin{macrocode}
1077   \mdw@addtotitle\dopackages\package{package}{packages}%
1078   \mdw@addtotitle\doclasses\package{document class}{document classes}%
1079   \mdw@addtotitle\dootherfiles\texttt{file}{files}%
1080 %    \end{macrocode}
1081 %
1082 % Now I want to end the group and set the title from my string.  The
1083 % following hacking will do this.
1084 %
1085 %    \begin{macrocode}
1086   \edef\next{\endgroup\noexpand\title{\mdw@title}}%
1087   \next%
1088 }
1089 %    \end{macrocode}
1090 %
1091 % \end{macro}
1092 %
1093 %
1094 % \subsection{Starting the main document}
1095 %
1096 % \begin{macro}{\mdwdoc}
1097 %
1098 % Once the document preamble has done all of its stuff, it calls the
1099 % |\mdwdoc| command, which takes over and really starts the documentation
1100 % going.
1101 %
1102 %    \begin{macrocode}
1103 \def\mdwdoc{%
1104 %    \end{macrocode}
1105 %
1106 % First, I'll construct the title string.
1107 %
1108 %    \begin{macrocode}
1109   \mdw@buildtitle%
1110   \author{Mark Wooding}%
1111 %    \end{macrocode}
1112 %
1113 % Set up the date string based on the date of the package which shares
1114 % the same name as the current file.
1115 %
1116 %    \begin{macrocode}
1117   \datefrom\@basename%
1118 %    \end{macrocode}
1119 %
1120 % Set up verbatim characters after all the packages have started.
1121 %
1122 %    \begin{macrocode}
1123   \shortverb\|%
1124   \shortverb\"%
1125 %    \end{macrocode}
1126 %
1127 % Start the document, and put the title in.
1128 %
1129 %    \begin{macrocode}
1130   \begin{document}
1131   \maketitle%
1132 %    \end{macrocode}
1133 %
1134 % This is nasty.  It makes maths displays work properly in demo environments.
1135 % \emph{The \LaTeX\ Companion} exhibits the bug which this hack fixes.  So
1136 % ner.
1137 %
1138 %    \begin{macrocode}
1139   \abovedisplayskip\z@%
1140 %    \end{macrocode}
1141 %
1142 % Now start the contents tables.  After starting each one, I'll make it
1143 % be multicolumnar.
1144 %
1145 %    \begin{macrocode}
1146   \def\do##1##2{%
1147     ##2%
1148     \ifhave@multicol\addtocontents{##1}{%
1149       \protect\begin{multicols}{2}%
1150       \hbadness\@M%
1151     }\fi%
1152   }%
1153   \docontents%
1154 %    \end{macrocode}
1155 %
1156 % Input the main file now.
1157 %
1158 %    \begin{macrocode}
1159   \DocInput{\@basefile}%
1160 %    \end{macrocode}
1161 %
1162 % That's it.  I'm done.
1163 %
1164 %    \begin{macrocode}
1165   \end{document}
1166 }
1167 %    \end{macrocode}
1168 %
1169 % \end{macro}
1170 %
1171 %
1172 % \subsection{And finally\dots}
1173 %
1174 % Right at the end I'll put a hook for the configuration file.
1175 %
1176 %    \begin{macrocode}
1177 \ifx\mdwhook\@@undefined\else\expandafter\mdwhook\fi
1178 %    \end{macrocode}
1179 %
1180 % That's all the code done now.  I'll change back to `user' mode, where
1181 % all the magic control sequences aren't allowed any more.
1182 %
1183 %    \begin{macrocode}
1184 \makeatother
1185 %</mdwtools>
1186 %    \end{macrocode}
1187 %
1188 % Oh, wait!  What if I want to typeset this documentation?  Aha.  I'll cope
1189 % with that by comparing |\jobname| with my filename |mdwtools|.  However,
1190 % there's some fun here, because |\jobname| contains category-12 letters,
1191 % while my letters are category-11.  Time to play with |\string| in a messy
1192 % way.
1193 %
1194 %    \begin{macrocode}
1195 %<*driver>
1196 \makeatletter
1197 \edef\@tempa{\expandafter\@gobble\string\mdwtools}
1198 \edef\@tempb{\jobname}
1199 \ifx\@tempa\@tempb
1200   \describesfile*{mdwtools.tex}
1201   \docfile{mdwtools.tex}
1202   \makeatother
1203   \expandafter\mdwdoc
1204 \fi
1205 \makeatother
1206 %</driver>
1207 %    \end{macrocode}
1208 %
1209 % That's it.  Done!
1210 %
1211 % \hfill Mark Wooding, \today
1212 %
1213 % \Finale
1214 %
1215 \endinput