chiark / gitweb /
Release 1.8.2.
[mdwtools] / mdwlist.dtx
1 % \begin{meta-comment}
2 %
3 % $Id: mdwlist.dtx,v 1.2 2003/09/05 16:13:44 mdw Exp $
4 %
5 % Various list-related things
6 %
7 % (c) 1996 Mark Wooding
8 %
9 % \end{meta-comment}
10 %
11 % \begin{meta-comment} <general public licence>
12 %%
13 %% mdwlist package -- various list-related things
14 %% Copyright (c) 1996 Mark Wooding
15 %%
16 %% This program is free software; you can redistribute it and/or modify
17 %% it under the terms of the GNU General Public License as published by
18 %% the Free Software Foundation; either version 2 of the License, or
19 %% (at your option) any later version.
20 %%
21 %% This program is distributed in the hope that it will be useful,
22 %% but WITHOUT ANY WARRANTY; without even the implied warranty of
23 %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24 %% GNU General Public License for more details.
25 %%
26 %% You should have received a copy of the GNU General Public License
27 %% along with this program; if not, write to the Free Software
28 %% Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 %%
30 % \end{meta-comment}
31 %
32 % \begin{meta-comment} <Package preambles>
33 %<+package>\NeedsTeXFormat{LaTeX2e}
34 %<+package>\ProvidesPackage{mdwlist}
35 %<+package>                [1996/05/02 1.1 Various list-related things]
36 % \end{meta-comment}
37 %
38 % \CheckSum{183}
39 %% \CharacterTable
40 %%  {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
41 %%   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
42 %%   Digits        \0\1\2\3\4\5\6\7\8\9
43 %%   Exclamation   \!     Double quote  \"     Hash (number) \#
44 %%   Dollar        \$     Percent       \%     Ampersand     \&
45 %%   Acute accent  \'     Left paren    \(     Right paren   \)
46 %%   Asterisk      \*     Plus          \+     Comma         \,
47 %%   Minus         \-     Point         \.     Solidus       \/
48 %%   Colon         \:     Semicolon     \;     Less than     \<
49 %%   Equals        \=     Greater than  \>     Question mark \?
50 %%   Commercial at \@     Left bracket  \[     Backslash     \\
51 %%   Right bracket \]     Circumflex    \^     Underscore    \_
52 %%   Grave accent  \`     Left brace    \{     Vertical bar  \|
53 %%   Right brace   \}     Tilde         \~}
54 %%
55 %
56 % \begin{meta-comment}
57 %
58 %<*driver>
59 \input{mdwtools}
60 \describespackage{mdwlist}
61 \def\defaultdesc{%
62   \desclabelwidth{80pt}%
63   \desclabelstyle\nextlinelabel%
64   \def\makelabel{\bfseries}%
65 }
66 \newenvironment{cmdlist}
67   {\basedescript{\let\makelabel\cmd}}
68   {\endbasedescript}
69 \mdwdoc
70 %</driver>
71 %
72 % \end{meta-comment}
73 %
74 % \section{User guide}
75 %
76 % This package provides some vaguely useful list-related commands and
77 % environments:
78 % \begin{itemize*}
79 % \item A way of building \env{description}-like environments.
80 % \item Commands for making `compacted' versions of list environments
81 % \item A method for suspending and resuming enumerated lists.
82 % \end{itemize*}
83 %
84 % \subsection{Description list handling}
85 %
86 % Different sorts of description-type lists require different sorts of
87 % formatting: I think that's fairly obvious.  There are essentially three
88 % different attributes which should be changable:
89 % \begin{itemize*}
90 % \item the indentation of the items being described,
91 % \item the handling of labels which don't fit properly, and
92 % \item the style used to typeset the label text.
93 % \end{itemize*}
94 % The first two items should usually be decided for all description-like
95 % lists in the document, to ensure consistency of appearance.  The last
96 % depends much more on the content of the labels.
97 %
98 % \DescribeEnv{basedescript}
99 % The \env{basedescript} environment acts as a `skeleton' for description
100 % environments.  It takes one argument, which contains declarations to
101 % be performed while constructing the list.  I'd consider it unusual for
102 % the \env{basedescript} environment to be used in the main text: it's
103 % intended to be used to build other environments.
104 %
105 % The declarations which can be used to define description-type environments
106 % include all of those which are allowed when setting up a list (see the
107 % \LaTeX\ book for information here).  Some others, which apply specifically
108 % to description lists, are also provided:
109 %
110 % \begin{itemize}
111 %
112 % \item \DescribeMacro{\desclabelwidth}
113 %       The \syntax{"\\desclabelwidth{"<length>"}"} declaration sets labels
114 %       to be left-aligned, with a standard width of \<length>; the item
115 %       text is indented by \<length> plus the value of |\labelsep|.
116 %
117 % \item \DescribeMacro{\desclabelstyle}
118 %       The label style determines how overlong labels are typeset.  A style
119 %       may be set using the \syntax{"\\desclabelstyle{"<style>"}"}
120 %       declaration.  The following \<style>s are provided:
121 %       \begin{cmdlist}
122 %       \item [\nextlinelabel] If the label is too wide to fit next to the
123 %             first line of text, then it is placed on a line by itself;
124 %             the main text is started on the next line with the usual
125 %             indentation.
126 %       \item [\multilinelabel] The label is typeset in a parbox with the
127 %             appropriate width; if it won't fit on one line, then the
128 %             text will be split onto subsequent lines.
129 %       \item [\pushlabel] If the label is too wide to fit in the space
130 %             allocated to it, the start of the item's text will be `pushed'
131 %             over to the right to provide space for the label.  This is
132 %             the standard \LaTeX\ \env{description} behaviour.
133 %       \end{cmdlist}
134 %
135 % \item \DescribeMacro{\makelabel}
136 %       The |\makelabel| command is responsible for typesetting a label.
137 %       It is given one argument, which is the text given as an argument
138 %       to the |\item| command; it should typeset it appropriately.  The
139 %       text will then be arranged appropriately according to the chosen
140 %       label style.  This command should be redefined using |\renewcommand|.
141 %
142 % \end{itemize}
143 %
144 % \begin{figure}
145 % \begin{demo}[w]{Various labelling styles}
146 %\begin{basedescript}{\desclabelstyle{\nextlinelabel}}
147 %\item [Short label] This is a short item, although it has quite a
148 %      lot of text attached to it.
149 %\item [Slightly longer label text] This is a rather longer piece
150 %      of text, with a correspondingly slightly longer label.
151 %\end{basedescript}
152 %\medskip
153 %\begin{basedescript}{\desclabelstyle{\multilinelabel}}
154 %\item [Short label] This is a short item, although it has quite a
155 %      lot of text attached to it.
156 %\item [Slightly longer label text] This is a rather longer piece
157 %      of text, with a correspondingly slightly longer label.
158 %\end{basedescript}
159 %\medskip
160 %\begin{basedescript}{\desclabelstyle{\pushlabel}}
161 %\item [Short label] This is a short item, although it has quite a
162 %      lot of text attached to it.
163 %\item [Slightly longer label text] This is a rather longer piece
164 %      of text, with a correspondingly slightly longer label.
165 %\end{basedescript}
166 % \end{demo}
167 % \end{figure}
168 %
169 % \DescribeMacro{\defaultdesc}
170 % To allow document designers to control the global appearance of description
171 % lists, the |\defaultdesc| command may be redefined; it is called while
172 % setting up a new \env{basedescript} list, before performing the user's
173 % declarations.  By default, it attempts to emulate the standard \LaTeX\
174 % \env{description} environment:\footnote{^^A
175 %   This is a slightly sanitised version of the real definition, which is
176 %   given in the implementation section of this document.}
177 % \begin{listing}
178 %\providecommand{\defaultdesc}{%
179 %  \desclabelstyle{\pushlabel}%
180 %  \renewcommand{\makelabel}[1]{\bfseries##1}%
181 %  \setlength{\labelwidth}{0pt}%
182 %}
183 % \end{listing}
184 % Unfortunately, \LaTeX\ doesn't provide a means for overriding a command
185 % which may or may not have been defined yet; in this case, I'd probably
186 % recommend using the \TeX\ primitive |\def| to redefine |\defaultdesc|.
187 %
188 % If you want to redefine the \env{description} environment in terms of
189 % the commands in this package, the following method is recommended:
190 % \begin{listing}
191 %\renewenvironment{description}{%
192 %  \begin{basedescript}{%
193 %    \renewcommand{\makelabel}[1]{\bfseries##1}%
194 %  }%
195 %}{%
196 %  \end{basedescript}%
197 %}
198 % \end{listing}
199 % This ensures that labels are typeset in bold, as is usual, but other
200 % properties of the list are determined by the overall document style.
201 %
202 % \subsection{Compacted lists}
203 %
204 % \LaTeX\ tends to leave a certain amount of vertical space between list
205 % items.  While this is normally correct for lists in which the items are
206 % several lines long, it tends to look odd if all or almost all the items
207 % are only one line long.
208 %
209 % \DescribeMacro{\makecompactlist}
210 % The command
211 % \syntax{"\\makecompactlist{"<new-env-name>"}{"<old-env-name>"}"}
212 % defines a new environment \<new-env-name> to be a `compacted' version of
213 % the existing environment \<old-env-name>; i.e., the two environments are
214 % the same except that the compacted version leaves no space between items
215 % or paragraphs within the list.
216 %
217 % \DescribeEnv{itemize*}
218 % \DescribeEnv{enumerate*}
219 % \DescribeEnv{description*}
220 % So that the most common cases are already handled, the package creates
221 % compacted $*$-variants of the \env{itemize}, \env{enumerate} and
222 % \env{description} environments.  These were created using the commands
223 % \begin{listing}
224 %\makecompactlist{itemize*}{itemize}
225 %\makecompactlist{enumerate*}{enumerate}
226 %\makecompactlist{description*}{description}
227 % \end{listing}
228 %
229 % Some list environments accept arguments.  You can pass an argument to a
230 % list environment using an optional argument to its compact variant.  For
231 % example,
232 % \begin{listing}
233 %\begin{foolist*}[{someargument}]
234 % \end{listing}
235 %
236 % \subsection{Suspending and resuming list environments}
237 %
238 % \DescribeMacro{\suspend}
239 % \DescribeMacro{\resume}
240 % The |\suspend| and |\resume| commands allow you to temporarily end a list
241 % environment and then pick it up where you left off.  The syntax is fairly
242 % simple:
243 %
244 % \begin{grammar}
245 %
246 % <suspend-cmd> ::= \[[
247 %   "\\suspend"
248 %   \begin{stack} \\ "[" <name> "]" \end{stack} "{" <env-name> "}"
249 % \]]%
250 %
251 % <resume-cmd> ::= \[[
252 %   "\\resume"
253 %   \begin{stack} \\ "[" <name> "]" \end{stack} "{" <env-name> "}"
254 %   \begin{stack} \\ "[" <text> "]" \end{stack}
255 % \]]%
256 %
257 % \end{grammar}
258 %
259 % The \<env-name> is the name of the environment; this will more often than
260 % not be the \env{enumerate} environment.  The \<name> is a magic name you
261 % can use to identify the suspended environment; if you don't specify this,
262 % the environment name is used instead.
263 %
264 % \begin{demo}{Suspended environments}
265 %Here's some initial text.  It's
266 %not very interesting.
267 %\begin{enumerate*}
268 %\item This is an item.
269 %\item This is another.
270 %\suspend{enumerate*}
271 %Some more commentry text.
272 %\resume{enumerate*}
273 %\item Another item.
274 %\end{enumerate*}
275 % \end{demo}
276 %
277 % You can pass arguments to a resumed list environment through the second
278 % optional argument of the |\resume| command.  If, for example, you're using
279 % David Carlisle's \package{enumerate} package, you could say something like
280 % \begin{listing}
281 %\begin{enumerate}[\bfseries{Item} i]
282 %\item An item
283 %\item Another item
284 %\suspend{enumerate}
285 %Some intervening text.
286 %\resume{enumerate}[{[\bfseries{Item} i]}]
287 %\item Yet another item
288 %\end{enumerate}
289 % \end{listing}
290 %
291 % \implementation
292 %
293 % \section{Implementation}
294 %
295 %    \begin{macrocode}
296 %<*package>
297 %    \end{macrocode}
298 %
299 % \subsection{Description lists}
300 %
301 % \subsubsection{Label styles}
302 %
303 % \begin{macro}{\nextlinelabel}
304 %
305 % The idea here is that if the label is too long to fit in its box, we put
306 % it on its own line and start the text of the item on the next.  I've
307 % used |\sbox| here to capture colour changes properly, even though I have
308 % deep moral objections to the use of \LaTeX\ boxing commands.  Anyway,
309 % I capture the text in box~0 and compare its width to the amount of space
310 % I have in the label box.  If there's enough, I can just unbox the box;
311 % otherwise I build a vbox containing the label text and an empty hbox --
312 % |\baselineskip| glue inserted between the two boxes makes sure we get
313 % the correct spacing between the two lines, and the vboxness of the vbox
314 % ensures that the baseline of my strange thing is the baseline of the
315 % \emph{bottom} box.  I then bash the vbox on the nose, so as to make its
316 % width zero, and leave that as the result.  Either way, I then add glue
317 % to left align whatever it is I've created.
318 %
319 %    \begin{macrocode}
320 \def\nextlinelabel#1{%
321   \sbox\z@{#1}%
322   \ifdim\wd\z@>\labelwidth%
323     \setbox\z@\vbox{\box\z@\hbox{}}%
324     \wd\z@\z@%
325     \box\z@%
326   \else%
327     \unhbox\z@%
328   \fi%
329   \hfil%
330 }
331 %    \end{macrocode}
332 %
333 % \end{macro}
334 %
335 % \begin{macro}{\multilinelabel}
336 %
337 % A different idea -- make the label text wrap around onto the next line if
338 % it's too long.  This is really easy, actually.  I use a parbox to contain
339 % the label text, set to be ragged right, because there won't be enough
340 % space to do proper justification.  There's also a funny hskip there --
341 % this is because \TeX\ only hyphenates things it finds sitting \emph{after}
342 % glue items.  The parbox is top-aligned, so the label text and the item
343 % run downwards together.  I put the result in box~0, and remove the depth,
344 % so as not to make the top line of the item text look really strange.
345 %
346 % All this leaves a little problem, though: if the item text isn't very long,
347 % the label might go further down the page than the main item, and possibly
348 % collide with the label below.  I must confess that I'm not actually sure
349 % how to deal with this possibility, so I just hope it doesn't happen.
350 %
351 % By the way, I don't have moral objections to |\parbox|.
352 %
353 %    \begin{macrocode}
354 \def\multilinelabel#1{%
355   \setbox\z@\hbox{%
356     \parbox[t]\labelwidth{\raggedright\hskip\z@skip#1}%
357   }%
358   \dp\z@\z@%
359   \box\z@%
360   \hfil%
361 }
362 %    \end{macrocode}
363 %
364 % \end{macro}
365 %
366 % \begin{macro}{\pushlabel}
367 %
368 % Now we implement the old style behaviour -- if the label is too wide, we
369 % just push the first line of the item further over to the right.  This
370 % is really very easy indeed -- we just stick some |\hfil| space on the
371 % right hand side (to left align if the label comes up too short).  The
372 % `push' behaviour is handled automatically by \LaTeX's item handling.
373 %
374 %    \begin{macrocode}
375 \def\pushlabel#1{{#1}\hfil}
376 %    \end{macrocode}
377 %
378 % \end{macro}
379 %
380 % \subsubsection{The main environment}
381 %
382 % \begin{macro}{\desclabelstyle}
383 %
384 % This is a declaration intended to be used only in the argument to the
385 % \env{basedescript} environment.  It sets the label style for the list.
386 % All we do is take the argument and assign it to a magic control sequence
387 % which \env{basedescript} will understand later.
388 %
389 %    \begin{macrocode}
390 \def\desclabelstyle#1{\def\desc@labelstyle{#1}}
391 %    \end{macrocode}
392 %
393 % \end{macro}
394 %
395 % \begin{macro}{\desclabelwidth}
396 %
397 % We set the label width and various other bits of information which will
398 % make all the bits of the description line up beautifully.  We set
399 % |\labelwidth| to the value we're given (using |\setlength|, so that
400 % people can use the \package{calc} package if they so wish), and make
401 % the |\leftmargin| equal $|\labelwidth|+|\labelsep|$.
402 %
403 %    \begin{macrocode}
404 \def\desclabelwidth#1{%
405   \setlength\labelwidth{#1}%
406   \leftmargin\labelwidth%
407   \advance\leftmargin\labelsep%
408 }
409 %    \end{macrocode}
410 %
411 % \end{macro}
412 %
413 % \begin{environment}{basedescript}
414 %
415 % This is the new description environment.  It does almost everything you
416 % could want from a description environment, I think.  The argument is a
417 % collection of declarations to be performed while setting up the list.
418 %
419 % This environment isn't really intended to be used by users -- it's here
420 % so that you can define other description environments in terms of it,
421 %
422 % The environment is defined in two bits -- the `start' bit here simply
423 % starts the list and inserts the user declarations in an appropriate
424 % point, although sensible details will be inerted if the argument was
425 % empty.
426 %
427 %    \begin{macrocode}
428 \def\basedescript#1{%
429 %    \end{macrocode}
430 %
431 % We must start the list.  If the |\item| command's optional argument is
432 % missing, we should just leave a blank space, I think.
433 %
434 %    \begin{macrocode}
435   \list{}{%
436 %    \end{macrocode}
437 %
438 % So far, so good.  Now put in some default declarations.  I'll use a
439 % separate macro for this, so that the global appearance of lists can be
440 % configured.
441 %
442 %    \begin{macrocode}
443     \defaultdesc%
444 %    \end{macrocode}
445 %
446 % Now we do the user's declarations.
447 %
448 %    \begin{macrocode}
449     #1%
450 %    \end{macrocode}
451 %
452 % Now set up the other parts of the list.  We set |\itemindent| so that the
453 % label is up against the current left margin.  (The standard version
454 % actually leaves the label hanging to the left of the margin by a
455 % distance of |\labelsep| for a reason I can't quite comprehend -- there's
456 % an |\hspace{\labelsep}| in the standard |\makelabel| to compensate for
457 % this.  Strange\dots)
458 %
459 % To make the label start in the right place, the text of the item must
460 % start a distance of $|\labelwidth|+|\labelsep|$ from the (pre-list) left
461 % hand margin; this means that we must set |\itemindent| to be
462 % $|\labelwidth|+|\labelsep|-|\leftmargin|$.  Time for some \TeX\ arithmetic.
463 %
464 %    \begin{macrocode}
465     \itemindent\labelwidth%
466     \advance\itemindent\labelsep%
467     \advance\itemindent-\leftmargin%
468 %    \end{macrocode}
469 %
470 % Now we must set up the label typesetting.  We'll take the |\makelabel|
471 % provided by the user, remember it, and then redefine |\makelabel| in
472 % terms of the |\desclabelstyle| and the saved |\makelabel|.
473 %
474 %    \begin{macrocode}
475     \let\desc@makelabel\makelabel%
476     \def\makelabel##1{\desc@labelstyle{\desc@makelabel{##1}}}%
477 %    \end{macrocode}
478 %
479 % I can't think of anything else which needs doing, so I'll call it a day
480 % there.
481 %
482 %    \begin{macrocode}
483   }%
484 }
485 %    \end{macrocode}
486 %
487 % Now we define the `end-bit' of the environment.  Since all we need to do
488 % is to close the list, we can be ever-so slightly clever and use |\let|.
489 %
490 %    \begin{macrocode}
491 \let\endbasedescript\endlist
492 %    \end{macrocode}
493 %
494 % Note that with these definitions, the standard \env{description}
495 % environment can be emulated by saying simply:
496 % \begin{listing}
497 %\renewenvironment{description}{%
498 %  \begin{basedescript}{}%
499 %}{%
500 %  \end{basedescript}
501 %}
502 % \end{listing}
503 %
504 % \end{environment}
505 %
506 % \begin{macro}{\defaultdesc}
507 %
508 % Now to set up the standard description appearance.  In the absence
509 % of any other declarations, the label will `push' the text out the way if
510 % the text is too long.  The standard |\labelsep| and |\leftmargin| are not
511 % our problem.  We typeset the label text in bold by default. Also,
512 % |\labelwidth| is cleared to 0\,pt, because this is what \LaTeX's usual
513 % \env{description} does.
514 %
515 %    \begin{macrocode}
516 \providecommand\defaultdesc{%
517   \desclabelstyle\pushlabel%
518   \def\makelabel##1{\bfseries##1}%
519   \labelwidth\z@%
520 }
521 %    \end{macrocode}
522 %
523 % \end{macro}
524 %
525 % \subsubsection{An example}
526 %
527 % \begin{environment}{note}
528 %
529 % The \env{note} environment is a simple application of the general
530 % description list shown above.  It typesets the label (by default, the
531 % text `\textbf{note}') at the left margin, and the note text indented by
532 % the width of the label.
533 %
534 % The code is simple -- we take the environment's argument (which may have
535 % been omitted), store it in a box (using |\sbox| again, to handle colour
536 % changes correctly), set the label width from the width of the box, and
537 % then create a single item containing the label text.  The text of the
538 % environment then appears in exactly the desired place.
539 %
540 % I've not used |\newcommand| here, for the following reasons:
541 % \begin{itemize}
542 %
543 % \item I don't like it much, to be honest.
544 %
545 % \item Until very recently, |\newcommand| only allowed you to define
546 %       `long' commands, where new paragraphs were allowed to be started
547 %       in command arguments; this removes a useful check which traps
548 %       common errors like missing out `|}|' characters.  I'd prefer to
549 %       be compatible with older \LaTeX s than to use the new |\newcommand|
550 %       which provides a $*$-form to work around this restriction.
551 %
552 % \end{itemize}
553 %
554 %    \begin{macrocode}
555 \ifx\note\@@undefined
556   \def\note{\@ifnextchar[\note@i{\note@i[Note]}}
557   \def\note@i[#1]{%
558     \basedescript{%
559       \sbox\z@{\makelabel{#1}}%
560       \desclabelwidth{\wd\z@}%
561     }%
562     \item[\box\z@]%
563   }
564   \let\endnote\endbasedescript
565 \fi
566 %    \end{macrocode}
567 %
568 % \end{environment}
569 %
570 %
571 % \subsection{Compacted environments}
572 %
573 % Normal lists tend to have rather too much space between items if all or
574 % most of the item texts are one line or less each.  We therefore define
575 % a macro |\makecompactlist| whuch creates `compacted' versions of existing
576 % environments.
577 %
578 % \begin{macro}{\makecompactlist}
579 %
580 % We're given two arguments: the name of the new environment to create, and
581 % the name of the existing list environment to create.
582 %
583 % The first thing to do is to ensure that the environment we're creating is
584 % actually valid (i.e., it doesn't exist already, and it has a sensible
585 % name).  We can do this with the internal \LaTeX\ macro |\@ifdefinable|.
586 %
587 %    \begin{macrocode}
588 \def\makecompactlist#1#2{%
589   \expandafter\@ifdefinable\csname#1\endcsname%
590     {\makecompactlist@i{#1}{#2}}%
591 }
592 %    \end{macrocode}
593 %
594 % We also ought to ensure that the other environment already exists.  This
595 % isn't too tricky.  We'll steal \LaTeX's error and message for this.
596 %
597 %    \begin{macrocode}
598 \def\makecompactlist@i#1#2{%
599   \@ifundefined{#2}{\me@err{Environment `#2' not defined}\@ehc}{}%
600 %    \end{macrocode}
601 %
602 % The main work for starting a compact list is done elsewhere.
603 %
604 %    \begin{macrocode}
605   \@namedef{#1}{\@compact@list{#2}}%
606 %    \end{macrocode}
607 %
608 % Now to define the end of the environment; this isn't terribly difficult.
609 %
610 %    \begin{macrocode}
611   \expandafter\let\csname end#1\expandafter\endcsname%
612                   \csname end#2\endcsname%
613 %    \end{macrocode}
614 %
615 % That's a compacted environment created.  Easy, no?
616 %
617 %    \begin{macrocode}
618 }
619 %    \end{macrocode}
620 %
621 % The general case macro has to try slurping some arguments, calling the
622 % underlying environment, and removing vertical space.
623 %
624 %    \begin{macrocode}
625 \def\@compact@list#1{\@testopt{\@compact@list@i{#1}}{}}
626 \def\@compact@list@i#1[#2]{%
627   \@nameuse{#1}#2%
628   \parskip\z@%
629   \itemsep\z@%
630 }%
631 %    \end{macrocode}
632 %
633 % \end{macro}
634 %
635 % \begin{environment}{itemize*}
636 % \begin{environment}{enumerate*}
637 % \begin{environment}{description*}
638 %
639 % Let's build some compacted environments now.  These are easy now that
640 % we've done all the work above.
641 %
642 %    \begin{macrocode}
643 \makecompactlist{itemize*}{itemize}
644 \makecompactlist{enumerate*}{enumerate}
645 \makecompactlist{description*}{description}
646 %    \end{macrocode}
647 %
648 % \end{environment}
649 % \end{environment}
650 % \end{environment}
651 %
652 %
653 % \subsection{Suspending and resuming lists}
654 %
655 % This is nowhere near perfect; it relies a lot on the goodwill of the user,
656 % although it seems to work fairly well.
657 %
658 % \begin{macro}{\suspend}
659 %
660 % The only thing that needs saving here is the list counter, whose name
661 % is stored in |\@listctr|.  When I get a request to save the counter, I'll
662 % build a macro which will restore it when the environment is restored later.
663 %
664 % The first thing to do is to handle the optional argument.  |\@dblarg| will
665 % sort this out, giving me a copy of the mandatory argument if there's no
666 % optional one provided.
667 %
668 %    \begin{macrocode}
669 \def\suspend{\@dblarg\suspend@i}
670 %    \end{macrocode}
671 %
672 % That's all we need to do here.
673 %
674 %    \begin{macrocode}
675 \def\suspend@i[#1]#2{%
676 %    \end{macrocode}
677 %
678 % Now I have a little problem; when I |\end| the environment, it will close
679 % off the grouping level, and the counter value will be forgotten.  This is
680 % bad.  I'll store all my definitions into a macro, and build the |\end|
681 % command into it; that way, everything will be expanded correctly.  This
682 % requires the use of |\edef|, which means I must be a little careful.
683 %
684 %    \begin{macrocode}
685   \edef\@tempa{%
686 %    \end{macrocode}
687 %
688 % The first thing to do is to end the environment.  I don't want |\end|
689 % expanded yet, so I'll use |\noexpand|.
690 %
691 %    \begin{macrocode}
692     \noexpand\end{#2}%
693 %    \end{macrocode}
694 %
695 % Now I must define the `resume' macro.  I'll use |\csname| to build the
696 % named identifier into the name, so it won't go wrong (maybe).  There's
697 % a little fun here to make the control sequence name but not expand it
698 % here.
699 %
700 %    \begin{macrocode}
701     \def\expandafter\noexpand\csname resume.#1\endcsname{%
702 %    \end{macrocode}
703 %
704 % The counter name is hidden inside |\@listctr|, so the actual counter is
705 % called `|\csname c@\@listctr\endcsname|'.  I'll use |\the| to read its
706 % current value, and assign it to the counter when the macro is used later.
707 %
708 %    \begin{macrocode}
709       \csname c@\@listctr\endcsname\the\csname c@\@listctr\endcsname%
710 %    \end{macrocode}
711 %
712 % That's all we need to do there.  Now close the macros and run them.
713 %
714 %    \begin{macrocode}
715     }%
716   }%
717   \@tempa%
718 }
719 %    \end{macrocode}
720 %
721 % \end{macro}
722 %
723 % \begin{macro}{\resume}
724 %
725 % Resuming environments is much easier.  Since I use |\csname| to build the
726 % name, nothing happens if you try to resume environments which weren't
727 % suspended.  I'll trap this and raise an error.  Provide an optional
728 % argument for collecting arguments to the target list.
729 %
730 %    \begin{macrocode}
731 \def\resume{\@dblarg\resume@i}
732 \def\resume@i[#1]#2{\@testopt{\resume@ii{#1}{#2}}{}}
733 \def\resume@ii#1#2[#3]{%
734   \begin{#2}#3%
735   \@ifundefined{resume.#1}{\ml@err@resume}{\@nameuse{resume.#1}}%
736 }
737 %    \end{macrocode}
738 %
739 % \end{macro}
740 %
741 % That's all there is.
742 %
743 %    \begin{macrocode}
744 %</package>
745 %    \end{macrocode}
746 %
747 % \hfill Mark Wooding, \today
748 %
749 % \Finale
750 %
751 \endinput