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