chiark / gitweb /
Merge branch 'master' of /home/mdw/public-git/mdwtools
[mdwtools] / sverb.dtx
1 % \begin{meta-comment}
2 %
3 % $Id: sverb.dtx,v 1.2 2003/09/05 16:09:30 mdw Exp $
4 %
5 % Verbatim typesetting done properly (ahem)
6 %
7 % (c) 1996 Mark Wooding
8 %
9 % \end{meta-comment}
10 %
11 % \begin{meta-comment} <general public licence>
12 %%
13 %% sverb package -- handling of verbatim text
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 preamble>
33 %<+package>\NeedsTeXFormat{LaTeX2e}
34 %<+package>\ProvidesPackage{sverb}
35 %<+package>                [2003/09/04 1.4 Verbatim typesetting]
36 %<+colour>\NeedsTeXFormat{LaTeX2e}
37 %<+colour>\ProvidesPackage{svcolour}
38 %<+colour>                [2003/09/04 1.4 Colour support for sverb]
39 %<+color>\NeedsTeXFormat{LaTeX2e}
40 %<+color>\ProvidesPackage{svcolor}
41 %<+color>                [2003/09/04 1.4 Fix for people who can't spell]
42 %<+split>\NeedsTeXFormat{LaTeX2e}
43 %<+split>\ProvidesPackage{svsplit}
44 %<+split>                [2003/09/04 1.4 Verbatim, but with line breaking]
45 % \end{meta-comment}
46 %
47 % \CheckSum{1009}
48 %% \CharacterTable
49 %%  {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
50 %%   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
51 %%   Digits        \0\1\2\3\4\5\6\7\8\9
52 %%   Exclamation   \!     Double quote  \"     Hash (number) \#
53 %%   Dollar        \$     Percent       \%     Ampersand     \&
54 %%   Acute accent  \'     Left paren    \(     Right paren   \)
55 %%   Asterisk      \*     Plus          \+     Comma         \,
56 %%   Minus         \-     Point         \.     Solidus       \/
57 %%   Colon         \:     Semicolon     \;     Less than     \<
58 %%   Equals        \=     Greater than  \>     Question mark \?
59 %%   Commercial at \@     Left bracket  \[     Backslash     \\
60 %%   Right bracket \]     Circumflex    \^     Underscore    \_
61 %%   Grave accent  \`     Left brace    \{     Vertical bar  \|
62 %%   Right brace   \}     Tilde         \~}
63 %%
64 %
65 % \begin{meta-comment}
66 %
67 %<*driver>
68 \input{mdwtools}
69 \describespackage{sverb}
70 \describespackage{svcolour}
71 \describespackage{svsplit}
72 \mdwdoc
73 %</driver>
74 %
75 % \end{meta-comment}
76 %
77 % \section{User guide}
78 %
79 % The \package{sverb} package provides some useful commands and environments
80 % for doing things with verbatim text.  I prefer this code to the standard
81 % \package{verbatim} package (by Rainer Sch\"opf et al.)\ although I'm
82 % biased.
83 %
84 % The package was written to fulfil a particular purpose: I wanted to be able
85 % to typeset ARM assembler code, 77~columns wide, on A5~paper, with the
86 % fields separated by \textit{tab} characters.  It's grown up fairly
87 % organically from that, and I've tidied it when I've seen the code get too
88 % ugly.
89 %
90 % The current features are:
91 %
92 % \begin{itemize}
93 %
94 % \item A `listing' environment which typesets verbatim text nicely.
95 %
96 % \item A command to read verbatim text from an external file.
97 %
98 % \item Support for arbitrary-sized chunks of text without overflowing \TeX's
99 %       memory.
100 %
101 % \item Support for \textit{tab} characters in the verbatim text.
102 %
103 % \item An environment for typesetting demonstrations of \LaTeX\ markup.
104 %
105 % \item It all works correctly with the \package{doc} system for documenting
106 %       \LaTeX\ packages.
107 %
108 % \item A fairly hairy but quite powerful programmer interface to the yukky
109 %       bits of the package.
110 %
111 % \end{itemize}
112 %
113 % The interface is described in its own section, so that more timid readers
114 % can avoid it.  That said, some of the stuff in this section gets rather
115 % technical.
116 %
117 % Note that this package doesn't even try to do anything with short bits of
118 % verbatim text (as handled by the |\verb:...:| command).  I have a separate
119 % package (\package{syntax}) which does all sorts of horrible things along
120 % those lines.
121 %
122 % \subsection{The \env{listing} environment}
123 %
124 % \DescribeEnv{listing}
125 % The main method for typesetting verbatim text is the \env{listing}
126 % environment.  This works pretty much the same as the standard
127 % \env{verbatim} environment, with some exceptions, which are described
128 % below.
129 %
130 % So that you know exactly what you're getting, here are the rules by which
131 % \package{sverb} decides what the verbatim text actually is:
132 %
133 % \begin{itemize}
134 %
135 % \item If there's any text, other than spaces, on the same line as the
136 %       `|\begin{listing}|', then the contents of the environment begins
137 %       immediately after the closing brace (with all leading spaces
138 %       preserved).  Otherwise, the text begins on the following line.
139 %
140 % \item If there is any text, other than spaces, before the
141 %       `|\end{listing}|', but on the same line, this is considered to be the
142 %       last line of the text; otherwise the text is presumed to have ended
143 %       at the end of the previous line.
144 %
145 % \item Any text following the |\end{listing}| on the same line is thrown
146 %       away.  There are good reasons for this, but they're technical.
147 %       Essentially there's nothing I can do about it.
148 %
149 % \end{itemize}
150 %
151 % \begin{figure}
152 % \begin{demo}[w]{The \env{listing} environment}
153 %\dots in the following code:
154 %
155 %\begin{listing}
156 %init            MOV     R0,#200         ;Version 2.00 please
157 %                LDR     R1,=&4B534154   ;Magic number (`TASK')
158 %                ADR     R2,appName      ;Find application name
159 %                SWI     Wimp_Initialise ;Register as a WIMP task
160 %\end{listing}
161 %
162 %The next step is to \dots
163 % \end{demo}
164 % \end{figure}
165 %
166 % Tab characters are supported within the environment: tab stops are set
167 % every eighth column, although this can be modified.
168 %
169 % \subsubsection{Configuring the \env{listing} environment}
170 %
171 % \DescribeMacro\listingsize
172 % The text size used in the \env{listing} environment is set by the
173 % |\listingsize| command.  By default, this is set to |\footnotesize|,
174 % although you can redefine it in the document preamble, or it can be set in
175 % the document class.  You can put other declarations (e.g., colours) here if
176 % you like.
177 %
178 % \DescribeMacro\listingindent
179 % The amount by which the listing text is indented is controlled by the
180 % |\listingindent| length parameter.  This is a fixed length, whose default
181 % value is 1\,em.
182 %
183 % \DescribeMacro\listinghook
184 % \DescribeMacro\svafter
185 % \DescribeMacro\svline
186 % \DescribeMacro\svdoline
187 % \DescribeEnv{listinglist}
188 % The |\listinghook| command is called by the \env{listing} environment (and
189 % |\verbinput| and \env{demo}) to set up the formatting of the listing.  It
190 % can do any setting up it likes, and may configure |\svline| and |\svafter|
191 % as necessary.  The macro |\svline| is run once for each line of verbatim
192 % text, with the line gathered into a box register, the number of which is
193 % given as an argument.  The macro |\svafter| is called when processing has
194 % finished.
195 %
196 % The default setting for |\listinghook| is (similar to)
197 %\begin{listing}
198 %\newcommand{\listinghook}{%
199 %  \par%
200 %  \begin{listinglist}%
201 %  \listingsize%
202 %  \renewcommand{\svline}{\listingline}%
203 %  \renewcommand{\svafter}{\end{listinglist}}%
204 %}
205 %\end{listing}
206 % (see the source for the true definition).  The default |\listingline| macro
207 % just writes out the line using |\svdoline|, which is a simple no-nonsense
208 % macro which just writes the text.  As an example, you could say
209 %\begin{listing}
210 %\renewcommand{\listingline}{\leavevmode\llap{\strut\vrule\space}\svdoline}
211 %\end{listing}
212 % to put a rule down the left-hand side of your listings.
213 %
214 % The \env{listinglist} environment is a relatively straightforward
215 % \env{list}-based environment which sets pu the indentation of a listing.
216 % Feel free to redefine it.
217 %
218 % \subsubsection{Choosing a different end-text}
219 %
220 % \DescribeEnv{listing*}
221 % The \env{listing} environment is terminated by the exact character sequence
222 % `|\end{listing}|'.  This isn't too much of a problem, unless you want to
223 % include this string in the text.  This is achieved by the \env{listing$*$}
224 % environment, which allows you to specify the end-text to find as an
225 % argument.
226 %
227 % For example:
228 %
229 % \begin{demo}{The \env{listing$*$} environment}
230 %Type a listing as follows:
231 %
232 %\begin{listing*}{<end-listing*>}
233 %\begin{listing}
234 %This is a listing.  Yes.
235 %\end{listing}
236 %<end-listing*>
237 %\end{demo}
238 %
239 % Don't include `special' characters in your chosen end-text unless you know
240 % what you're doing.
241 %
242 % \subsection{Writing text to a file}
243 %
244 % \DescribeEnv{verbwrite}
245 % You can write verbatim text to a file using the \env{verbwrite}
246 % environment.  The syntax is fairly straightforward:
247 %
248 % \begin{quote}
249 % \syntax{"\\begin{verbwrite}{"<file-name>"}" \dots "\\end{verbwrite}"}
250 % \end{quote}
251 %
252 % The text of the environment is written to the named file.  The rules about
253 % where the text actually starts and ends are the same as for the
254 % \env{listing} environment.
255 %
256 % There is also a $*$-variant, like \env{listing$*$}, which allows you to
257 % choose the end-text.  The end-text is the first argument, the filename
258 % comes second.
259 %
260 % There is a restriction on the characters you can write to the file: they
261 % must all be considered `printable' by \TeX; otherwise they will be read
262 % back in as `\syntax{"^^"<chars>}' which isn't too good.  Unfortunately,
263 % this includes tab characters, so you can't write them.\footnote{^^A
264 %   Well, not without doing serious surgery on \TeX\ itself, anyway. }
265 %
266 % \iffalse [Example time...  Ho hum.  There is evilness here.] \fi
267 %\begin{verbwrite*}{<end-write>}{wrdemo1.tmp}
268 %\begin{verbwrite}{wrdemo.tmp}
269 %This is some text written to
270 %a file near the beginning of
271 %the file.
272 %\end{verbwrite}
273 %<end-write>
274 %
275 % For example: \verbinput{wrdemo1.tmp}
276 %
277 % \input{wrdemo1.tmp} \iffalse [Now build the file ;-) ] \fi
278 %
279 % \subsection{The \cmd\verbinput\ command}
280 %
281 % \DescribeMacro{\verbinput}
282 % You can input a pre-prepared text file exactly as it is in the input using
283 % the |\verbinput| command.  The filename is given as an argument.  For
284 % example:
285 %
286 % \begin{demo}{The \cmd\verbinput\ command}
287 %\verbinput{wrdemo.tmp}
288 % \end{demo}
289 %
290 % \subsection{The \env{demo} environment}
291 %
292 % Package authors need to document their packages, and it's common to want
293 % to display examples showing the original text and the output side-by-side
294 % (or, when space doesn't permit this, one above the other).  Both the
295 % \LaTeX\ book and \textit{The \LaTeX\ Companion} contain such examples.
296 %
297 % The \env{demo} environment allows such displays to be created easily.  The
298 % syntax of the environment is as follows:
299 %
300 % \begin{quote}
301 % \syntax{"\\begin{demo}["<shape>"]{"<title>"}" \dots "\\end{demo}"}
302 % \end{quote}
303 %
304 % The optional \synt{shape} argument can be either `|w|' (wide), or `|n|'
305 % (narrow).  A `wide' shape places the input and output one above the other,
306 % while the `narrow' shape puts them side-by-side.  The default shape is
307 % `narrow'.  An attractive border is drawn around the display to finish it
308 % off nicely.
309 %
310 % An example:
311 %
312 %\begin{demo*}{<end-demo>}[w]{The \env{demo} environment}
313 %\begin{demo}{From the \textit{\TeX book}}
314 %\[ \sum_{p\;\rm prime}
315 %   f(p) = \int_{t>1}
316 %      f(t)\,{\rm d}\pi(t) \]
317 %\end{demo}
318 %<end-demo>
319 %
320 % \DescribeEnv{demo*}
321 % As with the other environments created by this package, there's a
322 % $*$-variant which takes the end-text as an argument.
323 %
324 % \DescribeMacro\demohook
325 % The |\demohook| does the same job for \env{demo} environments as
326 % |\listinghook| does for \env{listing}s.  The default version just says
327 %\begin{listing}
328 %\newcommand{\demohook}{\setlength{\listingindent}{0pt}\listinghook}
329 %\end{listing}
330 % (near enough), which turns off the indentation for the listing (which would
331 % otherwise look rather odd).
332 %
333 %
334 % \section{Programmer interface}
335 %
336 % This section describes the publicly available routines provided by the
337 % \package{sverb} package.  Routines not described here are libable to be
338 % changed or even removed without warning, so don't use them.
339 %
340 % \subsection{Environment hooks}
341 %
342 % Each of the environments created here works in the same way.  For each
343 % environment \env{foo}, there's a main command responsible for doing the
344 % work, called |\sv@foo|.  This is given all the arguments of the normal
345 % environment, and two more:
346 %
347 % \begin{itemize}
348 %
349 % \item The `end-text' to search for, which marks the end of the environment.
350 %
351 % \item Some actions to perform after the text has been read and processed.
352 %       This allows the calling macro to do some extra actions, like closing
353 %       boxes, etc.
354 %
355 % \end{itemize}
356 %
357 % All the environments do is call the main command with appropriate
358 % arguments.
359 %
360 % \subsection{Reading the verbatim text}
361 %
362 % \DescribeMacro{\sv@read}
363 % The main scanning routine is |\sv@read|.  It is called with three
364 % arguments:
365 %
366 % \begin{itemize}
367 %
368 % \item The end-text marking the end of the environment.
369 %
370 % \item The name of a macro (which must be a single token) which is called
371 %       with a line of text as its single argument.  This is given each
372 %       line of text which is read from the environment in turn.
373 %
374 % \item A macro, or other sort of action, which is to be done when the text
375 %       has been read and processed.
376 %
377 % \end{itemize}
378 %
379 % The macro |\sv@read| assumes that the caller has already made some
380 % provision for removing the category codes of the following text, by either
381 % calling |\@verbatim| or using the construction
382 % \begin{listing}
383 %\let\do=\@makeother
384 %\dospecials
385 % \end{listing}
386 %
387 % \DescribeMacro{\sv@safespc}
388 % Note that any space characters you read using |\sv@read| will be catcoded
389 % as |\active|.  Normally this is OK because |\obeyspaces| (or
390 % |\@vobeyspaces|) will be in effect.  If you're doing something more exotic,
391 % like writing text to a file or building a command string, you can call
392 % |\sv@safespc| which defines the active-space character to be a normal
393 % whitespace-space when expanded.
394 %
395 % \section{Colour support}
396 %
397 % There's now a little colour support in \package{sverb}.  To use it, give
398 % the \textsf{colour} (or \textsf{color}) package option, or load the
399 % \package{svcolour} package.
400 %
401 % \DescribeMacro\svcolourline
402 % Say \syntax{"\\svcolourline["<model>"]{"<colour>"}{"<box>"}"} to typeset
403 % \<box> against a background of the given colour.  This is a good thing to
404 % put in your |\listingline| command.
405 %\begin{demo}{Coloured listings}
406 %\renewcommand{\listingline}
407 %  {\svcolourline[rgb]{1, 0.8, 0.9}}
408 %Consider, for example, this more
409 %complicated program.
410 %\begin{listing}
411 %#include <stdio.h>
412 %
413 %int main(void)
414 %{
415 %  puts("Hello, world!");
416 %  return (0);
417 %}
418 %\end{listing}
419 %\end{demo}
420 % For coloured text rather than background, put a |\color| command in
421 % |\listinghook| itself.
422 %
423 % \section{The \package{svsplit} package}
424 %
425 % A new toy!
426 %
427 % \DescribeEnv{splitverb}
428 % \DescribeEnv{splitverb*}
429 % \DescribeMacro\svsplitchars
430 % The \env{splitverb} environment typesets verbatim material very slowly.  On
431 % the plus side, however, it does know how to do simple line-breaking.  It
432 % will break lines at spaces or tabs, or after any character listed in
433 % |\svsplitchars|.  Continuation lines have the same initial intentation as
434 % the original.  If a line has no `good' breaking point, it's broken as late
435 % as possible, and a little hyphen is inserted.
436 %\begin{demo}[w]{The \env{splitverb} environment}
437 %\begin{multicols}{2}
438 %\begin{splitverb}
439 %The \package{url} package is rather fine at splitting up long URLs such as
440 %  \url{http://www.excessus.demon.co.uk/tex}
441 %though it can't do its thing in the midst of verbatim text.  It
442 %also doesn't cope when
443 %  allthespacesinalongphrasehavemysteriouslydisappeared!
444 %\end{splitverb}
445 %\end{multicols}
446 %\end{demo}
447 %
448 % \implementation
449 %
450 % \section{Implementation}
451 %
452 % This section defines several macros and environments which allow verbatim
453 % typing, with a high degree of configurability.  OK, so this sort of
454 % thing's been done so often before that it isn't true, but I don't really
455 % care.
456 %
457 %    \begin{macrocode}
458 %<*package>
459 %    \end{macrocode}
460 %
461 % \subsection{Options processing}
462 %
463 % Notice options, load package.
464 %
465 %    \begin{macrocode}
466 \newif\ifsv@colour\sv@colourfalse
467 \DeclareOption{colour}{\sv@colourtrue}
468 \DeclareOption{color}{\sv@colourtrue}
469 \ProcessOptions
470 %    \end{macrocode}
471 %
472 % \subsection{Simple things}
473 %
474 % To help us build funny macros which involve strange and different category
475 % codes, I'll write some simple macros which I can use while building my
476 % complicated and clever ones.
477 %
478 % \begin{macro}{\@cspecials}
479 %
480 % This macro is used to assist the definition of some of the environments.
481 % It makes `|\|', `|{|' and `|}|' into `other' characters, and replaces them
482 % with `\verb"|"', `|<|' and `|>|' respectively.  Note that `|[|' and `|]|'
483 % aren't used, because they make defining commands which take optional
484 % arguments awkward.  Note that we open a group here.  This should be closed
485 % using \verb"|endgroup" at the end of the special section.
486 %
487 %    \begin{macrocode}
488 \def\@cspecials{%
489   \begingroup%
490   \catcode`|0%
491   \catcode`<1%
492   \catcode`>2%
493   \catcode`\{12%
494   \catcode`\}12%
495   \catcode`\\12%
496 }
497 %    \end{macrocode}
498 % \end{macro}
499 %
500 % \begin{macro}{\sv@addtobox}
501 %
502 % Add stuff to a horizontal box.
503 %
504 %    \begin{macrocode}
505 \def\sv@addtobox#1#2{\setbox#1\hbox{\unhbox#1\box#2}}
506 %    \end{macrocode}
507 %
508 % \end{macro}
509 %
510 % \begin{macro}{\sv@emptybox}
511 %
512 % Clear out a horizontal box.
513 %
514 %    \begin{macrocode}
515 \def\sv@emptybox#1{\setbox#1\hbox{}}
516 %    \end{macrocode}
517 %
518 % \end{macro}
519 %
520 % \begin{macro}{\sv@startlisting}
521 %
522 % This macro sets everything up nicely for a \env{listing}-type verbatim
523 % environment.
524 %
525 %    \begin{macrocode}
526 \def\sv@startlisting{%
527   \def\par{\@@par\penalty\interlinepenalty}%
528   \@@par%
529   \leftskip\@totalleftmargin%
530   \obeylines%
531   \@noligs%
532   \let\do\@makeother\dospecials%
533   \verbatim@font%
534   \frenchspacing%
535   \@vobeyspaces%
536   \settabwidth%
537   \catcode9\active%
538   \lccode`\~9\lowercase{\let~\sv@vtab}%
539   \lccode`\~13\lowercase{\let~\vinput@cr}%
540   \interlinepenalty500%
541 }
542 %    \end{macrocode}
543 %
544 % \end{macro}
545 %
546 % \subsection{Tab character handling}
547 %
548 % One of the things we want to do here is handle tab characters properly.
549 % (Here, `properly' means `moving to the next column which is a multiple of
550 % eight', the way these things were always meant to.)
551 %
552 % \begin{macro}{\settabwidth}
553 %
554 % The tabs used by our tabbed verbatim environments are set up by this
555 % routine.  It sets the tab width parameter |\svtab| to 8 times the width
556 % of a |\tt| space.  If you really want, you can redefine this macro.
557 %
558 %    \begin{macrocode}
559 \newdimen\svtab
560 \def\settabwidth{\setbox\z@\hbox{\texttt{\space}}\svtab8\wd\z@}
561 %    \end{macrocode}
562 %
563 % \end{macro}
564 %
565 % \begin{macro}{\sv@vtab}
566 %
567 % Here we handle tabs inside verbatim environments.  We expect to be inside
568 % |\box|~0.  This is padded to the correct width and contributed to |\box|~2;
569 % |\box|~0 is then cleared and re-entered.
570 %
571 % The idea is that you make tab active, and set it to this macro.  We stop
572 % the current box, stretch it to the right width, and start another one
573 % straight after, so nobody knows the difference.  The code here is straight
574 % from Appendix~D of \textit{The \TeX book}.
575 %
576 %    \begin{macrocode}
577 \def\sv@vtab{%
578   \hfill\egroup%
579   \@tempdima\wd\z@%
580   \divide\@tempdima\svtab%
581   \multiply\@tempdima\svtab%
582   \advance\@tempdima\svtab%
583   \wd\z@\@tempdima%
584   \sv@addtobox\tw@\z@%
585   \setbox\z@\hbox\bgroup%
586 }
587 %    \end{macrocode}
588 %
589 % \end{macro}
590 %
591 % \begin{macro}{\verbinput}
592 %
593 % We allow input from a file, by the |\verbinput| command.  We display the
594 % text pretty much the same as the \env{listing} environment below.
595 %
596 % We set tab and return active, and get them to do appropriate things.  This
597 % isn't actually all that hard.
598 %
599 %    \begin{macrocode}
600 \def\verbinput{\listinghook\@ifstar{\verbinput@\@input}{\verbinput@\input}}
601 \def\verbinput@#1#2{%  
602   \sv@startlisting%
603   \setbox\z@\hbox\bgroup%
604   #1{#2}%
605   \sv@stripspc%
606   \egroup%
607   \sv@addtobox\tw@\z@%
608   \ifdim\wd\tw@=\z@\listingline\tw@\fi%
609   \svafter%
610 }
611 %    \end{macrocode}
612 %
613 % \end{macro}
614 %
615 % \begin{macro}{\vinput@cr}
616 %
617 % This macro handles return characters while inputting text in |\verbinput|.
618 % We just output our current box, and start another.
619 %
620 %    \begin{macrocode}
621 \def\vinput@cr{%
622   \egroup%
623   \sv@addtobox\tw@\z@%
624   \listingline\tw@%
625   \sv@emptybox\tw@%
626   \setbox\z@\hbox\bgroup%
627 }
628 %    \end{macrocode}
629 %
630 % \end{macro}
631 %
632 % \subsection{Reading verbatim text}
633 %
634 % The traditional way of reading verbatim text is to use a delimited
635 % argument, as described in the \textit{\TeX book}.  This works well-ish if
636 % the text isn't very long.  A better solution would be to pick out the text
637 % line-by-line and process it like that.  So this is what we do.
638 %
639 % \begin{macro}{\matcher}
640 %
641 % For long verbatim environments, we need to be able to find the end text.
642 % This is rather tricky.  The solution here is rather horrible.  The
643 % environment picks out each line of the text at a time, as an argument, and
644 % tests to see if it contains the text we're after.  We do the test in a
645 % particularly yukky way: we add the actual target text to the end of the
646 % line, and inspect the text following the match to see if the match is at
647 % the end.
648 %
649 % The |\matcher| macro creates a `matcher' which will test strings to see if
650 % they contain something interesting.
651 %
652 % To create a matcher, say
653 % \syntax{"\\matcher{"<cmd-name>"}{"<target>"}{"<process-cmd>"}"}.  The
654 % command \synt{cmd-name} accepts a line of text as an argument and calls
655 % the \synt{process-cmd} with the text of the line before the match, or the
656 % whole lot.  It also sets |\@ifmatched| appropriately.
657 %
658 % (Having spent ages coming up with this cruft myself, I found some very
659 % similar, but slightly better, code in Appendix~D.  So I've changed mine to
660 % match Donald's.  Anyway, credit where it's due: cheers Don.)
661 %
662 %    \begin{macrocode}
663 \newif\if@matched
664 \def\matcher#1#2#3{%
665   \expandafter\def\csname\string#1$match\endcsname##1#2##2##3\end{%
666     \ifx##2\relax%
667       \@matchedfalse%
668     \else%
669       \@matchedtrue%
670     \fi%
671     #3{##1}%
672   }%
673   \expandafter\def\expandafter#1\expandafter##\expandafter1\expandafter{%
674     \csname\string#1$match\endcsname##1#2\relax\end%
675   }%
676 }
677 %    \end{macrocode}
678 %
679 % \end{macro}
680 %
681 % \begin{macro}{\sv@stripspc}
682 %
683 % This macro strips any trailing glue in the current horizontal list.  This
684 % is fairly simple, actually: we just loop while glue is the last item.  It's
685 % slightly complicated by penalties which \TeX\ puts into the list between
686 % the glue items, but we just remove them too.
687 %
688 %    \begin{macrocode}
689 \def\sv@stripspc{%
690   \unpenalty%
691   \ifdim\lastskip=\z@\else%
692     \unskip\expandafter\sv@stripspc%
693   \fi%
694 }
695 %    \end{macrocode}
696 %
697 % \end{macro}
698 %
699 % \begin{macro}{\sv@percent}
700 %
701 % This macro strips a single leading percent character if there is one, and
702 % if the \env{doc} package is loaded.  We store the possibly stripped text in
703 % |\@tempa|.
704 %
705 %    \begin{macrocode}
706 \begingroup
707 \catcode`\%=12
708 \gdef\sv@percent#1#2\relax
709     {\ifx\check@percent\@@undefined
710                      \ifx#1\relax\def\@tempa{}\else
711                          \def\@tempa{#1#2}\fi\else
712                      \ifx#1\relax\def\@tempa{}\else
713                          \ifx#1%\def\@tempa{#2}\else
714                              \def\@tempa{#1#2}\fi\fi\fi}
715 \endgroup
716 %    \end{macrocode}
717 %
718 % \end{macro}
719 %
720 % \begin{macro}{\@isspaces}
721 %
722 % We want to avoid writing the first and last lines of the environment to the
723 % file if there's nothing in them.  To do this, we need to know whether a
724 % piece of text contains only space characters.  This macro does this, in a
725 % rather nasty way.  See the other macros below for details of how this
726 % works.
727 %
728 % We define |\sv@safespc| at the same time: this makes space active and
729 % expand to a space character which is not active.  Neat, huh?
730 %
731 %    \begin{macrocode}
732 \lccode`\~32
733 \lccode`\!32
734 \lowercase{%
735   \def\@isspaces#1{%
736     \ifx#1\relax%
737       \def\@tempb{\@tempswafalse}%
738     \else\ifx#1~%
739       \let\@tempb\@isspaces%
740     \else%
741       \def\@tempb##1\relax{}%
742     \fi\fi%
743     \@tempb%
744   }
745   \def\sv@safespc{%
746     \catcode32\active%
747     \def~{ }%
748   }
749 }
750 %    \end{macrocode}
751 %
752 % \end{macro}
753 %
754 % \begin{macro}{\sv@read}
755 %
756 % This macro does the main job of reading a chunk of verbatim text.  You call
757 % it like this:
758 %
759 % \begin{quote}
760 % \syntax{"\\sv@read{"<end-text>"}{"<process-line-proc>"}{"<end-proc>"}"}
761 % \end{quote}
762 %
763 % The \synt{end-text} is the text to find at the end of the `environment': we
764 % stop when we find it.
765 %
766 % The \synt{process-line-proc} is a macro which is passed as an argument each
767 % line which we read from the text.
768 %
769 % The \synt{end-proc} is a macro to call once we've finished reading all of
770 % the text.  This can tidy up an environment or close a file or whatever.
771 %
772 % We read the text by picking out newlines using a delimited macro.  We have
773 % to be a little clever, because newlines are active in verbatim text.
774 %
775 % We will also strip `|%|' signs off the beginning if the \package{doc}
776 % package is here (\package{doc} tries to play with \LaTeX's verbatim stuff,
777 % and doesn't understand the way we do things).
778 %
779 %    \begin{macrocode}
780 \def\sv@read#1#2#3{%
781 %    \end{macrocode}
782 %
783 % This code does all sorts of evil things, so I'll start by opening a group.
784 %
785 %    \begin{macrocode}
786   \begingroup%
787 %    \end{macrocode}
788 %
789 % So that I can spot the end-text, I'll create a matcher macro.
790 %
791 %    \begin{macrocode}
792   \matcher\@match{#1}\sv@read@ii%
793 %    \end{macrocode}
794 %
795 % So that I can identify line ends, I'll make them active.  I'll also make
796 % spaces active so that they can expand to whatever they ought to expand
797 % to (spaces in files, or funny \verb*" " characters or whatever.
798 %
799 %    \begin{macrocode}
800   \catcode13\active%
801   \catcode32\active%
802 %    \end{macrocode}
803 %
804 % I'll use the |\if@tempswa| flag to tell me whether I ought to output the
805 % current line.  This is a little messy, so I'll describe it later.  I'll
806 % initialise it to false because this is the correct thing to do.
807 %
808 %    \begin{macrocode}
809   \@tempswafalse%
810 %    \end{macrocode}
811 %
812 % Most of the job is done by two submacros.  I'll define them in terms of
813 % my current arguments (to save lots of token munging).  The first just
814 % extracts the next line (which ends at the next newline character) and
815 % tries to match it.
816 %
817 %    \begin{macrocode}
818   \lccode`\~13\lowercase{%
819     \def\sv@read@i##1~{\@match{##1}}%
820   }%
821 %    \end{macrocode}
822 %
823 % The results of the match get passed here, along with the text of the
824 % line up to the matched text.
825 %
826 %    \begin{macrocode}
827   \def\sv@read@ii##1{%
828 %    \end{macrocode}
829 %
830 % The first job to do is to maybe strip off percent signs from the beginning,
831 % to keep \package{doc} happy.
832 %
833 %    \begin{macrocode}
834     \sv@percent##1\relax\relax%
835 %    \end{macrocode}
836 %
837 % Now I need to decide whether I ought to output this line.  The method goes
838 % like this: if this is the first line (|\if@tempswa| is false) or the last
839 % (|\if@matched| is true), \emph{and} the text consists only of spaces, then
840 % I'll ignore it.
841 %
842 % The first thing to do is to notice the last line -- if |\if@matched| is
843 % true, then I'll make |\if@tempswa| false to make the first-line and
844 % last-line cases work the same way.
845 %
846 %    \begin{macrocode}
847     \if@matched\@tempswafalse\fi%
848 %    \end{macrocode}
849 %
850 % Now if this is the first or last line, I'll examine it for spaces.  This
851 % is done in a separate macro.  It will set |\if@tempswa| false if the
852 % text contains only spaces.
853 %
854 %    \begin{macrocode}
855     \if@tempswa\else\@tempswatrue\expandafter\@isspaces\@tempa\relax\fi%
856 %    \end{macrocode}
857 %
858 % Now, if |\if@tempswa| is still true, perform the \<process-line-proc> on
859 % the line of text.  I'll provide a group, so that it doesn't upset me
860 % too much.
861 %
862 %    \begin{macrocode}
863     \if@tempswa%
864       \begingroup%
865       \expandafter#2\expandafter{\@tempa}%
866       \endgroup%
867     \fi%
868 %    \end{macrocode}
869 %
870 % The next line won't be the first one, so I'll set the flag true in
871 % readiness.
872 %
873 %    \begin{macrocode}
874     \@tempswatrue%
875 %    \end{macrocode}
876 %
877 % Now, if that wasn't the last line, go round again; otherwise end the group
878 % I started ages ago, and do the user's \<end-proc>.
879 %
880 %    \begin{macrocode}
881     \if@matched\def\@tempa{\endgroup#3}\else\let\@tempa\sv@read@i\fi%
882     \@tempa%
883   }%
884 %    \end{macrocode}
885 %
886 % Now to start the thing up.  I'll read the first line.
887 %
888 %    \begin{macrocode}
889   \sv@read@i%
890 }
891 %    \end{macrocode}
892 %
893 % \end{macro}
894 %
895 % \begin{macro}{\sv@readenv}
896 %
897 % This macro works out an appropriate end-text for the current environment.
898 % If you say \syntax{"\\sv@readenv{"<macro-name>"}"}, it will expand do
899 % \begin{listinglist} \listingsize \synshorts
900 % <macro-name>"{\\"$_{12}$"end{"$_{12}$<current-env-name>"}"$_{12}$"}"^^A
901 %               "{\\end{"<current-env-name>"}}"
902 % \end{listinglist}
903 % Easy, no?
904 %
905 % This is all done with mirrors.  No, err\dots\ it's done with
906 % |\expandafter|.
907 %
908 %    \begin{macrocode}
909 \begingroup
910 \lccode`\<=`\{
911 \lccode`\>=`\}
912 \lccode`\|=`\\
913 \lowercase{\endgroup
914 \def\sv@readenv#1{\expandafter\sv@readenv@i\expandafter{\@currenvir}{#1}}
915 \def\sv@readenv@i#1#2{#2{|end<#1>}{\end{#1}}}
916 }
917 %    \end{macrocode}
918 %
919 % \end{macro}
920 %
921 % \begin{macro}{\sv@verbline}
922 %
923 % This macro typesets a line in a verbatim way, so you can construct a real
924 % verbatim environment from it.  It's a bit tricky in the way that it catches
925 % the last line.  Don't worry about this: it's easy really.  Note the
926 % |\relax| after the |\par| -- this is because \package{doc} tries to do
927 % clever things with |\par| to strip `|%|' signs out.
928 %
929 %    \begin{macrocode}
930 \def\sv@verbline#1{%
931   \sv@emptybox\tw@%
932   \setbox\z@\hbox{#1\sv@stripspc}%
933   \sv@addtobox\tw@\z@%
934   \if1\ifdim\wd\tw@=\z@\if@matched0\else1\fi\else1\fi%
935     \svline\tw@\relax%
936   \fi%
937 }
938 %    \end{macrocode}
939 %
940 % \end{macro}
941 %
942 % \subsection{Listing environments}
943 %
944 % The \env{listing} environment is our equivalent of the standard
945 % \env{verbatim} environment.  We do some slightly cleverer things, though,
946 % to make sure (for example) that even text which contains |\end{listing}|
947 % can be typeset.
948 %
949 % \begin{macro}{\listinghook}
950 %
951 % Set everything up as required.  This is here for customization.  The
952 % underlying machinery doesn't mess with this directly, but assumes that
953 % |\svline| and |\svafter| are set up appropriately.
954 %
955 %    \begin{macrocode}
956 \def\listinghook{%
957   \par%
958   \begingroup
959   \listinglist%
960   \listingsize%
961   \let\svline\listingline%
962   \def\svafter{\endlistinglist\endgroup}%
963 }
964 %    \end{macrocode}
965 %
966 % \end{macro}
967 %
968 % \begin{macro}{\listinglist}
969 % \begin{environment}{listinglist}
970 %
971 % This defines the layout for the \env{listing} environment.  It starts a
972 % list with the appropriate shape.  It's also made into an environment, so
973 % that the end-paragraph-environment bits work correctly.
974 %
975 % The |\listingindent| length parameter sets up the indentation of the
976 % listings.  If there's a |\parindent| setting, I'll line listings up with
977 % that; otherwise I'll just choose something which looks right.
978 %
979 %    \begin{macrocode}
980 \newdimen\listingindent
981 \AtBeginDocument{%
982   \ifdim\parindent=\z@\listingindent1em\else\listingindent\parindent\fi%
983 }
984 %    \end{macrocode}
985 %
986 % Now to define a size hook for the environment.  This is fairly simple
987 % stuff.
988 %
989 %    \begin{macrocode}
990 \ifx\listingsize\@@undefined
991   \let\listingsize\footnotesize
992 \fi
993 %    \end{macrocode}
994 %
995 % Now to define the environment itself.  Suppress the indentation if we're
996 % first thing on a new list item, so that the listing lines up with
997 % everything else.
998 %
999 %    \begin{macrocode}
1000 \def\listinglist{%
1001   \list{}{%
1002     \if@inlabel%
1003       \leftmargin\z@%
1004     \else%
1005       \leftmargin\listingindent%
1006     \fi%
1007     \rightmargin\z@%
1008     \labelwidth\z@%
1009     \labelsep\z@%
1010     \itemindent\z@%
1011     \listparindent\z@%
1012     \let\makelabel\relax%
1013     \parsep\z@skip%
1014   }%
1015   \parfillskip\@flushglue%
1016   \item\relax%
1017 }
1018 \let\endlistinglist\endlist
1019 %    \end{macrocode}
1020 %
1021 % \end{environment}
1022 % \end{macro}
1023 %
1024 % \begin{macro}{\svline}
1025 % \begin{macro}{\svdoline}
1026 % \begin{macro}{\listingline}
1027 %
1028 % The simple spit-out-a-line macro.
1029 %
1030 %    \begin{macrocode}
1031 \def\svdoline#1{\leavevmode\box#1\par}
1032 \let\svline\svdoline
1033 \let\listingline\svline
1034 %    \end{macrocode}
1035 %
1036 % \end{macro}
1037 % \end{macro}
1038 % \end{macro}
1039 %
1040 % \begin{macro}{\svafter}
1041 %
1042 % This is called when the machinery finishes.  A default is set for safety's
1043 % sake.
1044 %
1045 %    \begin{macrocode}
1046 \let\svafter\relax
1047 %    \end{macrocode}
1048 %
1049 % \end{macro}
1050 %
1051 % \begin{environment}{listing}
1052 %
1053 % The \env{listing} environment is the only real verbatim-like environment we
1054 % create will all this kit, although it does the job very nicely.
1055 %
1056 % The environment indents its contents slightly, unlike \env{verbatim}, and
1057 % uses a smaller typeface in an attempt to fit 77-column text on an A5~page.
1058 % There is also a $*$-variant, which allows you to specify the terminating
1059 % text.  This enables you to include absolutely any text in the environment,
1060 % including |\end{listing}|.
1061 %
1062 % First, we must define the |\listing| command.
1063 %
1064 %    \begin{macrocode}
1065 \def\listing{\listinghook\sv@readenv\sv@listing}
1066 %    \end{macrocode}
1067 %
1068 % Now we define the |\@listing| command, which does most of the work.  We
1069 % base the \env{listing} environment on a \env{list}.
1070 %
1071 %    \begin{macrocode}
1072 \def\sv@listing#1#2{\sv@startlisting\sv@read{#1}\sv@verbline{\svafter#2}}
1073 %    \end{macrocode}
1074 %
1075 % Now we define the starred version.  The command name needs to include the
1076 % `|*|' character, so we must use |\csname|.  There's some hacking here to
1077 % allow us to read the name using the appropriate catcodes for otherwise
1078 % normal characters: \LaTeX\ activates some characters and makes them typeset
1079 % themselves to suppress some ligaturing.
1080 %
1081 %    \begin{macrocode}
1082 \expandafter\def\csname listing*\endcsname{%
1083   \listinghook\begingroup\@noligs\listing@star%
1084 }
1085 \def\listing@star#1{\endgroup\sv@listing{#1}{\end{listing*}}}
1086 %    \end{macrocode}
1087 %
1088 % \end{environment}
1089 %
1090 % \begin{environment}{ignore}
1091 %
1092 % The \env{ignore} environment entirely ignores its contents.  Anything at
1093 % all may be put into the environment: it is discarded utterly.
1094 %
1095 % We define some macros for defining ignoring environments, because this can
1096 % be useful for version control, possibly.
1097 %
1098 %    \begin{macrocode}
1099 \def\sv@ignore#1#2{%
1100   \@bsphack%
1101   \let\do\@makeother\dospecials%
1102   \sv@read{#1}\@gobble{\@esphack#2}%
1103 }
1104 \def\ignore{\sv@readenv\sv@ignore}
1105 \def\ignoreenv#1{%
1106   \expandafter\let\csname #1\endcsname\ignore%
1107 }
1108 \def\unignoreenv#1{%
1109   \expandafter\def\csname #1\endcsname{\endgroup}%
1110   \expandafter\def\csname end#1\endcsname%
1111       {\begingroup\def\@currenvir{#1}}%
1112 }
1113 %    \end{macrocode}
1114 %
1115 % \end{environment}
1116 %
1117 % \subsection{The \env{verbwrite} environment}
1118 %
1119 % The \env{verbwrite} environment allows text to be written to a file in a
1120 % verbatim way.  Note that tab characters don't work, because \TeX\ refuses
1121 % to be nice.
1122 %
1123 % \begin{macro}{\sv@write}
1124 %
1125 % As seems to be traditional now, we first define a general hookable macro
1126 % which allows a caller to specify the end-text and what to do afterwards.
1127 %
1128 %    \begin{macrocode}
1129 \newwrite\sv@writefile
1130 \def\sv@write#1#2{%
1131   \begingroup%
1132   \@bsphack%
1133   \let\do\@makeother\dospecials%
1134   \sv@safespc%
1135   \sv@read{#1}\sv@writeline{\sv@endwrite#2}%
1136 }
1137 \def\sv@writeline#1{%
1138   \immediate\write\sv@writefile{#1}%
1139 }
1140 \def\sv@endwrite{%
1141   \@esphack%
1142   \endgroup%
1143 }
1144 %    \end{macrocode}
1145 %
1146 % \end{macro}
1147 %
1148 % \begin{environment}{verbwrite}
1149 %
1150 % Now we can define the actual environment.  We define a $*$-variant which
1151 % allows the user to specify the end-text, just to make sure.
1152 %
1153 %    \begin{macrocode}
1154 \def\verbwrite#1{%
1155   \immediate\openout\sv@writefile#1\relax%
1156   \sv@readenv\sv@write%
1157 }
1158 \def\endverbwrite{\immediate\closeout\sv@writefile}
1159 \expandafter\def\csname verbwrite*\endcsname#1#2{%
1160   \immediate\openout\sv@writefile#2\relax%
1161   \sv@write{#1}{\immediate\closeout\sv@writefile\end{verbwrite*}}%
1162 }
1163 %    \end{macrocode}
1164 %
1165 % \end{environment}
1166 %
1167 % \subsection{The \env{demo} environment}
1168 %
1169 % By way of tying all of this together, I present an environment for
1170 % displaying demonstrations of \LaTeX\ markup.  We read the contents of the
1171 % environment, write it to a temporary file, and read it back twice,
1172 % typesetting it the first time and displaying it verbatim the second time.
1173 %
1174 % \begin{macro}{\sv@demoname}
1175 %
1176 % This macro expands to the filename to use for the temporary data.  To
1177 % allow the package documentation to demonstrate the \env{demo} environment
1178 % itself, we need to keep a nesting count.  This avoids too much hackery,
1179 % which unfortunately appears to plague all of my \TeX\ code.
1180 %
1181 %    \begin{macrocode}
1182 \newcount\sv@nestcount
1183 \def\sv@demoname{demo\number\sv@nestcount.tmp}
1184 %    \end{macrocode}
1185 %
1186 % \end{macro}
1187 %
1188 % \begin{macro}{\sv@demo}
1189 %
1190 % As for listing, we do all the business through a private macro.  This is
1191 % good because it means we can leave the main macro readable.  The argument
1192 % is the end-text to spot.
1193 %
1194 %    \begin{macrocode}
1195 \def\sv@demo#1#2{%
1196   \@ifnextchar[{\sv@demo@i{#1}{#2}}{\sv@demo@i{#1}{#2}[n]}%
1197 }
1198 \def\sv@demo@i#1#2[#3]#4{%
1199   \advance\sv@nestcount by\@ne%
1200   \immediate\openout\sv@writefile\sv@demoname\relax%
1201   \sv@write{#1}{%
1202     \immediate\closeout\sv@writefile%
1203     \sv@dodemo{#2}{#3}{#4}%
1204   }%
1205 }
1206 %    \end{macrocode}
1207 %
1208 % \end{macro}
1209 %
1210 % \begin{environment}{demo}
1211 %
1212 % This is the real environment.  We provide \env{demo$*$} too, to allow the
1213 % user to choose the end-text.
1214 %
1215 %    \begin{macrocode}
1216 \def\demo{\let\@demohook\demohook\sv@readenv\sv@demo}
1217 \expandafter\def\csname demo*\endcsname#1%
1218   {\let\@demohook\demohook\sv@demo{#1}{\end{demo*}}}
1219 %    \end{macrocode}
1220 %
1221 % \end{environment}
1222 %
1223 % \begin{macro}{\demohook}
1224 %
1225 % Like |\listinghook|.  So much so that we just call it, but first ensure
1226 % that the indent is zero (otherwise it looks really odd!).
1227 %
1228 %    \begin{macrocode}
1229 \def\demohook{\listingindent\z@\listinghook}
1230 %    \end{macrocode}
1231 %
1232 % \end{macro}
1233 %
1234 % \begin{macro}{\sv@dodemo}
1235 %
1236 % First, let's define some common bits of code in the stuff below.  The
1237 % minipages used to typeset the material has some clever stuff to avoid
1238 % strange spacing in the output.
1239 %
1240 %    \begin{macrocode}
1241 \def\sv@demosmp{%
1242   \begin{minipage}[t]{\@tempdima}%
1243   \vskip8\p@%
1244   \hrule\@height\z@%
1245   \raggedright%
1246   \vbox\bgroup%
1247 }
1248 \def\sv@demoemp{%
1249     \par\unpenalty\unskip%
1250   \egroup%
1251   \vskip8\p@%
1252   \hrule\@height\z@%
1253   \end{minipage}%
1254 }
1255 %    \end{macrocode}
1256 %
1257 % This is the macro which actually typesets the demonstration.
1258 %
1259 %    \begin{macrocode}
1260 \def\sv@dodemo#1#2#3{%
1261 %    \end{macrocode}
1262 %
1263 % Now work out some values.  We set |\hsize| to the line width leaving 2\,em
1264 % of space on either side.  The size of the minipages is calculated depending
1265 % on the shape of the demonstration.  This is all fairly simple.
1266 %
1267 %    \begin{macrocode}
1268   \begingroup%
1269   \@tempdima\linewidth%
1270   \advance\@tempdima-2em%
1271   \hsize\@tempdima%
1272   \if#2w%
1273     \advance\@tempdima-2em%
1274   \else%
1275     \advance\@tempdima-3em%
1276     \divide\@tempdima2%
1277   \fi%
1278 %    \end{macrocode}
1279 %
1280 % Now we open a big vertical box, and put in a header to mark off the
1281 % demonstration.
1282 %
1283 %    \begin{macrocode}
1284   \par%
1285   \setbox\z@\hbox{\strut\enspace#3\enspace\strut}%
1286   \@tempdimb.5\dp\z@%
1287   \advance\@tempdimb-.5\ht\z@%
1288   \ht\z@\@tempdimb\dp\z@\@tempdimb%
1289   \noindent\hskip1em\vtop{%
1290     \hb@xt@\hsize{%
1291       \hrulefill%
1292       \raise\@tempdimb\box\z@%
1293       \hrulefill%
1294     }%
1295     \nointerlineskip%
1296     \hb@xt@\hsize{\vrule\@height5\p@\hfil\vrule\@height5\p@}%
1297     \nointerlineskip%
1298 %    \end{macrocode}
1299 %
1300 % Now we insert the output text in the first minipage.  I'll force `|%|'
1301 % to be a comment character, in case something like \package{doc} has had its
1302 % wicked way.
1303 %
1304 %    \begin{macrocode}
1305     \vskip-\parskip%
1306     \noindent\hbox{}\hskip1em%
1307     \sv@demosmp%
1308     \catcode`\%14\relax%
1309     \@input{\sv@demoname}%
1310     \sv@demoemp%
1311 %    \end{macrocode}
1312 %
1313 % Insert some kind of separation between the two.  In `wide' format, we start
1314 % a new line, and put a ruleoff between the two.  In `narrow' format, we just
1315 % leave some space.
1316 %
1317 %    \begin{macrocode}
1318     \if#2w%
1319       \vskip8\p@\hrule\vskip8\p@%
1320       \noindent\hbox{}%
1321     \fi%
1322     \hskip1em%
1323 %    \end{macrocode}
1324 %
1325 % Now we put the verbatim copy of the text in the other minipage.
1326 %
1327 %    \begin{macrocode}
1328     \sv@demosmp%
1329     \@demohook%
1330     \verbinput@\@input\sv@demoname%
1331     \sv@demoemp%
1332     \par%
1333     \nointerlineskip%
1334     \hb@xt@\hsize{\vrule\@height5\p@\hfil\vrule\@height5\p@}%
1335     \hrule%
1336   }%
1337   \endgroup%
1338   \par%
1339   \vskip\baselineskip%
1340   #1%
1341 }
1342 %    \end{macrocode}
1343 %
1344 % \end{macro}
1345 %
1346 % \subsection{Loading the colour package}
1347 %
1348 % If requested, we load the \package{svcolour} package here.  This ensures
1349 % that it can patch this code if it needs to.
1350 %
1351 %    \begin{macrocode}
1352 \ifsv@colour
1353   \RequirePackage{svcolour}
1354 \fi
1355 %    \end{macrocode}
1356 %
1357 % That's all there is.  Have fun.
1358 %
1359 %    \begin{macrocode}
1360 %</package>
1361 %    \end{macrocode}
1362 %
1363 % \subsection{The \package{svcolour} package}
1364 %
1365 % This is in a separate package to avoid dragging in the \package{color}
1366 % package if it's unwanted.
1367 %
1368 % I prefer English spellings.  Here's a trivial redirection for Americans.
1369 %
1370 %    \begin{macrocode}
1371 %<*color>
1372 \DeclareOption*{\PassOptionsToPackage{\CurrentOption}{svcolour}}
1373 \ProcessOptions
1374 \RequirePackage{svcolour}
1375 %</color>
1376 %    \end{macrocode}
1377 %
1378 % And now we can start the thing properly.
1379 %
1380 %    \begin{macrocode}
1381 %<*colour>
1382 \RequirePackage{color}
1383 %    \end{macrocode}
1384 %
1385 % \begin{macro}{\@snarfcolour}
1386 %
1387 % Reading a colour specification is something we'll need to do a few times,
1388 % so an abstraction is useful.  Its single argument is a continuation to
1389 % which we pass a colour-spec acceptable to the |\color| command.  (This is
1390 % the same code as found in the \package{mdwtab} package.  Remember to keep
1391 % them in step.)
1392 %
1393 %    \begin{macrocode}
1394 \def\@snarfcolour#1{%
1395   \@ifnextchar[{\@snarfcolour@i{#1}}{\@snarfcolour@ii{#1}{}}%
1396 }
1397 \def\@snarfcolour@i#1[#2]{\@snarfcolour@ii{#1}{[#2]}}
1398 \def\@snarfcolour@ii#1#2#3{#1{#2{#3}}}
1399 %    \end{macrocode}
1400 %
1401 % \end{macro}
1402 %
1403 % \begin{macro}{\svcolourline}
1404 % \begin{macro}{\svcolorline}
1405 %
1406 % Snarf the option, and plot the coloured bar.  Note the penalties which are
1407 % meant to stick the glue and leaders onto the colour specials.
1408 %
1409 %    \begin{macrocode}
1410 \def\svcolourline{\@snarfcolour\svcl@i}
1411 \def\svcl@i#1#2{%
1412   \skip@\wd#2%
1413   \advance\skip@\parfillskip%
1414   \advance\skip@.2em%
1415   \strut%
1416   \kern.2em%
1417   \begingroup\color#1\nobreak\leaders\vrule\hskip\skip@\endgroup%
1418   \nobreak\hskip-\skip@%
1419   \kern.2em%
1420   \box#2%
1421   \nobreak\hskip-\rightskip\vadjust{}%
1422   \par%
1423 }
1424 \let\svcolorline\svcolourline
1425 %    \end{macrocode}
1426 %
1427 % \end{macro}
1428 % \end{macro}
1429 %
1430 % Done!
1431 %
1432 %    \begin{macrocode}
1433 %</colour>
1434 %    \end{macrocode}
1435 %
1436 % \subsection{The \package{svsplit} package}
1437 %
1438 %    \begin{macrocode}
1439 %<*split>
1440 \RequirePackage{sverb}
1441 %    \end{macrocode}
1442 %
1443 % \begin{environment}{splitverb}
1444 % \begin{environment}{splitverb*}
1445 %
1446 % The basic environments are simple enough.
1447 %
1448 %    \begin{macrocode}
1449 \def\splitverb{\listinghook\sv@readenv\splitverb@}
1450 \expandafter\def\csname splitverb*\endcsname%
1451   {\listinghook\begingroup\@noligs\svsplit@star}
1452 \def\svsplit@star#1{\endgroup\splitverb@{#1}{\end{splitverb*}}}
1453 %    \end{macrocode}
1454 %
1455 % \end{environment}
1456 % \end{environment}
1457 %
1458 % \begin{macro}{\splitverb@}
1459 %
1460 % Even this isn't so bad, really.
1461 %
1462 %    \begin{macrocode}
1463 \def\splitverb@#1#2{\sv@startlisting\sv@read{#1}\svsplit@line{\svafter#2}}
1464 %    \end{macrocode}
1465 %
1466 % \end{macro}
1467 %
1468 % \begin{macro}{\svsplit@line}
1469 %
1470 % For the sake of readability (and maybe saving a few tokens), we define some
1471 % synonyms for \TeX's scratch registers.  |\svsplit@remain| will be a
1472 % |\global| register containing the remaining horizontal space on the line;
1473 % |\svsplit@indent| is a local register containing the amount of initial
1474 % whitespace on the line.
1475 %
1476 %    \begin{macrocode}
1477 \dimendef\svsplit@remain=1 
1478 \dimendef\svsplit@indent=2
1479 %    \end{macrocode}
1480 %
1481 % The switch |\svsplit@| is set if we've found a good place to split the
1482 % current line.
1483 %
1484 %    \begin{macrocode}
1485 \newif\ifsvsplit@
1486 %    \end{macrocode}
1487 %
1488 % And finally a delimiter.  This is the same one I use everywhere else.
1489 %
1490 %    \begin{macrocode}
1491 \def\q@delim{\q@delim}
1492 %    \end{macrocode}
1493 %
1494 %    \begin{macrocode}
1495 \begingroup
1496 \catcode`\~=\active \lccode`\~=32
1497 \catcode`\!=\active \lccode`\!=9
1498 \lowercase{\endgroup
1499 %    \end{macrocode}
1500 %
1501 % So far, so good.  The |\svsplit@line| macro is given a line of text.  We
1502 % initialize |\svtab| to be a \emph{single} space, |\svsplit@remain| to be
1503 % the text width, and |\svsplit@indent| to zero.  Then we embark on the first
1504 % loop, which attempts to find the width of the leading whitespace.
1505 %
1506 %    \begin{macrocode}
1507 \def\svsplit@line#1{%
1508   \divide\svtab8%
1509   \global\svsplit@remain\linewidth%
1510   \svsplit@indent\z@%
1511   \sv@emptybox\tw@%
1512   \let\next@\svsplit@findindent%
1513   \next@#1\q@delim%
1514 }
1515 %    \end{macrocode}
1516 %
1517 % A straightforward tail-recursive loop finds out how much whitespace there
1518 % is at the start of the current line.  Note that |\next@| is already set up
1519 % for the optimized case of continuing the loop.  Also, if we reach the end
1520 % then this is a blank line, so only emit something if we didn't see the
1521 % end-marker.  This is the only place we need to check for this.
1522 %
1523 %    \begin{macrocode}
1524 \def\svsplit@findindent#1{%
1525   \ifx~#1%
1526     \advance\svsplit@indent\svtab%
1527   \else\ifx!#1%
1528     \dimen@8\svtab%
1529     \divide\svsplit@indent\dimen@%
1530     \multiply\svsplit@indent\dimen@%
1531     \advance\svsplit@indent\dimen@%
1532   \else\ifx\q@delim#1%
1533     \if@matched\else\svline\tw@\fi%
1534     \let\next@\relax%
1535   \else%
1536     \def\next@{\svsplit@scanline{#1}}%
1537   \fi\fi\fi%
1538   \next@%
1539 }
1540 %    \end{macrocode}
1541 %
1542 % Now we have to actually scan the line to find breakpoints.  We build the
1543 % current unbreakable chunk in |\box|~0.  When we find a breakpoint, we close
1544 % the box, maybe stretch it to take into account trailing space, and attach
1545 % it to |\box|~2, which is gathering the current line.  If |\svsplit@remain|
1546 % hits zero then we flush |\box|~2 to the output and continue on the next
1547 % line with a (more-or-less) clean slate.
1548 %
1549 % If there's no breakpoint then we're hosed.  In that case, we just insert a
1550 % (|\normalfont|) hyphen and eject what we've got.
1551 %
1552 % Note that this assumes that the indentation will fit.  If not, then we're
1553 % deeply stuffed.
1554 %
1555 %    \begin{macrocode}
1556 \def\svsplit@scanline{%
1557   \svsplit@false%
1558   \let\next@\svsplit@char%
1559   \setbox\z@\hbox\bgroup%
1560     \kern\svsplit@indent%
1561     \global\advance\svsplit@remain-\svsplit@indent%
1562     \next@%
1563 }
1564 %    \end{macrocode}
1565 %
1566 % Scanning a character isn't so bad, if we take it a step at a time.
1567 %
1568 %    \begin{macrocode}
1569 \def\svsplit@char#1{%
1570 %    \end{macrocode}
1571 %
1572 % If the character is a space or a tab, then we call |\svsplit@space| which
1573 % knows about adding breakable whitespace.  For tabs, this involves computing
1574 % the correct tab size.
1575 %
1576 %    \begin{macrocode}
1577     \ifx~#1%
1578       \svsplit@space\svtab%
1579     \else\ifx!#1%
1580       \@tempdima\linewidth%
1581       \advance\@tempdima-\svsplit@remain%
1582       \@tempdimb\@tempdima%
1583       \dimen@8\svtab%
1584       \divide\@tempdimb\dimen@%
1585       \multiply\@tempdimb\dimen@%
1586       \advance\@tempdimb\dimen@%
1587       \advance\@tempdimb-\@tempdima%
1588       \svsplit@space\@tempdimb%
1589 %    \end{macrocode}
1590 %
1591 % We might have reached the end of the line.  If so, then we finish off.
1592 %
1593 %    \begin{macrocode}
1594     \else\ifx\q@delim#1%
1595       \let\next@\svsplit@done%
1596 %    \end{macrocode}
1597 %
1598 % Otherwise it's a normal character.  If there's not enough space then force
1599 % a break.  
1600 %
1601 %    \begin{macrocode}
1602     \else%
1603       \ifdim\svsplit@remain<2\svtab%
1604         \ifsvsplit@\else\normalfont-\svsplit@break\fi%
1605         \svsplit@eject%
1606       \fi%
1607 %    \end{macrocode}
1608 %
1609 % Insert the character and decrement the distance-left register.
1610 %
1611 %    \begin{macrocode}
1612       #1%
1613       \global\advance\svsplit@remain-\svtab%
1614 %    \end{macrocode}
1615 %
1616 % Now we see if it's a breakable-after character and if so mark it as being
1617 % breakable.
1618 %
1619 %    \begin{macrocode}
1620       \def\temp@##1#1##2\q@delim%
1621         {\ifx\q@delim##2\q@delim\else\svsplit@break\fi}%
1622       \expandafter\temp@\svsplitchars#1\q@delim%
1623 %    \end{macrocode}
1624 %
1625 % And with that, we're done.
1626 %
1627 %    \begin{macrocode}
1628     \fi\fi\fi%
1629     \next@%
1630 }
1631 %    \end{macrocode}
1632 %
1633 % Our next macro is the break-insertion subroutine, which is quite easy.
1634 %
1635 %    \begin{macrocode}
1636 \def\svsplit@break{%
1637   \egroup%
1638   \sv@addtobox\tw@\z@%
1639   \svsplit@true%
1640   \setbox\z@\hbox\bgroup%
1641 }
1642 %    \end{macrocode}
1643 %
1644 % Now we add space to the current box.  The argument is a dimen register.
1645 %
1646 %    \begin{macrocode}
1647 \def\svsplit@space#1{%
1648     \ifdim\svsplit@remain>#1\kern#1\global\advance\svsplit@remain-#1\fi%
1649     \svsplit@break%
1650     \ifdim\svsplit@remain>#1\else\svsplit@eject\fi%
1651 }
1652 %    \end{macrocode}
1653 %
1654 % We now come to a slightly involved piece of code, which is how to flush out
1655 % a line, and then fix up the registers for the next line correctly.
1656 %
1657 %    \begin{macrocode}
1658 \def\svsplit@eject{%
1659   \egroup%
1660   \svline\tw@%
1661   \sv@emptybox\tw@%
1662   \svsplit@false%
1663   \setbox\z@\hbox\bgroup%
1664     \kern\svsplit@indent%
1665     \global\svsplit@remain\linewidth%
1666     \global\advance\svsplit@remain-\svsplit@indent%
1667     \global\advance\svsplit@remain-\wd\z@%
1668     \unhbox\z@%
1669 }
1670 %    \end{macrocode}
1671 %
1672 % Finally, how to finish the line and go home.
1673 %
1674 %    \begin{macrocode}
1675 \def\svsplit@done{%
1676   \egroup%
1677   \sv@addtobox\tw@\z@%
1678   \svline\tw@%
1679 }
1680 %    \end{macrocode}
1681 %
1682 % End the |\lowercase| hack.
1683 %
1684 %    \begin{macrocode}
1685 }
1686 %    \end{macrocode}
1687 %
1688 % \end{macro}
1689 %
1690 % Finally, set the breakable characters to something plausible.
1691 %
1692 %    \begin{macrocode}
1693 \def\svsplitchars{:/.}
1694 %    \end{macrocode}
1695 %
1696 % And with that, we're done!
1697 %
1698 %    \begin{macrocode}
1699 %</split>
1700 %    \end{macrocode}
1701 %
1702 % \hfill Mark Wooding, \today
1703 %
1704 % \Finale
1705 %
1706 \endinput