mdwtools.tex 34 KB

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