% \begin{meta-comment}
%
-% $Id: sverb.dtx,v 1.1 2002/02/03 20:49:03 mdw Exp $
+% $Id: sverb.dtx,v 1.2 2003/09/05 16:09:30 mdw Exp $
%
% Verbatim typesetting done properly (ahem)
%
% (c) 1996 Mark Wooding
%
-%----- Revision history -----------------------------------------------------
-%
-% $Log: sverb.dtx,v $
-% Revision 1.1 2002/02/03 20:49:03 mdw
-% Checkin for new build system.
-%
-% Revision 1.3 1996/11/19 21:01:18 mdw
-% Entered into RCS
-%
-%
% \end{meta-comment}
%
% \begin{meta-comment} <general public licence>
% \begin{meta-comment} <Package preamble>
%<+package>\NeedsTeXFormat{LaTeX2e}
%<+package>\ProvidesPackage{sverb}
-%<+package> [1996/05/08 1.3 Verbatim typesetting]
+%<+package> [2003/09/04 1.4 Verbatim typesetting]
+%<+colour>\NeedsTeXFormat{LaTeX2e}
+%<+colour>\ProvidesPackage{svcolour}
+%<+colour> [2003/09/04 1.4 Colour support for sverb]
+%<+color>\NeedsTeXFormat{LaTeX2e}
+%<+color>\ProvidesPackage{svcolor}
+%<+color> [2003/09/04 1.4 Fix for people who can't spell]
+%<+split>\NeedsTeXFormat{LaTeX2e}
+%<+split>\ProvidesPackage{svsplit}
+%<+split> [2003/09/04 1.4 Verbatim, but with line breaking]
% \end{meta-comment}
%
-% \CheckSum{651}
+% \CheckSum{1011}
%% \CharacterTable
%% {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
%% 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
%<*driver>
\input{mdwtools}
\describespackage{sverb}
+\describespackage{svcolour}
+\describespackage{svsplit}
\mdwdoc
%</driver>
%
%
% \subsubsection{Configuring the \env{listing} environment}
%
+% \DescribeMacro\listingsize
% The text size used in the \env{listing} environment is set by the
-% |\listingsize| command. By default, this is set to |\small|, although you
-% can redefine it in the document preamble, or it can be set in the document
-% class.
+% |\listingsize| command. By default, this is set to |\footnotesize|,
+% although you can redefine it in the document preamble, or it can be set in
+% the document class. You can put other declarations (e.g., colours) here if
+% you like.
%
+% \DescribeMacro\listingindent
% The amount by which the listing text is indented is controlled by the
% |\listingindent| length parameter. This is a fixed length, whose default
% value is 1\,em.
%
+% \DescribeMacro\listinghook
+% \DescribeMacro\svafter
+% \DescribeMacro\svline
+% \DescribeMacro\svdoline
+% \DescribeEnv{listinglist}
+% The |\listinghook| command is called by the \env{listing} environment (and
+% |\verbinput| and \env{demo}) to set up the formatting of the listing. It
+% can do any setting up it likes, and may configure |\svline| and |\svafter|
+% as necessary. The macro |\svline| is run once for each line of verbatim
+% text, with the line gathered into a box register, the number of which is
+% given as an argument. The macro |\svafter| is called when processing has
+% finished.
+%
+% The default setting for |\listinghook| is (similar to)
+%\begin{listing}
+%\newcommand{\listinghook}{%
+% \par%
+% \begin{listinglist}%
+% \listingsize%
+% \renewcommand{\svline}{\listingline}%
+% \renewcommand{\svafter}{\end{listinglist}}%
+%}
+%\end{listing}
+% (see the source for the true definition). The default |\listingline| macro
+% just writes out the line using |\svdoline|, which is a simple no-nonsense
+% macro which just writes the text. As an example, you could say
+%\begin{listing}
+%\renewcommand{\listingline}{\leavevmode\llap{\strut\vrule\space}\svdoline}
+%\end{listing}
+% to put a rule down the left-hand side of your listings.
+%
+% The \env{listinglist} environment is a relatively straightforward
+% \env{list}-based environment which sets pu the indentation of a listing.
+% Feel free to redefine it.
+%
% \subsubsection{Choosing a different end-text}
%
% \DescribeEnv{listing*}
% As with the other environments created by this package, there's a
% $*$-variant which takes the end-text as an argument.
%
+% \DescribeMacro\demohook
+% The |\demohook| does the same job for \env{demo} environments as
+% |\listinghook| does for \env{listing}s. The default version just says
+%\begin{listing}
+%\newcommand{\demohook}{\setlength{\listingindent}{0pt}\listinghook}
+%\end{listing}
+% (near enough), which turns off the indentation for the listing (which would
+% otherwise look rather odd).
+%
%
% \section{Programmer interface}
%
% |\sv@safespc| which defines the active-space character to be a normal
% whitespace-space when expanded.
%
+% \section{Colour support}
+%
+% There's now a little colour support in \package{sverb}. To use it, give
+% the \textsf{colour} (or \textsf{color}) package option, or load the
+% \package{svcolour} package.
+%
+% \DescribeMacro\svcolourline
+% Say \syntax{"\\svcolourline["<model>"]{"<colour>"}{"<box>"}"} to typeset
+% \<box> against a background of the given colour. This is a good thing to
+% put in your |\listingline| command.
+%\begin{demo}{Coloured listings}
+%\renewcommand{\listingline}
+% {\svcolourline[rgb]{1, 0.8, 0.9}}
+%Consider, for example, this more
+%complicated program.
+%\begin{listing}
+%#include <stdio.h>
+%
+%int main(void)
+%{
+% puts("Hello, world!");
+% return (0);
+%}
+%\end{listing}
+%\end{demo}
+% For coloured text rather than background, put a |\color| command in
+% |\listinghook| itself.
+%
+% \section{The \package{svsplit} package}
+%
+% A new toy!
+%
+% \DescribeEnv{splitverb}
+% \DescribeEnv{splitverb*}
+% \DescribeMacro\svsplitchars
+% The \env{splitverb} environment typesets verbatim material very slowly. On
+% the plus side, however, it does know how to do simple line-breaking. It
+% will break lines at spaces or tabs, or after any character listed in
+% |\svsplitchars|. Continuation lines have the same initial intentation as
+% the original. If a line has no `good' breaking point, it's broken as late
+% as possible, and a little hyphen is inserted.
+%\begin{demo}[w]{The \env{splitverb} environment}
+%\begin{multicols}{2}
+%\begin{splitverb}
+%The \package{url} package is rather fine at splitting up long URLs such as
+% \url{http://www.excessus.demon.co.uk/tex}
+%though it can't do its thing in the midst of verbatim text. It
+%also doesn't cope when
+% allthespacesinalongphrasehavemysteriouslydisappeared!
+%\end{splitverb}
+%\end{multicols}
+%\end{demo}
+%
% \implementation
%
% \section{Implementation}
%<*package>
% \end{macrocode}
%
+% \subsection{Options processing}
+%
+% Notice options, load package.
+%
+% \begin{macrocode}
+\newif\ifsv@colour\sv@colourfalse
+\DeclareOption{colour}{\sv@colourtrue}
+\DeclareOption{color}{\sv@colourtrue}
+\ProcessOptions
+% \end{macrocode}
+%
% \subsection{Simple things}
%
% To help us build funny macros which involve strange and different category
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}{\sv@addtobox}
+%
+% Add stuff to a horizontal box.
+%
+% \begin{macrocode}
+\def\sv@addtobox#1#2{\setbox#1\hbox{\unhbox#1\box#2}}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\sv@emptybox}
+%
+% Clear out a horizontal box.
+%
+% \begin{macrocode}
+\def\sv@emptybox#1{\setbox#1\hbox{}}
+% \end{macrocode}
+%
+% \end{macro}
+%
% \begin{macro}{\sv@startlisting}
%
% This macro sets everything up nicely for a \env{listing}-type verbatim
%
% \begin{macro}{\sv@vtab}
%
-% Here we handle tabs inside verbatim environments. We expect each line to
-% be typeset as a box, using something like
-%
-% \begin{listing}
-%\setbox0\hbox{#1}
-%\leavevmode
-%\box0
-%\par
-% \end{listing}
+% Here we handle tabs inside verbatim environments. We expect to be inside
+% |\box|~0. This is padded to the correct width and contributed to |\box|~2;
+% |\box|~0 is then cleared and re-entered.
%
% The idea is that you make tab active, and set it to this macro. We stop
% the current box, stretch it to the right width, and start another one
-% straight after, so nobody know the difference. The code here is straight
+% straight after, so nobody knows the difference. The code here is straight
% from Appendix~D of \textit{The \TeX book}.
%
% \begin{macrocode}
\multiply\@tempdima\svtab%
\advance\@tempdima\svtab%
\wd\z@\@tempdima%
- \leavevmode\box\z@%
+ \sv@addtobox\tw@\z@%
\setbox\z@\hbox\bgroup%
}
% \end{macrocode}
% isn't actually all that hard.
%
% \begin{macrocode}
-\def\verbinput#1{%
- \begin{listinglist}%
- \listingsize%
+\def\verbinput{\listinghook\@ifstar{\verbinput@\@input}{\verbinput@\input}}
+\def\verbinput@#1#2{%
\sv@startlisting%
\setbox\z@\hbox\bgroup%
- \input{#1}%
+ #1{#2}%
\sv@stripspc%
\egroup%
- \ifdim\wd\z@=\z@%
- \ifhmode\par\fi%
- \else%
- \leavevmode\box\z@\par%
- \fi%
- \end{listinglist}%
+ \sv@addtobox\tw@\z@%
+ \ifdim\wd\tw@=\z@\listingline\tw@\fi%
+ \svafter%
}
% \end{macrocode}
%
% \begin{macrocode}
\def\vinput@cr{%
\egroup%
- \leavevmode\box\z@%
- \par%
+ \sv@addtobox\tw@\z@%
+ \listingline\tw@%
+ \sv@emptybox\tw@%
\setbox\z@\hbox\bgroup%
}
% \end{macrocode}
% expand to a space character which is not active. Neat, huh?
%
% \begin{macrocode}
+\begingroup
\lccode`\~32
\lccode`\!32
\lowercase{%
+ \endgroup
\def\@isspaces#1{%
\ifx#1\relax%
\def\@tempb{\@tempswafalse}%
% If you say \syntax{"\\sv@readenv{"<macro-name>"}"}, it will expand do
% \begin{listinglist} \listingsize \synshorts
% <macro-name>"{\\"$_{12}$"end{"$_{12}$<current-env-name>"}"$_{12}$"}"^^A
-% "{\\end{"<current-env-name>"}}"
+% "{\\end{"<current-env-name>"}}"
% \end{listinglist}
% Easy, no?
%
\lccode`\>=`\}
\lccode`\|=`\\
\lowercase{\endgroup
-\def\sv@readenv#1{%
- \expandafter\expandafter\expandafter%
- #1\expandafter\sv@readenv@i\@currenvir\@@%
-}
-\def\sv@readenv@i#1\@@{{|end<#1>}{\end{#1}}}
+\def\sv@readenv#1{\expandafter\sv@readenv@i\expandafter{\@currenvir}{#1}}
+\def\sv@readenv@i#1#2{#2{|end<#1>}{\end{#1}}}
}
% \end{macrocode}
%
%
% \begin{macrocode}
\def\sv@verbline#1{%
+ \sv@emptybox\tw@%
\setbox\z@\hbox{#1\sv@stripspc}%
- \ifdim\wd\z@=\z@%
- \if@matched\ifhmode\par\relax\fi\else\leavevmode\par\relax\fi%
- \else%
- \leavevmode\box\z@\par\relax%
+ \sv@addtobox\tw@\z@%
+ \if1\ifdim\wd\tw@=\z@\if@matched0\else1\fi\else1\fi%
+ \svline\tw@\relax%
\fi%
}
% \end{macrocode}
% to make sure (for example) that even text which contains |\end{listing}|
% can be typeset.
%
+% \begin{macro}{\listinghook}
+%
+% Set everything up as required. This is here for customization. The
+% underlying machinery doesn't mess with this directly, but assumes that
+% |\svline| and |\svafter| are set up appropriately.
+%
+% \begin{macrocode}
+\def\listinghook{%
+ \par%
+ \begingroup
+ \listinglist%
+ \listingsize%
+ \let\svline\listingline%
+ \def\svafter{\endlistinglist\endgroup}%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
% \begin{macro}{\listinglist}
% \begin{environment}{listinglist}
%
%
% \begin{macrocode}
\ifx\listingsize\@@undefined
- \let\listingsize\small
+ \let\listingsize\footnotesize
\fi
% \end{macrocode}
%
% \end{environment}
% \end{macro}
%
+% \begin{macro}{\svline}
+% \begin{macro}{\svdoline}
+% \begin{macro}{\listingline}
+%
+% The simple spit-out-a-line macro.
+%
+% \begin{macrocode}
+\def\svdoline#1{\leavevmode\box#1\par}
+\let\svline\svdoline
+\let\listingline\svline
+% \end{macrocode}
+%
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\svafter}
+%
+% This is called when the machinery finishes. A default is set for safety's
+% sake.
+%
+% \begin{macrocode}
+\let\svafter\relax
+% \end{macrocode}
+%
+% \end{macro}
+%
% \begin{environment}{listing}
%
% The \env{listing} environment is the only real verbatim-like environment we
% First, we must define the |\listing| command.
%
% \begin{macrocode}
-\def\listing{%
- \listinglist%
- \listingsize%
- \sv@readenv\sv@listing%
-}
+\def\listing{\listinghook\sv@readenv\sv@listing}
% \end{macrocode}
%
% Now we define the |\@listing| command, which does most of the work. We
% base the \env{listing} environment on a \env{list}.
%
% \begin{macrocode}
-\def\sv@listing#1#2{%
- \sv@startlisting%
- \sv@read{#1}\sv@verbline{\endlistinglist#2}%
-}
+\def\sv@listing#1#2{\sv@startlisting\sv@read{#1}\sv@verbline{\svafter#2}}
% \end{macrocode}
%
% Now we define the starred version. The command name needs to include the
%
% \begin{macrocode}
\expandafter\def\csname listing*\endcsname{%
- \listinglist%
- \listingsize%
- \begingroup%
- \@noligs%
- \def\@tempa##1{\endgroup\sv@listing{##1}{\end{listing*}}}%
- \@tempa%
+ \listinghook\begingroup\@noligs\listing@star%
}
+\def\listing@star#1{\endgroup\sv@listing{#1}{\end{listing*}}}
% \end{macrocode}
%
% \end{environment}
% user to choose the end-text.
%
% \begin{macrocode}
-\def\demo{\sv@readenv\sv@demo}
-\expandafter\def\csname demo*\endcsname#1{\sv@demo{#1}{\end{demo*}}}
+\def\demo{\let\@demohook\demohook\sv@readenv\sv@demo}
+\expandafter\def\csname demo*\endcsname#1%
+ {\let\@demohook\demohook\sv@demo{#1}{\end{demo*}}}
% \end{macrocode}
%
% \end{environment}
%
+% \begin{macro}{\demohook}
+%
+% Like |\listinghook|. So much so that we just call it, but first ensure
+% that the indent is zero (otherwise it looks really odd!).
+%
+% \begin{macrocode}
+\def\demohook{\listingindent\z@\listinghook}
+% \end{macrocode}
+%
+% \end{macro}
+%
% \begin{macro}{\sv@dodemo}
%
% First, let's define some common bits of code in the stuff below. The
\noindent\hbox{}\hskip1em%
\sv@demosmp%
\catcode`\%14\relax%
- \input{\sv@demoname}%
+ \@input{\sv@demoname}%
\sv@demoemp%
% \end{macrocode}
%
%
% \begin{macrocode}
\sv@demosmp%
- \listingindent\z@%
- \verbinput\sv@demoname%
+ \@demohook%
+ \verbinput@\@input\sv@demoname%
\sv@demoemp%
\par%
\nointerlineskip%
%
% \end{macro}
%
+% \subsection{Loading the colour package}
+%
+% If requested, we load the \package{svcolour} package here. This ensures
+% that it can patch this code if it needs to.
+%
+% \begin{macrocode}
+\ifsv@colour
+ \RequirePackage{svcolour}
+\fi
+% \end{macrocode}
+%
% That's all there is. Have fun.
%
% \begin{macrocode}
%</package>
% \end{macrocode}
%
+% \subsection{The \package{svcolour} package}
+%
+% This is in a separate package to avoid dragging in the \package{color}
+% package if it's unwanted.
+%
+% I prefer English spellings. Here's a trivial redirection for Americans.
+%
+% \begin{macrocode}
+%<*color>
+\DeclareOption*{\PassOptionsToPackage{\CurrentOption}{svcolour}}
+\ProcessOptions
+\RequirePackage{svcolour}
+%</color>
+% \end{macrocode}
+%
+% And now we can start the thing properly.
+%
+% \begin{macrocode}
+%<*colour>
+\RequirePackage{color}
+% \end{macrocode}
+%
+% \begin{macro}{\@snarfcolour}
+%
+% Reading a colour specification is something we'll need to do a few times,
+% so an abstraction is useful. Its single argument is a continuation to
+% which we pass a colour-spec acceptable to the |\color| command. (This is
+% the same code as found in the \package{mdwtab} package. Remember to keep
+% them in step.)
+%
+% \begin{macrocode}
+\def\@snarfcolour#1{%
+ \@ifnextchar[{\@snarfcolour@i{#1}}{\@snarfcolour@ii{#1}{}}%
+}
+\def\@snarfcolour@i#1[#2]{\@snarfcolour@ii{#1}{[#2]}}
+\def\@snarfcolour@ii#1#2#3{#1{#2{#3}}}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\svcolourline}
+% \begin{macro}{\svcolorline}
+%
+% Snarf the option, and plot the coloured bar. Note the penalties which are
+% meant to stick the glue and leaders onto the colour specials.
+%
+% \begin{macrocode}
+\def\svcolourline{\@snarfcolour\svcl@i}
+\def\svcl@i#1#2{%
+ \skip@\wd#2%
+ \advance\skip@\parfillskip%
+ \advance\skip@.2em%
+ \strut%
+ \kern.2em%
+ \begingroup\color#1\nobreak\leaders\vrule\hskip\skip@\endgroup%
+ \nobreak\hskip-\skip@%
+ \kern.2em%
+ \box#2%
+ \nobreak\hskip-\rightskip\vadjust{}%
+ \par%
+}
+\let\svcolorline\svcolourline
+% \end{macrocode}
+%
+% \end{macro}
+% \end{macro}
+%
+% Done!
+%
+% \begin{macrocode}
+%</colour>
+% \end{macrocode}
+%
+% \subsection{The \package{svsplit} package}
+%
+% \begin{macrocode}
+%<*split>
+\RequirePackage{sverb}
+% \end{macrocode}
+%
+% \begin{environment}{splitverb}
+% \begin{environment}{splitverb*}
+%
+% The basic environments are simple enough.
+%
+% \begin{macrocode}
+\def\splitverb{\listinghook\sv@readenv\splitverb@}
+\expandafter\def\csname splitverb*\endcsname%
+ {\listinghook\begingroup\@noligs\svsplit@star}
+\def\svsplit@star#1{\endgroup\splitverb@{#1}{\end{splitverb*}}}
+% \end{macrocode}
+%
+% \end{environment}
+% \end{environment}
+%
+% \begin{macro}{\splitverb@}
+%
+% Even this isn't so bad, really.
+%
+% \begin{macrocode}
+\def\splitverb@#1#2{\sv@startlisting\sv@read{#1}\svsplit@line{\svafter#2}}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\svsplit@line}
+%
+% For the sake of readability (and maybe saving a few tokens), we define some
+% synonyms for \TeX's scratch registers. |\svsplit@remain| will be a
+% |\global| register containing the remaining horizontal space on the line;
+% |\svsplit@indent| is a local register containing the amount of initial
+% whitespace on the line.
+%
+% \begin{macrocode}
+\dimendef\svsplit@remain=1
+\dimendef\svsplit@indent=2
+% \end{macrocode}
+%
+% The switch |\svsplit@| is set if we've found a good place to split the
+% current line.
+%
+% \begin{macrocode}
+\newif\ifsvsplit@
+% \end{macrocode}
+%
+% And finally a delimiter. This is the same one I use everywhere else.
+%
+% \begin{macrocode}
+\def\q@delim{\q@delim}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\begingroup
+\catcode`\~=\active \lccode`\~=32
+\catcode`\!=\active \lccode`\!=9
+\lowercase{\endgroup
+% \end{macrocode}
+%
+% So far, so good. The |\svsplit@line| macro is given a line of text. We
+% initialize |\svtab| to be a \emph{single} space, |\svsplit@remain| to be
+% the text width, and |\svsplit@indent| to zero. Then we embark on the first
+% loop, which attempts to find the width of the leading whitespace.
+%
+% \begin{macrocode}
+\def\svsplit@line#1{%
+ \divide\svtab8%
+ \global\svsplit@remain\linewidth%
+ \svsplit@indent\z@%
+ \sv@emptybox\tw@%
+ \let\next@\svsplit@findindent%
+ \next@#1\q@delim%
+}
+% \end{macrocode}
+%
+% A straightforward tail-recursive loop finds out how much whitespace there
+% is at the start of the current line. Note that |\next@| is already set up
+% for the optimized case of continuing the loop. Also, if we reach the end
+% then this is a blank line, so only emit something if we didn't see the
+% end-marker. This is the only place we need to check for this.
+%
+% \begin{macrocode}
+\def\svsplit@findindent#1{%
+ \ifx~#1%
+ \advance\svsplit@indent\svtab%
+ \else\ifx!#1%
+ \dimen@8\svtab%
+ \divide\svsplit@indent\dimen@%
+ \multiply\svsplit@indent\dimen@%
+ \advance\svsplit@indent\dimen@%
+ \else\ifx\q@delim#1%
+ \if@matched\else\svline\tw@\fi%
+ \let\next@\relax%
+ \else%
+ \def\next@{\svsplit@scanline{#1}}%
+ \fi\fi\fi%
+ \next@%
+}
+% \end{macrocode}
+%
+% Now we have to actually scan the line to find breakpoints. We build the
+% current unbreakable chunk in |\box|~0. When we find a breakpoint, we close
+% the box, maybe stretch it to take into account trailing space, and attach
+% it to |\box|~2, which is gathering the current line. If |\svsplit@remain|
+% hits zero then we flush |\box|~2 to the output and continue on the next
+% line with a (more-or-less) clean slate.
+%
+% If there's no breakpoint then we're hosed. In that case, we just insert a
+% (|\normalfont|) hyphen and eject what we've got.
+%
+% Note that this assumes that the indentation will fit. If not, then we're
+% deeply stuffed.
+%
+% \begin{macrocode}
+\def\svsplit@scanline{%
+ \svsplit@false%
+ \let\next@\svsplit@char%
+ \setbox\z@\hbox\bgroup%
+ \kern\svsplit@indent%
+ \global\advance\svsplit@remain-\svsplit@indent%
+ \next@%
+}
+% \end{macrocode}
+%
+% Scanning a character isn't so bad, if we take it a step at a time.
+%
+% \begin{macrocode}
+\def\svsplit@char#1{%
+% \end{macrocode}
+%
+% If the character is a space or a tab, then we call |\svsplit@space| which
+% knows about adding breakable whitespace. For tabs, this involves computing
+% the correct tab size.
+%
+% \begin{macrocode}
+ \ifx~#1%
+ \svsplit@space\svtab%
+ \else\ifx!#1%
+ \@tempdima\linewidth%
+ \advance\@tempdima-\svsplit@remain%
+ \@tempdimb\@tempdima%
+ \dimen@8\svtab%
+ \divide\@tempdimb\dimen@%
+ \multiply\@tempdimb\dimen@%
+ \advance\@tempdimb\dimen@%
+ \advance\@tempdimb-\@tempdima%
+ \svsplit@space\@tempdimb%
+% \end{macrocode}
+%
+% We might have reached the end of the line. If so, then we finish off.
+%
+% \begin{macrocode}
+ \else\ifx\q@delim#1%
+ \let\next@\svsplit@done%
+% \end{macrocode}
+%
+% Otherwise it's a normal character. If there's not enough space then force
+% a break.
+%
+% \begin{macrocode}
+ \else%
+ \ifdim\svsplit@remain<2\svtab%
+ \ifsvsplit@\else\normalfont-\svsplit@break\fi%
+ \svsplit@eject%
+ \fi%
+% \end{macrocode}
+%
+% Insert the character and decrement the distance-left register.
+%
+% \begin{macrocode}
+ #1%
+ \global\advance\svsplit@remain-\svtab%
+% \end{macrocode}
+%
+% Now we see if it's a breakable-after character and if so mark it as being
+% breakable.
+%
+% \begin{macrocode}
+ \def\temp@##1#1##2\q@delim%
+ {\ifx\q@delim##2\q@delim\else\svsplit@break\fi}%
+ \expandafter\temp@\svsplitchars#1\q@delim%
+% \end{macrocode}
+%
+% And with that, we're done.
+%
+% \begin{macrocode}
+ \fi\fi\fi%
+ \next@%
+}
+% \end{macrocode}
+%
+% Our next macro is the break-insertion subroutine, which is quite easy.
+%
+% \begin{macrocode}
+\def\svsplit@break{%
+ \egroup%
+ \sv@addtobox\tw@\z@%
+ \svsplit@true%
+ \setbox\z@\hbox\bgroup%
+}
+% \end{macrocode}
+%
+% Now we add space to the current box. The argument is a dimen register.
+%
+% \begin{macrocode}
+\def\svsplit@space#1{%
+ \ifdim\svsplit@remain>#1\kern#1\global\advance\svsplit@remain-#1\fi%
+ \svsplit@break%
+ \ifdim\svsplit@remain>#1\else\svsplit@eject\fi%
+}
+% \end{macrocode}
+%
+% We now come to a slightly involved piece of code, which is how to flush out
+% a line, and then fix up the registers for the next line correctly.
+%
+% \begin{macrocode}
+\def\svsplit@eject{%
+ \egroup%
+ \svline\tw@%
+ \sv@emptybox\tw@%
+ \svsplit@false%
+ \setbox\z@\hbox\bgroup%
+ \kern\svsplit@indent%
+ \global\svsplit@remain\linewidth%
+ \global\advance\svsplit@remain-\svsplit@indent%
+ \global\advance\svsplit@remain-\wd\z@%
+ \unhbox\z@%
+}
+% \end{macrocode}
+%
+% Finally, how to finish the line and go home.
+%
+% \begin{macrocode}
+\def\svsplit@done{%
+ \egroup%
+ \sv@addtobox\tw@\z@%
+ \svline\tw@%
+}
+% \end{macrocode}
+%
+% End the |\lowercase| hack.
+%
+% \begin{macrocode}
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% Finally, set the breakable characters to something plausible.
+%
+% \begin{macrocode}
+\def\svsplitchars{:/.}
+% \end{macrocode}
+%
+% And with that, we're done!
+%
+% \begin{macrocode}
+%</split>
+% \end{macrocode}
+%
% \hfill Mark Wooding, \today
%
% \Finale