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