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