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