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