mdwtools.tex 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218
  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 2000-07-13 09:10:21 michael
  13. % + Initial import
  14. %
  15. % Revision 1.1 1998/09/21 10:19:01 michael
  16. % Initial implementation
  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{668}
  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. \fi%
  1032. }%
  1033. % \end{macrocode}
  1034. %
  1035. % Finally, if $|\count@| \ne 0$, I must set |\@prefix| to \lit{ and the }.
  1036. %
  1037. % \begin{macrocode}
  1038. \ifnum\count@>\z@\def\@prefix{ and the }\fi%
  1039. }
  1040. % \end{macrocode}
  1041. %
  1042. % \end{macro}
  1043. %
  1044. % \begin{macro}{\mdw@buildtitle}
  1045. %
  1046. % This macro will actually do the job of building the title string.
  1047. %
  1048. % \begin{macrocode}
  1049. \tdef\mdw@buildtitle{%
  1050. % \end{macrocode}
  1051. %
  1052. % First of all, I'll open a group to avoid polluting the namespace with
  1053. % my gubbins (although the code is now much tidier than it has been in
  1054. % earlier releases).
  1055. %
  1056. % \begin{macrocode}
  1057. \begingroup%
  1058. % \end{macrocode}
  1059. %
  1060. % The title building stuff makes extensive use of |\edef|. I'll set
  1061. % |\protect| appropriately. (For those not in the know,
  1062. % |\@unexpandable@protect| expands to `|\noexpand\protect\noexpand|',
  1063. % which prevents expansion of the following macro, and inserts a |\protect|
  1064. % in front of it ready for the next |\edef|.)
  1065. %
  1066. % \begin{macrocode}
  1067. \let\@@protect\protect\let\protect\@unexpandable@protect%
  1068. % \end{macrocode}
  1069. %
  1070. % Set up some simple macros ready for the main code.
  1071. %
  1072. % \begin{macrocode}
  1073. \def\mdw@title{}%
  1074. \def\@prefix{The }%
  1075. % \end{macrocode}
  1076. %
  1077. % Now build the title. This is fun.
  1078. %
  1079. % \begin{macrocode}
  1080. \mdw@addtotitle\dopackages\package{package}{packages}%
  1081. \mdw@addtotitle\doclasses\package{document class}{document classes}%
  1082. \mdw@addtotitle\dootherfiles\texttt{file}{files}%
  1083. % \end{macrocode}
  1084. %
  1085. % Now I want to end the group and set the title from my string. The
  1086. % following hacking will do this.
  1087. %
  1088. % \begin{macrocode}
  1089. \edef\next{\endgroup\noexpand\title{\mdw@title}}%
  1090. \next%
  1091. }
  1092. % \end{macrocode}
  1093. %
  1094. % \end{macro}
  1095. %
  1096. %
  1097. % \subsection{Starting the main document}
  1098. %
  1099. % \begin{macro}{\mdwdoc}
  1100. %
  1101. % Once the document preamble has done all of its stuff, it calls the
  1102. % |\mdwdoc| command, which takes over and really starts the documentation
  1103. % going.
  1104. %
  1105. % \begin{macrocode}
  1106. \def\mdwdoc{%
  1107. % \end{macrocode}
  1108. %
  1109. % First, I'll construct the title string.
  1110. %
  1111. % \begin{macrocode}
  1112. \mdw@buildtitle%
  1113. \author{Mark Wooding}%
  1114. % \end{macrocode}
  1115. %
  1116. % Set up the date string based on the date of the package which shares
  1117. % the same name as the current file.
  1118. %
  1119. % \begin{macrocode}
  1120. \datefrom\@basename%
  1121. % \end{macrocode}
  1122. %
  1123. % Set up verbatim characters after all the packages have started.
  1124. %
  1125. % \begin{macrocode}
  1126. \shortverb\|%
  1127. \shortverb\"%
  1128. % \end{macrocode}
  1129. %
  1130. % Start the document, and put the title in.
  1131. %
  1132. % \begin{macrocode}
  1133. \begin{document}
  1134. \maketitle%
  1135. % \end{macrocode}
  1136. %
  1137. % This is nasty. It makes maths displays work properly in demo environments.
  1138. % \emph{The \LaTeX\ Companion} exhibits the bug which this hack fixes. So
  1139. % ner.
  1140. %
  1141. % \begin{macrocode}
  1142. \abovedisplayskip\z@%
  1143. % \end{macrocode}
  1144. %
  1145. % Now start the contents tables. After starting each one, I'll make it
  1146. % be multicolumnar.
  1147. %
  1148. % \begin{macrocode}
  1149. \def\do##1##2{%
  1150. ##2%
  1151. \ifhave@multicol\addtocontents{##1}{%
  1152. \protect\begin{multicols}{2}%
  1153. \hbadness\@M%
  1154. }\fi%
  1155. }%
  1156. \docontents%
  1157. % \end{macrocode}
  1158. %
  1159. % Input the main file now.
  1160. %
  1161. % \begin{macrocode}
  1162. \DocInput{\@basefile}%
  1163. % \end{macrocode}
  1164. %
  1165. % That's it. I'm done.
  1166. %
  1167. % \begin{macrocode}
  1168. \end{document}
  1169. }
  1170. % \end{macrocode}
  1171. %
  1172. % \end{macro}
  1173. %
  1174. %
  1175. % \subsection{And finally\dots}
  1176. %
  1177. % Right at the end I'll put a hook for the configuration file.
  1178. %
  1179. % \begin{macrocode}
  1180. \ifx\mdwhook\@@undefined\else\expandafter\mdwhook\fi
  1181. % \end{macrocode}
  1182. %
  1183. % That's all the code done now. I'll change back to `user' mode, where
  1184. % all the magic control sequences aren't allowed any more.
  1185. %
  1186. % \begin{macrocode}
  1187. \makeatother
  1188. %</mdwtools>
  1189. % \end{macrocode}
  1190. %
  1191. % Oh, wait! What if I want to typeset this documentation? Aha. I'll cope
  1192. % with that by comparing |\jobname| with my filename |mdwtools|. However,
  1193. % there's some fun here, because |\jobname| contains category-12 letters,
  1194. % while my letters are category-11. Time to play with |\string| in a messy
  1195. % way.
  1196. %
  1197. % \begin{macrocode}
  1198. %<*driver>
  1199. \makeatletter
  1200. \edef\@tempa{\expandafter\@gobble\string\mdwtools}
  1201. \edef\@tempb{\jobname}
  1202. \ifx\@tempa\@tempb
  1203. \describesfile*{mdwtools.tex}
  1204. \docfile{mdwtools.tex}
  1205. \makeatother
  1206. \expandafter\mdwdoc
  1207. \fi
  1208. \makeatother
  1209. %</driver>
  1210. % \end{macrocode}
  1211. %
  1212. % That's it. Done!
  1213. %
  1214. % \hfill Mark Wooding, \today
  1215. %
  1216. % \Finale
  1217. %
  1218. \endinput