mdwlist.dtx 25 KB

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