diff options
Diffstat (limited to 'Master/texmf-dist/doc/latex/mdwtools/mdwtools.tex')
-rw-r--r-- | Master/texmf-dist/doc/latex/mdwtools/mdwtools.tex | 1212 |
1 files changed, 1212 insertions, 0 deletions
diff --git a/Master/texmf-dist/doc/latex/mdwtools/mdwtools.tex b/Master/texmf-dist/doc/latex/mdwtools/mdwtools.tex new file mode 100644 index 00000000000..63abfc4acf4 --- /dev/null +++ b/Master/texmf-dist/doc/latex/mdwtools/mdwtools.tex @@ -0,0 +1,1212 @@ +% \begin{meta-comment} +% +% $Id: mdwtools.tex,v 1.4 1996/11/19 20:55:55 mdw Exp $ +% +% Common declarations for mdwtools.dtx files +% +% (c) 1996 Mark Wooding +% +%----- Revision history ----------------------------------------------------- +% +% $Log: mdwtools.tex,v $ +% Revision 1.4 1996/11/19 20:55:55 mdw +% Entered into RCS +% +% +% \end{meta-comment} +% +% \begin{meta-comment} <general public licence> +%% +%% mdwtools common declarations +%% Copyright (c) 1996 Mark Wooding +%% +%% This program is free software; you can redistribute it and/or modify +%% it under the terms of the GNU General Public License as published by +%% the Free Software Foundation; either version 2 of the License, or +%% (at your option) any later version. +%% +%% This program is distributed in the hope that it will be useful, +%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +%% GNU General Public License for more details. +%% +%% You should have received a copy of the GNU General Public License +%% along with this program; if not, write to the Free Software +%% Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +%% +% \end{meta-comment} +% +% \begin{meta-comment} <file preamble> +%<*mdwtools> +\ProvidesFile{mdwtools.tex} + [1996/05/10 1.4 Shared definitions for mdwtools .dtx files] +%</mdwtools> +% \end{meta-comment} +% +% \CheckSum{668} +%% \CharacterTable +%% {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 +%% 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 +%% Digits \0\1\2\3\4\5\6\7\8\9 +%% Exclamation \! Double quote \" Hash (number) \# +%% Dollar \$ Percent \% Ampersand \& +%% Acute accent \' Left paren \( Right paren \) +%% Asterisk \* Plus \+ Comma \, +%% Minus \- Point \. Solidus \/ +%% Colon \: Semicolon \; Less than \< +%% Equals \= Greater than \> Question mark \? +%% Commercial at \@ Left bracket \[ Backslash \\ +%% Right bracket \] Circumflex \^ Underscore \_ +%% Grave accent \` Left brace \{ Vertical bar \| +%% Right brace \} Tilde \~} +%% +% +% \section{Introduction and user guide} +% +% This file is really rather strange; it gets |\input| by other package +% documentation files to set up most of the environmental gubbins for them. +% It handles almost everything, like loading a document class, finding any +% packages, and building and formatting the title. +% +% It also offers an opportunity for users to customise my nice documentation, +% by using a |mdwtools.cfg| file (not included). +% +% +% \subsection{Declarations} +% +% A typical documentation file contains something like +% \begin{listinglist} \listingsize \obeylines +% |\input{mdwtools}| +% \<declarations> +% |\mdwdoc| +% \end{listinglist} +% The initial |\input| reads in this file and sets up the various commands +% which may be needed. The final |\mdwdoc| actually starts the document, +% inserting a title (which is automatically generated), a table of +% contents etc., and reads the documentation file in (using the |\DocInput| +% command from the \package{doc} package. +% +% \subsubsection{Describing packages} +% +% \DescribeMacro{\describespackage} +% \DescribeMacro{\describesclass} +% \DescribeMacro{\describesfile} +% \DescribeMacro{\describesfile*} +% The most important declarations are those which declare what the +% documentation describes. Saying \syntax{"\\describespackage{<package>}"} +% loads the \<package> (if necessary) and adds it to the auto-generated +% title, along with a footnote containing version information. Similarly, +% |\describesclass| adds a document class name to the title (without loading +% it -- the document itself must do this, with the |\documentclass| command). +% For files which aren't packages or classes, use the |\describesfile| or +% |\describesfile*| command (the $*$-version won't |\input| the file, which +% is handy for files like |mdwtools.tex|, which are already input). +% +% \DescribeMacro{\author} +% \DescribeMacro{\date} +% \DescribeMacro{\title} +% The |\author|, |\date| and |\title| declarations work slightly differently +% to normal -- they ensure that only the \emph{first} declaration has an +% effect. (Don't you play with |\author|, please, unless you're using this +% program to document your own packages.) Using |\title| suppresses the +% automatic title generation. +% +% \DescribeMacro{\docdate} +% The default date is worked out from the version string of the package or +% document class whose name is the same as that of the documentation file. +% You can choose a different `main' file by saying +% \syntax{"\\docdate{"<file>"}"}. +% +% \subsubsection{Contents handling} +% +% \DescribeMacro{\addcontents} +% A documentation file always has a table of contents. Other +% contents-like lists can be added by saying +% \syntax{"\\addcontents{"<extension>"}{"<command>"}"}. The \<extension> +% is the file extension of the contents file (e.g., \lit{lot} for the +% list of tables); the \<command> is the command to actually typeset the +% contents file (e.g., |\listoftables|). +% +% \subsubsection{Other declarations} +% +% \DescribeMacro{\implementation} +% The \package{doc} package wants you to say +% \syntax{"\\StopEventually{"<stuff>"}"}' before describing the package +% implementation. Using |mdwtools.tex|, you just say |\implementation|, and +% everything works. It will automatically read in the licence text (from +% |gpl.tex|, and wraps some other things up. +% +% +% \subsection{Other commands} +% +% The |mdwtools.tex| file includes the \package{syntax} and \package{sverb} +% packages so that they can be used in documentation files. It also defines +% some trivial commands of its own. +% +% \DescribeMacro{\<} +% Saying \syntax{"\\<"<text>">" is the same as "\\synt{"<text>"}"}; this +% is a simple abbreviation. +% +% \DescribeMacro{\smallf} +% Saying \syntax{"\\smallf" <number>"/"<number>} typesets a little fraction, +% like this: \smallf 3/4. It's useful when you want to say that the default +% value of a length is 2 \smallf 1/2\,pt, or something like that. +% +% +% \subsection{Customisation} +% +% You can customise the way that the package documentation looks by writing +% a file called |mdwtools.cfg|. You can redefine various commands (before +% they're defined here, even; |mdwtools.tex| checks most of the commands that +% it defines to make sure they haven't been defined already. +% +% \DescribeMacro{\indexing} +% If you don't want the prompt about whether to generate index files, you +% can define the |\indexing| command to either \lit{y} or \lit{n}. I'd +% recommend that you use |\providecommand| for this, to allow further +% customisation from the command line. +% +% \DescribeMacro{\mdwdateformat} +% If you don't like my date format (maybe you're American or something), +% you can redefine the |\mdwdateformat| command. It takes three arguments: +% the year, month and date, as numbers; it should expand to something which +% typesets the date nicely. The default format gives something like +% `10 May 1996'. You can produce something rather more exotic, like +% `10\textsuperscript{th} May \textsc{\romannumeral 1996}' by saying +%\begin{listing} +%\newcommand{\mdwdateformat}[3]{% +% \number#3\textsuperscript{\numsuffix{#3}}\ % +% \monthname{#2}\ % +% \textsc{\romannumeral #1}% +%} +%\end{listing} +% \DescribeMacro{\monthname} +% \DescribeMacro{\numsuffix} +% Saying \syntax{"\\monthname{"<number>"}"} expands to the name of the +% numbered month (which can be useful when doing date formats). Saying +% \syntax{"\\numsuffix{"<number>"}"} will expand to the appropriate suffix +% (`th' or `rd' or whatever) for the \<number>. You'll have to superscript +% it yourself, if this is what you want to do. Putting the year number +% in roman numerals is just pretentious |;-)|. +% +% \DescribeMacro{\mdwhook} +% After all the declarations in |mdwtools.tex|, the command |\mdwhook| is +% executed, if it exists. This can be set up by the configuration file +% to do whatever you want. +% +% There are lots of other things you can play with; you should look at the +% implementation section to see what's possible. +% +% \implementation +% +% \section{Implementation} +% +% \begin{macrocode} +%<*mdwtools> +% \end{macrocode} +% +% The first thing is that I'm not a \LaTeX\ package or anything official +% like that, so I must enable `|@|' as a letter by hand. +% +% \begin{macrocode} +\makeatletter +% \end{macrocode} +% +% Now input the user's configuration file, if it exists. This is fairly +% simple stuff. +% +% \begin{macrocode} +\@input{mdwtools.cfg} +% \end{macrocode} +% +% Well, that's the easy bit done. +% +% +% \subsection{Initialisation} +% +% Obviously the first thing to do is to obtain a document class. Obviously, +% it would be silly to do this if a document class has already been loaded, +% either by the package documentation or by the configuration file. +% +% The only way I can think of for finding out if a document class is already +% loaded is by seeing if the |\documentclass| command has been redefined +% to raise an error. This isn't too hard, really. +% +% \begin{macrocode} +\ifx\documentclass\@twoclasseserror\else + \documentclass[a4paper]{ltxdoc} + \ifx\doneclasses\mdw@undefined\else\doneclasses\fi +\fi +% \end{macrocode} +% +% As part of my standard environment, I'll load some of my more useful +% packages. If they're already loaded (possibly with different options), +% I'll not try to load them again. +% +% \begin{macrocode} +\@ifpackageloaded{doc}{}{\usepackage{doc}} +\@ifpackageloaded{syntax}{}{\usepackage[rounded]{syntax}} +\@ifpackageloaded{sverb}{}{\usepackage{sverb}} +% \end{macrocode} +% +% +% \subsection{Some macros for interaction} +% +% I like the \LaTeX\ star-boxes, although it's a pain having to cope with +% \TeX's space-handling rules. I'll define a new typing-out macro which +% makes spaces more significant, and has a $*$-version which doesn't put +% a newline on the end, and interacts prettily with |\read|. +% +% First of all, I need to make spaces active, so I can define things about +% active spaces. +% +% \begin{macrocode} +\begingroup\obeyspaces +% \end{macrocode} +% +% Now to define the main macro. This is easy stuff. Spaces must be +% carefully rationed here, though. +% +% I'll start a group, make spaces active, and make spaces expand to ordinary +% space-like spaces. Then I'll look for a star, and pass either |\message| +% (which doesn't start a newline, and interacts with |\read| well) or +% |\immediate\write 16| which does a normal write well. +% +% \begin{macrocode} +\gdef\mdwtype{% +\begingroup\catcode`\ \active\let \space% +\@ifstar{\mdwtype@i{\message}}{\mdwtype@i{\immediate\write\sixt@@n}}% +} +\endgroup +% \end{macrocode} +% +% Now for the easy bit. I have the thing to do, and the thing to do it to, +% so do that and end the group. +% +% \begin{macrocode} +\def\mdwtype@i#1#2{#1{#2}\endgroup} +% \end{macrocode} +% +% +% \subsection{Decide on indexing} +% +% A configuration file can decide on indexing by defining the |\indexing| +% macro to either \lit{y} or \lit{n}. If it's not set, then I'll prompt +% the user. +% +% First of all, I want a switch to say whether I'm indexing. +% +% \begin{macrocode} +\newif\ifcreateindex +% \end{macrocode} +% +% Right: now I need to decide how to make progress. If the macro's not set, +% then I want to set it, and start a row of stars. +% +% \begin{macrocode} +\ifx\indexing\@@undefined + \mdwtype{*****************************} + \def\indexing{?} +\fi +% \end{macrocode} +% +% Now enter a loop, asking the user whether to do indexing, until I get +% a sensible answer. +% +% \begin{macrocode} +\loop + \@tempswafalse + \if y\indexing\@tempswatrue\createindextrue\fi + \if Y\indexing\@tempswatrue\createindextrue\fi + \if n\indexing\@tempswatrue\createindexfalse\fi + \if N\indexing\@tempswatrue\createindexfalse\fi + \if@tempswa\else + \mdwtype*{* Create index files? (y/n) *} + \read\sixt@@n to\indexing% +\repeat +% \end{macrocode} +% +% Now, based on the results of that, display a message about the indexing. +% +% \begin{macrocode} +\mdwtype{*****************************} +\ifcreateindex + \mdwtype{* Creating index files *} + \mdwtype{* This may take some time *} +\else + \mdwtype{* Not creating index files *} +\fi +\mdwtype{*****************************} +% \end{macrocode} +% +% Now I can play with the indexing commands of the \package{doc} package +% to do whatever it is that the user wants. +% +% \begin{macrocode} +\ifcreateindex + \CodelineIndex + \EnableCrossrefs +\else + \CodelineNumbered + \DisableCrossrefs +\fi +% \end{macrocode} +% +% And register lots of plain \TeX\ things which shouldn't be indexed. +% This contains lots of |\if|\dots\ things which don't fit nicely in +% conditionals, which is a shame. Still, it doesn't matter that much, +% really. +% +% \begin{macrocode} +\DoNotIndex{\def,\long,\edef,\xdef,\gdef,\let,\global} +\DoNotIndex{\if,\ifnum,\ifdim,\ifcat,\ifmmode,\ifvmode,\ifhmode,% + \iftrue,\iffalse,\ifvoid,\ifx,\ifeof,\ifcase,\else,\or,\fi} +\DoNotIndex{\box,\copy,\setbox,\unvbox,\unhbox,\hbox,% + \vbox,\vtop,\vcenter} +\DoNotIndex{\@empty,\immediate,\write} +\DoNotIndex{\egroup,\bgroup,\expandafter,\begingroup,\endgroup} +\DoNotIndex{\divide,\advance,\multiply,\count,\dimen} +\DoNotIndex{\relax,\space,\string} +\DoNotIndex{\csname,\endcsname,\@spaces,\openin,\openout,% + \closein,\closeout} +\DoNotIndex{\catcode,\endinput} +\DoNotIndex{\jobname,\message,\read,\the,\m@ne,\noexpand} +\DoNotIndex{\hsize,\vsize,\hskip,\vskip,\kern,\hfil,\hfill,\hss} +\DoNotIndex{\m@ne,\z@,\z@skip,\@ne,\tw@,\p@} +\DoNotIndex{\dp,\wd,\ht,\vss,\unskip} +% \end{macrocode} +% +% Last bit of indexing stuff, for now: I'll typeset the index in two columns +% (the default is three, which makes them too narrow for my tastes). +% +% \begin{macrocode} +\setcounter{IndexColumns}{2} +% \end{macrocode} +% +% +% \subsection{Selectively defining things} +% +% I don't want to tread on anyone's toes if they redefine any of these +% commands and things in a configuration file. The following definitions +% are fairly evil, but should do the job OK. +% +% \begin{macro}{\@gobbledef} +% +% This macro eats the following |\def|inition, leaving not a trace behind. +% +% \begin{macrocode} +\def\@gobbledef#1#{\@gobble} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\tdef} +% \begin{macro}{\tlet} +% +% The |\tdef| command is a sort of `tentative' definition -- it's like +% |\def| if the control sequence named doesn't already have a definition. +% |\tlet| does the same thing with |\let|. +% +% \begin{macrocode} +\def\tdef#1{ + \ifx#1\@@undefined% + \expandafter\def\expandafter#1% + \else% + \expandafter\@gobbledef% + \fi% +} +\def\tlet#1#2{\ifx#1\@@undefined\let#1=#2\fi} +% \end{macrocode} +% +% \end{macro} +% \end{macro} +% +% +% \subsection{General markup things} +% +% Now for some really simple things. I'll define how to typeset package +% names and environment names (both in the sans serif font, for now). +% +% \begin{macrocode} +\tlet\package\textsf +\tlet\env\textsf +% \end{macrocode} +% +% I'll define the |\<|\dots|>| shortcut for syntax items suggested in the +% \package{syntax} package. +% +% \begin{macrocode} +\tdef\<#1>{\synt{#1}} +% \end{macrocode} +% +% And because it's used in a few places (mainly for typesetting lengths), +% here's a command for typesetting fractions in text. +% +% \begin{macrocode} +\tdef\smallf#1/#2{\ensuremath{^{#1}\!/\!_{#2}}} +% \end{macrocode} +% +% +% \subsection{A table environment} +% +% \begin{environment}{tab} +% +% Most of the packages don't use the (obviously perfect) \package{mdwtab} +% package, because it's big, and takes a while to load. Here's an +% environment for typesetting centred tables. The first (optional) argument +% is some declarations to perform. The mandatory argument is the table +% preamble (obviously). +% +% \begin{macrocode} +\@ifundefined{tab}{% + \newenvironment{tab}[2][\relax]{% + \par\vskip2ex% + \centering% + #1% + \begin{tabular}{#2}% + }{% + \end{tabular}% + \par\vskip2ex% + } +}{} +% \end{macrocode} +% +% \end{environment} +% +% +% \subsection{Commenting out of stuff} +% +% \begin{environment}{meta-comment} +% +% Using |\iffalse|\dots|\fi| isn't much fun. I'll define a gobbling +% environment using the \package{sverb} stuff. +% +% \begin{macrocode} +\ignoreenv{meta-comment} +% \end{macrocode} +% +% \end{environment} +% +% +% \subsection{Float handling} +% +% This gubbins will try to avoid float pages as much as possible, and (with +% any luck) encourage floats to be put on the same pages as text. +% +% \begin{macrocode} +\def\textfraction{0.1} +\def\topfraction{0.9} +\def\bottomfraction{0.9} +\def\floatpagefraction{0.7} +% \end{macrocode} +% +% Now redefine the default float-placement parameters to allow `here' floats. +% +% \begin{macrocode} +\def\fps@figure{htbp} +\def\fps@table{htbp} +% \end{macrocode} +% +% +% \subsection{Other bits of parameter tweaking} +% +% Make \env{grammar} environments look pretty, by indenting the left hand +% sides by a large amount. +% +% \begin{macrocode} +\grammarindent1in +% \end{macrocode} +% +% I don't like being told by \TeX\ that my paragraphs are hard to linebreak: +% I know this already. This lot should shut \TeX\ up about most problems. +% +% \begin{macrocode} +\sloppy +\hbadness\@M +\hfuzz10\p@ +% \end{macrocode} +% +% Also make \TeX\ shut up in the index. The \package{multicol} package +% irritatingly plays with |\hbadness|. This is the best hook I could find +% for playing with this setting. +% +% \begin{macrocode} +\expandafter\def\expandafter\IndexParms\expandafter{% + \IndexParms% + \hbadness\@M% +} +% \end{macrocode} +% +% The other thing I really don't like is `Marginpar moved' warnings. This +% will get rid of them, and lots of other \LaTeX\ warnings at the same time. +% +% \begin{macrocode} +\let\@latex@warning@no@line\@gobble +% \end{macrocode} +% +% Put some extra space between table rows, please. +% +% \begin{macrocode} +\def\arraystretch{1.2} +% \end{macrocode} +% +% Most of the code is at guard level one, so typeset that in upright text. +% +% \begin{macrocode} +\setcounter{StandardModuleDepth}{1} +% \end{macrocode} +% +% +% \subsection{Contents handling} +% +% I use at least one contents file (the main table of contents) although +% I may want more. I'll keep a list of contents files which I need to +% handle. +% +% There are two things I need to do to contents files here: +% \begin{itemize} +% \item I must typeset the table of contents at the beginning of the +% document; and +% \item I want to typeset tables of contents in two columns (using the +% \package{multicol} package). +% \end{itemize} +% +% The list consists of items of the form +% \syntax{"\\do{"<extension>"}{"<command>"}"}, where \<extension> is the +% file extension of the contents file, and \<command> is the command to +% typeset it. +% +% \begin{macro}{\docontents} +% +% This is where I keep the list of contents files. I'll initialise it to +% just do the standard contents table. +% +% \begin{macrocode} +\def\docontents{\do{toc}{\tableofcontents}} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\addcontents} +% +% By saying \syntax{"\\addcontents{"<extension>"}{"<command>"}"}, a document +% can register a new table of contents which gets given the two-column +% treatment properly. This is really easy to implement. +% +% \begin{macrocode} +\def\addcontents#1#2{% + \toks@\expandafter{\docontents\do{#1}{#2}}% + \edef\docontents{\the\toks@}% +} +% \end{macrocode} +% +% \end{macro} +% +% +% \subsection{Finishing it all off} +% +% \begin{macro}{\finalstuff} +% +% The |\finalstuff| macro is a hook for doing things at the end of the +% document. Currently, it inputs the licence agreement as an appendix. +% +% \begin{macrocode} +\tdef\finalstuff{\appendix\part*{Appendix}\input{gpl}} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\implementation} +% +% The |\implementation| macro starts typesetting the implementation of +% the package(s). If we're not doing the implementation, it just does +% this lot and ends the input file. +% +% I define a macro with arguments inside the |\StopEventually|, which causes +% problems, since the code gets put through an extra level of |\def|fing +% depending on whether the implementation stuff gets typeset or not. I'll +% store the code I want to do in a separate macro. +% +% \begin{macrocode} +\def\implementation{\StopEventually{\attheend}} +% \end{macrocode} +% +% Now for the actual activity. First, I'll do the |\finalstuff|. Then, if +% \package{doc}'s managed to find the \package{multicol} package, I'll add +% the end of the environment to the end of each contents file in the list. +% Finally, I'll read the index in from its formatted |.ind| file. +% +% \begin{macrocode} +\tdef\attheend{% + \finalstuff% + \ifhave@multicol% + \def\do##1##2{\addtocontents{##1}{\protect\end{multicols}}}% + \docontents% + \fi% + \PrintIndex% +} +% \end{macrocode} +% +% \end{macro} +% +% +% \subsection{File version information} +% +% \begin{macro}{\mdwpkginfo} +% +% For setting up the automatic titles, I'll need to be able to work out +% file versions and things. This macro will, given a file name, extract +% from \LaTeX\ the version information and format it into a sensible string. +% +% First of all, I'll put the original string (direct from the +% |\Provides|\dots\ command). Then I'll pass it to another macro which can +% parse up the string into its various bits, along with the original +% filename. +% +% \begin{macrocode} +\def\mdwpkginfo#1{% + \edef\@tempa{\csname ver@#1\endcsname}% + \expandafter\mdwpkginfo@i\@tempa\@@#1\@@% +} +% \end{macrocode} +% +% Now for the real business. I'll store the string I build in macros called +% \syntax{"\\"<filename>"date", "\\"<filename>"version" and +% "\\"<filename>"info"}, which store the file's date, version and +% `information string' respectively. (Note that the file extension isn't +% included in the name.) +% +% This is mainly just tedious playing with |\expandafter|. The date format +% is defined by a separate macro, which can be modified from the +% configuration file. +% +% \begin{macrocode} +\def\mdwpkginfo@i#1/#2/#3 #4 #5\@@#6.#7\@@{% + \expandafter\def\csname #6date\endcsname% + {\protect\mdwdateformat{#1}{#2}{#3}}% + \expandafter\def\csname #6version\endcsname{#4}% + \expandafter\def\csname #6info\endcsname{#5}% +} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\mdwdateformat} +% +% Given three arguments, a year, a month and a date (all numeric), build a +% pretty date string. This is fairly simple really. +% +% \begin{macrocode} +\tdef\mdwdateformat#1#2#3{\number#3\ \monthname{#2}\ \number#1} +\def\monthname#1{% + \ifcase#1\or% + January\or February\or March\or April\or May\or June\or% + July\or August\or September\or October\or November\or December% + \fi% +} +\def\numsuffix#1{% + \ifnum#1=1 st\else% + \ifnum#1=2 nd\else% + \ifnum#1=3 rd\else% + \ifnum#1=21 st\else% + \ifnum#1=22 nd\else% + \ifnum#1=23 rd\else% + \ifnum#1=31 st\else% + th% + \fi\fi\fi\fi\fi\fi\fi% +} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\mdwfileinfo} +% +% Saying \syntax{"\\mdwfileinfo{"<file-name>"}{"<info>"}"} extracts the +% wanted item of \<info> from the version information for file \<file-name>. +% +% \begin{macrocode} +\def\mdwfileinfo#1#2{\mdwfileinfo@i{#2}#1.\@@} +\def\mdwfileinfo@i#1#2.#3\@@{\csname#2#1\endcsname} +% \end{macrocode} +% +% \end{macro} +% +% +% \subsection{List handling} +% +% There are several other lists I need to build. These macros will do +% the necessary stuff. +% +% \begin{macro}{\mdw@ifitem} +% +% The macro \syntax{"\\mdw@ifitem"<item>"\\in"<list>"{"<true-text>"}"^^A +% "{"<false-text>"}"} does \<true-text> if the \<item> matches any item in +% the \<list>; otherwise it does \<false-text>. +% +% \begin{macrocode} +\def\mdw@ifitem#1\in#2{% + \@tempswafalse% + \def\@tempa{#1}% + \def\do##1{\def\@tempb{##1}\ifx\@tempa\@tempb\@tempswatrue\fi}% + #2% + \if@tempswa\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi% +} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\mdw@append} +% +% Saying \syntax{"\\mdw@append"<item>"\\to"<list>} adds the given \<item> +% to the end of the given \<list>. +% +% \begin{macrocode} +\def\mdw@append#1\to#2{% + \toks@{\do{#1}}% + \toks\tw@\expandafter{#2}% + \edef#2{\the\toks\tw@\the\toks@}% +} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\mdw@prepend} +% +% Saying \syntax{"\\mdw@prepend"<item>"\\to"<list>} adds the \<item> to the +% beginning of the \<list>. +% +% \begin{macrocode} +\def\mdw@prepend#1\to#2{% + \toks@{\do{#1}}% + \toks\tw@\expandafter{#2}% + \edef#2{\the\toks@\the\toks\tw@}% +} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\mdw@add} +% +% Finally, saying \syntax{"\\mdw@add"<item>"\\to"<list>} adds the \<item> +% to the list only if it isn't there already. +% +% \begin{macrocode} +\def\mdw@add#1\to#2{\mdw@ifitem#1\in#2{}{\mdw@append#1\to#2}} +% \end{macrocode} +% +% \end{macro} +% +% +% \subsection{Described file handling} +% +% I'l maintain lists of packages, document classes, and other files +% described by the current documentation file. +% +% First of all, I'll declare the various list macros. +% +% \begin{macrocode} +\def\dopackages{} +\def\doclasses{} +\def\dootherfiles{} +% \end{macrocode} +% +% \begin{macro}{\describespackage} +% +% A document file can declare that it describes a package by saying +% \syntax{"\\describespackage{"<package-name>"}"}. I add the package to +% my list, read the package into memory (so that the documentation can +% offer demonstrations of it) and read the version information. +% +% \begin{macrocode} +\def\describespackage#1{% + \mdw@ifitem#1\in\dopackages{}{% + \mdw@append#1\to\dopackages% + \usepackage{#1}% + \mdwpkginfo{#1.sty}% + }% +} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\describesclass} +% +% By saying \syntax{"\\describesclass{"<class-name>"}"}, a document file +% can declare that it describes a document class. I'll assume that the +% document class is already loaded, because it's much too late to load +% it now. +% +% \begin{macrocode} +\def\describesclass#1{\mdw@add#1\to\doclasses\mdwpkginfo{#1.cls}} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\describesfile} +% +% Finally, other `random' files, which don't have the status of real \LaTeX\ +% packages or document classes, can be described by saying \syntax{^^A +% "\\describesfile{"<file-name>"}" or "\\describesfile*{"<file-name>"}"}. +% The difference is that the starred version will not |\input| the file. +% +% \begin{macrocode} +\def\describesfile{% + \@ifstar{\describesfile@i\@gobble}{\describesfile@i\input}% +} +\def\describesfile@i#1#2{% + \mdw@ifitem#2\in\dootherfiles{}{% + \mdw@add#2\to\dootherfiles% + #1{#2}% + \mdwpkginfo{#2}% + }% +} +% \end{macrocode} +% +% \end{macro} +% +% +% \subsection{Author and title handling} +% +% I'll redefine the |\author| and |\title| commands so that I get told +% whether I need to do it myself. +% +% \begin{macro}{\author} +% +% This is easy: I'll save the old meaning, and then redefine |\author| to +% do the old thing and redefine itself to then do nothing. +% +% \begin{macrocode} +\let\mdw@author\author +\def\author{\let\author\@gobble\mdw@author} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\title} +% +% And oddly enough, I'll do exactly the same thing for the title, except +% that I'll also disable the |\mdw@buildtitle| command, which constructs +% the title automatically. +% +% \begin{macrocode} +\let\mdw@title\title +\def\title{\let\title\@gobble\let\mdw@buildtitle\relax\mdw@title} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\date} +% +% This works in a very similar sort of way. +% +% \begin{macrocode} +\def\date#1{\let\date\@gobble\def\today{#1}} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\datefrom} +% +% Saying \syntax{"\\datefrom{"<file-name>"}"} sets the document date from +% the given filename. +% +% \begin{macrocode} +\def\datefrom#1{% + \protected@edef\@tempa{\noexpand\date{\csname #1date\endcsname}}% + \@tempa% +} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\docfile} +% +% Saying \syntax{"\\docfile{"<file-name>"}"} sets up the file name from which +% documentation will be read. +% +% \begin{macrocode} +\def\docfile#1{% + \def\@tempa##1.##2\@@{\def\@basefile{##1.##2}\def\@basename{##1}}% + \edef\@tempb{\noexpand\@tempa#1\noexpand\@@}% + \@tempb% +} +% \end{macrocode} +% +% I'll set up a default value as well. +% +% \begin{macrocode} +\docfile{\jobname.dtx} +% \end{macrocode} +% +% \end{macro} +% +% +% \subsection{Building title strings} +% +% This is rather tricky. For each list, I need to build a legible looking +% string. +% +% \begin{macro}{\mdw@addtotitle} +% +% By saying +%\syntax{"\\mdw@addtotitle{"<list>"}{"<command>"}{"<singular>"}{"<plural>"}"} +% I can add the contents of a list to the current title string in the +% |\mdw@title| macro. +% +% \begin{macrocode} +\tdef\mdw@addtotitle#1#2#3#4{% +% \end{macrocode} +% +% Now to get to work. I need to keep one `lookahead' list item, and a count +% of the number of items read so far. I'll keep the lookahead item in +% |\@nextitem| and the counter in |\count@|. +% +% \begin{macrocode} + \count@\z@% +% \end{macrocode} +% +% Now I'll define what to do for each list item. The |\protect| command is +% already set up appropriately for playing with |\edef| commands. +% +% \begin{macrocode} + \def\do##1{% +% \end{macrocode} +% +% The first job is to add the previous item to the title string. If this +% is the first item, though, I'll just add the appropriate \lit{The } or +% \lit{ and the } string to the title (this is stored in the |\@prefix| +% macro). +% +% \begin{macrocode} + \edef\mdw@title{% + \mdw@title% + \ifcase\count@\@prefix% + \or\@nextitem% + \else, \@nextitem% + \fi% + }% +% \end{macrocode} +% +% That was rather easy. Now I'll set up the |\@nextitem| macro for the +% next time around the loop. +% +% \begin{macrocode} + \edef\@nextitem{% + \protect#2{##1}% + \protect\footnote{% + The \protect#2{##1} #3 is currently at version % + \mdwfileinfo{##1}{version}, dated \mdwfileinfo{##1}{date}.% + }\space% + }% +% \end{macrocode} +% +% Finally, I need to increment the counter. +% +% \begin{macrocode} + \advance\count@\@ne% + }% +% \end{macrocode} +% +% Now execute the list. +% +% \begin{macrocode} + #1% +% \end{macrocode} +% +% I still have one item left over, unless the list was empty. I'll add +% that now. +% +% \begin{macrocode} + \edef\mdw@title{% + \mdw@title% + \ifcase\count@% + \or\@nextitem\space#3% + \or\ and \@nextitem\space#4% + \fi% + }% +% \end{macrocode} +% +% Finally, if $|\count@| \ne 0$, I must set |\@prefix| to \lit{ and the }. +% +% \begin{macrocode} + \ifnum\count@>\z@\def\@prefix{ and the }\fi% +} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\mdw@buildtitle} +% +% This macro will actually do the job of building the title string. +% +% \begin{macrocode} +\tdef\mdw@buildtitle{% +% \end{macrocode} +% +% First of all, I'll open a group to avoid polluting the namespace with +% my gubbins (although the code is now much tidier than it has been in +% earlier releases). +% +% \begin{macrocode} + \begingroup% +% \end{macrocode} +% +% The title building stuff makes extensive use of |\edef|. I'll set +% |\protect| appropriately. (For those not in the know, +% |\@unexpandable@protect| expands to `|\noexpand\protect\noexpand|', +% which prevents expansion of the following macro, and inserts a |\protect| +% in front of it ready for the next |\edef|.) +% +% \begin{macrocode} + \let\@@protect\protect\let\protect\@unexpandable@protect% +% \end{macrocode} +% +% Set up some simple macros ready for the main code. +% +% \begin{macrocode} + \def\mdw@title{}% + \def\@prefix{The }% +% \end{macrocode} +% +% Now build the title. This is fun. +% +% \begin{macrocode} + \mdw@addtotitle\dopackages\package{package}{packages}% + \mdw@addtotitle\doclasses\package{document class}{document classes}% + \mdw@addtotitle\dootherfiles\texttt{file}{files}% +% \end{macrocode} +% +% Now I want to end the group and set the title from my string. The +% following hacking will do this. +% +% \begin{macrocode} + \edef\next{\endgroup\noexpand\title{\mdw@title}}% + \next% +} +% \end{macrocode} +% +% \end{macro} +% +% +% \subsection{Starting the main document} +% +% \begin{macro}{\mdwdoc} +% +% Once the document preamble has done all of its stuff, it calls the +% |\mdwdoc| command, which takes over and really starts the documentation +% going. +% +% \begin{macrocode} +\def\mdwdoc{% +% \end{macrocode} +% +% First, I'll construct the title string. +% +% \begin{macrocode} + \mdw@buildtitle% + \author{Mark Wooding}% +% \end{macrocode} +% +% Set up the date string based on the date of the package which shares +% the same name as the current file. +% +% \begin{macrocode} + \datefrom\@basename% +% \end{macrocode} +% +% Set up verbatim characters after all the packages have started. +% +% \begin{macrocode} + \shortverb\|% + \shortverb\"% +% \end{macrocode} +% +% Start the document, and put the title in. +% +% \begin{macrocode} + \begin{document} + \maketitle% +% \end{macrocode} +% +% This is nasty. It makes maths displays work properly in demo environments. +% \emph{The \LaTeX\ Companion} exhibits the bug which this hack fixes. So +% ner. +% +% \begin{macrocode} + \abovedisplayskip\z@% +% \end{macrocode} +% +% Now start the contents tables. After starting each one, I'll make it +% be multicolumnar. +% +% \begin{macrocode} + \def\do##1##2{% + ##2% + \ifhave@multicol\addtocontents{##1}{% + \protect\begin{multicols}{2}% + \hbadness\@M% + }\fi% + }% + \docontents% +% \end{macrocode} +% +% Input the main file now. +% +% \begin{macrocode} + \DocInput{\@basefile}% +% \end{macrocode} +% +% That's it. I'm done. +% +% \begin{macrocode} + \end{document} +} +% \end{macrocode} +% +% \end{macro} +% +% +% \subsection{And finally\dots} +% +% Right at the end I'll put a hook for the configuration file. +% +% \begin{macrocode} +\ifx\mdwhook\@@undefined\else\expandafter\mdwhook\fi +% \end{macrocode} +% +% That's all the code done now. I'll change back to `user' mode, where +% all the magic control sequences aren't allowed any more. +% +% \begin{macrocode} +\makeatother +%</mdwtools> +% \end{macrocode} +% +% Oh, wait! What if I want to typeset this documentation? Aha. I'll cope +% with that by comparing |\jobname| with my filename |mdwtools|. However, +% there's some fun here, because |\jobname| contains category-12 letters, +% while my letters are category-11. Time to play with |\string| in a messy +% way. +% +% \begin{macrocode} +%<*driver> +\makeatletter +\edef\@tempa{\expandafter\@gobble\string\mdwtools} +\edef\@tempb{\jobname} +\ifx\@tempa\@tempb + \describesfile*{mdwtools.tex} + \docfile{mdwtools.tex} + \makeatother + \expandafter\mdwdoc +\fi +\makeatother +%</driver> +% \end{macrocode} +% +% That's it. Done! +% +% \hfill Mark Wooding, \today +% +% \Finale +% +\endinput |