3 % $Id: sverb.dtx,v 1.2 2003/09/05 16:09:30 mdw Exp $
5 % Verbatim typesetting done properly (ahem)
7 % (c) 1996 Mark Wooding
11 % \begin{meta-comment} <general public licence>
13 %% sverb package -- handling of verbatim text
14 %% Copyright (c) 1996 Mark Wooding
16 %% This program is free software; you can redistribute it and/or modify
17 %% it under the terms of the GNU General Public License as published by
18 %% the Free Software Foundation; either version 2 of the License, or
19 %% (at your option) any later version.
21 %% This program is distributed in the hope that it will be useful,
22 %% but WITHOUT ANY WARRANTY; without even the implied warranty of
23 %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 %% GNU General Public License for more details.
26 %% You should have received a copy of the GNU General Public License
27 %% along with this program; if not, write to the Free Software
28 %% Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 % \begin{meta-comment} <Package preamble>
33 %<+package>\NeedsTeXFormat{LaTeX2e}
34 %<+package>\ProvidesPackage{sverb}
35 %<+package> [2003/09/04 1.4 Verbatim typesetting]
36 %<+colour>\NeedsTeXFormat{LaTeX2e}
37 %<+colour>\ProvidesPackage{svcolour}
38 %<+colour> [2003/09/04 1.4 Colour support for sverb]
39 %<+color>\NeedsTeXFormat{LaTeX2e}
40 %<+color>\ProvidesPackage{svcolor}
41 %<+color> [2003/09/04 1.4 Fix for people who can't spell]
42 %<+split>\NeedsTeXFormat{LaTeX2e}
43 %<+split>\ProvidesPackage{svsplit}
44 %<+split> [2003/09/04 1.4 Verbatim, but with line breaking]
49 %% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
50 %% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
51 %% Digits \0\1\2\3\4\5\6\7\8\9
52 %% Exclamation \! Double quote \" Hash (number) \#
53 %% Dollar \$ Percent \% Ampersand \&
54 %% Acute accent \' Left paren \( Right paren \)
55 %% Asterisk \* Plus \+ Comma \,
56 %% Minus \- Point \. Solidus \/
57 %% Colon \: Semicolon \; Less than \<
58 %% Equals \= Greater than \> Question mark \?
59 %% Commercial at \@ Left bracket \[ Backslash \\
60 %% Right bracket \] Circumflex \^ Underscore \_
61 %% Grave accent \` Left brace \{ Vertical bar \|
62 %% Right brace \} Tilde \~}
65 % \begin{meta-comment}
69 \describespackage{sverb}
70 \describespackage{svcolour}
71 \describespackage{svsplit}
77 % \section{User guide}
79 % The \package{sverb} package provides some useful commands and environments
80 % for doing things with verbatim text. I prefer this code to the standard
81 % \package{verbatim} package (by Rainer Sch\"opf et al.)\ although I'm
84 % The package was written to fulfil a particular purpose: I wanted to be able
85 % to typeset ARM assembler code, 77~columns wide, on A5~paper, with the
86 % fields separated by \textit{tab} characters. It's grown up fairly
87 % organically from that, and I've tidied it when I've seen the code get too
90 % The current features are:
94 % \item A `listing' environment which typesets verbatim text nicely.
96 % \item A command to read verbatim text from an external file.
98 % \item Support for arbitrary-sized chunks of text without overflowing \TeX's
101 % \item Support for \textit{tab} characters in the verbatim text.
103 % \item An environment for typesetting demonstrations of \LaTeX\ markup.
105 % \item It all works correctly with the \package{doc} system for documenting
108 % \item A fairly hairy but quite powerful programmer interface to the yukky
109 % bits of the package.
113 % The interface is described in its own section, so that more timid readers
114 % can avoid it. That said, some of the stuff in this section gets rather
117 % Note that this package doesn't even try to do anything with short bits of
118 % verbatim text (as handled by the |\verb:...:| command). I have a separate
119 % package (\package{syntax}) which does all sorts of horrible things along
122 % \subsection{The \env{listing} environment}
124 % \DescribeEnv{listing}
125 % The main method for typesetting verbatim text is the \env{listing}
126 % environment. This works pretty much the same as the standard
127 % \env{verbatim} environment, with some exceptions, which are described
130 % So that you know exactly what you're getting, here are the rules by which
131 % \package{sverb} decides what the verbatim text actually is:
135 % \item If there's any text, other than spaces, on the same line as the
136 % `|\begin{listing}|', then the contents of the environment begins
137 % immediately after the closing brace (with all leading spaces
138 % preserved). Otherwise, the text begins on the following line.
140 % \item If there is any text, other than spaces, before the
141 % `|\end{listing}|', but on the same line, this is considered to be the
142 % last line of the text; otherwise the text is presumed to have ended
143 % at the end of the previous line.
145 % \item Any text following the |\end{listing}| on the same line is thrown
146 % away. There are good reasons for this, but they're technical.
147 % Essentially there's nothing I can do about it.
152 % \begin{demo}[w]{The \env{listing} environment}
153 %\dots in the following code:
156 %init MOV R0,#200 ;Version 2.00 please
157 % LDR R1,=&4B534154 ;Magic number (`TASK')
158 % ADR R2,appName ;Find application name
159 % SWI Wimp_Initialise ;Register as a WIMP task
162 %The next step is to \dots
166 % Tab characters are supported within the environment: tab stops are set
167 % every eighth column, although this can be modified.
169 % \subsubsection{Configuring the \env{listing} environment}
171 % \DescribeMacro\listingsize
172 % The text size used in the \env{listing} environment is set by the
173 % |\listingsize| command. By default, this is set to |\footnotesize|,
174 % although you can redefine it in the document preamble, or it can be set in
175 % the document class. You can put other declarations (e.g., colours) here if
178 % \DescribeMacro\listingindent
179 % The amount by which the listing text is indented is controlled by the
180 % |\listingindent| length parameter. This is a fixed length, whose default
183 % \DescribeMacro\listinghook
184 % \DescribeMacro\svafter
185 % \DescribeMacro\svline
186 % \DescribeMacro\svdoline
187 % \DescribeEnv{listinglist}
188 % The |\listinghook| command is called by the \env{listing} environment (and
189 % |\verbinput| and \env{demo}) to set up the formatting of the listing. It
190 % can do any setting up it likes, and may configure |\svline| and |\svafter|
191 % as necessary. The macro |\svline| is run once for each line of verbatim
192 % text, with the line gathered into a box register, the number of which is
193 % given as an argument. The macro |\svafter| is called when processing has
196 % The default setting for |\listinghook| is (similar to)
198 %\newcommand{\listinghook}{%
200 % \begin{listinglist}%
202 % \renewcommand{\svline}{\listingline}%
203 % \renewcommand{\svafter}{\end{listinglist}}%
206 % (see the source for the true definition). The default |\listingline| macro
207 % just writes out the line using |\svdoline|, which is a simple no-nonsense
208 % macro which just writes the text. As an example, you could say
210 %\renewcommand{\listingline}{\leavevmode\llap{\strut\vrule\space}\svdoline}
212 % to put a rule down the left-hand side of your listings.
214 % The \env{listinglist} environment is a relatively straightforward
215 % \env{list}-based environment which sets pu the indentation of a listing.
216 % Feel free to redefine it.
218 % \subsubsection{Choosing a different end-text}
220 % \DescribeEnv{listing*}
221 % The \env{listing} environment is terminated by the exact character sequence
222 % `|\end{listing}|'. This isn't too much of a problem, unless you want to
223 % include this string in the text. This is achieved by the \env{listing$*$}
224 % environment, which allows you to specify the end-text to find as an
229 % \begin{demo}{The \env{listing$*$} environment}
230 %Type a listing as follows:
232 %\begin{listing*}{<end-listing*>}
234 %This is a listing. Yes.
239 % Don't include `special' characters in your chosen end-text unless you know
242 % \subsection{Writing text to a file}
244 % \DescribeEnv{verbwrite}
245 % You can write verbatim text to a file using the \env{verbwrite}
246 % environment. The syntax is fairly straightforward:
249 % \syntax{"\\begin{verbwrite}{"<file-name>"}" \dots "\\end{verbwrite}"}
252 % The text of the environment is written to the named file. The rules about
253 % where the text actually starts and ends are the same as for the
254 % \env{listing} environment.
256 % There is also a $*$-variant, like \env{listing$*$}, which allows you to
257 % choose the end-text. The end-text is the first argument, the filename
260 % There is a restriction on the characters you can write to the file: they
261 % must all be considered `printable' by \TeX; otherwise they will be read
262 % back in as `\syntax{"^^"<chars>}' which isn't too good. Unfortunately,
263 % this includes tab characters, so you can't write them.\footnote{^^A
264 % Well, not without doing serious surgery on \TeX\ itself, anyway. }
266 % \iffalse [Example time... Ho hum. There is evilness here.] \fi
267 %\begin{verbwrite*}{<end-write>}{wrdemo1.tmp}
268 %\begin{verbwrite}{wrdemo.tmp}
269 %This is some text written to
270 %a file near the beginning of
275 % For example: \verbinput{wrdemo1.tmp}
277 % \input{wrdemo1.tmp} \iffalse [Now build the file ;-) ] \fi
279 % \subsection{The \cmd\verbinput\ command}
281 % \DescribeMacro{\verbinput}
282 % You can input a pre-prepared text file exactly as it is in the input using
283 % the |\verbinput| command. The filename is given as an argument. For
286 % \begin{demo}{The \cmd\verbinput\ command}
287 %\verbinput{wrdemo.tmp}
290 % \subsection{The \env{demo} environment}
292 % Package authors need to document their packages, and it's common to want
293 % to display examples showing the original text and the output side-by-side
294 % (or, when space doesn't permit this, one above the other). Both the
295 % \LaTeX\ book and \textit{The \LaTeX\ Companion} contain such examples.
297 % The \env{demo} environment allows such displays to be created easily. The
298 % syntax of the environment is as follows:
301 % \syntax{"\\begin{demo}["<shape>"]{"<title>"}" \dots "\\end{demo}"}
304 % The optional \synt{shape} argument can be either `|w|' (wide), or `|n|'
305 % (narrow). A `wide' shape places the input and output one above the other,
306 % while the `narrow' shape puts them side-by-side. The default shape is
307 % `narrow'. An attractive border is drawn around the display to finish it
312 %\begin{demo*}{<end-demo>}[w]{The \env{demo} environment}
313 %\begin{demo}{From the \textit{\TeX book}}
314 %\[ \sum_{p\;\rm prime}
316 % f(t)\,{\rm d}\pi(t) \]
320 % \DescribeEnv{demo*}
321 % As with the other environments created by this package, there's a
322 % $*$-variant which takes the end-text as an argument.
324 % \DescribeMacro\demohook
325 % The |\demohook| does the same job for \env{demo} environments as
326 % |\listinghook| does for \env{listing}s. The default version just says
328 %\newcommand{\demohook}{\setlength{\listingindent}{0pt}\listinghook}
330 % (near enough), which turns off the indentation for the listing (which would
331 % otherwise look rather odd).
334 % \section{Programmer interface}
336 % This section describes the publicly available routines provided by the
337 % \package{sverb} package. Routines not described here are libable to be
338 % changed or even removed without warning, so don't use them.
340 % \subsection{Environment hooks}
342 % Each of the environments created here works in the same way. For each
343 % environment \env{foo}, there's a main command responsible for doing the
344 % work, called |\sv@foo|. This is given all the arguments of the normal
345 % environment, and two more:
349 % \item The `end-text' to search for, which marks the end of the environment.
351 % \item Some actions to perform after the text has been read and processed.
352 % This allows the calling macro to do some extra actions, like closing
357 % All the environments do is call the main command with appropriate
360 % \subsection{Reading the verbatim text}
362 % \DescribeMacro{\sv@read}
363 % The main scanning routine is |\sv@read|. It is called with three
368 % \item The end-text marking the end of the environment.
370 % \item The name of a macro (which must be a single token) which is called
371 % with a line of text as its single argument. This is given each
372 % line of text which is read from the environment in turn.
374 % \item A macro, or other sort of action, which is to be done when the text
375 % has been read and processed.
379 % The macro |\sv@read| assumes that the caller has already made some
380 % provision for removing the category codes of the following text, by either
381 % calling |\@verbatim| or using the construction
387 % \DescribeMacro{\sv@safespc}
388 % Note that any space characters you read using |\sv@read| will be catcoded
389 % as |\active|. Normally this is OK because |\obeyspaces| (or
390 % |\@vobeyspaces|) will be in effect. If you're doing something more exotic,
391 % like writing text to a file or building a command string, you can call
392 % |\sv@safespc| which defines the active-space character to be a normal
393 % whitespace-space when expanded.
395 % \section{Colour support}
397 % There's now a little colour support in \package{sverb}. To use it, give
398 % the \textsf{colour} (or \textsf{color}) package option, or load the
399 % \package{svcolour} package.
401 % \DescribeMacro\svcolourline
402 % Say \syntax{"\\svcolourline["<model>"]{"<colour>"}{"<box>"}"} to typeset
403 % \<box> against a background of the given colour. This is a good thing to
404 % put in your |\listingline| command.
405 %\begin{demo}{Coloured listings}
406 %\renewcommand{\listingline}
407 % {\svcolourline[rgb]{1, 0.8, 0.9}}
408 %Consider, for example, this more
409 %complicated program.
415 % puts("Hello, world!");
420 % For coloured text rather than background, put a |\color| command in
421 % |\listinghook| itself.
423 % \section{The \package{svsplit} package}
427 % \DescribeEnv{splitverb}
428 % \DescribeEnv{splitverb*}
429 % \DescribeMacro\svsplitchars
430 % The \env{splitverb} environment typesets verbatim material very slowly. On
431 % the plus side, however, it does know how to do simple line-breaking. It
432 % will break lines at spaces or tabs, or after any character listed in
433 % |\svsplitchars|. Continuation lines have the same initial intentation as
434 % the original. If a line has no `good' breaking point, it's broken as late
435 % as possible, and a little hyphen is inserted.
436 %\begin{demo}[w]{The \env{splitverb} environment}
437 %\begin{multicols}{2}
439 %The \package{url} package is rather fine at splitting up long URLs such as
440 % \url{http://www.excessus.demon.co.uk/tex}
441 %though it can't do its thing in the midst of verbatim text. It
442 %also doesn't cope when
443 % allthespacesinalongphrasehavemysteriouslydisappeared!
450 % \section{Implementation}
452 % This section defines several macros and environments which allow verbatim
453 % typing, with a high degree of configurability. OK, so this sort of
454 % thing's been done so often before that it isn't true, but I don't really
461 % \subsection{Options processing}
463 % Notice options, load package.
466 \newif\ifsv@colour\sv@colourfalse
467 \DeclareOption{colour}{\sv@colourtrue}
468 \DeclareOption{color}{\sv@colourtrue}
472 % \subsection{Simple things}
474 % To help us build funny macros which involve strange and different category
475 % codes, I'll write some simple macros which I can use while building my
476 % complicated and clever ones.
478 % \begin{macro}{\@cspecials}
480 % This macro is used to assist the definition of some of the environments.
481 % It makes `|\|', `|{|' and `|}|' into `other' characters, and replaces them
482 % with `\verb"|"', `|<|' and `|>|' respectively. Note that `|[|' and `|]|'
483 % aren't used, because they make defining commands which take optional
484 % arguments awkward. Note that we open a group here. This should be closed
485 % using \verb"|endgroup" at the end of the special section.
500 % \begin{macro}{\sv@addtobox}
502 % Add stuff to a horizontal box.
505 \def\sv@addtobox#1#2{\setbox#1\hbox{\unhbox#1\box#2}}
510 % \begin{macro}{\sv@emptybox}
512 % Clear out a horizontal box.
515 \def\sv@emptybox#1{\setbox#1\hbox{}}
520 % \begin{macro}{\sv@startlisting}
522 % This macro sets everything up nicely for a \env{listing}-type verbatim
526 \def\sv@startlisting{%
527 \def\par{\@@par\penalty\interlinepenalty}%
529 \leftskip\@totalleftmargin%
532 \let\do\@makeother\dospecials%
538 \lccode`\~9\lowercase{\let~\sv@vtab}%
539 \lccode`\~13\lowercase{\let~\vinput@cr}%
540 \interlinepenalty500%
546 % \subsection{Tab character handling}
548 % One of the things we want to do here is handle tab characters properly.
549 % (Here, `properly' means `moving to the next column which is a multiple of
550 % eight', the way these things were always meant to.)
552 % \begin{macro}{\settabwidth}
554 % The tabs used by our tabbed verbatim environments are set up by this
555 % routine. It sets the tab width parameter |\svtab| to 8 times the width
556 % of a |\tt| space. If you really want, you can redefine this macro.
560 \def\settabwidth{\setbox\z@\hbox{\texttt{\space}}\svtab8\wd\z@}
565 % \begin{macro}{\sv@vtab}
567 % Here we handle tabs inside verbatim environments. We expect to be inside
568 % |\box|~0. This is padded to the correct width and contributed to |\box|~2;
569 % |\box|~0 is then cleared and re-entered.
571 % The idea is that you make tab active, and set it to this macro. We stop
572 % the current box, stretch it to the right width, and start another one
573 % straight after, so nobody knows the difference. The code here is straight
574 % from Appendix~D of \textit{The \TeX book}.
580 \divide\@tempdima\svtab%
581 \multiply\@tempdima\svtab%
582 \advance\@tempdima\svtab%
585 \setbox\z@\hbox\bgroup%
591 % \begin{macro}{\verbinput}
593 % We allow input from a file, by the |\verbinput| command. We display the
594 % text pretty much the same as the \env{listing} environment below.
596 % We set tab and return active, and get them to do appropriate things. This
597 % isn't actually all that hard.
600 \def\verbinput{\listinghook\@ifstar{\verbinput@\@input}{\verbinput@\input}}
601 \def\verbinput@#1#2{%
603 \setbox\z@\hbox\bgroup%
608 \ifdim\wd\tw@=\z@\listingline\tw@\fi%
615 % \begin{macro}{\vinput@cr}
617 % This macro handles return characters while inputting text in |\verbinput|.
618 % We just output our current box, and start another.
626 \setbox\z@\hbox\bgroup%
632 % \subsection{Reading verbatim text}
634 % The traditional way of reading verbatim text is to use a delimited
635 % argument, as described in the \textit{\TeX book}. This works well-ish if
636 % the text isn't very long. A better solution would be to pick out the text
637 % line-by-line and process it like that. So this is what we do.
639 % \begin{macro}{\matcher}
641 % For long verbatim environments, we need to be able to find the end text.
642 % This is rather tricky. The solution here is rather horrible. The
643 % environment picks out each line of the text at a time, as an argument, and
644 % tests to see if it contains the text we're after. We do the test in a
645 % particularly yukky way: we add the actual target text to the end of the
646 % line, and inspect the text following the match to see if the match is at
649 % The |\matcher| macro creates a `matcher' which will test strings to see if
650 % they contain something interesting.
652 % To create a matcher, say
653 % \syntax{"\\matcher{"<cmd-name>"}{"<target>"}{"<process-cmd>"}"}. The
654 % command \synt{cmd-name} accepts a line of text as an argument and calls
655 % the \synt{process-cmd} with the text of the line before the match, or the
656 % whole lot. It also sets |\@ifmatched| appropriately.
658 % (Having spent ages coming up with this cruft myself, I found some very
659 % similar, but slightly better, code in Appendix~D. So I've changed mine to
660 % match Donald's. Anyway, credit where it's due: cheers Don.)
665 \expandafter\def\csname\string#1$match\endcsname##1#2##2##3\end{%
673 \expandafter\def\expandafter#1\expandafter##\expandafter1\expandafter{%
674 \csname\string#1$match\endcsname##1#2\relax\end%
681 % \begin{macro}{\sv@stripspc}
683 % This macro strips any trailing glue in the current horizontal list. This
684 % is fairly simple, actually: we just loop while glue is the last item. It's
685 % slightly complicated by penalties which \TeX\ puts into the list between
686 % the glue items, but we just remove them too.
691 \ifdim\lastskip=\z@\else%
692 \unskip\expandafter\sv@stripspc%
699 % \begin{macro}{\sv@percent}
701 % This macro strips a single leading percent character if there is one, and
702 % if the \env{doc} package is loaded. We store the possibly stripped text in
708 \gdef\sv@percent#1#2\relax
709 {\ifx\check@percent\@@undefined
710 \ifx#1\relax\def\@tempa{}\else
711 \def\@tempa{#1#2}\fi\else
712 \ifx#1\relax\def\@tempa{}\else
713 \ifx#1%\def\@tempa{#2}\else
714 \def\@tempa{#1#2}\fi\fi\fi}
720 % \begin{macro}{\@isspaces}
722 % We want to avoid writing the first and last lines of the environment to the
723 % file if there's nothing in them. To do this, we need to know whether a
724 % piece of text contains only space characters. This macro does this, in a
725 % rather nasty way. See the other macros below for details of how this
728 % We define |\sv@safespc| at the same time: this makes space active and
729 % expand to a space character which is not active. Neat, huh?
739 \def\@tempb{\@tempswafalse}%
741 \let\@tempb\@isspaces%
743 \def\@tempb##1\relax{}%
756 % \begin{macro}{\sv@read}
758 % This macro does the main job of reading a chunk of verbatim text. You call
762 % \syntax{"\\sv@read{"<end-text>"}{"<process-line-proc>"}{"<end-proc>"}"}
765 % The \synt{end-text} is the text to find at the end of the `environment': we
766 % stop when we find it.
768 % The \synt{process-line-proc} is a macro which is passed as an argument each
769 % line which we read from the text.
771 % The \synt{end-proc} is a macro to call once we've finished reading all of
772 % the text. This can tidy up an environment or close a file or whatever.
774 % We read the text by picking out newlines using a delimited macro. We have
775 % to be a little clever, because newlines are active in verbatim text.
777 % We will also strip `|%|' signs off the beginning if the \package{doc}
778 % package is here (\package{doc} tries to play with \LaTeX's verbatim stuff,
779 % and doesn't understand the way we do things).
785 % This code does all sorts of evil things, so I'll start by opening a group.
791 % So that I can spot the end-text, I'll create a matcher macro.
794 \matcher\@match{#1}\sv@read@ii%
797 % So that I can identify line ends, I'll make them active. I'll also make
798 % spaces active so that they can expand to whatever they ought to expand
799 % to (spaces in files, or funny \verb*" " characters or whatever.
806 % I'll use the |\if@tempswa| flag to tell me whether I ought to output the
807 % current line. This is a little messy, so I'll describe it later. I'll
808 % initialise it to false because this is the correct thing to do.
814 % Most of the job is done by two submacros. I'll define them in terms of
815 % my current arguments (to save lots of token munging). The first just
816 % extracts the next line (which ends at the next newline character) and
820 \lccode`\~13\lowercase{%
821 \def\sv@read@i##1~{\@match{##1}}%
825 % The results of the match get passed here, along with the text of the
826 % line up to the matched text.
832 % The first job to do is to maybe strip off percent signs from the beginning,
833 % to keep \package{doc} happy.
836 \sv@percent##1\relax\relax%
839 % Now I need to decide whether I ought to output this line. The method goes
840 % like this: if this is the first line (|\if@tempswa| is false) or the last
841 % (|\if@matched| is true), \emph{and} the text consists only of spaces, then
844 % The first thing to do is to notice the last line -- if |\if@matched| is
845 % true, then I'll make |\if@tempswa| false to make the first-line and
846 % last-line cases work the same way.
849 \if@matched\@tempswafalse\fi%
852 % Now if this is the first or last line, I'll examine it for spaces. This
853 % is done in a separate macro. It will set |\if@tempswa| false if the
854 % text contains only spaces.
857 \if@tempswa\else\@tempswatrue\expandafter\@isspaces\@tempa\relax\fi%
860 % Now, if |\if@tempswa| is still true, perform the \<process-line-proc> on
861 % the line of text. I'll provide a group, so that it doesn't upset me
867 \expandafter#2\expandafter{\@tempa}%
872 % The next line won't be the first one, so I'll set the flag true in
879 % Now, if that wasn't the last line, go round again; otherwise end the group
880 % I started ages ago, and do the user's \<end-proc>.
883 \if@matched\def\@tempa{\endgroup#3}\else\let\@tempa\sv@read@i\fi%
888 % Now to start the thing up. I'll read the first line.
897 % \begin{macro}{\sv@readenv}
899 % This macro works out an appropriate end-text for the current environment.
900 % If you say \syntax{"\\sv@readenv{"<macro-name>"}"}, it will expand do
901 % \begin{listinglist} \listingsize \synshorts
902 % <macro-name>"{\\"$_{12}$"end{"$_{12}$<current-env-name>"}"$_{12}$"}"^^A
903 % "{\\end{"<current-env-name>"}}"
907 % This is all done with mirrors. No, err\dots\ it's done with
916 \def\sv@readenv#1{\expandafter\sv@readenv@i\expandafter{\@currenvir}{#1}}
917 \def\sv@readenv@i#1#2{#2{|end<#1>}{\end{#1}}}
923 % \begin{macro}{\sv@verbline}
925 % This macro typesets a line in a verbatim way, so you can construct a real
926 % verbatim environment from it. It's a bit tricky in the way that it catches
927 % the last line. Don't worry about this: it's easy really. Note the
928 % |\relax| after the |\par| -- this is because \package{doc} tries to do
929 % clever things with |\par| to strip `|%|' signs out.
934 \setbox\z@\hbox{#1\sv@stripspc}%
936 \if1\ifdim\wd\tw@=\z@\if@matched0\else1\fi\else1\fi%
944 % \subsection{Listing environments}
946 % The \env{listing} environment is our equivalent of the standard
947 % \env{verbatim} environment. We do some slightly cleverer things, though,
948 % to make sure (for example) that even text which contains |\end{listing}|
951 % \begin{macro}{\listinghook}
953 % Set everything up as required. This is here for customization. The
954 % underlying machinery doesn't mess with this directly, but assumes that
955 % |\svline| and |\svafter| are set up appropriately.
963 \let\svline\listingline%
964 \def\svafter{\endlistinglist\endgroup}%
970 % \begin{macro}{\listinglist}
971 % \begin{environment}{listinglist}
973 % This defines the layout for the \env{listing} environment. It starts a
974 % list with the appropriate shape. It's also made into an environment, so
975 % that the end-paragraph-environment bits work correctly.
977 % The |\listingindent| length parameter sets up the indentation of the
978 % listings. If there's a |\parindent| setting, I'll line listings up with
979 % that; otherwise I'll just choose something which looks right.
982 \newdimen\listingindent
984 \ifdim\parindent=\z@\listingindent1em\else\listingindent\parindent\fi%
988 % Now to define a size hook for the environment. This is fairly simple
992 \ifx\listingsize\@@undefined
993 \let\listingsize\footnotesize
997 % Now to define the environment itself. Suppress the indentation if we're
998 % first thing on a new list item, so that the listing lines up with
1007 \leftmargin\listingindent%
1014 \let\makelabel\relax%
1017 \parfillskip\@flushglue%
1020 \let\endlistinglist\endlist
1026 % \begin{macro}{\svline}
1027 % \begin{macro}{\svdoline}
1028 % \begin{macro}{\listingline}
1030 % The simple spit-out-a-line macro.
1033 \def\svdoline#1{\leavevmode\box#1\par}
1034 \let\svline\svdoline
1035 \let\listingline\svline
1042 % \begin{macro}{\svafter}
1044 % This is called when the machinery finishes. A default is set for safety's
1053 % \begin{environment}{listing}
1055 % The \env{listing} environment is the only real verbatim-like environment we
1056 % create will all this kit, although it does the job very nicely.
1058 % The environment indents its contents slightly, unlike \env{verbatim}, and
1059 % uses a smaller typeface in an attempt to fit 77-column text on an A5~page.
1060 % There is also a $*$-variant, which allows you to specify the terminating
1061 % text. This enables you to include absolutely any text in the environment,
1062 % including |\end{listing}|.
1064 % First, we must define the |\listing| command.
1067 \def\listing{\listinghook\sv@readenv\sv@listing}
1070 % Now we define the |\@listing| command, which does most of the work. We
1071 % base the \env{listing} environment on a \env{list}.
1074 \def\sv@listing#1#2{\sv@startlisting\sv@read{#1}\sv@verbline{\svafter#2}}
1077 % Now we define the starred version. The command name needs to include the
1078 % `|*|' character, so we must use |\csname|. There's some hacking here to
1079 % allow us to read the name using the appropriate catcodes for otherwise
1080 % normal characters: \LaTeX\ activates some characters and makes them typeset
1081 % themselves to suppress some ligaturing.
1084 \expandafter\def\csname listing*\endcsname{%
1085 \listinghook\begingroup\@noligs\listing@star%
1087 \def\listing@star#1{\endgroup\sv@listing{#1}{\end{listing*}}}
1092 % \begin{environment}{ignore}
1094 % The \env{ignore} environment entirely ignores its contents. Anything at
1095 % all may be put into the environment: it is discarded utterly.
1097 % We define some macros for defining ignoring environments, because this can
1098 % be useful for version control, possibly.
1101 \def\sv@ignore#1#2{%
1103 \let\do\@makeother\dospecials%
1104 \sv@read{#1}\@gobble{\@esphack#2}%
1106 \def\ignore{\sv@readenv\sv@ignore}
1108 \expandafter\let\csname #1\endcsname\ignore%
1110 \def\unignoreenv#1{%
1111 \expandafter\def\csname #1\endcsname{\endgroup}%
1112 \expandafter\def\csname end#1\endcsname%
1113 {\begingroup\def\@currenvir{#1}}%
1119 % \subsection{The \env{verbwrite} environment}
1121 % The \env{verbwrite} environment allows text to be written to a file in a
1122 % verbatim way. Note that tab characters don't work, because \TeX\ refuses
1125 % \begin{macro}{\sv@write}
1127 % As seems to be traditional now, we first define a general hookable macro
1128 % which allows a caller to specify the end-text and what to do afterwards.
1131 \newwrite\sv@writefile
1135 \let\do\@makeother\dospecials%
1137 \sv@read{#1}\sv@writeline{\sv@endwrite#2}%
1139 \def\sv@writeline#1{%
1140 \immediate\write\sv@writefile{#1}%
1150 % \begin{environment}{verbwrite}
1152 % Now we can define the actual environment. We define a $*$-variant which
1153 % allows the user to specify the end-text, just to make sure.
1157 \immediate\openout\sv@writefile#1\relax%
1158 \sv@readenv\sv@write%
1160 \def\endverbwrite{\immediate\closeout\sv@writefile}
1161 \expandafter\def\csname verbwrite*\endcsname#1#2{%
1162 \immediate\openout\sv@writefile#2\relax%
1163 \sv@write{#1}{\immediate\closeout\sv@writefile\end{verbwrite*}}%
1169 % \subsection{The \env{demo} environment}
1171 % By way of tying all of this together, I present an environment for
1172 % displaying demonstrations of \LaTeX\ markup. We read the contents of the
1173 % environment, write it to a temporary file, and read it back twice,
1174 % typesetting it the first time and displaying it verbatim the second time.
1176 % \begin{macro}{\sv@demoname}
1178 % This macro expands to the filename to use for the temporary data. To
1179 % allow the package documentation to demonstrate the \env{demo} environment
1180 % itself, we need to keep a nesting count. This avoids too much hackery,
1181 % which unfortunately appears to plague all of my \TeX\ code.
1184 \newcount\sv@nestcount
1185 \def\sv@demoname{demo\number\sv@nestcount.tmp}
1190 % \begin{macro}{\sv@demo}
1192 % As for listing, we do all the business through a private macro. This is
1193 % good because it means we can leave the main macro readable. The argument
1194 % is the end-text to spot.
1198 \@ifnextchar[{\sv@demo@i{#1}{#2}}{\sv@demo@i{#1}{#2}[n]}%
1200 \def\sv@demo@i#1#2[#3]#4{%
1201 \advance\sv@nestcount by\@ne%
1202 \immediate\openout\sv@writefile\sv@demoname\relax%
1204 \immediate\closeout\sv@writefile%
1205 \sv@dodemo{#2}{#3}{#4}%
1212 % \begin{environment}{demo}
1214 % This is the real environment. We provide \env{demo$*$} too, to allow the
1215 % user to choose the end-text.
1218 \def\demo{\let\@demohook\demohook\sv@readenv\sv@demo}
1219 \expandafter\def\csname demo*\endcsname#1%
1220 {\let\@demohook\demohook\sv@demo{#1}{\end{demo*}}}
1225 % \begin{macro}{\demohook}
1227 % Like |\listinghook|. So much so that we just call it, but first ensure
1228 % that the indent is zero (otherwise it looks really odd!).
1231 \def\demohook{\listingindent\z@\listinghook}
1236 % \begin{macro}{\sv@dodemo}
1238 % First, let's define some common bits of code in the stuff below. The
1239 % minipages used to typeset the material has some clever stuff to avoid
1240 % strange spacing in the output.
1244 \begin{minipage}[t]{\@tempdima}%
1251 \par\unpenalty\unskip%
1259 % This is the macro which actually typesets the demonstration.
1262 \def\sv@dodemo#1#2#3{%
1265 % Now work out some values. We set |\hsize| to the line width leaving 2\,em
1266 % of space on either side. The size of the minipages is calculated depending
1267 % on the shape of the demonstration. This is all fairly simple.
1271 \@tempdima\linewidth%
1272 \advance\@tempdima-2em%
1275 \advance\@tempdima-2em%
1277 \advance\@tempdima-3em%
1282 % Now we open a big vertical box, and put in a header to mark off the
1287 \setbox\z@\hbox{\strut\enspace#3\enspace\strut}%
1289 \advance\@tempdimb-.5\ht\z@%
1290 \ht\z@\@tempdimb\dp\z@\@tempdimb%
1291 \noindent\hskip1em\vtop{%
1294 \raise\@tempdimb\box\z@%
1298 \hb@xt@\hsize{\vrule\@height5\p@\hfil\vrule\@height5\p@}%
1302 % Now we insert the output text in the first minipage. I'll force `|%|'
1303 % to be a comment character, in case something like \package{doc} has had its
1308 \noindent\hbox{}\hskip1em%
1310 \catcode`\%14\relax%
1311 \@input{\sv@demoname}%
1315 % Insert some kind of separation between the two. In `wide' format, we start
1316 % a new line, and put a ruleoff between the two. In `narrow' format, we just
1321 \vskip8\p@\hrule\vskip8\p@%
1327 % Now we put the verbatim copy of the text in the other minipage.
1332 \verbinput@\@input\sv@demoname%
1336 \hb@xt@\hsize{\vrule\@height5\p@\hfil\vrule\@height5\p@}%
1341 \vskip\baselineskip%
1348 % \subsection{Loading the colour package}
1350 % If requested, we load the \package{svcolour} package here. This ensures
1351 % that it can patch this code if it needs to.
1355 \RequirePackage{svcolour}
1359 % That's all there is. Have fun.
1365 % \subsection{The \package{svcolour} package}
1367 % This is in a separate package to avoid dragging in the \package{color}
1368 % package if it's unwanted.
1370 % I prefer English spellings. Here's a trivial redirection for Americans.
1374 \DeclareOption*{\PassOptionsToPackage{\CurrentOption}{svcolour}}
1376 \RequirePackage{svcolour}
1380 % And now we can start the thing properly.
1384 \RequirePackage{color}
1387 % \begin{macro}{\@snarfcolour}
1389 % Reading a colour specification is something we'll need to do a few times,
1390 % so an abstraction is useful. Its single argument is a continuation to
1391 % which we pass a colour-spec acceptable to the |\color| command. (This is
1392 % the same code as found in the \package{mdwtab} package. Remember to keep
1396 \def\@snarfcolour#1{%
1397 \@ifnextchar[{\@snarfcolour@i{#1}}{\@snarfcolour@ii{#1}{}}%
1399 \def\@snarfcolour@i#1[#2]{\@snarfcolour@ii{#1}{[#2]}}
1400 \def\@snarfcolour@ii#1#2#3{#1{#2{#3}}}
1405 % \begin{macro}{\svcolourline}
1406 % \begin{macro}{\svcolorline}
1408 % Snarf the option, and plot the coloured bar. Note the penalties which are
1409 % meant to stick the glue and leaders onto the colour specials.
1412 \def\svcolourline{\@snarfcolour\svcl@i}
1415 \advance\skip@\parfillskip%
1419 \begingroup\color#1\nobreak\leaders\vrule\hskip\skip@\endgroup%
1420 \nobreak\hskip-\skip@%
1423 \nobreak\hskip-\rightskip\vadjust{}%
1426 \let\svcolorline\svcolourline
1438 % \subsection{The \package{svsplit} package}
1442 \RequirePackage{sverb}
1445 % \begin{environment}{splitverb}
1446 % \begin{environment}{splitverb*}
1448 % The basic environments are simple enough.
1451 \def\splitverb{\listinghook\sv@readenv\splitverb@}
1452 \expandafter\def\csname splitverb*\endcsname%
1453 {\listinghook\begingroup\@noligs\svsplit@star}
1454 \def\svsplit@star#1{\endgroup\splitverb@{#1}{\end{splitverb*}}}
1460 % \begin{macro}{\splitverb@}
1462 % Even this isn't so bad, really.
1465 \def\splitverb@#1#2{\sv@startlisting\sv@read{#1}\svsplit@line{\svafter#2}}
1470 % \begin{macro}{\svsplit@line}
1472 % For the sake of readability (and maybe saving a few tokens), we define some
1473 % synonyms for \TeX's scratch registers. |\svsplit@remain| will be a
1474 % |\global| register containing the remaining horizontal space on the line;
1475 % |\svsplit@indent| is a local register containing the amount of initial
1476 % whitespace on the line.
1479 \dimendef\svsplit@remain=1
1480 \dimendef\svsplit@indent=2
1483 % The switch |\svsplit@| is set if we've found a good place to split the
1490 % And finally a delimiter. This is the same one I use everywhere else.
1493 \def\q@delim{\q@delim}
1498 \catcode`\~=\active \lccode`\~=32
1499 \catcode`\!=\active \lccode`\!=9
1500 \lowercase{\endgroup
1503 % So far, so good. The |\svsplit@line| macro is given a line of text. We
1504 % initialize |\svtab| to be a \emph{single} space, |\svsplit@remain| to be
1505 % the text width, and |\svsplit@indent| to zero. Then we embark on the first
1506 % loop, which attempts to find the width of the leading whitespace.
1509 \def\svsplit@line#1{%
1511 \global\svsplit@remain\linewidth%
1514 \let\next@\svsplit@findindent%
1519 % A straightforward tail-recursive loop finds out how much whitespace there
1520 % is at the start of the current line. Note that |\next@| is already set up
1521 % for the optimized case of continuing the loop. Also, if we reach the end
1522 % then this is a blank line, so only emit something if we didn't see the
1523 % end-marker. This is the only place we need to check for this.
1526 \def\svsplit@findindent#1{%
1528 \advance\svsplit@indent\svtab%
1531 \divide\svsplit@indent\dimen@%
1532 \multiply\svsplit@indent\dimen@%
1533 \advance\svsplit@indent\dimen@%
1534 \else\ifx\q@delim#1%
1535 \if@matched\else\svline\tw@\fi%
1538 \def\next@{\svsplit@scanline{#1}}%
1544 % Now we have to actually scan the line to find breakpoints. We build the
1545 % current unbreakable chunk in |\box|~0. When we find a breakpoint, we close
1546 % the box, maybe stretch it to take into account trailing space, and attach
1547 % it to |\box|~2, which is gathering the current line. If |\svsplit@remain|
1548 % hits zero then we flush |\box|~2 to the output and continue on the next
1549 % line with a (more-or-less) clean slate.
1551 % If there's no breakpoint then we're hosed. In that case, we just insert a
1552 % (|\normalfont|) hyphen and eject what we've got.
1554 % Note that this assumes that the indentation will fit. If not, then we're
1558 \def\svsplit@scanline{%
1560 \let\next@\svsplit@char%
1561 \setbox\z@\hbox\bgroup%
1562 \kern\svsplit@indent%
1563 \global\advance\svsplit@remain-\svsplit@indent%
1568 % Scanning a character isn't so bad, if we take it a step at a time.
1571 \def\svsplit@char#1{%
1574 % If the character is a space or a tab, then we call |\svsplit@space| which
1575 % knows about adding breakable whitespace. For tabs, this involves computing
1576 % the correct tab size.
1580 \svsplit@space\svtab%
1582 \@tempdima\linewidth%
1583 \advance\@tempdima-\svsplit@remain%
1584 \@tempdimb\@tempdima%
1586 \divide\@tempdimb\dimen@%
1587 \multiply\@tempdimb\dimen@%
1588 \advance\@tempdimb\dimen@%
1589 \advance\@tempdimb-\@tempdima%
1590 \svsplit@space\@tempdimb%
1593 % We might have reached the end of the line. If so, then we finish off.
1596 \else\ifx\q@delim#1%
1597 \let\next@\svsplit@done%
1600 % Otherwise it's a normal character. If there's not enough space then force
1605 \ifdim\svsplit@remain<2\svtab%
1606 \ifsvsplit@\else\normalfont-\svsplit@break\fi%
1611 % Insert the character and decrement the distance-left register.
1615 \global\advance\svsplit@remain-\svtab%
1618 % Now we see if it's a breakable-after character and if so mark it as being
1622 \def\temp@##1#1##2\q@delim%
1623 {\ifx\q@delim##2\q@delim\else\svsplit@break\fi}%
1624 \expandafter\temp@\svsplitchars#1\q@delim%
1627 % And with that, we're done.
1635 % Our next macro is the break-insertion subroutine, which is quite easy.
1638 \def\svsplit@break{%
1640 \sv@addtobox\tw@\z@%
1642 \setbox\z@\hbox\bgroup%
1646 % Now we add space to the current box. The argument is a dimen register.
1649 \def\svsplit@space#1{%
1650 \ifdim\svsplit@remain>#1\kern#1\global\advance\svsplit@remain-#1\fi%
1652 \ifdim\svsplit@remain>#1\else\svsplit@eject\fi%
1656 % We now come to a slightly involved piece of code, which is how to flush out
1657 % a line, and then fix up the registers for the next line correctly.
1660 \def\svsplit@eject{%
1665 \setbox\z@\hbox\bgroup%
1666 \kern\svsplit@indent%
1667 \global\svsplit@remain\linewidth%
1668 \global\advance\svsplit@remain-\svsplit@indent%
1669 \global\advance\svsplit@remain-\wd\z@%
1674 % Finally, how to finish the line and go home.
1679 \sv@addtobox\tw@\z@%
1684 % End the |\lowercase| hack.
1692 % Finally, set the breakable characters to something plausible.
1695 \def\svsplitchars{:/.}
1698 % And with that, we're done!
1704 % \hfill Mark Wooding, \today