summaryrefslogtreecommitdiff
path: root/macros/generic
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2020-10-01 03:04:13 +0000
committerNorbert Preining <norbert@preining.info>2020-10-01 03:04:13 +0000
commitd2a6bb90e56a2836bb59477b8f27248aab9149f5 (patch)
tree5d6be29a531495452688a3c8456355fa58d485f2 /macros/generic
parent36f406d8d1fc994af516d837e6a87c68839cdb2d (diff)
CTAN sync 202010010304
Diffstat (limited to 'macros/generic')
l---------macros/generic/fltpoint1
-rw-r--r--macros/generic/fltpoint/README11
-rw-r--r--macros/generic/fltpoint/fltpoint.dtx1791
-rw-r--r--macros/generic/fltpoint/fltpoint.ins8
-rw-r--r--macros/generic/fltpoint/fltpoint.pdfbin0 -> 206320 bytes
l---------macros/generic/iftex1
-rw-r--r--macros/generic/iftex/README.md65
-rw-r--r--macros/generic/iftex/ifetex.sty18
-rw-r--r--macros/generic/iftex/ifluatex.sty17
-rw-r--r--macros/generic/iftex/ifpdf.sty17
-rw-r--r--macros/generic/iftex/iftex.pdfbin0 -> 214587 bytes
-rw-r--r--macros/generic/iftex/iftex.sty241
-rw-r--r--macros/generic/iftex/iftex.tex199
-rw-r--r--macros/generic/iftex/ifvtex.sty45
-rw-r--r--macros/generic/iftex/ifxetex.sty17
l---------macros/generic/localloc1
-rw-r--r--macros/generic/localloc/localloc.README43
-rw-r--r--macros/generic/localloc/localloc.dtx1026
-rw-r--r--macros/generic/localloc/localloc.pdfbin0 -> 259706 bytes
-rw-r--r--macros/generic/soul/Makefile57
-rw-r--r--macros/generic/soul/soul.dtx4520
-rw-r--r--macros/generic/soul/soul.ins10
-rw-r--r--macros/generic/soul/soul.pdfbin0 -> 388702 bytes
-rw-r--r--macros/generic/soul/soul.txt59
-rw-r--r--macros/generic/youngtab/README94
-rwxr-xr-xmacros/generic/youngtab/makeydoc59
-rw-r--r--macros/generic/youngtab/makeydoc.bat45
-rw-r--r--macros/generic/youngtab/youngtab.dtx842
-rw-r--r--macros/generic/youngtab/youngtab.el42
-rw-r--r--macros/generic/youngtab/youngtab.ins36
-rw-r--r--macros/generic/youngtab/youngtab.pdfbin0 -> 166158 bytes
-rw-r--r--macros/generic/youngtab/youngtab.tex146
32 files changed, 9408 insertions, 3 deletions
diff --git a/macros/generic/fltpoint b/macros/generic/fltpoint
deleted file mode 120000
index 381cdc815a..0000000000
--- a/macros/generic/fltpoint
+++ /dev/null
@@ -1 +0,0 @@
-../latex/contrib/fltpoint \ No newline at end of file
diff --git a/macros/generic/fltpoint/README b/macros/generic/fltpoint/README
new file mode 100644
index 0000000000..d071febe8a
--- /dev/null
+++ b/macros/generic/fltpoint/README
@@ -0,0 +1,11 @@
+The fltpoint package for use with TeX / LaTeX
+Current Version: 1.1b, dated 2004/11/12
+Copyright 2000-2004
+License: LPPL, see fltpoint.dtx for more details
+Eckhart Guthoehrlein
+e-mail <e_w_g@web.de>
+
+This package provides commands for simple floating point
+arithmetic with TeX. At the moment, there is support for the basic
+operations addition, subtraction, multiplication and division as
+well as for rounding numbers to a given precision.
diff --git a/macros/generic/fltpoint/fltpoint.dtx b/macros/generic/fltpoint/fltpoint.dtx
new file mode 100644
index 0000000000..af3363725d
--- /dev/null
+++ b/macros/generic/fltpoint/fltpoint.dtx
@@ -0,0 +1,1791 @@
+% \iffalse META-COMMENT
+%
+% The fltpoint package for use with TeX / LaTeX
+% Current Version: 1.1b, dated 2004/11/12
+% Copyright 2000-2004
+% Eckhart Guthoehrlein
+% e-mail <e_w_g@web.de>
+%
+% This program may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.2
+% of this license or (at your option) any later version.
+% The latest version of this license is in
+% http://www.latex-project.org/lppl.txt
+% and version 1.2 or later is part of all distributions of LaTeX
+% version 1999/12/01 or later.
+%
+% This program consists of the files 'fltpoint.dtx', 'fltpoint.ins'
+% and 'README_fltpoint.txt'.
+%
+% The package provides simple arithmetic with TeX. It should work with
+% all formats and has been tested with plain TeX and LaTeX.
+%
+% Run TeX over fltpoint.ins to produce the docstripped version
+% of the file. The documentation can be typeset by running
+% LaTeX over fltpoint.dtx.
+%
+% Comments and bug-reports are welcome under the above
+% e-mail address.
+%
+% \fi ^^A end meta-comment
+% \CheckSum{1150}
+% \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
+% Digits \0\1\2\3\4\5\6\7\8\9
+% Exclamation \! Double quote \" Hash (number) \#
+% Dollar \$ Percent \% Ampersand \&
+% Acute accent \' Left paren \( Right paren \)
+% Asterisk \* Plus \+ Comma \,
+% Minus \- Point \. Solidus \/
+% Colon \: Semicolon \; Less than \<
+% Equals \= Greater than \> Question mark \?
+% Commercial at \@ Left bracket \[ Backslash \\
+% Right bracket \] Circumflex \^ Underscore \_
+% Grave accent \` Left brace \{ Vertical bar \|
+% Right brace \} Tilde \~}
+%
+%
+% \DoNotIndex{\def,\edef,\xdef,\gdef,\let,\global,\the,^^A
+% \newcount,\if,\ifx,\else,\fi,\ifnum,\catcode,^^A
+% \@,\expandafter,\csname,\endcsname,\number^^A
+% \relax,\end,\advance,\multiply,\divide,\endinput^^A
+% \iterate,\body,\repeat,\iiterate,\ibody,\irepeat,^^A
+% \xiterate,\xbody,\xrepeat.
+% \,,\active,\AlsoImplementation,\AtBegin\Document,
+% \begin,\CodelineIndex,\CommaCheck,\CommaOrdinary,
+% \CommaPunct,\DeclareOption,\DisableCrossrefs,
+% \DocInput,\documentclass,\EnableCrossrefs,\endinput,
+% \futurelet,\long,\mathchardef,\mathcode,\mbox,
+% \NeedsTeXFormat,\newcommand,\noexpand,\number,
+% \obeyspaces,\OnlyDescription,\ProcessOptions,
+% \ProvidesPackage,\RecordChanges,\rightarrow,
+% \space,\tt,\usepackage}
+%
+% \MakeShortVerb{\"}
+%
+% \changes{v1.0a}{2000/08/23}{First public release}
+% \changes{v1.0b}{2000/08/25}{Some spaces sneaked into the output.
+% Fixed.}
+% \changes{v1.0c}{2000/09/05}{Changes necessary for
+% the \texttt{rccol} package.}
+% \changes{v1.1}{2001/11/17}{Cleanup to freeze development.}
+% \changes{v1.1b}{2004/11/12}{Some more freezing cleanup.}
+% \GetFileInfo{fltpoint.sty}
+% \title{The \texttt{fltpoint} package\thanks{This
+% file has version number \fileversion{} dated \filedate.}}
+% \author{Eckhart Guth\"ohrlein\thanks{Send comments
+% or bug-reports to the author via e-mail
+% \texttt{<e\_w\_g@web.de>}.}}
+% \date{Printed \today}
+% \maketitle
+%
+% \begin{abstract}
+% This package provides commands for simple
+% arithmetic with generic \TeX. At the moment, there is support for the
+% basic operations addition, subtraction, multiplication and division as
+% well as for rounding numbers to a given precision.
+% \end{abstract}
+%
+% \newif\ifmulticols
+% \IfFileExists{multicol.sty}{\multicolstrue}{}
+% \ifmulticols
+% \addtocontents{toc}{\protect\begin{multicols}{2}}
+% \fi
+% ^^A{\parskip0mm\tableofcontents}
+%
+% \section{Introduction}
+% The need for calculations inside \TeX\ was encountered when working on
+% some macros to convert positions on a linear scale into angle values,
+% since integer values proved not to be sufficiently exact. Although
+% the capabilities of this package are currently rather limited,
+% they may be of some use if you do not need more than the
+% provided functions. The \texttt{rccol} package may serve as an
+% example application; it uses the rounding facilities of this package.
+%
+% \section{User interface}
+% The user commands are divided into two categories:
+% the normal and the register commands. Each command
+% is available in those two variants, as decribed below.
+% At first, we have to agree about the syntax for floating
+% point numbers.
+%
+% \subsection{Syntax of floating point numbers}
+% In the syntax descriptions below, \meta{fp number}
+% will be used to denote a number according to the following
+% syntax.
+% \begin{flushleft}
+% $\mbox{\meta{fp number}}:=\mbox{\meta{opt signs}}
+% \mbox{\meta{opt digits}}\mbox{\meta{opt dot}}
+% \mbox{\meta{opt digits}}$
+% \end{flushleft}
+% \meta{opt signs} may be any number of `"+"' and/or `"-"'
+% characters, where each `"-"' toggles the sign of
+% the number. \meta{opt digits} may be any number
+% of characters `"0"'\dots `"9"', and \meta{opt dot}
+% is the optional decimal sign. For example, the
+% following inputs for \meta{fp number} are valid,
+% resulting into the specified numbers.
+% \fpexample{100}, \fpexample{010,98700}, \fpexample{-,99},
+% \fpexample{-+-+0001,}, \fpexample{}, \fpexample{---,50}.
+% As you can see, leading and trailing zeros are removed
+% as far as possible, and an `empty number' (omitting anything
+% optional) is understood as zero.
+%
+% There is no syntax checking, so if you do not obey the
+% rules above, you are likely to encounter strange error
+% messages, as well as everything might work properly in
+% some cases.
+% Of course, it is also possible to
+% use a macro as \meta{fp number} if it expands to a
+% string satisfying the syntax rules.
+%
+% \subsection{Standard operations}
+% \DescribeMacro\fpAdd\DescribeMacro\fpSub
+% \DescribeMacro\fpMul\DescribeMacro\fpDiv
+% The standard commands for binary operations have the following
+% common syntax:
+% \begin{flushleft}
+% "\fp"\meta{bOp}"{"\meta{command sequence}"}{"\meta{fp number}"}"^^A
+% "{"\meta{fp number}"}".
+% \end{flushleft}
+% This will perform the operation specified by \meta{bOp}
+% with the two given numbers, saving the result in
+% \meta{command sequence}. Possibilities for
+% \meta{bOp} are `"Add"', `"Sub"', `"Mul"' and `"Div"',
+% specifying addition, subtraction, multiplication,
+% and division. Example:
+% \begin{flushleft}
+% "\fpAdd{\exmplsum}{100,0}{-99,1}"\\
+% "\fpMul{\exmplprod}{5}{\exmplsum}"
+% \end{flushleft}
+% \fpAdd{\exmplsum}{100,0}{-99,1}^^A
+% \fpMul{\exmplprod}{5}{\exmplsum}^^A
+% After this, the results of the computations will
+% be stored in the macros "\exmplsum" and "\exmplprod",
+% expanding to \exmplsum\ and \exmplprod.
+%
+% \DescribeMacro\fpNeg\DescribeMacro\fpAbs
+% Similar to the binary operations, the unary operations
+% share the common syntax
+% \begin{flushleft}
+% "\fp"\meta{uOp}"{"\meta{command sequence}"}{"\meta{fp number}"}".
+% \end{flushleft}
+% Possibilities for \meta{uOp} are `"Abs"' and `"Neg"',
+% meaning absolute amount and negation.
+%
+% \DescribeMacro\fpRound
+% With "\fpRound{"\meta{command sequence}"}{"\meta{fp number}^^A
+% "}{"\meta{precision}"}",
+% a number can be rounded to the desired precision (a power of ten).
+% The result
+% is saved in \meta{command sequence} as usual.
+%
+% \subsection{Register operations}
+% You may use register variants of all operations,
+% which means that you perform the operation on
+% a register which contains a number. A register is
+% referred to using its name; the name may
+% contain any characters including digits.
+%
+% \DescribeMacro\fpRegSet\DescribeMacro\fpRegGet
+% Registers are initialized by assigning them values,
+% using "\fpRegSet". They can be read out into
+% command sequences using "\fpRegGet".
+% \begin{flushleft}
+% "\fpRegSet{"\meta{reg name}"}{"\meta{fp number}"}"\\
+% "\fpRegGet{"\meta{reg name}"}{"\meta{command sequence}"}"
+% \end{flushleft}
+%
+% \DescribeMacro\fpRegAdd\DescribeMacro\fpRegSub
+% \DescribeMacro\fpRegMul\DescribeMacro\fpRegDiv
+% The binary operations need two register names.
+% After execution, the first register will hold
+% the result of the specified computation,
+% performed with its former value and the
+% value of the second register.
+% \begin{flushleft}
+% "\fp"\meta{bOp}"{"\meta{reg name 1}"}{"\meta{reg name 2}"}"
+% \end{flushleft}
+% \DescribeMacro\fpRegAbs\DescribeMacro\fpRegNeg
+% Consequently, the unary operations only need
+% the name of the register.
+% \begin{flushleft}
+% "\fp"\meta{uOp}"{"\meta{reg name}"}"
+% \end{flushleft}
+% \DescribeMacro\fpRegRound
+% Rounding of registers is also possible.
+% \begin{flushleft}
+% "\fpRegRound{"\meta{reg name}"}{"\meta{precision}"}"
+% \end{flushleft}
+% \DescribeMacro\fpRegCopy
+% Furthermore, there is one binary operation only available for
+% registers, this is "\fpRegCopy" which assigns the
+% value of \meta{reg name 2} to register \meta{reg name 1}.
+%
+% For example, consider the following statements.
+% \begin{flushleft}
+% "\fpRegSet{test1}{36} \fpRegSet{test2}{-3}"\\
+% "\fpRegDiv{test1}{test2} \fpRegMul{test1}{test1}"\\
+% "\fpRegGet{test1}{\fpresult}"
+% \end{flushleft}
+% \fpRegSet{test1}{36}\fpRegSet{test2}{-3}^^A
+% \fpRegDiv{test1}{test2}\fpRegMul{test1}{test1}^^A
+% \fpRegGet{test1}{\fpresult}^^A
+% After this, "test1" will hold the value \fpresult, which
+% "\fpresult" will expand to.
+%
+%
+% \subsection{Configuration and Parameters}
+%
+% \DescribeMacro\fpAccuracy
+% The macro "\fpAccuracy" takes one argument (a number),
+% determining the number of digits after the decimal sign,
+% i.\,e., the accuracy of the computations.
+% The default value is five.
+% At the moment, the name promises too much.
+% The command only affects "\fpDiv" and "\fpRegDiv".
+%
+% \DescribeMacro\fpDecimalSign
+% With "\fpDecimalSign{"\meta{character}"}" you can chose any character
+% for use as the decimal sign. Normally, this will be either
+% a point or a comma; the default is a comma.
+% You can furthermore use the package options
+% \texttt{comma} or \texttt{point}.
+% The support for options like \texttt{english} or \texttt{german}
+% has been removed. It will not be added again, and there will be no
+% detection of packages like \texttt{babel} or \texttt{german}.
+% In my view, a comma is the better choice regardless of the language
+% in question (and it is the \textsc{iso} standard). On the other hand,
+% many people think that a point should be used even in German texts.
+% So, you have to make an explicit decision.
+%
+% \section{Final Remarks}
+% After the first release, I intended to include the features listed
+% below in the near future.
+% Unfortunately, I didn't have time to do so, and maybe I will
+% never have, since I am currently not interested in extending this
+% package. If I continued the development some day, the
+% first extensions might be what is listed here.
+% \begin{itemize}
+% \item Extend syntax to support numbers like $1,7\mathrm{E}{-}1$ or
+% $2,765\cdot 10^5$ in input and output.
+% \item Formatted, customizable output.
+% \item User access to the comparison of registers.
+% \item A better concept for chosing the accuracy of the computations.
+% \item More operations like $\mathrm{e}^x$, $\sqrt{x}$, $\sin x$,
+% $\ln x$\ldots
+% \end{itemize}
+%
+% Some users have pointed out that the terminus \lq floating-point\rq\
+% is not strictly correct for what is provided by the package. Alas! I
+% happily stick to the package name.
+%
+% If you encounter needs not satisfied by this package, you may
+% wait for the unlikely event of an extension from my part, or you can
+% have a look at the following packages and see if they do what you want:
+% \begin{itemize}
+% \item {\tt fp} by Michael Mehlich for calculations,
+% \item {\tt numprint} by Harald Harders for formatted printing of
+% numbers.
+% \end{itemize}
+% Finally, the license of this package is LPPL, so feel free to do
+% it yourself.
+%
+% \StopEventually{%
+% \ifmulticols
+% \addtocontents{toc}{\protect\end{multicols}}
+% \fi}
+% \section{Implementation}
+%
+% \subsection{General ideas}
+% The main idea was to represent numbers internally by storing their
+% digits in an array/record-like construction (to be referred to as
+% an array or as a register from now on) whose numbering
+% reflects the decimal position factor of the digit, with
+% some information about the range of the numbering
+% and the sign of the number.
+% An array consists of a couple of command sequences,
+% sharing a common name followed by an element number.
+% E.\,g., `$120.3$' means $1\cdot 10^2+2\cdot 10^1+
+% 0\cdot 10^0+3\cdot 10^{-1}$. So, if the number is to be stored
+% in the array "\exmpl", the command sequences
+% "\exmpl@2", "\exmpl@1", "\exmpl@0" and "\exmpl@-1"
+% will be defined as `"1"', `"2"', `"0"' and `"3"', respectively.
+% The sign information `"+"' will be stored in "\exmpl@sig".
+% "\exmpl@ul" (`upper limit') will be `"2"', "\exmpl@ll" (`lower
+% limit') will be `"-1"'.
+%
+% The computations are performed as
+% you do it with paper and pencil.
+% E.\,g., for an addition, all corresponding digits
+% are summed, taking over anything
+% exceeding ten to the next pair of digits.
+% Thus, there is no limit to the range of numbers or to the
+% number of digits after the decimal sign, except
+% \TeX's memory and, probably the limiting factor, your patience.
+%
+% Initially, the computations were not performed inside of
+% groups, and side-effects were avoided using more
+% counters and constructions like "\xloop" etc.
+% This may make more efficient use of \TeX, as far as speed
+% and save stack usage is concerned, but I think that further
+% extensions will be much simpler now without the
+% need to worry about possible side-effects and the surprising
+% result when, once again, something happens you simply
+% did not think of. Furthermore, this provides
+% a simple mechanism of removing temporary stuff
+% from the memory.
+%
+% But now, let's reveal the code\dots
+%
+%
+% \subsection{Driver file}
+% The driver file can be generated from \texttt{fltpoint.dtx}
+% and then be used to produce the documentation (if you don't like
+% to run \LaTeX\ directly over the \texttt{dtx}-file).
+% \begin{macrocode}
+%<*deccomma>
+\mathchardef\CommaOrdinary="013B
+\mathchardef\CommaPunct ="613B
+\mathcode`,="8000
+{\catcode`\,=\active
+ \gdef ,{\obeyspaces\futurelet\next\CommaCheck}}
+\def\CommaCheck{\if\space\next\CommaPunct\else\CommaOrdinary\fi}
+%</deccomma>
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage{deccomma,fltpoint}
+%\OnlyDescription
+\AlsoImplementation
+\EnableCrossrefs % disable if index is ready
+\CodelineIndex
+\RecordChanges
+%\DisableCrossrefs
+\newcommand{\fpexample}[1]{%
+ \fpRegSet{fptemp}{#1}%
+ \fpRegGet{fptemp}{\fptemp}%
+ $\mbox{\tt`#1'}\rightarrow\fptemp$}
+\begin{document}
+ \DocInput{fltpoint.dtx}
+\end{document}
+%</driver>
+% \end{macrocode}
+%
+%
+% \subsection{\LaTeX\ package definitions}
+% If used as a \LaTeX\ package, the usual \LaTeX\ preliminaries
+% and some option declarations are necessary.
+% \begin{macrocode}
+%<*package>
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{fltpoint}[2004/11/12 v1.1b floating point arithmetic]
+\DeclareOption{comma}{\AtBeginDocument{\fpDecimalSign,}}
+\DeclareOption{point}{\AtBeginDocument{\fpDecimalSign.}}
+\ProcessOptions*\relax
+\input{fltpoint}
+%</package>
+% \end{macrocode}
+%
+% \iffalse
+%<*fltmain>
+% \fi
+% \subsection{Private letters}
+%
+% \begin{macro}{\atcatcode}
+% `"@"' is used for private command sequences. Its catcode is saved
+% in "\atcatcode" to be restored just before "\endinput".
+% \begin{macrocode}
+\edef\atcatcode{\the\catcode`\@}
+\catcode`\@=11
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{\LaTeX\ or not?}
+%
+% Check for \LaTeX, otherwise provide the "\@ifnextchar" mechanism
+% copied from the \LaTeX\ source, see there for explanation.
+% \begin{macrocode}
+\ifx\documentclass\relax
+\long\def\@ifnextchar#1#2#3{%
+ \let\reserved@d=#1%
+ \def\reserved@a{#2}%
+ \def\reserved@b{#3}%
+ \futurelet\@let@token\@ifnch}
+\def\@ifnch{%
+ \ifx\@let@token\@sptoken
+ \let\reserved@c\@xifnch
+ \else
+ \ifx\@let@token\reserved@d
+ \let\reserved@c\reserved@a
+ \else
+ \let\reserved@c\reserved@b
+ \fi
+ \fi
+ \reserved@c}
+\def\:{\let\@sptoken= } \:
+\def\:{\@xifnch} \expandafter\def\: {\futurelet\@let@token\@ifnch}
+\fi
+% \end{macrocode}
+% \subsection{Additional loop structures}
+%
+% \begin{macro}{\iloop}
+% \begin{macro}{\xloop}
+% To be able to nest loop structures without the need for
+% hiding the inner loop(s) in grouped blocks, the constructions
+% "\iloop...\irepeat" and "\xloop...\xrepeat" are defined
+% analogously to \PlainTeX's "\loop...\repeat".
+% "\iloop" will be used `internally' by macros which are
+% to be used in ordinary "\loop"s or in "\xloop"s.
+% "\xloop" will be used
+% `externally', surrounding ordinary "\loop"s.
+% \begin{macrocode}
+\def\iloop#1\irepeat{\def\ibody{#1}\iiterate}
+\def\iiterate{\ibody\let\inext=\iiterate\else\let\inext=\relax\fi
+ \inext}
+\def\xloop#1\xrepeat{\def\xbody{#1}\xiterate}
+\def\xiterate{\xbody\let\xnext\xiterate\else\let\xnext\relax\fi\xnext}
+% \end{macrocode}
+% The following assignments are necessary to make
+% "\loop"\dots"\if"\dots"\repeat"
+% constructions skippable inside another "\if".
+% \begin{macrocode}
+\let\repeat\fi
+\let\irepeat\fi
+\let\xrepeat\fi
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+% \subsection{Allocation of registers}
+%
+% \begin{macro}{\fp@loopcount}
+% \begin{macro}{\fp@loopcountii}
+% \begin{macro}{\fp@result}
+% \begin{macro}{\fp@carryover}
+% \begin{macro}{\fp@tempcount}
+% \begin{macro}{\fp@tempcountii}
+% Several count registers are needed. I have tried to keep this
+% number small, which means that, at some points, I may have chosen a
+% less logical or less readable usage of counts.
+% Nevertheless, I do not claim to have minimized the number
+% as far as possible\dots
+%
+% "\fp@loopcount" and "\fp@loopcountii" are often, but not always, used
+% for "\loop"s, "\fp@loopcountii" sometimes just stores the finishing
+% number. "\fp@result" and "\fp@carryover"
+% are used to store the intermediate results of computations.
+% "\fp@tempcount" and "\fp@tempcountii" are scratch registers
+% whose values should not be considered to be the same
+% after the use of any macro, except the simple array
+% accession abbreviations starting whith "\ar@", as explained below.
+% \begin{macrocode}
+\newcount\fp@loopcount
+\newcount\fp@loopcountii
+\newcount\fp@result
+\newcount\fp@carryover
+\newcount\fp@tempcount
+\newcount\fp@tempcountii
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Communication between macros and groups}
+%
+% \begin{macro}{\fp@setparam}
+% \begin{macro}{\fp@param}
+% To pass information from one macro to another, or from
+% inside a group to the outer world, the construction
+% "\fp@setparam{"\meta{information}"}" is used. It saves
+% \meta{information} globally in the command sequence "\fp@param".
+% This mechanism is used, e.\,g., by "\fp@regcomp",
+% "\fp@getdigit" to pass their result to the calling macro,
+% or by "\fp@regadd" etc.\ to make \meta{information} survive the end
+% of the current group. Since "\xdef" is used, \meta{information}
+% will be fully expanded.
+% \begin{macrocode}
+\def\fp@setparam#1{\xdef\fp@param{#1}}%
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Array accession}
+%
+% \begin{macro}{\ar@set}
+% \begin{macro}{\ar@get}
+% \begin{macro}{\ar@setsig}
+% \begin{macro}{\ar@getsig}
+% \begin{macro}{\ar@setul}
+% \begin{macro}{\ar@getul}
+% \begin{macro}{\ar@setll}
+% \begin{macro}{\ar@getll}
+% The idea of arrays using command sequences like
+% "\exmpl@-1" means typing a lot of unreadable
+% "\expandafter"s and "\csname"s, so the following
+% abbreviations were introduced. They take the base name of
+% the array as the first argument, if needed followed by
+% an element number, for the "set"-commands followed by
+% the third argument to be the (new) value.
+% No checks are performed if the element number
+% is inside the boundaries of the array, nor anything
+% else to ensure the validity of the operation.
+%
+% "\ar@set" is used to save digits.
+% "\ar@setsig", "\ar@setul" and "\ar@setll" set sign,
+% upper and lower limit of the array.
+% "\ar@get", "\ar@getsig", "\ar@getul" and "\ar@getll"
+% are used to access the respective command sequences.
+% \begin{macrocode}
+\def\ar@set#1#2#3{\expandafter\edef\csname#1@\number#2\endcsname{%
+ \number#3}}
+\def\ar@get#1#2{\csname#1@\number#2\endcsname}
+\def\ar@setsig#1#2{\expandafter\edef\csname#1@sig\endcsname{#2}}
+\def\ar@getsig#1{\csname#1@sig\endcsname}
+\def\ar@getul#1{\csname#1@ul\endcsname}
+\def\ar@getll#1{\csname#1@ll\endcsname}
+\def\ar@setul#1#2{\expandafter\edef\csname#1@ul\endcsname{\number#2}}
+\def\ar@setll#1#2{\expandafter\edef\csname#1@ll\endcsname{\number#2}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Miscellaneous}
+%
+% \begin{macro}{\fp@settomax}
+% The macro "\fp@settomax" assigns the maximum of the two
+% numbers given as "#2" and "#3" to the counter "#1".
+% \begin{macrocode}
+\def\fp@settomax#1#2#3{%
+ \ifnum#2<#3\relax
+ #1=#3\relax
+ \else
+ #1=#2\relax
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fp@settomin}
+% The macro "\fp@settomin" does the same with the minimum.
+% \begin{macrocode}
+\def\fp@settomin#1#2#3{%
+ \ifnum#2<#3\relax
+ #1=#2\relax
+ \else
+ #1=#3\relax
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fp@modulo}
+% The macro "\fp@modulo" computes the result of $\mbox{\#1}\bmod
+% \mbox{\#2}$ and saves it in "\fp@param".
+% \begin{macrocode}
+\def\fp@modulo#1#2{%
+ \fp@tempcount=#1\relax
+ \fp@tempcountii=#1\relax
+ \divide\fp@tempcountii#2\relax
+ \multiply\fp@tempcountii#2\relax
+ \advance\fp@tempcount-\fp@tempcountii
+ \edef\fp@param{\number\fp@tempcount}}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{Setting and getting register contents}
+%
+% \begin{macro}{\fp@regread}
+% \begin{macro}{\fp@regread@raw}
+% The macro "\fp@regread" reads the string or command sequence
+% (after expansion) given as "#2" into register "#1".
+% The main work is done by the subroutine
+% "\fp@readchars", where "\fp@tempcount" is used to indicate
+% the current position. "\fp@arrayname" is used to pass
+% "#1" to "\fp@readchars".
+% \begin{macrocode}
+\def\fp@regread#1#2{%
+ \fp@regread@raw{#1}{#2}%
+ \fp@cleanreg{#1}}
+\def\fp@regread@raw#1#2{%
+% \end{macrocode}
+% Initialize "\fp@tempcount".
+% Initialize "\fp@arrayname".
+% Make "#1" positive by default.
+% \begin{macrocode}
+ \fp@tempcount=0
+ \edef\fp@arrayname{#1}%
+ \ar@setsig{#1}{+}%
+% \end{macrocode}
+% Now call "\fp@readchars" with "#2" fully expanded,
+% followed by a decimal sign. The decimal sign is necessary because
+% "\fp@readchars" expects at least one decimal sign to occur in the
+% given string, so if "#2" is, say, "100", this will make it
+% readable. On the other hand, a superficial decimal sign at the end
+% of a number like $1.34$ will be ignored.
+% \begin{macrocode}
+ \edef\fp@scratch{#2\fp@decimalsign}%
+ \expandafter\fp@readchars\fp@scratch\end
+% \end{macrocode}
+% If the first character of "#2" has been a decimal sign, the upper
+% limit will be wrong, no pre-point digits will be present.
+% This does not conform the internal syntax and is
+% corrected now.
+% \begin{macrocode}
+ \ifnum\ar@getul{#1}=-1
+ \ar@setul{#1}{0}%
+ \ar@set{#1}{0}{0}%
+ \fi
+% \end{macrocode}
+% The $n$ digits before the decimal sign (if any) have been
+% read in from left to right, assigning positions from
+% $0\ldots n$, so they have to be swapped to
+% their correct positions. This is done with two counters,
+% one starting as $0$, the other as $n$, using
+% "\fp@scratch" for temporary storage.
+% \begin{macrocode}
+ \fp@tempcount=0
+ \fp@tempcountii=\ar@getul{#1}\relax
+ \iloop
+ \ifnum\fp@tempcount<\fp@tempcountii
+ \edef\fp@scratch{\ar@get{#1}{\fp@tempcountii}}%
+ \ar@set{#1}{\fp@tempcountii}{\ar@get{#1}{\fp@tempcount}}%
+ \ar@set{#1}{\fp@tempcount}{\fp@scratch}%
+ \advance\fp@tempcount by 1
+ \advance\fp@tempcountii by -1
+ \irepeat
+}% end \fp@regread@raw
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fp@readchars}
+% As mentioned above, this subroutine is called by
+% "\fp@regread" to do the actual work of reading
+% the given number character after character into the register
+% passed using "\fp@arrayname". It will stop if it sees
+% an \fbox{\tt end} token.
+% \begin{macrocode}
+\def\fp@readchars#1{%
+ \ifx#1\end
+% \end{macrocode}
+% If the condition is true, the token read before has been the final
+% one. So at the end, do not call "\fp@readchars" any more, and use
+% the current value of "\fp@tempcount" to assign the correct
+% lower limit to the register.
+% \begin{macrocode}
+ \let\inext=\relax
+ \ifnum\fp@tempcount<0
+ \advance\fp@tempcount by 1
+ \ar@setll{\fp@arrayname}{\fp@tempcount}%
+ \else
+ \ar@setll{\fp@arrayname}{0}%
+ \fi
+ \else % \ifx#1\end
+% \end{macrocode}
+% If the condition is false, further characters will
+% follow, so "\fp@readchars" will have to be called
+% again after finishing this character.
+% \begin{macrocode}
+ \let\inext=\fp@readchars
+% \end{macrocode}
+% Now check the character and perform the respective actions.
+% \begin{macrocode}
+ \ifx#1+%
+% \end{macrocode}
+% An optional `"+"' has been encountered, nothing to do.
+% \begin{macrocode}
+ \else
+ \ifx#1-%
+% \end{macrocode}
+% `"-"' sign, toggle sign.
+% \begin{macrocode}
+ \if\ar@getsig{\fp@arrayname}-%
+ \ar@setsig{\fp@arrayname}{+}%
+ \else
+ \ar@setsig{\fp@arrayname}{-}%
+ \fi
+ \else
+ \if\noexpand#1\fp@decimalsign%
+% \end{macrocode}
+% A decimal sign has been encountered. So, if it is the first
+% one, switch to reading afterpoint digits, otherwise ignore it.
+% \begin{macrocode}
+ \ifnum\fp@tempcount>-1
+ \advance\fp@tempcount by -1
+ \ar@setul{\fp@arrayname}{\fp@tempcount}%
+ \fp@tempcount=-1
+ \fi
+ \else
+% \end{macrocode}
+% None of the above characters was encountered, so assume
+% a digit, and read it into the current position. Then step
+% "\fp@tempcount" by $+1$ if prepoint digits are read in,
+% or by $-1$ if the decimal sign has already been seen.
+% \begin{macrocode}
+ \ar@set{\fp@arrayname}{\fp@tempcount}{#1}%
+ \ifnum\fp@tempcount<0
+ \advance\fp@tempcount by -1
+ \else
+ \advance\fp@tempcount by 1
+ \fi
+ \fi% end \if\noexpand#1\fp@decimalsign
+ \fi% end \ifx#1-
+ \fi% end \ifx#1+
+ \fi% end \ifx#1\end
+% \end{macrocode}
+% That's all, call "\inext".
+% \begin{macrocode}
+ \inext
+}% end \fp@readchars
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fp@regget}
+% The macro "\fp@regget" is used to read the contents of the
+% register "#1" into the command sequence "#2".
+% \begin{macrocode}
+\def\fp@regget#1#2{%
+% \end{macrocode}
+% First, we get the sign of the number. If negative,
+% "#2" is initialized as `"-"', otherwise as empty.
+% \begin{macrocode}
+ \if\ar@getsig{#1}-%
+ \def#2{-}%
+ \else
+ \def#2{}%
+ \fi
+% \end{macrocode}
+% Then we set up "\fp@tempcount" as the counter for an "\iloop",
+% starting at the upper limit of "#1".
+% \begin{macrocode}
+ \fp@tempcount=\ar@getul{#1}\relax
+ \iloop
+% \end{macrocode}
+% If the "\fp@tempcount" is $-1$, we have to append a decimal sign.
+% \begin{macrocode}
+ \ifnum\fp@tempcount=-1
+ \edef#2{#2\fp@decimalsign}%
+ \fi
+% \end{macrocode}
+% Now append the corresponding digit.
+% \begin{macrocode}
+ \edef#2{#2\ar@get{#1}{\fp@tempcount}}%
+% \end{macrocode}
+% And repeat if the lower limit of "#1" is not yet reached.
+% \begin{macrocode}
+ \ifnum\fp@tempcount>\ar@getll{#1}\relax
+ \advance\fp@tempcount by -1
+ \irepeat
+}% end \def\fp@regget
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fp@cleanreg}
+% The macro "\fp@cleanreg" will clean up the given register.
+% This means that leading and trailing zeros will be
+% removed, and that $-0$ will be turned into $+0$
+% to be recognised as equal later on.
+% \begin{macrocode}
+\def\fp@cleanreg#1{%
+% \end{macrocode}
+% First, we will iterate until all leading zeros
+% have been removed, except for digit $0$ that it is
+% expected to be `"0"' for all numbers $n$ with $-1<n<1$.
+% \begin{macrocode}
+ \fp@tempcount=\ar@getul{#1}\relax
+ \iloop
+ \ifnum\fp@tempcount>0
+ \ifnum\ar@get{#1}{\fp@tempcount}=0
+% \end{macrocode}
+% If this is true, the first digit is a zero and is `removed'
+% by changing the upper limit. It is not necessary to
+% erase it by setting the array element to "\empty" or something
+% like that, because it will not be looked at any more.
+% \begin{macrocode}
+ \advance\fp@tempcount by -1
+ \ar@setul{#1}{\fp@tempcount}%
+ \else
+% \end{macrocode}
+% So the condition is false, the first digit is not a zero
+% and the following ones need not to be looked at.
+% \begin{macrocode}
+ \fp@tempcount=0
+ \fi
+ \irepeat
+% \end{macrocode}
+% Similarly, the trailing zeros are removed.
+% \begin{macrocode}
+ \fp@tempcount=\ar@getll{#1}\relax
+ \iloop
+ \ifnum\fp@tempcount<0
+ \ifnum\ar@get{#1}{\fp@tempcount}=0
+ \advance\fp@tempcount by 1
+ \ar@setll{#1}{\fp@tempcount}%
+ \else
+ \fp@tempcount=0
+ \fi
+ \irepeat
+% \end{macrocode}
+% Now check if the number is zero, using
+% $(\mbox{x@ll}=\mbox{x@ul})\wedge(\mbox{x@0}=0)\Longleftrightarrow
+% \rm x=0$, and set the sign to `"+"' if this is the case.
+% \begin{macrocode}
+ \ifnum\ar@getll{#1}=\ar@getul{#1}\relax
+ \ifnum\ar@get{#1}{0}=0\relax
+ \ar@setsig{#1}{+}%
+ \fi
+ \fi
+}% end \fp@regclean
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fp@getdigit}
+% The macro "\fp@getdigit" will return the digit number "#2" of
+% register "#1" using "\fp@setparam". If "#2" is outside the
+% boundaries of the array, `"0"' is returned. (Which is not only
+% sensible, but also mathematically correct.)
+% \begin{macrocode}
+\def\fp@getdigit#1#2{%
+ \ifnum#2<\ar@getll{#1}\relax
+ \fp@setparam0%
+ \else
+ \ifnum#2>\ar@getul{#1}\relax
+ \fp@setparam0%
+ \else
+ \fp@setparam{\ar@get{#1}{#2}}%
+ \fi
+ \fi
+}% end \fp@getdigit
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fp@shiftright}
+% The macro "\fp@shiftright" takes register "#1" and shifts the decimal
+% sign "#2" digits to the right ("#2" may be negative or zero, too,
+% so there is no need for a "\fp@shiftleft").
+% The digits are read into "\fp@shiftnum", inserting the decimal
+% sign at the new place. Then, "\fp@shiftnum" is read
+% into "#1" via "\fp@regread".
+% \begin{macrocode}
+\def\fp@shiftright#1#2{%
+% \end{macrocode}
+% First, save the value of "#2" in "\fp@shiftamount".
+% This makes it possible to say, e.\,g.,
+% "\fpshiftright{exmpl}{\fp@tempcount}" without side-effects.
+% \begin{macrocode}
+ \edef\fp@shiftamount{\number#2}%
+% \end{macrocode}
+% Now, determine the start position.
+% The maximum of the upper limit and "-\fp@shiftamount" is used
+% in order to allow the decimal sign of, e.\,g.,
+% $1.1$ to be shifted $-5$ digits to the right.
+% \begin{macrocode}
+ \fp@settomax{\fp@tempcount}{\ar@getul{#1}}{-\fp@shiftamount}%
+% \end{macrocode}
+% Similarly, determine the stop position.
+% \begin{macrocode}
+ \fp@settomin{\fp@tempcountii}{\ar@getll{#1}}{-\fp@shiftamount}%
+% \end{macrocode}
+% Now, initialize "\fp@shiftnum" and begin the "\iloop".
+% Read digit after digit using "\fp@getdigit", therefore
+% getting a `"0"' outside the boundaries. Insert the
+% decimal sign at the new position given by
+% "-\fp@shiftamount".
+% \begin{macrocode}
+ \def\fp@shiftnum{}%
+ \iloop
+ \fp@getdigit{#1}{\fp@tempcount}%
+ \edef\fp@shiftnum{\fp@shiftnum\fp@param}%
+ \ifnum\fp@tempcount=-\fp@shiftamount\relax
+ \edef\fp@shiftnum{\fp@shiftnum\fp@decimalsign}%
+ \fi
+ \ifnum\fp@tempcount>\fp@tempcountii
+ \advance\fp@tempcount by -1
+ \irepeat
+% \end{macrocode}
+% Finally, assign the value to "#1".
+% \begin{macrocode}
+ \fp@regread{#1}{\fp@shiftnum}%
+}% end \fp@shiftright
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fp@firstnonzero}
+% The macro "\fp@firstnonzero" returns the first non-zero
+% digit of register "#1" via "\fp@setparam".
+% \begin{macrocode}
+\def\fp@firstnonzero#1{%
+% \end{macrocode}
+% If "#1" is zero, the "\iloop" below will run infinitely,
+% so this case has to be checked separately by comparing
+% "#1" to the internal register "@0" which holds zero.
+% `"0"' is returned if "#1" is zero.
+% \begin{macrocode}
+ \fp@regcomp{#1}{@0}%
+ \if\fp@param=%
+ \fp@setparam0%
+% \end{macrocode}
+% Otherwise, each digit is checked, starting at the upper limit,
+% and the position of first digit differing from zero is
+% returned in "\fp@param".
+% \begin{macrocode}
+ \else
+ \fp@tempcount=\ar@getul{#1}\relax%
+ \fp@tempcountii=\ar@getll{#1}\relax%
+ \iloop
+ \ifnum\ar@get{#1}{\fp@tempcount}>0
+ \fp@setparam{\number\fp@tempcount}%
+ \fp@tempcount=\fp@tempcountii
+ \fi
+ \ifnum\fp@tempcount>\fp@tempcountii
+ \advance\fp@tempcount by -1
+ \irepeat
+ \fi
+}% end \fp@firstnonzero
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{Comparison of registers}
+%
+% \begin{macro}{\fp@regcomp}
+% The macro "\fp@regcomp" compares the two specified registers.
+% It saves the result of the comparison (either `"<"', `">"',
+% or `"="') in "\fp@param". First, it checks whether the
+% two numbers have the same sign or not. If not,
+% the comparison is very easy, otherwise "\fp@regcomp@main"
+% is called to do the work.
+% \begin{macrocode}
+\def\fp@regcomp#1#2{%
+ {%
+ \if\ar@getsig{#1}-%
+ \if\ar@getsig{#2}-%
+ \fp@regcomp@main{#1}{#2}<>%
+ \else
+ \fp@setparam{<}%
+ \fi
+ \else
+ \if\ar@getsig{#2}-%
+ \fp@setparam{>}%
+ \else
+ \fp@regcomp@main{#1}{#2}><%
+ \fi
+ \fi
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fp@regcomp@main}
+% The macro "\fp@regcomp@main" takes four parameters:
+% The two registers to be compared, and two tokens
+% to be used as result. This is needed because
+% if, e.\,g., two numbers have the same sign and
+% are equal for all positions greater than
+% $10^2$, and number~1 has `"9"' at position $10^2$ and number~2
+% has `"5"', then the result must be `"<"' if $n_1<n_2<0$,
+% but `">"' if $n_1>n_2>0$.
+%
+% First, the range of digits to compare is determined.
+% Then, each pair of digits is compared. If different,
+% "\fp@param" is set and the loop is terminated by
+% setting the loop counter to the stop position.
+% If the digits are equal and there are no more digits
+% to compare, the numbers are equal.
+% \begin{macrocode}
+\def\fp@regcomp@main#1#2#3#4{%
+ \fp@settomax{\fp@loopcount}{\ar@getul{#1}}{\ar@getul{#2}}%
+ \fp@settomin{\fp@loopcountii}{\ar@getll{#1}}{\ar@getll{#2}}%
+ \loop
+ \fp@getdigit{#1}{\fp@loopcount}%
+ \fp@tempcount=\fp@param\relax
+ \fp@getdigit{#2}{\fp@loopcount}%
+ \fp@tempcountii=\fp@param\relax
+ \ifnum\fp@tempcount<\fp@tempcountii
+ \fp@setparam{#4}%
+ \fp@loopcount=\fp@loopcountii
+ \else
+ \ifnum\fp@tempcount>\fp@tempcountii
+ \fp@setparam{#3}%
+ \fp@loopcount=\fp@loopcountii
+ \else
+ \ifnum\fp@loopcount=\fp@loopcountii
+ \fp@setparam{=}%
+ \fi
+ \fi
+ \fi
+ \ifnum\fp@loopcount>\fp@loopcountii
+ \advance\fp@loopcount by -1
+ \repeat
+}% end \fp@regcomp@main
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{Unary Operations}
+%
+% \begin{macro}{\fp@regabs}
+% The macro "\fp@regabs" turns register "#1" into its amount.
+% This is rather trivial: just set the sign to `"+"'.
+% \begin{macrocode}
+\def\fp@regabs#1{%
+ \ar@setsig{#1}{+}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fp@regneg}
+% The macro "\fp@regneg" negates register "#1". It checks
+% whether the actual sign is `"+"' or `"-"' and sets it
+% to its opposite, except that nothing is done if the
+% number is zero.
+% \begin{macrocode}
+\def\fp@regneg#1{%
+ \if\ar@getsig{#1}-%
+ \ar@setsig{#1}{+}%
+ \else
+ \fp@regcomp{#1}{@0}%
+ \if\fp@param=%
+ \else
+ \ar@setsig{#1}{-}%
+ \fi
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fp@reground}
+% The macro "\fp@reground" rounds register "#1" with a target accuracy
+% given as "#2" (as a power of ten).
+% \begin{macrocode}
+\def\fp@reground#1#2{%
+% \end{macrocode}
+% Fist, if the desired accuracy is smaller than the lower limit of
+% "#1", nothing has to be done.
+% \begin{macrocode}
+ \ifnum#2>\ar@getll{#1}\relax
+ {%
+% \end{macrocode}
+% Otherwise, we check the following digit. If it is greater than four,
+% we have to advance digit "#2" before truncating the number. This
+% means adding $10^{\mathtt{\#2}}$ for positive "#1" and subtracting
+% $10^{\mathtt{\#2}}$ for negative "#1".
+% \begin{macrocode}
+ \fp@tempcount=#2\relax
+ \advance\fp@tempcount by -1
+ \fp@getdigit{#1}{\fp@tempcount}%
+ \ifnum\fp@param>4
+ \fp@regcopy{fp@temp}{@1}%
+ \fp@shiftright{fp@temp}{#2}%
+ \fp@regcomp{#1}{@0}%
+ \if\fp@param<%
+ \fp@regneg{fp@temp}%
+ \fi
+ \fp@regadd{#1}{fp@temp}%
+ \fi
+% \end{macrocode}
+% Afterwards, we set the lower limit to "#2". If "#2" is greater than
+% zero,
+% we set the lower limit and all digits~$n$ with $0\leq n<\texttt{\#2}$
+% to zero. Then we read the number using
+% "\fp@regget", make it globally available and read it into "#1"
+% after finishing the local group.
+% \begin{macrocode}
+ \ifnum#2>0
+ \fp@loopcount=#2\relax
+ \iloop
+ \ifnum\fp@loopcount>0
+ \advance\fp@loopcount by -1
+ \ar@set{#1}{\fp@loopcount}{0}%
+ \irepeat
+ \ar@setll{#1}{0}%
+ \else
+ \ar@setll{#1}{#2}%
+ \fi
+ \fp@regget{#1}{\fp@scratch}%
+ \fp@setparam\fp@scratch
+ }%
+ \fp@regread{#1}{\fp@param}%
+ \fi
+} % end \fp@reground
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{Binary operations}
+%
+% \begin{macro}{\fp@regcopy}
+% The macro "\fp@regcopy" assigns the value of register
+% "#2" to register "#1". This is done simply by reading
+% register "#2" into a scratch control sequence
+% and then reading this into register "#1".
+% \begin{macrocode}
+\def\fp@regcopy#1#2{%
+ \fp@regget{#2}{\fp@scratch}%
+ \fp@regread{#1}{\fp@scratch}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fp@regadd}
+% The macro "\fp@regadd" adds the value of register "#2" to
+% register "#1".
+% \begin{macrocode}
+\def\fp@regadd#1#2{%
+ {%
+% \end{macrocode}
+% First, check whether the two numbers have the same sign.
+% \begin{macrocode}
+ \if\ar@getsig{#1}\ar@getsig{#2}%
+% \end{macrocode}
+% If the two numbers have the same sign, the addition can be
+% done by adding each two corresponding digits and a possible
+% carryover, starting at $\min(\mbox{ll1},\mbox{ll2})$,
+% ending at $\max(\mbox{ul1},\mbox{ul2})$. Those values
+% are saved in "\fp@add@start" and "\fp@add@finish".
+% \begin{macrocode}
+ \fp@settomin{\fp@loopcount}{\ar@getll{#1}}{\ar@getll{#2}}%
+ \edef\fp@add@start{\number\fp@loopcount}%
+ \fp@settomax{\fp@tempcount}{\ar@getul{#1}}{\ar@getul{#2}}%
+ \edef\fp@add@finish{\number\fp@tempcount}%
+% \end{macrocode}
+% Initialize "\fp@carryover".
+% \begin{macrocode}
+ \fp@carryover=0
+% \end{macrocode}
+% Now start the main loop. Each digit is computed
+% in counter "\fp@result" as the
+% sum of the corresponding digits plus the carryover from
+% the previous pair. If the sum is greater than 10,
+% it is reduced by 10 and "\fp@carryover" is set to 1.
+% (No sum greater than 19 is possible.)
+% \begin{macrocode}
+ \loop
+ \fp@getdigit{#1}{\fp@loopcount}%
+ \fp@result=\fp@param\relax
+ \fp@getdigit{#2}{\fp@loopcount}%
+ \advance\fp@result by \fp@param\relax
+ \advance\fp@result by \fp@carryover
+ \ifnum\fp@result>9
+ \fp@carryover=1
+ \advance\fp@result by -10
+ \else
+ \fp@carryover=0
+ \fi
+ \ar@set{#1}{\fp@loopcount}{\fp@result}%
+ \ifnum\fp@loopcount<\fp@add@finish\relax
+ \advance\fp@loopcount by 1
+ \repeat
+% \end{macrocode}
+% If the last pair had a carryover, take it into account.
+% Then adjust the lower and upper limit of the result.
+% \begin{macrocode}
+ \ifnum\fp@carryover>0
+ \advance\fp@loopcount by 1
+ \ar@set{#1}{\fp@loopcount}{\fp@carryover}%
+ \fi
+ \ar@setll{#1}{\fp@add@start}%
+ \ar@setul{#1}{\fp@loopcount}%
+% \end{macrocode}
+% Finally, save the result in "\fp@param" to make it survive
+% the endgroup character after "\fi".
+% \begin{macrocode}
+ \fp@regget{#1}{\fp@scratch}%
+ \fp@setparam\fp@scratch
+% \end{macrocode}
+% That's it. But if the two numbers have different signs,
+% the situation is a bit more complicated. In this case,
+% the amounts of "#1" and "#2" are saved in two temporary registers
+% ("fp@tempi" and "fp@tempii"). The smaller one is subtracted
+% from the larger one, and the sign of the result is
+% adjusted according to the sign of "#1" and "#2".
+% This is done by the subroutine "\fp@regadd@sub", which also takes
+% care of saving the result in "\fp@param".
+% \begin{macrocode}
+ \else % \if sign
+ \fp@regcopy{fp@tempi}{#1}%
+ \fp@regcopy{fp@tempii}{#2}%
+ \fp@regabs{fp@tempi}%
+ \fp@regabs{fp@tempii}%
+ \fp@regcomp{fp@tempi}{fp@tempii}%
+ \if\fp@param>%
+ \fp@regadd@sub{#1}{fp@tempi}{fp@tempii}%
+ \else
+ \fp@regadd@sub{#2}{fp@tempii}{fp@tempi}%
+ \fi
+ \fi % end \if sign
+% \end{macrocode}
+% Now end the group to keep everything local, and read
+% the result in "\fp@param" into register "#1".
+% \begin{macrocode}
+ }%
+ \fp@regread{#1}{\fp@param}%
+}% end \fp@regadd
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fp@regadd@sub}
+% The macro "\fp@regadd@sub" is a subroutine of
+% "\fp@regadd".
+% \begin{macrocode}
+\def\fp@regadd@sub#1#2#3{%
+% \end{macrocode}
+% First, subtract "#3" from "#2". The restriction $\mbox{\tt\#2}>
+% \mbox{\tt\#3}$ is ensured by the calling "\fp@regadd".
+% \begin{macrocode}
+ \fp@regsub@restricted{#2}{#3}%
+% \end{macrocode}
+% "#1" is the original number of which "#2" is the amount.
+% So, if it is negative, the final result also has to be negative.
+% This is done by the following four lines.
+% \begin{macrocode}
+ \fp@regcomp{#1}{@0}%
+ \if\fp@param<%
+ \fp@regneg{#2}%
+ \fi
+% \end{macrocode}
+% Now, the final result is stored in "#2". Make it
+% globally available using "\fp@setparam".
+% \begin{macrocode}
+ \fp@regget{#2}{\fp@scratch}%
+ \fp@setparam\fp@scratch
+}% end \fp@regadd@sub
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fp@regsub@restricted}
+% The macro "\fp@regsub@restricted" does the actual
+% work of subtracting "#2" from "#1", provided that
+% "#1" is greater than "#2". It is called by
+% "\fp@regadd@sub" and by "\fp@regdiv".
+% \begin{macrocode}
+\def\fp@regsub@restricted#1#2{%
+% \end{macrocode}
+% First, we start a group to keep counters etc.\ local.
+% Then, we determine the start and end position for the
+% loop, as above for "\fp@regadd".
+% \begin{macrocode}
+ {%
+ \fp@settomin{\fp@loopcount}{\ar@getll{#1}}{\ar@getll{#2}}%
+ \edef\fp@lowermin{\number\fp@loopcount}%
+ \fp@settomax{\fp@tempcount}{\ar@getul{#1}}{\ar@getul{#2}}%
+ \edef\fp@uppermin{\number\fp@tempcount}%
+% \end{macrocode}
+% Now subtract the corresponding digits, taking into
+% account a possible carryover.
+% \begin{macrocode}
+ \fp@carryover=0
+ \loop
+ \fp@getdigit{#1}{\fp@loopcount}%
+ \fp@result=\fp@param\relax
+ \fp@getdigit{#2}{\fp@loopcount}%
+ \advance\fp@result by -\fp@param\relax
+ \advance\fp@result by \fp@carryover
+% \end{macrocode}
+% If the result is $<0$, add 10 to the result
+% and set the carryover to $-1$.
+% \begin{macrocode}
+ \ifnum\fp@result<0
+ \fp@carryover=-1
+ \advance\fp@result by 10
+ \else
+ \fp@carryover=0
+ \fi
+% \end{macrocode}
+% Now save the result and repeat if there are further
+% digits.
+% \begin{macrocode}
+ \ar@set{#1}{\fp@loopcount}{\fp@result}%
+ \ifnum\fp@loopcount<\fp@uppermin\relax
+ \advance\fp@loopcount by 1
+ \repeat
+% \end{macrocode}
+% If there is a carryover for the last two digits,
+% take it into account.
+% \begin{macrocode}
+ \ifnum\fp@carryover=-1
+ \advance\fp@loopcount by 1
+ \ar@set{#1}{\fp@loopcount}{-1}%
+ \fi
+% \end{macrocode}
+% Now adjust the upper and lower limit of the result,
+% and save it in "\fp@param".
+% \begin{macrocode}
+ \ar@setll{#1}{\fp@lowermin}%
+ \ar@setul{#1}{\fp@loopcount}%
+ \fp@regget{#1}{\fp@scratch}%
+ \fp@setparam\fp@scratch
+ }%
+% \end{macrocode}
+% Finally, assign the result to "#1" inside the current group.
+% \begin{macrocode}
+ \fp@regread{#1}{\fp@param}%
+}% end \fp@regsub@restricted
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\fp@regsub}
+% The macro "\fp@regsub" subtracts register "#2" from
+% register "#1". This is done by negating "#2" inside
+% a group and calling "\fp@regadd".
+% \begin{macrocode}
+\def\fp@regsub#1#2{%
+ {%
+ \fp@regneg{#2}%
+ \fp@regadd{#1}{#2}%
+ \fp@regget{#1}{\fp@scratch}%
+ \fp@setparam\fp@scratch
+ }%
+ \fp@regread{#1}{\fp@param}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fp@regmul}
+% The macro "\fp@regmul" multiplies the value
+% of register "#1" with the value of register "#2".
+% \begin{macrocode}
+\def\fp@regmul#1#2{%
+ {%
+% \end{macrocode}
+% First, we initialize the temporary register "fp@temp1"
+% as zero; it will be used to hold the results so far.
+% Then we start the outer "\xloop" which will
+% run through all digits of "#2", beginning at the lower limit.
+% \begin{macrocode}
+ \fp@regcopy{fp@temp1}{@0}%
+ \fp@loopcountii=\ar@getll{#2}\relax
+ \xloop
+% \end{macrocode}
+% Then we initialize the inner loop, which multplies the
+% current digit of "#2" with "#1" digit after digit,
+% saving the result in "\fp@newnum".
+% \begin{macrocode}
+ \fp@loopcount=\ar@getll{#1}\relax
+ \fp@carryover=0
+ \def\fp@newnum{}%
+ \loop
+ \fp@result=\ar@get{#2}{\fp@loopcountii}\relax
+ \multiply\fp@result by \ar@get{#1}{\fp@loopcount}\relax
+ \advance\fp@result by \fp@carryover
+% \end{macrocode}
+% If the result is greater than~9, we set the carryover
+% as $(\mbox{\tt\bslash fp@result}\bmod 10)$ and
+% the result to $(\mbox{\tt\bslash fp@result}\mathop{\mbox{div}}10)$.
+% \begin{macrocode}
+ \ifnum\fp@result>9
+ \fp@carryover=\fp@result
+ \divide\fp@carryover by 10
+ \fp@tempcount=\fp@carryover
+ \multiply\fp@tempcount by 10
+ \advance\fp@result by -\fp@tempcount
+ \else
+ \fp@carryover=0
+ \fi
+ \edef\fp@newnum{\number\fp@result\fp@newnum}%
+ \ifnum\fp@loopcount<\ar@getul{#1}\relax
+ \advance\fp@loopcount by 1
+ \repeat
+ \edef\fp@newnum{\number\fp@carryover\fp@newnum}%
+ \fp@regread{fp@temp2}{\fp@newnum}%
+% \end{macrocode}
+% Now "fp@temp2" holds the partial result for this digit of
+% "#2". We have to multiply it with $10^n$, if $n$ is the
+% number of digits of "#2" completed so far.
+% This is done by calling "\fp@shiftright" with $-n$ as
+% second argument.
+% \begin{macrocode}
+ \fp@tempcount=\fp@loopcountii
+ \advance\fp@tempcount by -\number\ar@getll{#2}\relax
+ \fp@shiftright{fp@temp2}{\fp@tempcount}%
+% \end{macrocode}
+% Now we add "fp@temp2" to the results so far and iterate
+% if there are further digits.
+% \begin{macrocode}
+ \fp@regadd{fp@temp1}{fp@temp2}%
+ \ifnum\fp@loopcountii<\ar@getul{#2}\relax
+ \advance\fp@loopcountii by 1
+ \xrepeat
+% \end{macrocode}
+% The final result of the multiplication will have
+% as much afterpoint digits as "#1" and "#2" have together.
+% Adjust this.
+% \begin{macrocode}
+ \fp@tempcount=\ar@getll{#1}\relax
+ \advance\fp@tempcount by \ar@getll{#2}\relax
+ \fp@shiftright{fp@temp1}{\fp@tempcount}%
+% \end{macrocode}
+% If "#1" and "#2" have different signs, the result is negative,
+% otherwise positive.
+% \begin{macrocode}
+ \if\ar@getsig{#1}\ar@getsig{#2}%
+ \else
+ \fp@regneg{fp@temp1}%
+ \fi
+% \end{macrocode}
+% Finally, save the result via "\fp@setparam" and assign it
+% to "#1" after the end of the group.
+% \begin{macrocode}
+ \fp@regget{fp@temp1}{\fp@scratch}%
+ \fp@setparam\fp@scratch
+ }%
+ \fp@regread{#1}{\fp@param}%
+} % end \fp@regmul
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fp@regdiv}
+% The macro "\fp@regdiv" divides register "#1" by register "#2".
+% It works by repeated subtraction.
+% \begin{macrocode}
+\def\fp@regdiv#1#2{%
+ {%
+% \end{macrocode}
+% The amount of the two numbers is read into the two
+% temporary registers "fp@temp1" and "fp@temp2".
+% \begin{macrocode}
+ \fp@regcopy{fp@temp1}{#1}%
+ \fp@regcopy{fp@temp2}{#2}%
+ \fp@regabs{fp@temp1}%
+ \fp@regabs{fp@temp2}%
+% \end{macrocode}
+% First, we determine the initial shift for "fp@temp2".
+% This is the shift which will make "fp@temp2" have as many
+% digits before the decimal sign as "fp@temp1".
+% "\fp@firstnonzero" is used, because the upper limit
+% need not be the first non-zero digit.
+% \begin{macrocode}
+ \fp@firstnonzero{fp@temp1}%
+ \fp@loopcountii=\fp@param\relax
+ \fp@firstnonzero{fp@temp2}%
+ \advance\fp@loopcountii by -\fp@param\relax
+ \fp@shiftright{fp@temp2}{\fp@loopcountii}%
+% \end{macrocode}
+% Now we initialize "\fp@divnum" which will hold the result.
+% If "\fp@loopcountii" is smaller than zero, i.\,e., if
+% the first digit of the result that will be computed
+% is after the decimal sign, we have to
+% initialize "\fp@divnum" with the decimal sign as well
+% as with an appropriate number of zeros following it.
+% \begin{macrocode}
+ \def\fp@divnum{}%
+ \ifnum\fp@loopcountii<0
+ \fp@tempcount=\fp@loopcountii
+ \loop
+ \ifnum\fp@tempcount<-1
+ \edef\fp@divnum{0\fp@divnum}%
+ \advance\fp@tempcount by 1
+ \repeat
+ \edef\fp@divnum{\fp@decimalsign\fp@divnum}%
+ \fi
+% \end{macrocode}
+% The main loop follows. Each digit is determined by
+% subtracting the divisor $n$ times from the dividend until
+% the result is smaller than the divisor.
+% This is done only if "\fp@loopcountii" plus one
+% is greater than "-\fp@accuracy".
+% If the divisor is equal to the dividend, the division is complete
+% and the "\xloop" is terminated. Therefore, "\fp@accuracy" is locally
+% set to `"0"', so that possibly following zeros are computed
+% until the digit representing $10^0$.
+% At the end, the divisor is divided
+% by 10, and the next digit follows.
+% \begin{macrocode}
+ \xloop
+ \fp@tempcount=\fp@loopcountii
+ \advance\fp@tempcount by 1
+ \ifnum\fp@tempcount>-\fp@accuracy\relax
+ \fp@loopcount=0
+ \loop
+ \fp@regcomp{fp@temp2}{fp@temp1}%
+ \if\fp@param=%
+ \def\fp@accuracy{0}%
+ \gdef\fp@param{<}%
+ \fi
+ \if\fp@param<%
+ \fp@regsub@restricted{fp@temp1}{fp@temp2}%
+ \advance\fp@loopcount by 1
+ \repeat
+ \ifnum\fp@loopcountii=-1
+ \edef\fp@divnum{\fp@divnum\fp@decimalsign}%
+ \fi
+ \edef\fp@divnum{\fp@divnum\number\fp@loopcount}%
+ \fp@shiftright{fp@temp2}{-1}%
+ \advance\fp@loopcountii by -1
+ \xrepeat
+% \end{macrocode}
+% The sign of the result is set according to the
+% signs of "#1" and "#2".
+% \begin{macrocode}
+ \if\ar@getsig{#1}\ar@getsig{#2}%
+ \fp@regread{fp@temp1}{\fp@divnum}%
+ \else
+ \fp@regread{fp@temp1}{-\fp@divnum}%
+ \fi
+% \end{macrocode}
+% Now save the result in "\fp@param". After endgroup,
+% read it into "#1".
+% \begin{macrocode}
+ \fp@regget{fp@temp1}{\fp@scratch}%
+ \fp@setparam\fp@scratch
+ }%
+ \fp@regread{#1}{\fp@param}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{User interface}
+%
+% \begin{macro}{\fp@call@bin}
+% The macro "\fp@call@bin" is a common calling command
+% used by the user commands for binary operations. It reads
+% the values given in "#2" and "#3" into temporary registers,
+% performs the operation specified in "#4",
+% and finally assigns the result to the command sequence
+% given as "#1".
+% \begin{macrocode}
+\def\fp@call@bin#1#2#3#4{%
+ {%
+ \fp@regread{fp@user1}{#2}%
+ \fp@regread{fp@user2}{#3}%
+ \csname fp@reg#4\endcsname{fp@user1}{fp@user2}%
+ \fp@regget{fp@user1}{\fp@scratch}%
+ \fp@setparam\fp@scratch
+ }%
+ \edef#1{\fp@param}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fpAdd}
+% As described above, the main work is done by "\fp@call@bin",
+% so this macro reduces to passing the parameters and
+% specifying the desired operation.
+% \begin{macrocode}
+\def\fpAdd#1#2#3{\fp@call@bin{#1}{#2}{#3}{add}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fpSub}
+% Just like "\fpAdd".
+% \begin{macrocode}
+\def\fpSub#1#2#3{\fp@call@bin{#1}{#2}{#3}{sub}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fpMul}
+% Just like "\fpAdd".
+% \begin{macrocode}
+\def\fpMul#1#2#3{\fp@call@bin{#1}{#2}{#3}{mul}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fpDiv}
+% Just like "\fpAdd".
+% \begin{macrocode}
+\def\fpDiv#1#2#3{\fp@call@bin{#1}{#2}{#3}{div}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fp@call@un}
+% Similarly, the unary operations "\fpAbs" and "\fpNeg"
+% refer to the common macro "\fp@call@un".
+% \begin{macrocode}
+\def\fp@call@un#1#2#3{%
+ {%
+ \fp@regread{fp@user1}{#2}%
+ \csname fp@reg#3\endcsname{fp@user1}%
+ \fp@regget{fp@user1}{\fp@scratch}%
+ \fp@setparam\fp@scratch
+ }%
+ \edef#1{\fp@param}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fpAbs}
+% Pass the information and specify the action.
+% \begin{macrocode}
+\def\fpAbs#1#2{\fp@call@un{#1}{#2}{abs}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fpNeg}
+% Just like "\fpAbs".
+% \begin{macrocode}
+\def\fpNeg#1#2{\fp@call@un{#1}{#2}{neg}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fpRound}
+% This macro does not fit into the scheme, so it has to be defined
+% seperately.
+% \begin{macrocode}
+\def\fpRound#1#2#3{%
+ {%
+ \fpRegSet{fp@user1}{#2}%
+ \fpRegRound{fp@user1}{#3}%
+ \fpRegGet{fp@user1}{\fp@scratch}%
+ \fp@setparam\fp@scratch
+ }%
+ \edef#1{\fp@param}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fpRegSet}
+% The register operations "\fpRegSet", "\fpRegGet",
+% "\fpRegAdd", "\fpRegSub", "\fpRegMul", "\fpRegDiv",
+% "\fpRegAbs", "\fpRegNeg", "\fpRegCopy" and "\fpRegRound"
+% have the same syntax as the internal variants, so their
+% definitions reduce to passing the parameters. The register name
+% is always given as the first parameter.
+% \begin{macrocode}
+\def\fpRegSet#1#2{\fp@regread{#1}{#2}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fpRegGet}
+% As described above.
+% \begin{macrocode}
+\def\fpRegGet#1#2{\fp@regget{#1}{#2}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fpRegAdd}
+% As described above.
+% \begin{macrocode}
+\def\fpRegAdd#1#2{\fp@regadd{#1}{#2}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fpRegSub}
+% As described above.
+% \begin{macrocode}
+\def\fpRegSub#1#2{\fp@regsub{#1}{#2}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fpRegMul}
+% As described above.
+% \begin{macrocode}
+\def\fpRegMul#1#2{\fp@regmul{#1}{#2}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fpRegDiv}
+% As described above.
+% \begin{macrocode}
+\def\fpRegDiv#1#2{\fp@regdiv{#1}{#2}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fpRegAbs}
+% As described above.
+% \begin{macrocode}
+\def\fpRegAbs#1{\fp@regabs{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fpRegNeg}
+% As described above.
+% \begin{macrocode}
+\def\fpRegNeg#1{\fp@regneg{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fpRegCopy}
+% As described above.
+% \begin{macrocode}
+\def\fpRegCopy#1#2{\fp@regcopy{#1}{#2}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fpRegRound}
+% As described above.
+% \begin{macrocode}
+\def\fpRegRound#1#2{\fp@reground{#1}{#2}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fpAccuracy}
+% \begin{macro}{\fp@accuracy}
+% The user command "\fpAccuracy" "\edef"s the internal
+% parameter "\fp@accuracy", which stores the maximum
+% number of digits after the decimal sign, i.\,e.,
+% the minimum for the lower limit of fp numbers.
+% At the moment, "\fp@accuracy" does not affect the accuracy
+% of any operation except "\fp@regdiv". In fact, it was
+% introduced when the definition of a termination condition
+% for the loop was not possible without an externally given limit.
+% "\fp@accuracy" is initialized to `"5"' digits after
+% the decimal sign.
+% \begin{macrocode}
+\def\fpAccuracy#1{\edef\fp@accuracy{#1}}
+\fpAccuracy{5}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fpDecimalSign}
+% \begin{macro}{\fp@decimalsign}
+% The command "\fpDecimalSign" allows the user to select any character
+% for use as the decimal sign. The character is stored in
+% "\fp@decimalsign". Normally, the decimal sign will be either `"."' or
+% `","'; a comma is the default. (Take a look at ISO~31-0, part 3.3.2,
+% if you dislike this.)
+% \begin{macrocode}
+\def\fpDecimalSign#1{\edef\fp@decimalsign{#1}}
+\fpDecimalSign{,}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fpThousandsep}
+% \begin{macro}{\fp@thousandsep}
+% Those macros are used to define and store a thousand seperator
+% used by "\fp@regoutput". By default, there is none.
+% \begin{macrocode}
+\def\fpThousandSep#1{\edef\fp@thousandsep{#1}}
+\fpThousandSep{}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Constants}
+%
+% \begin{macro}{@0}
+% \begin{macro}{@1}
+% The number zero ist stored
+% in register "@0", the number one in register "@1".
+% \begin{macrocode}
+\fp@regread{@0}{0}
+\fp@regread{@1}{1}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+% \subsection{Finish}
+% Finally, restore the catcode of `"@"' and "\endinput".
+% \begin{macrocode}
+\catcode`\@=\atcatcode\relax
+\endinput
+%</fltmain>
+% \end{macrocode}
+% \Finale
+% \PrintIndex
+% \PrintChanges
diff --git a/macros/generic/fltpoint/fltpoint.ins b/macros/generic/fltpoint/fltpoint.ins
new file mode 100644
index 0000000000..f8e4203913
--- /dev/null
+++ b/macros/generic/fltpoint/fltpoint.ins
@@ -0,0 +1,8 @@
+\input docstrip
+\keepsilent
+\usedir{tex/latex/fltpoint}
+\generate{\file{deccomma.sty}{\from{fltpoint.dtx}{deccomma}}}
+\generate{\file{fltpoint.sty}{\from{fltpoint.dtx}{package}}}
+\usedir{tex/generic/fltpoint}
+\generate{\file{fltpoint.tex}{\from{fltpoint.dtx}{fltmain}}}
+\endbatchfile
diff --git a/macros/generic/fltpoint/fltpoint.pdf b/macros/generic/fltpoint/fltpoint.pdf
new file mode 100644
index 0000000000..0dcb3b4a32
--- /dev/null
+++ b/macros/generic/fltpoint/fltpoint.pdf
Binary files differ
diff --git a/macros/generic/iftex b/macros/generic/iftex
deleted file mode 120000
index 9466159220..0000000000
--- a/macros/generic/iftex
+++ /dev/null
@@ -1 +0,0 @@
-../latex/contrib/iftex \ No newline at end of file
diff --git a/macros/generic/iftex/README.md b/macros/generic/iftex/README.md
new file mode 100644
index 0000000000..ec8f5b74cc
--- /dev/null
+++ b/macros/generic/iftex/README.md
@@ -0,0 +1,65 @@
+# iftex
+
+## TeX Engine Detection
+
+This iftex package provides a suite of commands for detecting
+different TeX variants.
+
+For each supported engine, tests are provided of the form
+
+ \ifpdftex which is true if PDFTeX is in use and \RequirePDFTeX
+ which stops the run with an error message if PDFTeX is not being used.
+
+The package (which works with plain TeX as well as LaTeX) has tests
+for:
+
+eTeX, PDFTeX, XeTeX, LuaTeX, LuaHBTeX, pTeX, upTeX, pTeX-ng, VTeX, Aleph.
+
+
+In addition, an \iftutex test is true for XeTeX and LuaTeX, and
+an \ifpdf test is provided to test the PDF or DVI output mode.
+
+## Compatibility Packages
+
+In addition to the main iftex.sty package, small wrapper packages are
+provided
+
+ifetex.sty ifluatex.sty ifvtex.sty ifxetex.sty ifpdf.sty
+
+These include iftex and in some cases emulate some additional
+commands to allow these packages to replace the original packages in TeX
+distributions. It is recommended that new documents do not use these
+packages, but instead load iftex.sty directly.
+
+This package may be used on any format (it may be loaded into initex)
+it does not assume LaTeX.
+
+
+----
+
+This is a merger and simplification of several packages
+Based on a suggestion of Norbert Preining
+
+https://github.com/bidi-tex/iftex/issues/1
+
+
+ * ifetex: Martin Scharrer
+ * ifxetex: Will Robertson
+ * iftex: Persian TeX Group / Vafa Khalighi
+ * ifluatex, ifvtex: Heiko Oberdiek
+ * ifptex: Takayuki Yato
+ * ifpdf: Heiko Oberdiek and LaTeX3 Project
+
+
+The existing if(u)ptex packages do far more extensive testing to
+distinguish different variants which are not copied here.
+
+A document specifically for Japanese texts may need the finer grained
+tests of the ifptex package which has tests for particular versions
+of the pTeX (Japanese TeX) variant in use, and for the mode that is
+active.
+
+This generic package only has coarser tests for the tex variant in
+use, so is sufficient for example to distinguish upTeX from pTeX, and
+to distinguish both of those from LuaTeX.
+
diff --git a/macros/generic/iftex/ifetex.sty b/macros/generic/iftex/ifetex.sty
new file mode 100644
index 0000000000..51027d89c5
--- /dev/null
+++ b/macros/generic/iftex/ifetex.sty
@@ -0,0 +1,18 @@
+% Compatibility stub package for ifetex
+
+%% LaTeX3 Project
+%%
+%% This work may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either
+%% version 1.3c of this license or (at your option) any later
+%% version.
+
+% The original ifetex package was written by Martin Scharrer
+
+\ifx\RequirePackage\undefined
+ \input iftex.sty
+\else
+ \ProvidesPackage{ifetex}[2019/10/25 v1.3 ifetex legacy package. Use iftex instead.]
+ \RequirePackage{iftex}
+ \newcommand*\NeedsETeX[1][]{\RequireeTeX}
+\fi
diff --git a/macros/generic/iftex/ifluatex.sty b/macros/generic/iftex/ifluatex.sty
new file mode 100644
index 0000000000..e762e8281f
--- /dev/null
+++ b/macros/generic/iftex/ifluatex.sty
@@ -0,0 +1,17 @@
+% Compatibility stub package for ifluatex
+
+%% LaTeX3 Project
+%%
+%% This work may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either
+%% version 1.3c of this license or (at your option) any later
+%% version.
+
+% The original ifluatex package was written by Heiko Oberdiek
+
+\ifx\RequirePackage\undefined
+ \input iftex.sty
+\else
+ \ProvidesPackage{ifluatex}[2019/10/25 v1.5 ifluatex legacy package. Use iftex instead.]
+ \RequirePackage{iftex}
+\fi
diff --git a/macros/generic/iftex/ifpdf.sty b/macros/generic/iftex/ifpdf.sty
new file mode 100644
index 0000000000..ec500fba25
--- /dev/null
+++ b/macros/generic/iftex/ifpdf.sty
@@ -0,0 +1,17 @@
+% Compatibility stub package for ifpdf
+
+%% LaTeX3 Project
+%%
+%% This work may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either
+%% version 1.3c of this license or (at your option) any later
+%% version.
+
+% The original ifpdf package was written by Heiko Oberdiek
+
+\ifx\RequirePackage\undefined
+ \input iftex.sty
+\else
+ \ProvidesPackage{ifpdf}[2019/10/25 v3.4 ifpdf legacy package. Use iftex instead.]
+ \RequirePackage{iftex}
+\fi
diff --git a/macros/generic/iftex/iftex.pdf b/macros/generic/iftex/iftex.pdf
new file mode 100644
index 0000000000..cbb7b48ec5
--- /dev/null
+++ b/macros/generic/iftex/iftex.pdf
Binary files differ
diff --git a/macros/generic/iftex/iftex.sty b/macros/generic/iftex/iftex.sty
new file mode 100644
index 0000000000..8306f8663a
--- /dev/null
+++ b/macros/generic/iftex/iftex.sty
@@ -0,0 +1,241 @@
+%% iftex TeX engine tests
+
+%% LaTeX3 Project
+%%
+%% This work may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either
+%% version 1.3c of this license or (at your option) any later
+%% version.
+%%
+%% Using ideas from:
+%%
+%% ifetex Martin Scharrer
+%% ifxetex Will Robertson
+%% iftex 0.2 Persian TeX Group / Vafa Khalighi
+%% ifluatex ifvtex Heiko Oberdiek
+%% ifptex Takayuki YATO
+%% ifpdf Heiko Oberdiek and LaTeX3 Project
+
+% Only load once (not needed in LaTeX, but does no harm).
+\csname IFTEX\string @loaded\endcsname
+\expandafter\let\csname IFTEX\string @loaded\endcsname\endinput
+
+% File loadable in initex
+% require { } # with standard catcodes.
+\catcode123=1
+\catcode125=2
+\catcode35=6
+
+
+% ProvidesPackage declaration in LaTeX
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname ProvidesPackage\endcsname\relax\else
+ \ProvidesPackage{iftex}[2020/03/06 v1.0d TeX engine tests]
+\fi
+
+% Save @ catcode, to restore at end, not needed in LaTeX.
+\expandafter\chardef\csname IFTEX\string @atcatcode\endcsname\catcode64
+\catcode 64 11
+
+% Message format used in several pre-existing if*tex packages
+% Modified here to do a hard stop and not show any error context lines.
+\def\IFTEX@Require#1#2#3{%
+ #1\else
+ \newlinechar 64\relax
+ \errorcontextlines -1\relax
+ \immediate\write20{@
+ ********************************************@
+ * #2 is required to compile this document.@
+ * Sorry!@
+ ********************************************}%
+ \batchmode\read -1 to \@tempa
+ #3%
+}
+
+
+% eTeX \protected if available.
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname protected\endcsname\relax
+ \let\IFTEX@protected\relax
+\else
+ \let\IFTEX@protected\protected
+\fi
+
+% make sure \detokenize and \protected are available in lualatex,
+% but avoid defining them after the package if not already defined.
+ {
+ \catcode34 12 % "
+ \catcode40 12 % (
+ \catcode41 12 % )
+ \catcode44 12 % ,
+ \catcode46 12 % .
+ \expandafter\ifx\csname directlua\endcsname\relax\else
+ \directlua{tex.enableprimitives("IFTEX@", {"detokenize","protected"})}
+ \fi
+ }
+
+% \Require... commands that stop if the wrong engine detected.
+\IFTEX@protected\def\RequireeTeX{\IFTEX@Require\ifetex{eTeX}\fi}
+\IFTEX@protected\def\RequirePDFTeX{\IFTEX@Require\ifpdftex{pdfTeX}\fi}
+\IFTEX@protected\def\RequireXeTeX{\IFTEX@Require\ifxetex{XeTeX}\fi}
+\IFTEX@protected\def\RequireLuaTeX{\IFTEX@Require\ifluatex{LuaTeX}\fi}
+\IFTEX@protected\def\RequireLuaHBTeX{\IFTEX@Require\ifluahbtex{LuaHBTeX}\fi}
+\IFTEX@protected\def\RequirepTeX{\IFTEX@Require\ifptex{pTeX}\fi}
+\IFTEX@protected\def\RequireupTeX{\IFTEX@Require\ifuptex{upTeX}\fi}
+\IFTEX@protected\def\RequirepTeXng{\IFTEX@Require\ifptexng{pTeX-ng}\fi}
+\IFTEX@protected\def\RequireVTeX{\IFTEX@Require\ifvtex{VTeX}\fi}
+% alephtex as aleph name too generic
+\IFTEX@protected\def\RequireAlephTeX{\IFTEX@Require\ifalephtex{Aleph}\fi}
+% tutex == has \Umathchardef == XeTeX or Lua(HB)TeX currently
+\IFTEX@protected\def\RequireTUTeX{\IFTEX@Require\iftutex{LuaTeX or XeTeX}\fi}
+
+
+% As a matter of policy over-write any existing \if*tex macro and set
+% by the tests here.
+
+% \csname and \let construct useful for hiding \ifzzz tokens from
+% outer level \if tests.
+\def\IFTEX@let#1#2{%
+ \expandafter\let\csname if#1\expandafter\endcsname
+ \csname if#2\endcsname}
+
+% etex (should always be true in latex based formats)
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname numexpr\endcsname\relax
+ \IFTEX@let{etex}{false}
+\else
+ \IFTEX@let{etex}{true}
+\fi
+\IFTEX@let{eTeX}{etex}
+
+% pdftex (including in dvi mode)
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname pdftexversion\endcsname\relax
+ \IFTEX@let{pdftex}{false}
+\else
+ \IFTEX@let{pdftex}{true}
+\fi
+\IFTEX@let{PDFTeX}{pdftex}
+
+% xetex
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname XeTeXrevision\endcsname\relax
+ \IFTEX@let{xetex}{false}
+\else
+ \IFTEX@let{xetex}{true}
+\fi
+\IFTEX@let{XeTeX}{xetex}
+
+
+% luatex (including luahbtex)
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname directlua\endcsname\relax
+ \IFTEX@let{luatex}{false}
+\else
+ \IFTEX@let{luatex}{true}
+\fi
+\IFTEX@let{LuaTeX}{luatex}
+
+
+% luahbtex (or luatex + luaharfbuzz)
+% Use luaharfbuzz test rather than status.luatex_engine=="luahbtex"
+% for issue #2.
+\IFTEX@let{luahbtex}{false}
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname directlua\endcsname\relax
+\else
+ \directlua{\IFTEX@detokenize{
+ if(pcall(require, 'luaharfbuzz')) then
+ tex.print("\\let\\ifluahbtex\\iftrue ")
+ end
+ }}
+
+\fi
+\IFTEX@let{LuaHBTeX}{luahbtex}
+
+
+% ptex (including all variants)
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname kanjiskip\endcsname\relax
+ \IFTEX@let{ptex}{false}
+\else
+ \IFTEX@let{ptex}{true}
+\fi
+\IFTEX@let{pTeX}{ptex}
+
+% uptex (including euptex)
+\ifx\enablecjktoken \@undefined
+ \IFTEX@let{uptex}{false}
+\else
+ \IFTEX@let{uptex}{true}
+\fi
+\IFTEX@let{upTeX}{uptex}
+
+% ptex-ng
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname ngbanner\endcsname\relax
+ \IFTEX@let{ptexng}{false}
+\else
+ \IFTEX@let{ptexng}{true}
+\fi
+\IFTEX@let{pTeXng}{ptexng}
+
+% vtex
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname VTeXversion\endcsname\relax
+ \IFTEX@let{vtex}{false}
+\else
+ \IFTEX@let{vtex}{true}
+\fi
+\IFTEX@let{VTeX}{vtex}
+
+% aleph
+\IFTEX@let{alephtex}{false}
+\ifptex\else
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname omathchardef\endcsname\relax
+\else
+ \IFTEX@let{alephtex}{true}
+\fi
+\fi
+\IFTEX@let{AlephTeX}{alephtex}
+
+
+% tutex (LuaTeX or XeTeX)
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname Umathchardef\endcsname\relax
+ \IFTEX@let{tutex}{false}
+\else
+ \IFTEX@let{tutex}{true}
+\fi
+\IFTEX@let{TUTeX}{tutex}
+
+% Output mode
+% declare as if with \newif
+\def\pdftrue{\let\ifpdf\iftrue}
+\def\pdffalse{\let\ifpdf\iffalse}
+\pdffalse
+\ifluatex
+\directlua{\IFTEX@detokenize{
+if (tex.outputmode or tex.pdfoutput or 0) > 0 then
+ tex.print('\\pdftrue')
+end
+}}
+\else
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname pdfoutput\endcsname\relax
+\ifvtex
+ \ifnum\OpMode=3 %
+ \pdftrue
+ \fi
+\fi
+\else
+ \ifnum\pdfoutput>0 %
+ \pdftrue
+ \fi
+\fi
+\fi
+
+
+% restore things
+\catcode64 \IFTEX@atcatcode
diff --git a/macros/generic/iftex/iftex.tex b/macros/generic/iftex/iftex.tex
new file mode 100644
index 0000000000..8e13546e77
--- /dev/null
+++ b/macros/generic/iftex/iftex.tex
@@ -0,0 +1,199 @@
+\documentclass{article}
+\usepackage[T1]{fontenc}
+\usepackage{hyperref}
+\hypersetup{colorlinks}
+\usepackage{iftex}
+
+\title{The iftex package}
+\author{The \LaTeX\ Project Team\thanks{%
+\url{https://github.com/latex3/iftex}}}
+
+\date{\csname ver@iftex.sty\endcsname}
+
+\newcommand\cs[1]{{\ttfamily\textbackslash #1}}
+\renewcommand*\descriptionlabel[1]{\makebox[\dimexpr\textwidth][l]{%
+ \normalfont\bfseries #1}}
+
+\begin{document}
+
+\maketitle
+\tableofcontents
+
+
+\section{Introduction}
+This original \textsf{iftex} was written as part of the \textsf{bidi}
+collection (by the Persian TeX Group / Vafa Khalighi)
+and provided checks for whether a document was being
+processed with PDF\TeX, or Xe\TeX, or Lua\TeX. This version recodes
+the package and incorporates similar tests from the \textsf{ifetex}
+package by Martin Scharrer, the \textsf{ifxetex} package by Will
+Robertson, the \textsf{ifluatex} and \textsf{ifvtex}
+packages from Heiko Oberdiek and parts of \textsf{ifptex} by Takayuki
+Yato.
+
+For each \TeX\ variant engine supported two commands are provided:
+\begin{itemize}
+\item
+ a conditional, \verb|\iffootex| that is true if the \textsf(footex)
+engine (or a compatible extension) is being used.
+
+For compatibility with earlier packages which did not all use the same
+naming convention all these conditionals are provided in two forms, a
+lowercase name \verb|\iffootex| and a mixed case name \verb|\iffooTeX|.
+
+\item a command \verb|RequireFooTeX| which checks that \textsf{footex}
+ is being used, and stops the run with an error message if a
+ different engine is detected.
+\end{itemize}
+
+\section{Loading the package}
+The package can be loaded in the usual way in both Plain \TeX\ and \LaTeX.
+\subsection{Loading the package in plain \TeX}
+\begin{verbatim}
+\input iftex.sty
+\end{verbatim}
+
+\subsection{Loading the package in \LaTeX}
+\begin{verbatim}
+\usepackage{iftex}
+\end{verbatim}
+
+\subsection{Loading the package in ini\TeX}
+The package assumes no existing macros and may be loaded
+during format setup in a format without the plain \TeX\ or \LaTeX\
+format being loaded. From an initial ini\TeX\ setup the package may
+be loaded as for plain \TeX.
+
+\section{Engine test conditionals}
+All the conditionals defined here are used in the same way:
+\begin{verbatim}
+\ifluatex
+ luatex specific code
+\else
+ code for other engines
+\fi
+\end{verbatim}
+
+
+
+\begin{description}
+\item[\cs{ifetex}, \cs{ifeTeX}]
+True if an e\TeX\ enabled format is in use. (This is necessarily true
+in all \LaTeX\ variants.)
+\item[\cs{ifpdftex}, \cs{ifPDFTeX}]
+True if PDF\TeX\ is in use (whether writing PDF or DVI), so this is
+true for documents processed with both the \textsf{latex} and
+\textsf{pdflatex} commands.
+\item[\cs{ifxetex}, \cs{ifXeTeX}]
+True if Xe\TeX\ is in use.
+\item[\cs{ifluatex}, \cs{ifLuaTeX}]
+True if Lua\TeX\ and extensions such as LuaHB\TeX\ are in use.
+\item[\cs{ifluahbtex}, \cs{ifLuaHBTeX}]
+True if the \textsf{luaharftex} Lua module is available.
+This will be true in \textsf{luahbtex} and may be true in
+\textsf{luatex} if a binary Lua \textsf{luaharftex} module has been
+compiled and is available in Lua's search path.
+\item[\cs{ifptex}, \cs{ifpTeX}]
+True if any of the p\TeX\ variants are in use.
+\item[\cs{ifuptex}, \cs{ifupTeX}]
+True if any of the up\TeX\ variants are in use. (\verb|\ifetex| could
+be used in addition to distinguish \textsf{uptex} and \textsf{euptex}.)
+\item[\cs{ifptexng}, \cs{ifpTeXng}]
+True if p\TeX-ng (Asiatic p\TeX) is in use.
+\item[\cs{ifvtex}, \cs{ifVTeX}]
+True if V\TeX\ is in use.
+\item[\cs{ifalephtex}, \cs{ifAlephTeX}]
+True if Aleph is in use. (The \textsf{aleph}-based \LaTeX\ command is
+\textsf{lamed}.)
+\item[\cs{iftutex}, \cs{ifTUTeX}]
+This is not strictly an engine variant, but it is true if
+\verb|\Umathchardef| is available, which essentially means that it is
+true for Lua\TeX\ and Xe\TeX, allowing constructs such as
+\begin{verbatim}
+\iftutex
+ \usepackage{fontspec}
+ \setmainfont{TeX Gyre Termes}
+ \usepackage{unicode-math}
+ \setmathfont{Stix Two Math}
+\else
+ \usepackage{newtxtext,newtxmath}
+\fi
+\end{verbatim}
+
+\end{description}
+
+\section{Requiring specific engines}
+For each supported engine, the package provides a command
+\verb|\Require...| which checks that the document is being processed
+with a suitable engine, and stops with an error message if not.
+
+\begin{description}
+\item[\cs{RequireeTeX}]
+\item[\cs{RequirePDFTeX}]
+\item[\cs{RequireXeTeX}]
+\item[\cs{RequireLuaTeX}]
+\item[\cs{RequireLuaHBTeX}]
+\item[\cs{RequirepTeX}]
+\item[\cs{RequireupTeX}]
+\item[\cs{RequirepTeXng}]
+\item[\cs{RequireVTeX}]
+\item[\cs{RequireAlephTeX}]
+\item[\cs{RequireTUTeX}]
+\end{description}
+
+
+\section{Output mode conditional}
+This package also provides an \verb|\ifpdf| conditional that is true
+if the format is set up to output in PDF mode rather than DVI. This is
+equivalent to the test in the existing \textsf{ifpdf} package.
+
+Unlike the engine tests above this is defined as if by \verb|\newif|
+with user-documented commands \verb|\pdftrue| and \verb|\pdffalse| that can
+change the boolean value. These would be needed to reset the boolean
+if the output mode is reset (for example by setting
+\verb|\pdfoutput=0| in PDF\LaTeX).
+
+Unlike the original \textsf{ifpdf} package, the version here also
+detects PDF output mode if running in V\TeX.
+
+\section{Additional packages}
+This extended \textsf{iftex} is designed to replace the original
+\textsf{iftex} and also the packages
+\textsf{ifetex},
+\textsf{ifluatex},
+\textsf{ifvtex},
+\textsf{ifxetex},
+\textsf{ifpdf}.
+
+This collection includes small packages with these names that include
+the main \textsf{iftex} package, and in some cases define additional
+commands for increased compatibility. These packages should mean that
+authors do not need to change existing documents, although it is
+recommended that new documents use the \textsf{iftex} package
+directly.
+
+
+Note that while this package provides basic support for detecting
+p\TeX\ (Japanese \TeX) variants and is broadly compatible with the
+\textsf{ifptex} package, the \textsf{ifptex} package has many more detailed
+tests for p\TeX\ variants and this package does \emph{not} replace the
+\textsf{ifptex} (or \textsf{ifxptex}) packages, which are maintained
+by their original authors and recommended for Japanese documents that
+need fine control over the Japanese \TeX\ system in use.
+
+\section{Compatibility with \textsf{scrbase}}
+The \textsf{scrbase} package (which is automatically included in the
+popular \textsf{KOMA-Script} classes) by default defines
+\verb|\ifpdftex| and \verb|\ifVTeX| with a different syntax. If you
+use the \textsf{scrbase} option \verb|internalonly| then
+\textsf{scrbase} will not define these and the definitions as
+described here will take effect. This is recommended and will not
+affect any \textsf{scrbase} package code as internally
+\textsf{scrbase} uses private versions of those commands prefixed with
+\verb|\scr@|. However this package detects if the \textsf{scrbase}
+definitions are in effect and if so does not redefine them, for
+compatibility with existing documents. The \textsf{iftex} versions
+will still be available under the names \verb|\ifPDFTeX| and
+\verb|\ifvtex|.
+
+\end{document}
diff --git a/macros/generic/iftex/ifvtex.sty b/macros/generic/iftex/ifvtex.sty
new file mode 100644
index 0000000000..109cf1cc09
--- /dev/null
+++ b/macros/generic/iftex/ifvtex.sty
@@ -0,0 +1,45 @@
+% Compatibility stub package for ifvtex
+
+%% LaTeX3 Project
+%%
+%% This work may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either
+%% version 1.3c of this license or (at your option) any later
+%% version.
+
+% The original ifvtex package was written by Heiko Oberdiek
+
+\ifx\RequirePackage\undefined
+ \input iftex.sty
+\else
+ \ProvidesPackage{ifvtex}[2019/10/25 v1.7 ifvtex legacy package. Use iftex instead.]
+ \RequirePackage{iftex}
+\fi
+
+
+\IFTEX@let{vtexdvi}{false}
+\IFTEX@let{vtexpdf}{false}
+\IFTEX@let{vtexps}{false}
+\IFTEX@let{vtexhtml}{false}
+\IFTEX@let{vtexgex}{false}
+
+\ifvtex
+ \ifcase\OpMode\relax
+ \IFTEX@let{vtexdvi}{true}
+ \or % 1
+ \IFTEX@let{vtexpdf}{true}
+ \or % 2
+ \IFTEX@let{vtexps}{true}
+ \or % 3
+ \IFTEX@let{vtexps}{true}
+ \or\or\or\or\or\or\or % 10
+ \IFTEX@let{vtexhtml}{true}
+ \fi
+ \begingroup\expandafter\expandafter\expandafter\endgroup
+ \expandafter\ifx\csname gexmode\endcsname\relax
+ \else
+ \ifnum\gexmode>0 %
+ \IFTEX@let{vtexgex}{true}
+ \fi
+ \fi
+\fi
diff --git a/macros/generic/iftex/ifxetex.sty b/macros/generic/iftex/ifxetex.sty
new file mode 100644
index 0000000000..8261ec2671
--- /dev/null
+++ b/macros/generic/iftex/ifxetex.sty
@@ -0,0 +1,17 @@
+% Compatibility stub package for ifxetex
+
+%% LaTeX3 Project
+%%
+%% This work may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either
+%% version 1.3c of this license or (at your option) any later
+%% version.
+
+% The original ifxetex package was written by Will Robertson
+
+\ifx\RequirePackage\undefined
+ \input iftex.sty
+\else
+ \ProvidesPackage{ifxetex}[2019/10/25 v0.7 ifxetex legacy package. Use iftex instead.]
+ \RequirePackage{iftex}
+\fi
diff --git a/macros/generic/localloc b/macros/generic/localloc
deleted file mode 120000
index 7af85ed8d9..0000000000
--- a/macros/generic/localloc
+++ /dev/null
@@ -1 +0,0 @@
-../latex/contrib/localloc \ No newline at end of file
diff --git a/macros/generic/localloc/localloc.README b/macros/generic/localloc/localloc.README
new file mode 100644
index 0000000000..395102aeae
--- /dev/null
+++ b/macros/generic/localloc/localloc.README
@@ -0,0 +1,43 @@
+Readme File for the package `localloc' by Bernd Raichle
+Copyright (C) 1991,1994,1995 Bernd Raichle. All rights reserved.
+
+ The `localloc' package reimplements plain-TeX's basic allocation
+macros to allow local allocation of registers. It can be used with
+ * plain-TeX,
+ * LaTeX2e,
+ * LaTeX 2.09,
+and all other formats which are based on plain-TeX.
+ In the past people complained about the restriction of 256
+registers imposed by TeX and want either more registers or a more
+clever way to maintain this limited resource. This package shows
+and implements a mechanism which doesn't remove this restrictions
+but allows local allocation of registers. Using this mechanism
+you can often replace global register allocations by ones local
+to a group allowing the register to be used for other purposes
+after the group is left.
+
+
+Installation:
+-------------
+
+This package contains 2 files, namely
+ * localloc.README This README file
+ * localloc.dtx The docstrip archive file containing the
+ source for the macro file `localloc.sty'
+ and the documentation.
+
+To unpack the archive file you need `docstrip.tex' version 2.x or
+newer. You can find this file in the LaTeX2e release; it can be
+used with plain-TeX _and_ LaTeX. Run `localloc.dtx' through
+plainTeX or LaTeX to unpack the archive file:
+ tex localloc.dtx
+or
+ latex localloc.dtx
+
+
+This package is supported by
+
+Bernd Raichle
+Stettener Str. 73
+D-73732 Esslingen, FRG
+Email: raichle@Informatik.Uni-Stuttgart.DE
diff --git a/macros/generic/localloc/localloc.dtx b/macros/generic/localloc/localloc.dtx
new file mode 100644
index 0000000000..ad770b5d85
--- /dev/null
+++ b/macros/generic/localloc/localloc.dtx
@@ -0,0 +1,1026 @@
+% \iffalse
+%
+% Package `localloc' to use with LaTeX 2e/2.09 and plain-TeX
+% Copyright (C) 1991,1994,1995 Bernd Raichle. All rights reserved.
+%
+%
+% Copying of this file is authorized only if either
+% (1) you make absolutely no changes to your copy, including name, or
+% (2) if you do make changes, you name it something other than
+% localloc.dtx, localloc.doc, localloc.tex, or localloc.sty.
+% This restriction helps ensure that all styles developed here
+% remain identical.
+%
+% Error reports in case of UNCHANGED versions please to:
+% Bernd Raichle
+% Stettener Str. 73
+% D-73732 Esslingen
+% Federal Republic of Germany
+% Email: raichle@Informatik.Uni-Stuttgart.DE
+%
+%
+% ========== INSTALLATION GUIDE: ==========
+%
+% The complete distribution consists of a set of files, which are
+% packed and documented in _one_ `docstrip archive file' called
+% `localloc.dtx' (the file you are currently reading). This archive
+% file can be unpacked to create the necessary files containing the
+% macros, documentation, etc.
+%
+% To unpack the archive file you need:
+%
+% * `localloc.dtx' (it is the file you are currently reading)
+%
+% * `docstrip.tex' version 2.x or newer
+% (You can find this file in the LaTeX 2e release.)
+%
+% Then run `localloc.dtx' through plainTeX or LaTeX to unpack the
+% archive file:
+%
+% tex localloc.dtx
+% or
+% latex localloc.dtx
+%
+% This will create a set of file which contain the macro code or
+% code to produce the documentation of the `localloc' package.
+%
+% --------------- start of docstrip archive file ------------------
+% \fi
+%
+% \CheckSum{369}
+%
+% \iffalse
+%<*install>
+\def\batchfile{localloc.dtx}
+\input docstrip.tex
+\preamble
+
+This is a file of the `localloc' package reimplementing
+plain-TeX's and LaTeX's basic allocation macros to allow
+local allocation of registers.
+
+-- Copyright (C) 1991-1995 Bernd Raichle. All rights reserved --
+
+This package is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+
+IMPORTANT NOTICE:
+
+Copying of this file is authorized only if either
+(1) you make absolutely no changes to your copy, including name, or
+(2) if you do make changes, you name it something other than
+ localloc.dtx, localloc.doc, localloc.tex, or localloc.sty.
+
+For error reports see original source file `localloc.dtx'.
+
+\endpreamble
+%\generateFile{localloc.ins}{t}{\from{localloc.dtx}{install}}
+\generateFile{localloc.sty}{t}{\from{localloc.dtx}{package}}
+\generateFile{localloc.drv}{t}{\from{localloc.dtx}{driver}}
+\generateFile{localtst.tex}{t}{\from{localloc.dtx}{test}}
+
+\Msg{***********************************************************}
+\Msg{*}
+\Msg{* To finish the installation you have to move the following}
+\Msg{* file into a directory searched by TeX:}
+\Msg{*}
+\Msg{* \space\space localloc.sty}
+\Msg{*}
+\Msg{* To produce the documentation of this archive file run the}
+\Msg{* file `localloc.drv' through LaTeX 2e:}
+\Msg{*}
+\Msg{* \space\space latex localloc.drv}
+\Msg{*}
+\Msg{* Happy TeXing}
+\Msg{***********************************************************}
+\relax\endinput
+%</install>
+% \fi
+%
+% \changes{v1.1b}{95/09/24}{Released after a long sleep in my
+% archives; prefixed some tokens with \cs{lcllc@}.}
+% \changes{v1.1a}{94/10/16}{English documentation; added support for
+% \LaTeXe; added self unpacking archive code.}
+% \changes{v1.0b}{91/09/06}{Error in \cs{newinsert}: consecutive calls
+% return the same insertion register number.}
+% \changes{v1.0a}{91/09/04}{All macros in {plain.tex} replaced.}
+%
+% \DoNotIndex{\fileversion,\filedate,\docdate,\filename}
+% \DoNotIndex{\begingroup,\endgroup,\def,\relax}
+% \DoNotIndex{\ifnum,\ifcase,\else,\fi}
+% \DoNotIndex{\expandafter,\the}
+% \DoNotIndex{\@ne,\m@ne,\next}
+%
+%
+% \newcommand{\PiCTeX}{\protect\pPiCTeX}
+% \newcommand{\pPiCTeX}{\relax
+% P\kern-.12em\lower.5ex\hbox{I}\kern-.075emC\kern-.11em\TeX}
+%
+%
+% \title{An Enhanced Implementation of the Allocation Macros in \LaTeXe,
+% \LaTeX~2.09, and plain-\TeX}
+% \date{\filedate~(\fileversion)}
+% \author{Bernd Raichle\\
+% Stettener Str.~73\\
+% D-73732 Esslingen, FRG\\
+% Email: {\tt raichle@Informatik.Uni-Stuttgart.DE}}
+%
+% \maketitle
+%
+% \begin{abstract}
+% This style option reimplements the allocation command macros
+% provided by plain-\TeX\ and adds macros to allow allocation
+% of local registers inside groups.
+% \end{abstract}
+%
+%^^A \tableofcontents
+%
+% \section{Introduction}
+%
+% \subsection{Restrictions of {\tt plain.tex}'s Register Allocation Macros}
+%
+% In {\tt plain.tex}, Donald E.\ Knuth writes about the macros for
+% register allocation~\cite[lines 149ff]{plain.tex-3.14159}:
+% \begin{quote}
+% When a register is used only temporarily, it need not be
+% allocated; grouping can be used, making the value previously in
+% the register return after the close of the group. The main use
+% of these macros is for registers that are defined by one macro
+% and used by others, possibly at different nesting levels. All
+% such registers should be defined through these macros; otherwise
+% conflicts may occur, especially when two or more more macro
+% packages are being used at once.
+% \end{quote}
+% Additional remarks can be read in the TeXbook~\cite[p.~346]{DEK91}:
+% \begin{quote}
+% {\it Allocation of registers.\/} The second major part of the
+% {\tt plain.tex} file provides a foundation on which systems of
+% independently developed macros can coexist peacefully without
+% interfering in their usage of registers. The idea is that macro
+% writers should abide by the macro conventions following ground
+% rules: [\ldots]
+% (4)~Furthermore, it's possible to use any register in a group, if
+% you ensure that \TeX's grouping mechanism will restore the
+% register when you're done with the group, and if you are certain
+% that other macros will not make global assignments to that
+% register when you need it. \
+% (5)~But when a register is used by several macros, or over long
+% spans of time, it should be allocated by \verb+\newcount+,
+% \verb+\newdimen+, \verb+\newbox+, etc. \ (6)~Similar remarks apply
+% [\ldots]
+% to insertions (which require \verb+\box+, \verb+\count+,
+% \verb+\dimen+, and \verb+\skip+ registers all having the same
+% number).
+% \end{quote}
+%
+% This means, that within plain-\TeX\ and all formats based on
+% plain-\TeX\ a user can not allocate a register for temporary use
+% using the given mechanisms. Nonetheless there is often the need
+% for a allocated register which is only used within a rather small
+% piece of document text and should be set free for reuse in the rest
+% of the formatting run:
+%
+% If a macro~\verb+\macroa+ needs a register which should never be
+% destroyed by another macro~\verb+\macrob+ which is called by
+% \verb+\macroa+, you either have to know about the realisation of
+% \verb+\macrob+ or you have to allocate a new register.
+%
+% The name of this newly allocated register is only known to the
+% macro package in which macro~\verb+\macroa+ resides. If you have
+% a lot of macros which needs registers by their own it is possible
+% that all of the 256~registers of one type will be allocated. In
+% most cases it would be possible to share some of these registers by
+% more than one macro because the register is only needed within (an
+% environment delimited by) a group. To share registers---if they are
+% used only locally---it will be necessary to provide a mechanism to
+% allocate registers locally. Unfortunately {\tt plain.tex} and all
+% derived formats, like \LaTeX, misses this mechanism leading to the
+% problem that some macro packages cannot be combined.
+%
+% In the following example it is necessary to call two macros
+% |\macroa| and |macrob| in the same group (e.g.\ because |\macroa|
+% performs special actions at the begin and |\macrob| at the end of
+% an environment). Further you do not have any knowledge about the
+% use of scratch register in |\macroa|, |\macrob| or the text in the
+% argument specified by the user. Therefore it is impossible to use
+% a scratch register to save the current value of |\hsize|; we have
+% to allocate a new register to save it.
+%\begin{verbatim}
+% \newdimen\savedhsize
+%\end{verbatim}
+%\begin{verbatim}
+% \def\callAandB#1{\begingroup
+% \savedhsize=\hsize
+% \hsize=0.8\hsize \macroa
+% #1\relax
+% \hsize=\savedhsize \macrob
+% \endgroup}
+%\end{verbatim}
+% If there will be a mechanism, e.g. by a macro |\lnewdimen|, to
+% allocate a local register it is possible to use this local register
+% inside the group without worrying about possible dependencies
+% between the macros and the user specified text. Additionally after
+% leaving the group, the dimen register will be free to be used by
+% other macros.
+%\begin{verbatim}
+% \def\callAandB#1{\begingroup
+% \lnewdimen\savedhsize \savedhsize=\hsize
+% \hsize=0.8\hsize \macroa
+% #1\relax
+% \hsize=\savedhsize \macrob
+% \endgroup}
+%\end{verbatim}
+%
+%
+% \subsection{Local Register Allocation Macros}
+%
+% \DescribeMacro{\newcount}
+% \DescribeMacro{\newdimen}
+% \DescribeMacro{\newskip}
+% \DescribeMacro{\newbox}
+% {\let\newinsert=\relax \DescribeMacro{\newinsert}}^^A
+% When using this reimplementation of the allocation macros, the {\tt
+% plain.tex} macros |\newcount|, |\newdimen|, |\newskip|, and
+% |\newbox| will have a changed behaviour in two aspects:
+% \begin{itemize}
+% \item Do not assume that registers which are allocated consecutively
+% have consecutive register numbers. In general you should not
+% make any assumption about the order of register numbers.
+% \item It is possible that a register was locally allocated and used
+% in the past. After leaving the group the register is set to free
+% and the old value---normally zero---is restored. Nonetheless
+% you should not assume that a newly allocated register is
+% initialised with the value zero.
+% \end{itemize}
+%
+% {\let\newmuskip=\relax \DescribeMacro{\newmuskip}}
+% {\let\newtoks=\relax \DescribeMacro{\newtoks}}^^A
+% The behaviour of the macros |\newmuskip| and |\newtoks| are not
+% changed because they are not used for insertions. Nonetheless this
+% can be changed in a future version.
+%
+% \DescribeMacro{\lnewcount}
+% \DescribeMacro{\lnewdimen}
+% \DescribeMacro{\lnewskip}
+% \DescribeMacro{\lnewmuskip}
+% \DescribeMacro{\lnewbox}
+% \DescribeMacro{\lnewtoks}
+% |\lnewcount|, |\lnewdimen|, |\lnewskip|, |\lnewmuskip|, |\lnewbox|,
+% and |\lnewtoks| are the set of new macros to allocate registers
+% within the scope of the current group. At the end of the current
+% group the allocated register is freed.
+%
+% As with their global counterparts you should not assume that the
+% registers are allocated in a consecutive order---neither increasing
+% nor decreasing---or that the allocated register is initialised with
+% zero.
+%
+%
+% \subsection{Usage Examples}
+%
+% \subsubsection{\LaTeX's Picture Environment}
+%
+% \LaTeX's picture environment uses the box register |\@picbox| and
+% the dimen register |\@picht| to save the contents of a picture and
+% the user specified height of this picture at the beginning of the
+% environment. These two registers are set at the beginning and used
+% at the end of the |picture| environment. Because the two registers
+% are used nowhere else, it is possible to share them by only
+% allocating them within the environment.
+%
+% This is the simplified code for the |\begin{picture}| and
+% |\end{picture}| commands; the macros |\begin| and |\end| start and
+% end a new group:
+%\begin{verbatim}
+%\newbox\@picbox
+%\newdimen\@picht
+%\end{verbatim}
+%\begin{verbatim}
+%\def\picture(#1,#2){%
+% \@picht = #2\unitlength % save picture height
+% \setbox\@picbox = \hbox to #1\unitlength\bgroup
+% \ignorespaces}
+%\end{verbatim}
+%\begin{verbatim}
+%\def\endpicture{%
+% \hss
+% \egroup % close picture box
+% \ht\@picbox = \@picht % set box height to save picture height
+% \dp\@picbox = 0pt % set box depth to 0pt
+% \mbox{\box\@picbox}} % output this box
+%\end{verbatim}
+%
+% Using the new local allocation macros the code changes is simple:
+% Move the |\newbox| and |\newdimen| command within the |\picture|
+% macro definition and rename them to |\lnewbox| and |\lnewdimen|:
+%\begin{verbatim}
+% %\newbox\@picbox
+% %\newdimen\@picht
+%\end{verbatim}
+%\begin{verbatim}
+%\def\picture(#1,#2){%
+% \lnewbox\@picbox
+% \lnewdimen\@picht
+% \@picht = #2\unitlength % save picture height
+% \setbox\@picbox = \hbox to #1\unitlength\bgroup
+% \ignorespaces}
+%\end{verbatim}
+%
+% Additionally we can use a property of the usage pattern of these
+% two registers:
+% Within a nested use of the |picture| environment---you can use
+% subpictures within a picture---these registers are allocated for
+% each nesting level. This is not really necessary because the box
+% and the dimen register is always used in a group and is never
+% changed globally.
+% It is possible to add tests to avoid a (local) reallocation of
+% these registers:
+%\begin{verbatim}
+%\let\@picbox=\relax % mark register as not yet allocated
+%\let\@picht =\relax % mark register as not yet allocated
+%\end{verbatim}
+%\begin{verbatim}
+%\def\picture(#1,#2){%
+% \ifx\@picbox\relax \lnewbox\@picbox \fi
+% \ifx\@picht\relax \lnewdimen\@picht \fi
+% \@picht = #2\unitlength % save picture height
+% \setbox\@picbox = \hbox to #1\unitlength\bgroup
+% \ignorespaces}
+%\end{verbatim}
+%
+%
+% \subsubsection{\LaTeX's {\tt\protect\bslash multiput} Macro}
+%
+% Another example of registers which are used only in one rarely
+% used macro, are the count register |\@multicnt| and the two dimen
+% registers |\@xdim| and |\@ydim| for the |\multiput| command. To
+% change it according to the scheme above you have to insert an
+% additional grouping.
+%
+% In \LaTeXe\ these three rarely used registers and some more are
+% shared with the |\bezier| command, whose definition has to be
+% changed accordingly. This shows the need---and advantage---of a
+% better allocation scheme.
+%
+% \subsubsection{\PiCTeX}
+%
+% The macro package \PiCTeX\ uses a lot of dimen registers. A subset
+% of these registers are only used within a picture or within a set
+% of drawing and parameter setting commands.
+%
+% As an example the dimen registers |\totalarclength| is only used in
+% a very restrictic set of commands, i.e., it can be allocated within
+% the scope of the higher level commands or within \PiCTeX's
+% |\beginpicture| \ldots\ |\endpicture| environment.
+%
+%
+% \StopEventually{^^A
+% \begin{thebibliography}{0}
+% \bibitem{DEK91} Donald E.\ Knuth,
+% {\it The \TeX{}book},
+% Addison-Wesley Publ., Reading, Mass., Juni 1991.
+% \bibitem{plain.tex-3.14159} File {\tt plain.tex},
+% version 3.14159,
+% March 1995.
+% \end{thebibliography}
+% }
+%
+%
+%
+% \section{Implementation}
+%
+%
+% \subsection{Prolog, \LaTeXe\ Package Declarations, etc.}
+%
+% The very first thing we do is to ensure that this file is not
+% read in twice. To this end we check whether the macro
+% |\lnewcount| is defined. If so, we just stop reading this file.
+% \begin{macrocode}
+%<+package>\expandafter\ifx\csname lnewcount\endcsname\relax
+%<+package>\else \expandafter\endinput \fi
+% \end{macrocode}
+%
+% For the sake of \LaTeXe\ users declarations for this package are
+% included. The additional group hack is needed to prevent the
+% definition of |\ProvidesPackage| as |\relax| if it is undefined.
+% \begin{macrocode}
+%<+package|test>\begingroup\expandafter\expandafter\expandafter\endgroup
+%<+package|test>\expandafter\ifx\csname ProvidesPackage\endcsname\relax
+%<+package|test>\else
+ \NeedsTeXFormat{LaTeX2e}
+%<+package> \ProvidesPackage{localloc}%
+%<+test> \ProvidesFile{localtst.tex}%
+%<*!package&!test>
+ \ProvidesFile{localloc.dtx}%
+%</!package&!test>
+ [1995/09/24 v1.1b %
+ Additional LaTeX Kernel Macros (local allocation)]
+%<+package|test>\fi
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% To allow the use of this file within a plain-\TeX\ job, we have
+% to change the category code of the `at' character~{\tt @}.
+% \begin{macrocode}
+\expandafter\chardef\csname lcllc@at\endcsname=\catcode`\@
+\catcode`\@=11 % \makeatletter
+% \end{macrocode}
+%
+%
+% \subsection{Accessing the {\tt muskip} registers}
+%
+% Beside the well-known \TeX\ registers, like |\count| or |\box|,
+% there is another set of registers which are used only in few
+% macros. The |\muskip| registers are normally used in math mode
+% only and the coercion of the value in a |\muskip| register to an
+% integer (|\count|), dimension (|\dimen|), or glue (|\glue|)
+% produces an error.
+%
+% The unit of a |\muskip| value is~$1$\,mu---there are $18$\,mu in
+% $1$\,em of the current font in {\em math family~2}. If you
+% assign a value to a |\muskip| register, this value is represented
+% in the unit~mu, not in~pt. The dimension of the |\muskip| value
+% is computed, if this value is used by |\mskip| or |\mkern|.
+%
+% To use a |\muskip| register as a replacement for a |\count|
+% register, it is necessary to do assignments, additions, and other
+% operations in units of~mu. If you want to coerce an
+% integer to a |\muskip| register, you have to get the value with
+% |\the| and add the keyword~|mu| while scanning the number. To get
+% the integer value of a |\muskip| register, you can use the
+% following macro~|\lcllc@cnvmutocnt|.
+%
+% \begin{macro}{\lcllc@cnvmutocnt}
+% The macro |\lcllc@cnvmutocnt| ist called with a |\muskip| register
+% or a value in~|mu| units as its argument. It will expand to the
+% integer value. To get the value of a register, we first expand
+% the value of this register to a list of tokens with \TeX's |\the|
+% primitive.
+% Example: if the register has the value~$3.4$\,mu, the expansion of
+% |\the| produces the tokens $\mbox{\tt 3}_{12} \mbox{\tt .}_{12}
+% \mbox{\tt 4}_{12} \mbox{\tt m}_{12} \mbox{\tt u}_{12}$.
+% \begin{macrocode}
+\def\lcllc@cnvmutocnt#1{\expandafter\lcllc@delmukey\the#1}
+% \end{macrocode}
+%
+% After we have expanded the value of the register, it is necessary
+% to strip of the unit keyword~|mu| and the fraction of the value.
+% To do this, we have to use tokens with {\em category code}~12 to
+% match the expansion string produced by~|\the|.
+% \begin{macrocode}
+\begingroup \catcode`\M=12 \catcode`\U=12 \catcode`\.=12
+ \lowercase{\endgroup
+\def\lcllc@delmukey#1.#2MU{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{Allocation registers}
+%
+% \subsubsection{Registers defined in {\tt plain.tex}}
+%
+% Plain-\TeX's allocation macros use a fixed set of |count|
+% registers containing a set of numbers with the highest allocated
+% register number. To make the following macro code more readable,
+% alias names for these |count| registers are defined.
+% \begin{macrocode}
+\countdef\count@ptr = 10
+\countdef\dimen@ptr = 11
+\countdef\skip@ptr = 12
+\countdef\muskip@ptr = 13
+\countdef\box@ptr = 14
+\countdef\toks@ptr = 15
+\countdef\read@ptr = 16
+\countdef\write@ptr = 17
+\countdef\mathfam@ptr = 18
+% \end{macrocode}
+% {\tt plain.tex} for \TeX~3 introduces a new allocation command
+% needing an additional allocation count register. To simplify the
+% code of this package with older versions of {\tt plain.tex}, a
+% dummy count register is allocated and used.
+% \begin{macrocode}
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname newlanguage\endcsname\relax
+ \csname newcount\endcsname\language@ptr
+\else
+ \countdef\language@ptr = 19
+\fi
+% \end{macrocode}
+%
+% The allocation command for insertion uses another register, which
+% is already aliased as |\insc@unt|.
+%\begin{verbatim}
+%\countdef\insc@unt = 20 % = 19 in older versions of `plain.tex'
+%\end{verbatim}
+%
+%
+% \subsubsection{Additional Registers}
+%
+% For the new local allocation macros additional registers are
+% needed containing the boundaries for all types of locally
+% allocated registers. Whereas all globally allocated registers
+% are located in the lower region of the register numbers (with the
+% exception of the set of registers needed for an insertion),
+% locally allocated registers are taken from the higher region of
+% the register numbers---from top towards the bottom.
+%
+% To avoid using six additional count registers we use |\muskip|
+% registers to save the current lower boundary of the allocatable
+% register region. These boundaries are initialised either
+% with~$256$ or the actual boundary of the insertion allocation
+% register.
+% \begin{macrocode}
+\newmuskip\count@limit \count@limit = \the\insc@unt mu
+\newmuskip\dimen@limit \dimen@limit = \the\insc@unt mu
+\newmuskip\skip@limit \skip@limit = \the\insc@unt mu
+\newmuskip\box@limit \box@limit = \the\insc@unt mu
+\newmuskip\muskip@limit \muskip@limit = 256mu
+\newmuskip\toks@limit \toks@limit = 256mu
+% \end{macrocode}
+%
+% To simplify the code of the following allocation macros and to
+% save macro space, two additional |\muskip| registers are
+% allocated and initialised with the constants $16$ and~$256$.
+% \begin{macrocode}
+\newmuskip\cclvi@mu \cclvi@mu = 256mu
+\newmuskip\xvi@mu \xvi@mu = 16mu
+% \end{macrocode}
+%
+%
+% \subsection{Allocation Macros for the ``End User''}
+%
+% \subsubsection{Global Allocation Macros}
+%
+% \begin{macro}{\newcount} \begin{macro}{\newdimen}
+% \begin{macro}{\newskip} \begin{macro}{\newmuskip}
+% \begin{macro}{\newbox} \begin{macro}{\newtoks}
+% \begin{macro}{\newread} \begin{macro}{\newwrite}
+% \begin{macro}{\newfam} \begin{macro}{\newlanguage}
+% We have to replace the original macros in {\tt plain.tex} by new
+% ones to allow locally allocated registers. Otherwise it will be
+% possible that the two regions, the lower one with globally
+% allocated registers and the higher one with locally allocated
+% registers, will overlap resulting in a double use of the same
+% register.
+%
+% With the new macros it will be unnecessary to un-outer the {\tt
+% plain.tex} macros, because the local allocation macros have to be
+% non outer. Nonetheless we want to use this package in
+% conjunction with \LaTeX\ and therefore we have to define some of
+% them as non outer.
+%
+% The top level macros use the low level macro |\alloc@| which has
+% the following parameters:
+% The boundaries of the lower and the higher region, the type of
+% the allocated register, a flag if we have to check on overlapping
+% with insertion registers, the \TeX\ primitive to be used to
+% define this register, and the user given control sequence.
+% \begin{macrocode}
+%\outer
+\def\newcount {\alloc@\count@ptr \count@limit \count 1\countdef }
+%\outer
+\def\newdimen {\alloc@\dimen@ptr \dimen@limit \dimen 1\dimendef }
+%\outer
+\def\newskip {\alloc@\skip@ptr \skip@limit \skip 1\skipdef }
+% \outer
+\def\newmuskip {\alloc@\muskip@ptr \muskip@limit\muskip 0\muskipdef}
+%\outer
+\def\newbox {\alloc@\box@ptr \box@limit \box 1\chardef }
+% \outer
+\def\newtoks {\alloc@\toks@ptr \toks@limit \toks 0\toksdef }
+% \outer
+\def\newread {\alloc@\read@ptr \xvi@mu \read 0\chardef }
+%\outer
+\def\newwrite {\alloc@\write@ptr \xvi@mu \write 0\chardef }
+%\outer
+\def\newfam {\alloc@\mathfam@ptr\xvi@mu \fam 0\chardef }
+% \outer
+\def\newlanguage{\alloc@\lang@ptr \cclvi@mu \language0\chardef }
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}\end{macro}\end{macro}
+% \end{macro}\end{macro}\end{macro}\end{macro}\end{macro}
+%
+% |\newinsert| needs additional code because this macro has to
+% allocate a set of |\box|, |\count|, |\dimen|, and |\skip|
+% registers with the restriction that all registers have to have
+% the same number. |\newinsert| is redefined at the end of this
+% file.
+%
+%
+% \subsubsection{Local Allocation Macros}
+%
+%
+% \begin{macro}{\lnewcount} \begin{macro}{\lnewdimen}
+% \begin{macro}{\lnewskip} \begin{macro}{\lnewmuskip}
+% \begin{macro}{\lnewbox} \begin{macro}{\lnewtoks}
+% There is an equivalent set of macros to allocate registers
+% locally. Instead of using the low level macro |\alloc@| it uses
+% the macro |\lalloc@| with the same set of parameters.
+% \begin{macrocode}
+\def\lnewcount {\lalloc@\count@ptr \count@limit \count 1\countdef }
+\def\lnewdimen {\lalloc@\dimen@ptr \dimen@limit \dimen 1\dimendef }
+\def\lnewskip {\lalloc@\skip@ptr \skip@limit \skip 1\skipdef }
+\def\lnewmuskip{\lalloc@\muskip@ptr\muskip@limit\muskip 0\muskipdef}
+\def\lnewbox {\lalloc@\box@ptr \box@limit \box 1\chardef }
+\def\lnewtoks {\lalloc@\toks@ptr \toks@limit \toks 0\toksdef }
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}\end{macro}\end{macro}\end{macro}
+%
+% Local allocation macros for |\read|, |\write| streams, math
+% |\fam|, |language| numbers, or insertions are possible but not
+% very useful because of the global nature of these resources.
+%
+%
+% \subsection{Low Level Allocation Macros}
+%
+% The allocation scheme used by the macros in {\tt plain.tex} is
+% simple:
+% \begin{itemize}
+% \item all allocations are global,
+% \item register, math family, language, input/output stream
+% numbers are allocated using the lowest possible number, i.e.,
+% it is done from lower number to higher numbers,
+% \item the set of insertion registers (|box|, |count|, |skip|, and
+% |dimen|), which have to have the same register number, are
+% allocated beginning from~$255$ to lower numbers.
+% \end{itemize}
+%
+% Contrary to this simple scheme this package uses numbers for
+% locally allocated registers from top to bottom interfering with
+% the original insertion register allocation scheme {\it and\/} the
+% simple test for a register number overflow.
+%
+% \begin{macro}{\lcllc@insnums}
+% Insertion registers are now allocated in a non-monotonous order
+% using the lowest possible number (because the allocation of the
+% needed set of registers is done in a global way). To allow the
+% checking of overlapping of globally or locally allocated
+% registers with the registers used for insertions, the insertion
+% register numbers are saved as a list in |\lcllc@insnums|.
+% Each entry in this list is saved as \mbox{\tt\string\do$\langle
+% n\rangle$.}; the list is initialised as empty.
+% \begin{macrocode}
+\def\lcllc@insnums{}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\lcllc@checkins}
+% Whenever a new |box|, |count|, |skip|, or |dimen| register is
+% allocated it has to be checked first, if the next possible
+% free register is already allocated for an insertion.
+%
+% To detect a collision between a possibly free register number and
+% the set of insertion registers, the macro |\lcllc@checkins| is
+% called with the register number to be tested in
+% |\allocationnumber|. The argument of this macro has to be either
+% $1$ or~$-1$ and is used to get the next register number to be
+% tested against the insertion number list if an additional
+% iteration is needed. The result is a register number in
+% |\allocationnumber| which is not used for an insertion. (Note:
+% Nonetheless it can be an out-of-region register number of an
+% already used register!)
+% \begin{macrocode}
+\def\lcllc@checkins#1{%
+ \begingroup
+% \end{macrocode}
+% After opening a new group, the macro |\do| is defined to read the
+% next insertion number delimited by a simple dot. It then tests
+% this number against the current |\allocationnumber| and if the
+% register numbers are equal, |\allocationnumber| is advanced by the
+% given argument (which is $1$ or~$-1$).
+%
+% To avoid a global change of |\allocationnumber|, a group hack
+% with expansion is used: If the list |\lcllc@insnums| is expanded
+% with this definition of |\do|, the result is empty if the
+% register number is not used for an insertion. Otherwise it
+% expands to the |\advance| command followed by an additional
+% |lcllc@checkins| (which has to be protected by |\noexpand|) to
+% start another iteration with the changed |\allocationnumber|.
+% \begin{macrocode}
+ \def\do##1.{%
+ \ifnum##1=\allocationnumber
+ \advance\allocationnumber#1\relax
+ \noexpand\lcllc@checkins{#1}%
+ \fi}%
+% \end{macrocode}
+% The following expanded definition text of |\x| contains code to
+% close the group and the expansion of |\lcllc@insnums|, which is
+% either empty or contains the change of |\allocationnumber| and an
+% iterative call of |\lcllc@checkins|. After the definition is
+% completed, the code is executed which closes the group.
+% \begin{macrocode}
+ \edef\x{\endgroup \lcllc@insnums}%
+ \x}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\alloc@}
+% |\alloc@| is the low level macro for global allocation, which is
+% called with six arguments. The macro itself only uses the first
+% four argument: The two boundaries, the item type to be allocated,
+% and a flag if this item is propably used for an insertion. The
+% remaining two arguments, the \TeX\ primitive and the control
+% sequence to assign the allocated number is used by
+% |\lcllc@def|.
+% \begin{macrocode}
+\def\alloc@#1#2#3#4{%
+% \end{macrocode}
+% In the first step we assign the boundary of the lower region for
+% this item type to |\allocationnumber| and increment it by one.
+% \begin{macrocode}
+ \allocationnumber#1%
+ \advance\allocationnumber\@ne
+% \end{macrocode}
+% If this item type is used by insertion, we have to check for
+% collision with the |\lcllc@checkins| macro. After the execution of
+% this macro, |\allocationnumber| contains the next free number to
+% be used for allocation. This number is assigned globally to the
+% register containing the boundary.
+% \begin{macrocode}
+ \ifnum#4=\@ne \lcllc@checkins\@ne \fi
+ \global#1\allocationnumber
+% \end{macrocode}
+% We now have found an unused register. Nonetheless it is possible
+% that the register number is either not in the range of existing
+% register number or it is used for a locally allocated register.
+% |\ch@ck| is used to test these things.
+% \begin{macrocode}
+ \ch@ck#1#2#3%
+% \end{macrocode}
+% At the end the \meta{control sequence} is defined using the
+% found |\allocationnumber|.
+% \begin{macrocode}
+ \lcllc@def\global{}#3}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\lalloc@}
+% |\lalloc@| is the low level macro for local allocation. The
+% definition of this macro a copy of |\alloc@| with some small
+% changes.
+% \begin{macrocode}
+\def\lalloc@#1#2#3#4{%
+% \end{macrocode}
+% In the first step we assign the boundary of the {\it higher\/}
+% region and {\it decrement\/} it by one. Because the higher
+% boundary is saved in a |\muskip| register, we have to use
+% |\lcllc@cnvmutocnt| to get the boundary value.
+% \begin{macrocode}
+ \allocationnumber\lcllc@cnvmutocnt#2%
+ \advance\allocationnumber\m@ne
+% \end{macrocode}
+% The check for insertion number collisions is called with~$-1$ to
+% decrement the register number to get the next free register
+% number. The |\allocationnumber| is then assigned {\it locally\/}
+% to the |\muskip| register containing the boundary.
+% \begin{macrocode}
+ \ifnum#4=\@ne \lcllc@checkins\m@ne \fi
+ #2\the\allocationnumber mu %
+% \end{macrocode}
+% The check for an already used globally allocated register or a
+% range underflow is needed, too.
+% \begin{macrocode}
+ \ch@ck#1#2#3%
+% \end{macrocode}
+% At the end the \meta{control sequence} is defined using the
+% found |\allocationnumber|.
+% \begin{macrocode}
+ \lcllc@def\relax{(local)}#3}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\ch@ck}
+% The test macro |\ch@ck| for a collision of the globally and
+% locally allocated registers from {\tt plain.tex} has to be
+% changed because the higher boundary is given as a |\muskip| value
+% instead of a normal integer.
+% \begin{macrocode}
+\def\ch@ck#1#2#3{%
+ \ifnum#1<\lcllc@cnvmutocnt#2\relax \else
+ \errmessage{No room for a new #3}%
+ % \allocationnumber\m@ne
+ \fi}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\lcllc@def}
+% |\lcllc@def| is used to assign the found |\allocationnumber|
+% to the \meta{control sequence} using the \TeX\ primitive.
+% Additionally an entry is written to the {\tt log} file.
+% \begin{macrocode}
+\def\lcllc@def#1#2#3#4#5{%
+ #1#4#5=\allocationnumber
+ \wlog{\string#5#2=\string#3\the\allocationnumber}}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsubsection{Low Level Insertion Allocation Macros}
+%
+% Insertions need a set of registers with the same register number.
+% To find a new register number when allocating an insertion, we
+% have to get the maximum of all boundaries used for an insertion.
+%
+% \begin{macro}{\lcllc@getmax}
+% |\lcllc@getmax| is used to assign |\allocationnumber| to the
+% maximum of |\allocationnumber| and its argument.
+% \begin{macrocode}
+\def\lcllc@getmax#1{%
+ \ifnum#1<\allocationnumber \else
+ \allocationnumber#1\advance\allocationnumber\@ne
+ \fi}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\newinsert}
+% |\newinsert| globally allocates a set of registers used for an
+% insertion.
+% \begin{macrocode}
+\outer\def\newinsert{%
+% \end{macrocode}
+% First we have to find the maximum of all globally allocated
+% register number used for an insertion. We start
+% by setting |\allocationnumber| to~$-1$\,\ldots
+% \begin{macrocode}
+ \allocationnumber\m@ne
+% \end{macrocode}
+% \ldots\,and get the maxmimum of the boundaries for |count|,
+% |dimen|, |skip|, and |box| registers.
+% \begin{macrocode}
+ \lcllc@getmax\count@ptr \lcllc@getmax\dimen@ptr
+ \lcllc@getmax\skip@ptr \lcllc@getmax\box@ptr
+% \end{macrocode}
+% Then we have to check if this |\allocationnumber| is already used
+% for another insertion.
+% \changes{v1.0b}{91/09/06}{\cs{lcllc@checkins} inserted}
+% \begin{macrocode}
+ \lcllc@checkins\@ne
+% \end{macrocode}
+% At last we have to check if this |\allocationnumber| is used for
+% one of the locally allocated registers.
+% \begin{macrocode}
+ \ch@ck\allocationnumber\count@limit\count
+ \ch@ck\allocationnumber\dimen@limit\dimen
+ \ch@ck\allocationnumber\skip@limit\skip
+ \ch@ck\allocationnumber\box@limit\box
+% \end{macrocode}
+% The found register number for insertions is then (globally)
+% inserted into the list of insertion numbers.
+% \begin{macrocode}
+ \begingroup
+ \let\do\relax
+ \xdef\lcllc@insnums{\do\the\allocationnumber.\lcllc@insnums}%
+ \endgroup
+% \end{macrocode}
+% At the end the \meta{control sequence} is defined using the
+% found |\allocationnumber|.
+% \begin{macrocode}
+ \lcllc@def\global{}\insert\chardef}
+% \end{macrocode}
+% \end{macro}
+%
+% The register |\insc@unt| which is used to contain the boundary
+% number for insertion registers in the original {\tt plain.tex}
+% macro is not used anymore.
+%
+%
+% Finally, the category code of the `at' character~{\tt @} is reset
+% to its original value.
+% \begin{macrocode}
+\catcode`\@=\lcllc@at
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+%
+% \iffalse
+%<*driver>
+\NeedsTeXFormat{LaTeX2e}
+\documentclass[a4paper]{ltxdoc}
+\GetFileInfo{localloc.dtx}
+\begin{document}
+ \DocInput{\filename}
+\end{document}
+%</driver>
+% \fi
+%
+% \iffalse
+%
+% \section{Test File}
+%
+% A first version of a test file which can be used for plain-TeX,
+% \LaTeX~2.09, and \LaTeXe. The result shows the allocated register
+% numbers. You should notice that the insertions and global box
+% registers are not contiguously allocated but interfere. Further
+% from one to the next line there is a new global register number
+% greater than the former one. Whereas the local register numbers
+% are set to zero when leaving a group and they are recycled in the
+% next lines.
+%
+% \begin{macrocode}
+%<*test>
+% This test file can be used with plain-TeX & LaTeX 2.09/2e.
+%
+\edef\FORMAT{%
+ \expandafter\ifx\csname documentstyle\endcsname\relax 0%
+ \else\expandafter\ifx\csname documentclass\endcsname\relax
+ 1\else 2\fi\fi}
+\immediate\write16{=====>>> You are using %
+ \ifcase\FORMAT plainTeX\or LaTeX 2.09\or LaTeX 2e\else ??\fi}
+\ifcase\FORMAT
+ \input localloc.sty\relax \or
+ \documentstyle[localloc]{article}\begin{document}\or
+ \documentclass{article}\usepackage{localloc}\begin{document}\fi
+\tracingstats=1
+% some macros
+\def\Message#1{\immediate\write16{#1}}
+\def\RegVal#1{\the\csname test#1\endcsname}
+\def\ShowSet#1{\if l#1local\else global\fi:
+ \RegVal{i#1} \RegVal{ii#1}/\RegVal{iii#1}
+ \RegVal{iv#1}}
+\def\ShowAll#1{\Message{#1 -- \ShowSet{g} -- \ShowSet{l}}}
+\def\ShowIns{\Message{Insertions:
+ \the\testinsi, \the\testinsii, \the\testinsiii}}
+% initialise
+\chardef\testig=0 \chardef\testil=0
+\chardef\testiig=0 \chardef\testiil=0
+\chardef\testiiig=0 \chardef\testiiil=0
+\chardef\testivg=0 \chardef\testivl=0
+\chardef\testinsii=0 \chardef\testinsiii=0
+% allocate an insertion/set of registers
+\newinsert\testinsi
+% make sure that a collision boxes/insertions occurs
+{\count0=\testinsi \advance\count0 -2
+ \loop\csname newbox\endcsname\testig
+ \ifnum\testig<\count0\repeat}
+%
+\newbox\testig \lnewbox\testil
+\ShowAll{Level 0}
+\begingroup
+ \lnewbox\testiil \newbox\testiig
+ \ShowAll{Level 1}
+ \begingroup
+ \newbox\testivg \lnewbox\testivl
+ \ShowAll{Level 2}\ShowIns
+ \endgroup
+ \lnewbox\testiiil \newbox\testiiig
+ \ShowAll{Level 1b}
+ \csname newinsert\endcsname\testinsii
+ \ShowIns
+ \begingroup
+ \newbox\testivg \lnewbox\testivl
+ \ShowAll{Level 2}
+ \endgroup
+ \ShowAll{Level 1b}
+\endgroup
+\newinsert\testinsiii
+\ShowAll{Level 0}\ShowIns
+\begingroup
+ \lnewbox\testiil \newbox\testiig
+ \lnewbox\testiiil \newbox\testiiig
+ \ShowAll{Level 1}
+ \begingroup
+ \newbox\testivg \lnewbox\testivl
+ \newbox\testvg \lnewbox\testvl
+ \ShowAll{Level 2}\ShowIns
+ \endgroup
+ \ShowAll{Level 1}
+\endgroup
+\ShowAll{Level 0}
+\end{document}
+%</test>
+% \end{macrocode}
+%
+% \fi
+%
+% \Finale
+%
+%% \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
+%% Digits \0\1\2\3\4\5\6\7\8\9
+%% Exclamation \! Double quote \" Hash (number) \#
+%% Dollar \$ Percent \% Ampersand \&
+%% Acute accent \' Left paren \( Right paren \)
+%% Asterisk \* Plus \+ Comma \,
+%% Minus \- Point \. Solidus \/
+%% Colon \: Semicolon \; Less than \<
+%% Equals \= Greater than \> Question mark \?
+%% Commercial at \@ Left bracket \[ Backslash \\
+%% Right bracket \] Circumflex \^ Underscore \_
+%% Grave accent \` Left brace \{ Vertical bar \|
+%% Right brace \} Tilde \~}
+%%
+%
+\endinput
diff --git a/macros/generic/localloc/localloc.pdf b/macros/generic/localloc/localloc.pdf
new file mode 100644
index 0000000000..3a25e8fd45
--- /dev/null
+++ b/macros/generic/localloc/localloc.pdf
Binary files differ
diff --git a/macros/generic/soul/Makefile b/macros/generic/soul/Makefile
new file mode 100644
index 0000000000..1a0103f695
--- /dev/null
+++ b/macros/generic/soul/Makefile
@@ -0,0 +1,57 @@
+# $Id: Makefile,v 1.7 2003/06/22 09:23:35 m Rel $
+
+NAME=soul
+ARCHNAME=$(NAME).tar.gz
+ARCHIVE=$(NAME).dtx Makefile $(NAME).txt $(NAME).ins
+MAKEIDXOPT=
+DVIPSOPT=#-Pcmz -Pamz
+DEP=$(NAME).sty
+
+all: $(NAME).sty $(NAME).ps
+
+print: $(NAME).ps
+ psbook $(NAME).ps|psnup -2|psselect -e|lpr
+ @ echo -n revert paper stack and hit return
+ @ read key
+ psbook $(NAME).ps|psnup -2|psselect -o -r|lpr
+
+ps: $(NAME).ps
+
+%.ps: %.dvi
+ dvips $(DVIPSOPT) $< -o $@
+
+hyper: $(NAME).dtx $(NAME).sty
+ pdflatex "\relax\let\makehyperref\active\input $(NAME).dtx"
+
+$(NAME).pdf: $(NAME).dtx $(NAME).sty
+ pdflatex $(NAME).dtx
+
+archive:
+ @ tar -czf $(ARCHNAME) $(ARCHIVE)
+ @ echo $(ARCHNAME)
+
+clean:
+ rm -f $(NAME).{log,toc,lot,lof,idx,ilg,ind,aux,blg,bbl,dvi,ins,out}
+
+distclean: clean
+ rm -f $(NAME).{ps,sty,pdf} $(ARCHNAME)
+
+
+REFWARN = 'Rerun to get cross-references'
+LATEXMAX = 5
+
+%.dvi: %.dtx $(DEP)
+ latex $< ; true
+ RUNS=$(LATEXMAX); \
+ while [ $$RUNS -gt 0 ] ; do \
+ if grep $(REFWARN) $*.log > /dev/null; \
+ then latex $< ; else break; fi; \
+ RUNS=`expr $$RUNS - 1`; \
+ done
+
+$(NAME).sty: $(NAME).ins soul.dtx
+ tex $(NAME).ins
+
+$(NAME).ins:
+ latex $(NAME).dtx
+
diff --git a/macros/generic/soul/soul.dtx b/macros/generic/soul/soul.dtx
new file mode 100644
index 0000000000..064634cf11
--- /dev/null
+++ b/macros/generic/soul/soul.dtx
@@ -0,0 +1,4520 @@
+% \iffalse
+%% File: soul.dtx Copyright (C) 1998--2003 Melchior FRANZ
+%% $Id: soul.dtx,v 1.128 2003/11/17 22:57:24 m Rel $
+%% $Version: 2.4 $
+%
+%<*batchfile>
+%
+% on Unix/Linux just run "make" to get the style file and the documentation,
+% else generate the driver soul.ins (if you don't already have it):
+%
+% $ latex soul.dtx
+%
+% You'll probably get an error message that you may ignore. Now generate
+% the style file:
+%
+% $ tex soul.ins
+%
+% And finally to produce the documentation run LaTeX three times:
+%
+% $ latex soul.dtx
+%
+%
+%
+%
+% DISCLAIMER: note that a Makefile could actually contain malign commands
+% that erase your whole account, so having a look at it before won't hurt!
+% I take no responsibility for any damage, but I do what I can to make
+% using the original Makefile safe.
+%
+% COPYRIGHT NOTICE:
+% This package is free software that can be redistributed and/or modified
+% under the terms of the LaTeX Project Public License as specified
+% in the file macros/latex/base/lppl.txt on any CTAN archive server,
+% such as ftp://ftp.dante.de/.
+%
+%$
+%% ====================================================================
+%% @LaTeX-package-file{
+%% author = "Melchior FRANZ",
+%% version = "2.4",
+%% date = "17 November 2003",
+%% filename = "soul.dtx",
+%% address = "Melchior FRANZ
+%% Rieder Hauptstrasse 52
+%% A-5212 SCHNEEGATTERN
+%% AUSTRIA",
+%% telephone = "++43 7746 3109",
+%% URL = "http://www.unet.univie.ac.at/~a8603365/",
+%% email = "a8603365@unet.univie.ac.at",
+%% codetable = "ISO/ASCII",
+%% keywords = "spacing out, letterspacing, underlining, striking out,
+%% highlighting",
+%% supported = "yes",
+%% docstring = "This article describes the `soul' package, which
+%% provides hyphenatable letterspacing (spacing out),
+%% underlining, and some derivatives.
+%% All features are based upon a common mechanism
+%% that allows to typeset text syllable by syllable,
+%% where the excellent TeX hyphenation algorithm is
+%% used to find the proper hyphenation points.
+%% Two examples show how to use the provided interface to
+%% implement things such as `an-a-lyz-ing syl-la-bles'.
+%% Although the package is optimized for LaTeX2e,
+%% it works with Plain TeX and with other
+%% packages, too.",
+%% }
+%% ====================================================================
+%
+%
+%
+%
+%
+\begin{filecontents}{soul.ins}
+\def\batchfile{soul.ins}
+\input docstrip.tex
+\askforoverwritefalse
+\keepsilent % <-- this is for you, Christina ;-)
+\generate{\file{soul.sty}{\from{soul.dtx}{package}}}
+\endbatchfile
+\end{filecontents}
+%</batchfile>
+%
+%
+%
+%
+%
+%<*driver>
+\def\fileversion{2.4}
+\def\filedate{2003/11/17}
+%
+%
+%
+\documentclass{ltxdoc}
+%
+%
+%
+\makeatletter\let\SOUL@sethyphenchar\relax\makeatother
+\IfFileExists{soul.sty}{%
+ \usepackage{soul}[2002/01/10]
+ \expandafter\ifx\csname sloppyword\endcsname\relax % old version?
+ \def\sloppyword{\textbf{?? [obsolete soul version]}}
+ \fi
+ \let\SOULSTYfound\active
+}{%
+ \GenericWarning{soul.dtx}{%
+ Package file `soul.sty' couldn't be found. You should however find^^J^^A
+ a file `soul.ins' in the current directory. If you type "tex soul.ins"^^J^^A
+ on the command line, `soul.sty' will be generated. After that
+ run "latex soul.dtx" again and you won't see this message again.
+ }%
+}%
+%
+%
+%
+\ifx\makehyperref\SOULundefined
+ \newcommand*\texorpdfstring[2]{#1}
+\else ^^A for "make hyper"
+ \usepackage{hyperref}
+ \hypersetup{
+ bookmarksopen,
+ colorlinks,
+ pdftitle={The soul package},
+ pdfauthor={Melchior FRANZ},
+ pdfsubject={${}$Id: soul.dtx,v 1.128 2003/11/17 22:57:24 m Rel ${}$},
+ pdfkeywords={space out, letterspacing, underlining, overstriking, highlighting}
+ }
+ \usepackage[pdftex]{graphicx,color}
+\fi
+%
+%
+%
+%\RecordChanges
+%
+\begin{document}
+\setcounter{tocdepth}{2}
+\DocInput{soul.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+%
+%
+%
+%
+%
+%
+% \CheckSum{2006}
+% \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
+% Digits \0\1\2\3\4\5\6\7\8\9
+% Exclamation \! Double quote \" Hash (number) \#
+% Dollar \$ Percent \% Ampersand \&
+% Acute accent \' Left paren \( Right paren \)
+% Asterisk \* Plus \+ Comma \,
+% Minus \- Point \. Solidus \/
+% Colon \: Semicolon \; Less than \<
+% Equals \= Greater than \> Question mark \?
+% Commercial at \@ Left bracket \[ Backslash \\
+% Right bracket \] Circumflex \^ Underscore \_
+% Grave accent \` Left brace \{ Vertical bar \|
+% Right brace \} Tilde \~}
+%
+%
+%
+% \title{The \texttt{soul} package}
+%
+% \author{Melchior \caps{FRANZ}}
+%
+% \date{November 17, 2003}
+%
+%^^A=====================================================
+%
+%^^A These messy macros allow to typeset the `example' sections
+%^^A conveniently. You'd better ignore them. I do! :-)
+%
+% \makeatletter
+%
+% \def\squarebull{\rule[.2ex]{.8ex}{.8ex}}
+%
+% \newenvironment{examples}
+% {\parindent\z@\small\fontencoding{OT1}\selectfont}
+% {\rule{\hsize}{.4pt}}
+%
+% \def\soultest#1|{\bgroup\rule[.5ex]{\hsize}{.4pt}\par
+% \parbox[t]{.34\hsize}{\raggedright\textit{#1\unskip.}}%
+% \hspace{1.5em}$\vtop\bgroup\hb@xt@.4\hsize\bgroup
+% \llap{\squarebull\hspace{.4em}}\soulttest}
+%
+% {\catcode`\|=13\gdef\soulttest{%
+% \bgroup\def\do##1{\catcode`##1=12}\dospecials\ttfamily
+% \catcode`\|=13\unskip\def|{\hss\egroup\egroup\soultttest}}}
+%
+% \def\soultttest#1{\hbox{\vtop{\hsize.4\hsize\hbadness\@M
+% \leavevmode\llap{\squarebull\hspace{.4em}}#1\null}}%
+% \egroup$\hspace{1.5em}\parbox[t]{1mm}{\hyphenpenalty-\@M
+% \exhyphenpenalty-\@M\hbadness\@M\hfuzz\maxdimen
+% \strut\llap{\squarebull\hspace{.4em}}#1\null}%
+% \goodbreak\vspace{2ex}
+% \egroup}
+%
+% \newcommand*\DescribeOption[1]{\marginpar{\raggedleft\textsf{#1}\ignorespaces}}
+%
+%
+%^^A similar to the `description' environment
+%
+% \def\describemacro{^^A
+% \bgroup
+% \let\do\@makeother
+% \dospecials
+% \catcode`{=1
+% \catcode`}=2
+% \SOUL@@@descmacro
+% }
+%
+% \def\SOUL@@@descmacro#1{^^A
+% \texttt{#1}^^A
+% \DescribeMacro{#1}^^A
+% \expandafter\edef\expandafter\x\expandafter{\expandafter\@gobble#1}^^A
+% \expandafter\label{cmd:\x}^^A
+% \egroup
+% }
+%
+%
+% \def\SOUL@@@verbitem[#1: {^^A
+% \bgroup
+% \let\do\@makeother
+% \dospecials
+% \SOUL@@@verbscan{#1}^^A
+% }
+%
+% \def\SOUL@@@verbscan#1#2]{^^A
+% \egroup
+% \goodbreak
+% \def\@currentlabel{\S\,\the\SOUL@@@itemnr}^^A
+% \label{par:#1}^^A
+% \SOUL@@@item[\textbf{\@currentlabel\hskip.6em#1:}]\hfil\break
+% Example: \texttt{#2}\hfil\break^^A
+% \advance\SOUL@@@itemnr1
+% }
+%
+% \let\SOUL@@@item\item
+% \newcount\SOUL@@@itemnr
+%
+% \newenvironment{verblist}[1]{^^A
+% \SOUL@@@itemnr=#1
+% \list{}{^^A
+% \settowidth{\labelwidth}{\indent\indent}^^A
+% \leftmargin\labelwidth
+% \advance\leftmargin\labelsep
+% \def\makelabel##1{##1}^^A
+% \let\item\SOUL@@@verbitem
+% }^^A
+% }{^^A
+% \endlist
+% }
+%
+% \newenvironment{labeling}[1]{^^A
+% \list{}{^^A
+% \settowidth{\labelwidth}{\textbf{#1}}^^A
+% \leftmargin\labelwidth\advance\leftmargin\labelsep
+% \def\makelabel##1{\textbf{##1}\hfil}^^A
+% }^^A
+% }{^^A
+% \endlist
+% }
+%
+% \newenvironment{syntax}{^^A
+% \par\medskip\def\<##1>{$\langle$\syn{##1}$\rangle$}^^A
+% \indent\begin{tabular}{l}^^A
+% }{^^A
+% \end{tabular}^^A
+% \noindentafter\medbreak
+% }
+%
+%
+% \newenvironment{example}[1][.9\textwidth]
+% {\par\medskip\indent\begin{tabular}{p{#1}l}}
+% {\end{tabular}\noindentafter\medbreak}
+%
+% \newcommand*\noindentafter{^^A
+% \global\everypar{{\setbox\z@\lastbox}\everypar{}}}
+%
+% \newcommand*\errsquare{\leavevmode\vrule height.8em depth.2em width1em\relax}
+%
+%
+% \ifx\SOULSTYfound\active
+%^^A analyze syllables---described somewhere below
+%
+% \DeclareRobustCommand*\sy{^^A
+% \SOUL@setup
+% \def\SOUL@preamble{\lefthyphenmin0\righthyphenmin0}^^A
+% \def\SOUL@everysyllable{\the\SOUL@syllable}^^A
+% \def\SOUL@everyspace##1{##1\space}^^A
+% \def\SOUL@everyhyphen{^^A
+% \discretionary{^^A
+% \SOUL@setkern\SOUL@hyphkern
+% \SOUL@sethyphenchar
+% }{}{^^A
+% \hbox{\kern1pt$\cdot$}^^A
+% }^^A
+% }^^A
+% \def\SOUL@everyexhyphen##1{^^A
+% \SOUL@setkern\SOUL@hyphkern
+% \hbox{##1}^^A
+% \discretionary{}{}{^^A
+% \SOUL@setkern\SOUL@charkern
+% }^^A
+% }^^A
+% \SOUL@}
+%
+%^^A analyze the engine---described somewhere below, too
+%
+% \DeclareRobustCommand*\an{^^A
+% \def\SOUL@preamble{$^{^P}$}^^A
+% \def\SOUL@everyspace##1{##1\texttt{\char`\ }}^^A
+% \def\SOUL@postamble{$^{^E}$}^^A
+% \def\SOUL@everyhyphen{$^{^-}$}^^A
+% \def\SOUL@everyexhyphen##1{##1$^{^=}$}^^A
+% \def\SOUL@everysyllable{$^{^S}$}^^A
+% \def\SOUL@everytoken{\the\SOUL@token$^{^T}$}^^A
+% \def\SOUL@everylowerthan{$^{^L}$}^^A
+% \SOUL@}
+%
+%^^A magazine-like (truly awful) paragraphs
+%^^A If you know what you're doing, you can copy it to your personal `soul.cfg' file.
+%
+% \DeclareRobustCommand*\magstylepar{\SOUL@sosetup
+% \def\SOUL@preamble{^^A
+% \edef\SOUL@soletterskip{\z@\@plus\fontdimen2\font\@minus\z@}^^A
+% \edef\SOUL@soinnerskip{\the\fontdimen2\font
+% \@plus\the\fontdimen3\font\@minus\the\fontdimen4\font}^^A
+% \let\SOUL@soouterskip\SOUL@soinnerskip
+% \SOUL@sopreamble}^^A
+% \lefthyphenmin2\righthyphenmin2\SOUL@}
+%
+%\else
+%
+%^^A The package has not been found, so we're providing some dummies, just
+%^^A to avoid all these `Undefined command sequence' messages.
+%
+% \def\SOUL@@@X#1{\textbf{??}}%
+% \let\so\SOUL@@@X
+% \let\textso\SOUL@@@X
+% \let\caps\SOUL@@@X
+% \let\textcaps\SOUL@@@X
+% \let\ul\SOUL@@@X
+% \let\textul\SOUL@@@X
+% \let\st\SOUL@@@X
+% \let\textst\SOUL@@@X
+% \let\hl\SOUL@@@X
+% \let\texthl\SOUL@@@X
+% \let\sy\SOUL@@@X
+% \let\an\SOUL@@@X
+% \let\magstylepar\SOUL@@@X
+% \let\sloppyword\SOUL@@@X
+% \def\sodef#1#2#3#4{\let#1\relax\SOUL@@@X}%
+% \fi
+%
+% \newcommand*\xpath{^^A
+% \bgroup
+% \let\do\@makeother
+% \dospecials
+% \catcode`\{=1
+% \catcode`\}=2
+% \def\{{\char"7B}^^A
+% \def\}{\char"7D}^^A
+% \SOUL@@@code
+% }
+%
+% \newcommand*\SOUL@@@code[1]{\normalfont\texttt{#1}\egroup}
+%
+% \let\cs\xpath
+% \let\option\textsf
+% \def\package#1{{\normalfont\texttt{#1}}}
+% \let\program\texttt
+% \let\bibtitle\textit
+% \let\syn\textit
+%
+% \sodef\person{\scshape}{0.06em}{0.45em}{0.4em}
+% \sodef\SOUL@@@versal{\upshape}{0.125em}{0.4583em}{0.5833em}
+% \DeclareRobustCommand*\versal[1]{^^A
+% \MakeUppercase{\SOUL@@@versal{#1}}^^A
+% }
+%
+% \def\ConTeXt{Con\TeX t}
+% \def\CTAN{{\small\caps{CTAN}}}
+% \def\soul{\package{soul}}
+%
+% ^^A set some parameters as used in Plain TeX
+% \def\plainsetup{^^A
+% \pretolerance100
+% \tolerance200
+% \hbadness1000
+% \linepenalty10
+% \hyphenpenalty50
+% \exhyphenpenalty50
+% \doublehyphendemerits10000
+% \finalhyphendemerits5000
+% \adjdemerits10000
+% \hfuzz.1pt
+% \overfullrule5pt
+% }
+%
+% \def\FIXME#1{\message{<FIXME>}#1}
+%
+% \makeatother
+%
+%
+% \lefthyphenmin2
+% \righthyphenmin3
+% \hyphenation{Le-se-ty-po-gra-phie Ver-bin-dung fak-si-mi-le}
+%
+%
+%^^A=====================================================
+%
+%
+% \changes{v1.0}{1998/10/16}{Initial version}%
+%^^A due to an error in the documentation of v1.0, there's no v1.1 :-(
+% \changes{v1.1a}{1998/12/08}{fixed a bunch of bugs; `magstylepar command
+% banned; `caps introduced; `so and `caps recognize following spaces;
+% error message added; `so parameters are mandatory}
+%
+% \changes{v1.2}{1999/01/11}{fixed the newline bug; added the `\(>\) command}
+%
+% \changes{v1.3}{1999/05/15}{changed allowhyphen, preambles; added a paragraph
+% in the `features' section}
+%
+% \changes{v2.0}{2002/01/03}{(almost) complete rewrite}
+%
+% \changes{v2.1}{2002/01/10}{Happy (64th) birthday, Don!
+% ``The now-traditional fix for the
+% now-traditional brown-paper-bag major release.''
+% as Eric S. RAYMOND commented on his CML2.0.1 release. ;-)}
+%
+% \changes{v2.2}{2002/05/12}{fixed a couple of bugs; added support for
+% the Plain TeX color.sty wrapper}
+%
+% \changes{v2.3}{2002/05/29}{compatibility with cmbright/ccfonts}
+%
+% \changes{v2.4}{2003/11/17}{Fix the font bug. Fix a scanner bug.
+% Other bugfixes; change caps set handling; add footnote and
+% textsuperscript support}
+%
+%
+%
+%
+%
+% \maketitle
+%
+%
+%
+% \begin{abstract}
+% This article describes the \soul\ package^^A
+%^^A%%
+% \footnote{This file has version number \fileversion, last revised \filedate.},
+%^^A%%
+% which provides \so{hyphenatable letterspacing (spacing out),} \ul{underlining}
+% and some derivatives such as \st{overstriking} and highlighting.
+% Although the package is optimized for \LaTeXe, it also works with
+% Plain \TeX\ and with other flavors of \TeX\ like, for instance, \ConTeXt.
+% By the way, the package name |soul| is only a combination
+% of the two macro names \cs{\so} (space out) and \cs{\ul}
+% (underline)---nothing poetic at all.^^A :-(
+% \end{abstract}
+%
+%
+% {\setlength\parskip{0pt}\tableofcontents }
+% \addtocontents{toc}{\protect\begin{multicols}{2}}
+%
+%
+%
+%
+%
+%
+%
+%
+%
+% \section{Typesetting rules}
+% \label{sec:typesetting}
+%
+% There are several possibilities to emphasize parts of a paragraph,
+% not all of which are considered good style. While underlining
+% is commonly rejected, experts dispute about whether letterspacing
+% should be used or not, and in which cases. If you are not interested
+% in such debates, you may well skip to the next section.
+%
+%
+% \subsection*{Theory \dots}
+% \label{sec:theory}
+%
+% To understand the experts' arguments we have to know about the
+% conception of \emph{page grayness.} The sum of all characters on
+% a page represents a certain amount of grayness, provided that
+% the letters are printed black onto white paper.
+%
+% \person{Jan Tschichold} \cite{Tschichold}, a well known and recognized
+% typographer, accepts only forms of emphasizing, which do not disturb this
+% grayness. This is only true of italic shape, caps, and
+% caps-and-small-caps fonts, but not of ordinary letterspacing, underlining,
+% bold face type and so on, all of which appear as either dark or light
+% spots in the text area. In his opinion emphasized text shall not catch the eye when
+% running over the text, but rather when actually reading the respective words.
+%
+% Other, less restrictive typographers \cite{Willberg} call this kind of emphasizing
+% `integrated' or `aesthetic', while they describe `active' emphasizing apart from it,
+% which actually \emph{has} to catch the reader's eye. To the latter group belong commonly
+% despised things like letterspacing, demibold face type and even underlined and colored text.
+%
+% On the other hand, \person{Tschichold} suggests
+% to space out caps and caps-and-small-caps fonts on title pages, headings and running headers from
+% 1\,pt up to 2\,pt.
+% Even in running text legibility of uppercase letters should be improved with slight
+% letterspacing, since (the Roman) majuscules don't look right, if they are spaced
+% like (the Carolingian) minuscules.\footnote{This suggestion is followed throughout this article,
+% although Prof.~\person{Knuth} already considered slight letterspacing with his |cmcsc| fonts.}
+%
+%
+%
+%\subsection*{\dots\ and Practice}
+%
+% However, in the last centuries letterspacing was excessively used,
+% underlining at least sometimes, because capitals and italic shape could
+% not be used together with the \emph{Fraktur} font and other black-letter fonts,
+% which are sometimes also called ``old German'' fonts.
+% This tradition is widely continued until today. The same limitations apply still today
+% to many languages with non-latin glyphs, which is why letterspacing has a strong
+% tradition in eastern countries where Cyrillic fonts are used.
+%
+% The \person{Duden} \cite{Duden}, a well known German dictionary, explains how to space out properly:
+% \emph{Punctuation marks are spaced out like letters, except quotation marks and periods.
+% Numbers are never spaced out. The German syllable \mbox{\emph{-sche}} is not spaced
+% out in cases like \emph{``der {\so{Virchow{sche}}} Versuch''}\footnote{the \person{Virchow} experiment}.
+% In the old German \emph{Fraktur} fonts the ligatures \emph{|ch|, |ck|, |sz|~(\ss)} and~\emph{|tz|} are
+% not broken within spaced out text.}
+%
+% While some books follow all these rules \cite{Muszynski}, others don't
+% \cite{Reglement}. In fact, most books in my personal library do \emph{not} space out commas.
+%
+%
+%
+%
+%
+%
+%
+%
+%
+% \section{Short introduction and common rules}
+%
+% The \soul\ package provides five commands that are aimed at emphasizing
+% text parts. Each of the commands takes one argument that can either be
+% the text itself or the name of a macro that contains text (e.\,g.~|\so\text|)^^A
+% ^^A
+% \footnote{See~\ref{par:Unexpandable material in command sequences} for
+% some additional information about the latter mode.}^^A
+% ^^A
+% .
+% See table~\ref{tab:survey} for a complete command survey.
+%
+% {\catcode`\|=12
+% \begin{center}
+% \begin{tabular}{r@{\hspace{1.5em}}l}
+% \verb+\so{letterspacing}+&\so{letterspacing}\\
+% \verb+\caps{CAPITALS, Small Capitals}+&\caps{CAPITALS, Small Capitals}\\
+% \verb+\ul{underlining}+&\ul{underlining}\\
+% \verb+\st{overstriking}+&\st{overstriking}\\
+% \verb+\hl{highlighting}+&highlighting\footnotemark\\
+% \end{tabular}
+% \end{center}
+% \footnotetext{The look of highlighting is nowhere demonstrated
+% in this documentation, because it requires a Postscript aware
+% output driver and would come out as ugly black bars on other
+% devices, looking very much like censoring bars. Think of it as
+% the effect of one of those coloring text markers.}
+% }
+%
+% \noindent
+% The \cs{\hl} command does only highlight if the \package{color} package
+% was loaded, otherwise it falls back to underlining.\footnote{Note that
+% you can also use \LaTeX's \package{color} package with Plain \TeX.
+% See~\ref{sec:plain} for details.} The highlighting
+% color is by default yellow, underlines and overstriking lines are by
+% default black. The colors can be changed using the following commands:
+%
+% {\catcode`\|=12
+% \begin{center}
+% \begin{tabular}{r@{\hspace{1.5em}}l}
+% \verb+\setulcolor{red}+&set underlining color\\
+% \verb+\setstcolor{green}+&set overstriking color\\
+% \verb+\sethlcolor{blue}+&set highlighting color\\
+% \end{tabular}
+% \end{center}
+% }
+%
+% \noindent
+% |\setulcolor{}| and |\setstcolor{}| turn coloring off.
+% There are only few colors predefined by the \package{color}
+% package, but you can easily add custom color definitions.
+% See the \package{color} package documentation~\cite{color} for further
+% information.
+%
+% \begin{example}
+% |\usepackage{color,soul}|\\
+% |\definecolor{lightblue}{rgb}{.90,.95,1}|\\
+% |\sethlcolor{lightblue}|\\
+% |...|\\
+% |\hl{this is highlighted in light blue color}|\\
+% \end{example}
+%
+%
+%
+%
+%
+%
+%
+% \subsection[Some things work]{Some things work \dots}
+%
+% The following examples may look boring and redundant, because they describe
+% nothing else than common \LaTeX\ notation with a few exceptions, but this is
+% only the half story: The \soul\ package has to pre-process the argument
+% before it can split it into characters and syllables, and all described
+% constructs are only allowed because the package explicitly implements them.
+%
+% \begin{verblist}{1}
+% \item[Accents: \so{na\"\i ve}]
+% Accents can be used naturally.
+% Support for the following accents is built-in: |\`|, |\'|, |\^|, |\"|, |\~|,
+% |\=|, |\.|, |\u|, |\v|, |\H|, |\t|, |\c|, |\d|, |\b|, and |\r|. Additionally,
+% if the \package{german} package \cite{german} is loaded you can also use the |"|
+% accent command and write |\so{na"ive}|. See section~\ref{sec:soulaccent} for how to add
+% further accents.
+% \item[Quotes: \so{``quotes''}]
+% The \soul\ package recognizes the quotes ligatures |``|, |''| and |,,|.
+% The Spanish ligatures |!`| and |?`| are not recognized and have, thus,
+% to be written enclosed in braces like in |\caps{{!`}Hola!}|.
+% \item[Mathematics: \so{foo$x^3$bar}]
+% Mathematic formulas are allowed, as long as they are
+% surrounded by~\texttt\$. Note that the \LaTeX\
+% equivalent |\(...\)| does not work.
+% \item[Hyphens and dashes: \so{re-sent}]
+% Explicit hyphens as well as en-dashes~(|--|), em-dashes~(|---|)
+% and the |\slash| command work as usual.
+% \item[Newlines: \so{new\\line}]
+% The |\\|~command fills the current line with white space
+% and starts a new line. Spaces or linebreaks afterwards are ignored.
+% Unlike the original \LaTeX\ command \soul's version does not handle
+% optional parameters like in |\\*[1ex]|.
+% \item[Breaking lines: \so{foo\linebreak bar}]
+% The \cs{\linebreak} command breaks the line without
+% filling it with white space at the end. \soul's version
+% does not handle optional parameters like in |\linebreak[1]|.
+% \cs{\break} can be used as a synonym.
+% \item[Unbreakable spaces: \so{don't~break}]
+% The |~|~command sets an unbreakable space.
+% \item[Grouping: \so{Virchow{sche}}]
+% A pair of braces can be used to let a group of characters
+% be seen as one entity, so that \soul\ does
+% for instance not space it out. The contents must, however,
+% not contain potential hyphenation points. (See~\ref{par:Protecting})
+% \item[Protecting: \so{foo \mbox{little} bar}]
+% An \cs{\mbox} also lets \soul\ see the contents as one
+% item, but these may even contain hyphenation points. \cs{\hbox} can
+% be used as a synonym.
+% \item[Omitting: \so{\soulomit{foo}}]
+% The contents of \cs{\soulomit} bypass the soul core and are typeset
+% as is, without being letterspaced or underlined. Hyphenation points are
+% allowed within the argument. The current font remains active, but can be
+% overridden with \cs{\normalfont} etc.
+% \item[Font switching commands: \so{foo \texttt{bar}}]
+% All standard \TeX\ and \LaTeX\ font switching commands are allowed, as
+% well as the \package{yfonts} package \cite{yfonts} font commands like \cs{\textfrak} etc.
+% Further commands have to be registered using the \cs{\soulregister}
+% command (see section~\ref{sec:soulregister}).
+% \item[Breaking up ligatures: \ul{Auf{}lage}]
+% Use |{}| or \cs{\null} to break up ligatures like `fl' in \cs{\ul}, \cs{\st} and \cs{\hl}
+% arguments.
+% This doesn't make sense for \cs{\so} and \cs{\caps}, though, because they break up
+% every unprotected (ungrouped\slash unboxed) ligature, anyway, and would
+% then just add undesirable extra space around the additional item.
+% \end{verblist}
+%
+%
+%
+%
+% \subsection{\texorpdfstring{\dots\ }{... }others don't}
+%
+% Although the new \soul\ is much more robust and forgiving than
+% versions prior to~2.0, there are
+% still some things that are not allowed in arguments.
+% This is due to the complex engine, which has to read and inspect every
+% character before it can hand it over to \TeX's paragraph builder.
+%
+% \begin{verblist}{20}
+% \item[Grouping hyphenatable material: \so{foo {little} bar}]
+% Grouped characters must not contain hyphenation points. Instead of
+% |\so{foo {little}}| write |\so{foo \mbox{little}}|. You get a
+% \texttt{`Re\-con\-struction failed'} error and a black square like
+% \errsquare\ in the \caps{DVI} file where you violated this rule.
+% \item[Discretionary hyphens: \so{Zu\discretionary{k-}{}{c}ker}]
+% The argument must not contain discretionary hyphens. Thus, you have to
+% handle cases like the German word |Zu\discretionary{k-}{}{c}ker| by yourself.
+% \item[Nested soul commands: \ul{foo \so{bar} baz}]
+% \soul\ commands must not be nested. If you really
+% need such, put the inner stuff in a box and use this box. It will, of
+% course, not get broken then.\\
+% \null\qquad|\newbox\anyboxname|\\
+% \null\qquad|\sbox\anyboxname{ \so{the worst} }|\\
+% \null\qquad|\ul{This is by far{\usebox\anyboxname}example!}|\\
+% yields:\\
+% \newbox\anyboxname
+% \sbox\anyboxname{ \so{the worst} }
+% \null\qquad\ul{This is by far{\usebox\anyboxname}example!}
+% \item[Leaking font switches: \def\foo{\bf bar} \so{\foo baz}]
+% A hidden font switching command that leaks into its neighborship
+% causes a \texttt{`Reconstruction failed'} error. To avoid this either
+% register the `container' (|\soulregister{\foo}{0}|), or limit its
+% scope as in |\def\foo{{\bf bar}}|. Note that both
+% solutions yield slightly different results.
+% \item[Material that needs expansion: \so{\romannumeral\year}]
+% In this example \cs{\so} would try to put space between \cs{\romannumeral}
+% and \cs{\year}, which can, of course, not work.
+% You have to expand the argument before you feed it to \soul, or even better:
+% Wrap the material up in a command sequence and let \soul\ expand it:
+% |\def\x{\romannumeral\year}| |\so\x|. \soul\ tries hard to expand
+% enough, yet not too much.
+% \item[Unexpandable material in command sequences: \def\foo{\bar} \so\foo]
+% Some macros might not be expandable in an \cs{\edef} definition^^A
+% \footnote{Try \texttt{\string\edef\string\x\char`\{\string\copyright\char`\}}.
+% Yet \texttt{\string\copyright} works in \soul\ arguments, because it is
+% explicitly taken care of by the package}
+% and have to be protected with \cs{\noexpand} in front. This is automatically done
+% for the following tokens: |~|, \cs{\,}, \cs{\TeX}, \cs{\LaTeX},
+% \cs{\S}, \cs{\slash}, \cs{\textregistered}, \cs{\textcircled}, and \cs{\copyright},
+% as well as for all registered fonts and accents. Instead of putting \cs{\noexpand}
+% manually in front of such commands, as in |\def\foo{foo {\noexpand\bar} bar}| |\so\foo|,
+% you can also register them as special (see section \ref{sec:soulregister}).
+% \item[Other weird stuff: \so{foo \verb|\bar| baz}]
+% \soul\ arguments must not contain \LaTeX\ environments, command definitions,
+% and fancy stuff like |\vadjust|. \soul's |\footnote| command replacement
+% does not support optional arguments. As long as you are writing simple,
+% ordinary `horizontal' material, you are on the safe side.
+% \end{verblist}
+%
+%
+%
+%
+%
+%
+%
+% \begin{table}
+% \begin{center}
+% \catcode`\|=12
+% \newcommand*\pref[1]{{\footnotesize\pageref{cmd:#1}}}
+% \newcommand*\Ast{\rlap{$^\ast$}}
+% \let\m\cs
+% \let\ti\textit
+% \begin{tabular}{r@{\hspace{.6em}}c@{\hspace{.6em}}l}
+% &\hbox to0pt{\hss\footnotesize page\hss}&\\[.5ex]
+% \verb+\so{letterspacing}+& \pref{so} &\so{letterspacing}\\
+% \verb+\caps{CAPITALS, Small Capitals}+& \pref{caps} &\caps{CAPITALS, Small Capitals}\\
+% \verb+\ul{underlining}+& \pref{ul} &\ul{underlining}\\
+% \verb+\st{striking out}+& \pref{st} &\st{striking out}\\
+% \verb+\hl{highlighting}+& \pref{hl} &highlighting\\
+% \\
+% \verb+\soulaccent{\cs}+& \pref{soulaccent} &\ti{add accent} \cs{\cs} \ti{to accent list}\\
+% \verb+\soulregister{\cs}{0}+& \pref{soulregister} &\ti{register command} \m{\cs}\\
+% \verb+\sloppyword{text}+& \pref{sloppyword} &\ti{typeset} \m{text} \ti{with stretchable spaces}\\
+% \\
+% \verb+\sodef\cs{1em}{2em}{3em}+& \pref{sodef} &\ti{define new spacing command} \m{\cs}\\
+% \verb+\resetso+& \pref{resetso} &\ti{reset} \m{\so} \ti{dimensions}\\
+% \verb+\capsdef{////}{1em}{2em}{3em}+\Ast& \pref{capsdef} &\ti{define (default)} \m{\caps} \ti{data entry}\\
+% \verb+\capssave{name}+\Ast& \pref{capssave} &\ti{save} \m{\caps} \ti{database under name} \rlap{\texttt{name}}\\
+% \verb+\capsselect{name}+\Ast& \pref{capssave} &\ti{restore} \m{\caps} \ti{database of name} \rlap{\texttt{name}}\\
+% \verb+\capsreset+\Ast& \pref{capsreset} &\ti{clear caps database}\\
+% \verb+\setul{1ex}{2ex}+& \pref{setul} &\ti{set} \m{\ul} \ti{dimensions}\\
+% \verb+\resetul+& \pref{resetul} &\ti{reset} \m{\ul} \ti{dimensions}\\
+% \verb+\setuldepth{y}+& \pref{setuldepth} &\ti{set underline depth to depth of an} y\\
+% \verb+\setuloverlap{1pt}+& \pref{setuloverlap} &\ti{set underline overlap width}\\
+% \verb+\setulcolor{red}+& \pref{setulcolor} &\ti{set underline color}\\
+% \verb+\setstcolor{green}+& \pref{setstcolor} &\ti{set overstriking color}\\
+% \verb+\sethlcolor{blue}+& \pref{sethlcolor} &\ti{set highlighting color}\\
+% \end{tabular}
+% \caption{List of all available commands. The number points to the
+% page where the command is described. Those marked
+% with a little asterisk are only available when the package
+% is used together with \LaTeX, because they rely on the
+% \emph{New Font Selection Scheme (NFSS)} used in \LaTeX.}
+% \label{tab:survey}
+% \end{center}
+% \end{table}
+%
+%
+%
+%
+%
+%
+%
+% \subsection{Troubleshooting}
+%
+% Unfortunately, there's just one helpful error message provided by
+% the \soul\ package, that actually describes the underlying problem. All other
+% messages are generated directly by \TeX\ and show the low-level
+% commands that \TeX\ wasn't happy with. They'll hardly point you
+% to the violated rule as described in the paragraphs above.
+% If you get such a mysterious error message for a line that contains
+% a \soul\ statement, then comment that statement out and see if the message
+% still appears.
+% \texttt{`Incomplete }\cs{\ifcat}\texttt{'} is such a non-obvious message.
+% If the message doesn't appear now, then check the argument for
+% violations of the rules as listed in~\S\S\,20--26.
+%
+%
+%
+% \subsubsection{\texttt{`Reconstruction failed'}}
+%
+% This message appears, if \ref{par:Grouping hyphenatable material} or
+% \ref{par:Leaking font switches} was
+% violated. It is caused by the fact that the reconstruction pass
+% couldn't collect tokens with an overall width of the syllable that
+% was measured by the analyzer. This does either occur when you
+% grouped hyphenatable text or used an unregistered command
+% that influences the syllable width. Font switching commands belong
+% to the latter group. See the above cited sections for how to fix
+% these problems.
+%
+%
+%
+% \subsubsection{Missing characters}
+%
+% If you have redefined the internal font as described in section \ref{sec:internalfont},
+% you may notice that some characters are omitted without any error message
+% being shown. This happens if you have chosen, let's say, a font with
+% only 128~characters like the |cmtt10| font, but are using characters
+% that aren't represented in this font, e.\,g.~characters with codes
+% greater than~127.
+%
+%
+%
+%
+%
+%
+%
+%
+%
+% \section{\texorpdfstring{\so{Letterspacing}}{Letterspacing}}
+%
+% \subsection{How it works}
+% \label{sec:so}
+%
+% The base macro for letterspacing is called \describemacro{\so}.
+% It typesets the given argument with \syn{inter-letter space}
+% between every two characters, \syn{inner space} between words
+% and \syn{outer space} before and after the spaced out text.
+% If we let ``$\cdot$'' stand for \syn{inter-letter space}, ``$\ast$''
+% for \syn{inner spaces} and ``$\bullet$'' for \syn{outer
+% spaces,} then the input on the left side of the following table
+% will yield the schematic output on the right side:
+%
+% \begin{center}
+% \def\.{$\cdot$}
+% \def\-{\kern1pt$\ast$\kern1pt}
+% \def\*{$\bullet$}
+% \def\_{\texttt{\char"20}}
+% \begin{tabular}{ccc}
+% 1.& \verb*|XX\so{aaa bbb ccc}YY|& \textsf{XXa\.a\.a\-b\.b\.b\-c\.c\.cYY}\\
+% 2.& \verb*|XX \so{aaa bbb ccc} YY|& \textsf{XX\*a\.a\.a\-b\.b\.b\-c\.c\.c\*\kern-1ptYY}\\
+% 3.& \verb*|XX {\so{aaa bbb ccc}} YY|& \textsf{XX\*a\.a\.a\-b\.b\.b\-c\.c\.c\*\kern-1ptYY}\\
+% 4.& \verb*|XX \null{\so{aaa bbb ccc}}{} YY|& \textsf{XX\_a\.a\.a\-b\.b\.b\-c\.c\.c\_YY}\\
+% \end{tabular}
+% \end{center}
+% ^^A* % fool vim (fixes syntax highlighting)
+%
+% \noindent
+% Case~1 shows how letterspacing macros (\cs{\so} and \cs{\caps}) behave if
+% they aren't following or followed by a space: they omit outer space around
+% the \soul\ statement. Case~2 is what you'll mostly need---letterspaced
+% text amidst running text. Following and leading space get replaced by
+% \syn{outer space}. It doesn't matter if there are opening braces before
+% or closing braces afterwards. \soul\ can see through both of them (case~3).
+% Note that leading space has to be at least |5sp| wide to be recognized as
+% space, because \LaTeX\ uses tiny spaces generated by |\hskip1sp| as marker.
+% Case~4 shows how to enforce normal spaces instead of \syn{outer spaces:}
+% Preceding space can be hidden by |\kern0pt| or \cs{\null} or any character.
+% Following space can also be hidden by any token, but note that a typical macro name
+% like \cs{\relax} or \cs{\null} would also hide the space thereafter.
+%
+%
+% The values are predefined for typesetting facsimiles mainly with
+% \emph{Fraktur} fonts.
+% You can define your own spacing
+% macros or overwrite the original \cs{\so} meaning using the macro
+% \describemacro{\sodef}:
+%
+% \begin{syntax}
+% |\sodef|\<cmd>|{|\<font>|}{|\<inter-letter space>|}{|\<inner space>|}{|\<outer space>|}|
+% \end{syntax}
+%
+% The space dimensions, all of which are mandatory, should be defined in terms of |em|
+% letting them grow and shrink with the respective fonts.
+%
+% \begin{example}
+% |\sodef\an{}{.4em}{1em plus1em}{2em plus.1em minus.1em}|
+% \end{example}
+%
+% After that you can type `|\an{example}|' to get
+% {\sodef\an{}{.4em}{1em plus1em}{2em plus.1em minus.1em}^^A
+% `\an{example}'.}
+% The \describemacro{\resetso} command resets \cs{\so}
+% to the default values.
+%
+%
+%
+%
+% \subsection{Some examples}
+%
+%^^A=====================================================
+% \begin{examples}
+%
+% \soultest{Ordinary text}
+% |\so{electrical industry}|
+% {\so{electrical industry}}
+%
+% \soultest{Use \texttt{\string\-} to mark hyphenation points}
+% |\so{man\-u\-script}|
+% {\so{man\-u\-script}}
+%
+% \soultest{Accents are recognized}
+% |\so{le th\'e\^atre}|
+% {\so{le th\'e\^atre}}
+%
+% \soultest{\texttt{\string\mbox} and \texttt{\string\hbox} protect material that
+% contains hyphenation points. The contents are treated as one, unbreakable entity}
+% |\so{just an \mbox{example}}|
+% {\so{just an \mbox{example}}}
+%
+% \soultest{Punctuation marks are spaced out, if they are
+% put into the group}
+% |\so{inside.} \& \so{outside}.|
+% {\so{inside.} \& \so{outside}.}
+%
+% \soultest{Space-out skips may be removed by typing \texttt{\string\<}.
+% It's, however, desirable to put the quotation marks out of
+% the argument}
+% |\so{``\<Pennsylvania\<''}|
+% {\so{``\<Pennsylvania\<''}}
+%
+% \soultest{Numbers should never be spaced out}
+% |\so{1\<3 December {1995}}|
+% {\so{1\<3 December {1995}}}
+%
+% \soultest{Explicit hyphens like |-|, |--| and |---| are recognized.
+% \texttt{\string\slash} outputs a slash and enables \TeX\ to break the line
+% afterwards}
+% |\so{input\slash output}|
+% {\so{input\slash output}}
+%
+% \soultest{To keep \TeX\ from breaking lines between the hyphen and `jet'
+% you have to protect the hyphen. This is no \soul\ restriction
+% but normal \TeX\ behavior}
+% |\so{\dots and \mbox{-}jet}|
+% {\so{\dots and \mbox{-}jet}}
+%
+% \soultest{The \texttt{\~} command inhibits line breaks}
+% |\so{unbreakable~space}|
+% {\so{unbreakable~space}}
+%
+% \soultest{\texttt{\string\\} works as usual. Additional arguments
+% like \texttt{*} or vertical space are not accepted, though}
+% |\so{broken\\line}|
+% {\so{broken\\line}}
+%
+% \soultest{\texttt{\string\break} breaks the line without filling it with white space}
+% |\so{pretty awful\break test}|
+% {\so{pretty awful\break test}}
+%
+% \end{examples}
+%^^A=====================================================
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+% \subsection[Typesetting \texorpdfstring{\caps{caps-and-small-caps}}{caps-and-small-caps} fonts]
+% {Typesetting capitals-and-small-capitals fonts}
+%
+% There is a special letterspacing command called \describemacro{\caps},
+% which differs from \cs{\so} in that it switches to caps-and-small-caps
+% font shape, defines only slight spacing and is able to select spacing
+% value sets from a database. This is a requirement for high-quality
+% typesetting \cite{Tschichold}. The following lines show the effect
+% of \cs{\caps} in comparison with the normal textfont and with
+% small-capitals shape:
+%
+% \def\sampletext{DONAUDAMPFSCHIFFAHRTSGESELLSCHAFT}
+% \medskip\noindent
+% \begin{tabular}{rl}
+% |\normalfont|&\sampletext\\
+% |\scshape|&{\scshape\sampletext}\\
+% |\caps|&\caps\sampletext\\
+% ^^A|\person|&\person\sampletext\\
+% \end{tabular}
+%
+% \medbreak\noindent
+% The \cs{\caps} font database is by default empty, i.\,e., it contains
+% just a single default entry, which yields the result as shown in the
+% example above.
+% New font entries may be added \emph{on top} of this list using the \describemacro{\capsdef}
+% command, which takes five arguments: The first argument describes the font with
+% \emph{encoding, family, series, shape,} and \emph{size,}^^A
+% \footnote{as defined by the \caps{NFSS}, the ``New Font Selection Scheme''}
+% each optionally
+% (e.\,g.~|OT1/cmr/m/n/10| for this very font, or only |/ppl///12| for all
+% \emph{palatino} fonts at size 12\,pt). The \emph{size} entry may also contain
+% a size range (\texttt{5-10}), where zero is assumed for an omitted lower
+% boundary (\texttt{-10}) and a very, very big number for an omitted upper
+% boundary (\texttt{5-}). The
+% upper boundary is not included in the range, so, in the example below, all
+% fonts with sizes greater or equal 5\,pt and smaller than 15\,pt are accepted
+% ($5\,\mbox{pt}\le size<15\,\mbox{pt}$).
+% The second argument may contain font switching commands such as \cs{\scshape},
+% it may as well be empty or contain debugging commands (e.\,g.~|\message{*}|).
+% The remaining three, mandatory arguments are the spaces as described in
+% section~\ref{sec:so}.
+%
+% \begin{example}
+% |\capsdef{T1/ppl/m/n/5-15}{\scshape}{.16em}{.4em}{.2em}|
+% \end{example}
+%
+% The \cs{\caps} command goes through the data list from top to bottom
+% and picks up the first matching set, so the order of definition is essential.
+% The last added entry is examined first, while the pre-defined default entry
+% will be examined last and will match any font, if no entry was taken before.
+%
+% To override the default values, just define a new default entry using
+% the identifier |{////}|. This entry should be defined first, because no
+% entry after it can be reached.
+%
+% The \cs{\caps} database can be cleared with the \describemacro{\capsreset}
+% command and will only contain the default entry thereafter. The
+% \describemacro{\capssave} command saves the whole current database
+% under the given name. \describemacro{\capsselect} restores such a database.
+% This allows to predefine different groups of \cs{\caps} data sets:
+%
+% \begin{example}
+% |\capsreset|\\
+% |\capsdef{/cmss///12}{}{12pt}{23pt}{34pt}|\\
+% |\capsdef{/cmss///}{}{1em}{2em}{3em}|\\
+% |...|\\
+% |\capssave{wide}|\\
+% \end{example}
+% \indent
+% \begin{example}
+% |%---------------------------------------|\\
+% |\capsreset|\\
+% |\capsdef{/cmss///}{}{.1em}{.2em}{.3em}|\\
+% |...|\\
+% |\capssave{narrow}|\\
+% \end{example}
+% \indent
+% \begin{example}
+% |%---------------------------------------|\\
+% |{\capsselect{wide}|\\
+% |\title{\caps{Yet Another Silly Example}}|\\
+% |}|\\
+% \end{example}
+%
+% See the `|example.cfg|' file for a detailed example.
+% If you have defined a bunch of sets for different fonts and sizes,
+% you may lose control over what fonts are used by the package. With the
+% package option \DescribeOption{capsdefault}\option{capsdefault} selected,
+% \cs{\caps} prints its argument underlined, if no set was specified for a
+% particular font and the default set had to be used.
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+% \subsection{Typesetting Fraktur}
+% \label{sec:fraktur}
+%
+% Black letter fonts^^A
+%^^A%%
+% \footnote{See the great black letter fonts, which \person{Yannis Haralambous}
+% kindly provided, and the \package{oldgerm} and \package{yfonts} package~\cite{yfonts}
+% as their \LaTeX\ interfaces.}
+%^^A%%
+% deserve some additional considerations. As stated in section~\ref{sec:typesetting},
+% the ligatures |ch|, |ck|, |sz|~(\cs{\ss}), and~|tz| have to remain unbroken in spaced out
+% \emph{Fraktur} text. This may look strange at first glance, but you'll get used to it:
+%
+% \begin{example}
+% |\textfrak{\so{S{ch}u{tz}vorri{ch}tung}}|
+% \end{example}
+%
+% You already know that grouping keeps the |soul| mechanism from separating such ligatures.
+% This is quite important for |s:|, |a*|, and~|"a|. As hyphenation is stronger than
+% grouping, especially the |sz| may cause an error, if hyphenation happens to occur between
+% the letters |s| and~|z|. (\TeX\ hyphenates the German word |auszer| wrongly like
+% |aus-zer| instead of like |au-szer|, because the German hyphenation patterns
+% do, for good reason, not see |sz| as `\cs{\ss}'.) In such cases you can protect tokens with the
+% sequence e.\,g.~|\mbox{sz}| or a properly defined command. The \cs{\ss} command,
+% which is defined by the \package{yfonts} package, and similar commands will suffice as well.
+%
+%
+%
+%
+%
+%
+%
+% \subsection{Dirty tricks}
+% \label{sec:dirtytricks}
+%
+% Narrow columns are hard to set, because they don't allow much spacing
+% flexibility, hence long words often cause overfull boxes. A macro
+% could use \cs{\so} to insert stretchability between the single
+% characters. Table~\ref{tab:dirtytricks} shows some text typeset with such
+% a macro at the left side and under \emph{plain} conditions at
+% the right side, both with a width of~6\,pc.
+%
+% \def\sampletext{Some magazines and newspapers prefer this kind of spacing
+% because it reduces hyphenation problems to a minimum\<. Unfortunately\<, such
+% paragraphs aren't especially beautiful\<.}
+% \newbox\dirtytrick
+% \setbox\dirtytrick\vbox{
+% \batchmode ^^A we don't want to see all these overfull boxes ...
+% \leavevmode\hspace{0ptplus1fil}
+% \hbox{\parindent0pt\plainsetup\let\<\relax
+% \vtop{\hsize6pc\raggedright\sampletext}\hskip1em
+% \vtop{\hsize6pc\magstylepar\sampletext}\hskip1em
+% \vtop{\hsize6pc\sampletext}\hss}
+% \errorstopmode}
+%
+% \begin{table}
+% \begin{center}
+% \overfullrule5pt
+% \usebox\dirtytrick
+% \caption{Ragged-right, magazine style (using \soul), and block-aligned
+% in comparison. But, frankly, none of them is really acceptable.
+% (Don't do this at home, children!)}
+% \label{tab:dirtytricks}
+% \end{center}
+% \end{table}
+%
+%
+%
+%
+%
+%
+%
+% \section{\texorpdfstring{\ul{Underlining}}{Underlining}}
+%
+% The underlining macros are my answer to Prof.~\person{Knuth'{\normalfont s}}
+% exercise 18.26 from his \TeX{}book~\cite{DEK}. \texttt{:-)} Most of what
+% is said about the macro \describemacro{\ul} is also true of the
+% striking out macro \describemacro{\st} and the highlighting macro \describemacro{\hl},
+% both of which are in fact derived from the former.
+%
+%
+%
+%
+% \subsection{Settings}
+%
+% \subsubsection{Underline depth and thickness}
+%
+% The predefined \syn{underline depth} and \syn{thickness}
+% work well with most fonts. They can be changed using the macro \describemacro{\setul}.
+%
+% \begin{syntax}
+% |\setul{|\<underline depth>|}{|\<underline thickness>|}|
+% \end{syntax}
+%
+% Either dimension can be omitted, in which case there has to be
+% an empty pair of braces.
+% Both values should be defined in terms of |ex|, letting them
+% grow and shrink with the respective fonts.
+% The \describemacro{\resetul} command restores the standard values.
+%
+% Another way to set the \syn{underline depth} is to use the macro
+% \describemacro{\setuldepth}. It sets the depth such that the
+% underline's upper edge lies 1\,pt beneath the given argument's
+% deepest depth. If the argument is empty, all
+% letters---i.\,e.\ all characters whose \cs{\catcode} currently
+% equals 11---are taken. Examples:
+%
+% \begin{example}
+% |\setuldepth{ygp}|\\
+% |\setuldepth\strut|\\
+% |\setuldepth{}|\\
+% \end{example}
+%
+%
+%
+% \subsubsection{Line color}
+%
+% The underlines are by default black. The color can be changed by
+% using the \describemacro{\setulcolor} command. It takes one argument that can be any
+% of the color specifiers as described in the |color| package. This package
+% has to be loaded explicitly.
+%
+% \indent
+% \begin{example}
+% |\documentclass{article}|\\
+% |\usepackage{color,soul}|\\
+% |\definecolor{darkblue}{rgb}{0,0,0.5}|\\
+% |\setulcolor{darkblue}|\\
+% \end{example}
+%
+% \indent
+% \begin{example}
+% |\begin{document}|\\
+% |...|\\
+% |\ul{Cave: remove all the underlines!}|\\
+% |...|\\
+% |\end{document}|\\
+% \end{example}
+%
+%
+% The colors for overstriking lines and highlighting are likewise set
+% with \describemacro{\setstcolor} (default: black) and \describemacro{\sethlcolor}
+% (default: yellow). If the \package{color} package wasn't loaded,
+% underlining and overstriking color are black, while highlighting
+% is replaced by underlining.
+%
+%
+%
+%
+%
+%
+%
+% \subsubsection{The \program{dvips} problem}
+% \label{sec:dvips}
+%
+% \ul{Underlining}, \st{striking out} and highlighting build up
+% their lines with many short line segments. If you used the `\program{dvips}'
+% program with default settings, you would get little gaps on some places, because
+% the \emph{maxdrift} parameter allows the single objects to drift
+% this many pixels from their real positions.
+% \bigbreak
+%
+% \noindent
+% There are two ways to avoid the problem, where the \soul\ package
+% chooses the second by default:
+% \begin{enumerate}
+% \item
+% Set the \emph{maxdrift} value to zero, e.\,g.: |dvips -e 0 file.dvi|.
+% This is probably not a good idea, since the letters may then no longer be
+% spaced equally on low resolution printers.
+% \item
+% Let the lines stick out by a certain amount on each side so that they
+% overlap. This overlap amount can be set using the \describemacro{\setuloverlap}
+% command. It is set to 0.25\,pt by default. |\setuloverlap{0pt}| turns overlapping off.
+% \end{enumerate}
+%
+%
+%
+%
+%
+%
+% \subsection{Some examples}
+%
+%^^A=====================================================
+% \begin{examples}
+%
+% \soultest{Ordinary text}
+% |\ul{electrical industry}|
+% {\ul{electrical industry}}
+%
+% \soultest{Use \texttt{\string\-} to mark hyphenation points}
+% |\ul{man\-u\-script}|
+% {\ul{man\-u\-script}}
+%
+% \soultest{Accents are recognized}
+% |\ul{le th\'e\^atre}|
+% {\ul{le th\'e\^atre}}
+%
+% \soultest{\texttt{\string\mbox} and \texttt{\string\hbox} protect material that
+% contains hyphenation points. The contents are treated as one, unbreakable entity}
+% |\ul{just an \mbox{example}}|
+% {\ul{just an \mbox{example}}}
+%
+% \soultest{Explicit hyphens like |-|, |--| and |---| are recognized.
+% \texttt{\string\slash} outputs a slash and enables \TeX\ to break the line
+% afterwards}
+% |\ul{input\slash output}|
+% {\ul{input\slash output}}
+%
+% \soultest{To keep \TeX\ from breaking lines between the hyphen and `jet'
+% you have to protect the hyphen. This is no \soul\ restriction
+% but normal \TeX\ behavior}
+% |\ul{\dots and \mbox{-}jet}|
+% {\ul{\dots and \mbox{-}jet}}
+%
+% \soultest{The \texttt{\~} command inhibits line breaks}
+% |\ul{unbreakable~space}|
+% {\ul{unbreakable~space}}
+%
+% \soultest{\texttt{\string\\} works as usual. Additional arguments
+% like \texttt{*} or vertical space are not accepted, though}
+% |\ul{broken\\line}|
+% {\ul{broken\\line}}
+%
+% \soultest{\texttt{\string\break} breaks the line without filling it with white space}
+% |\ul{pretty awful\break test}|
+% {\ul{pretty awful\break test}}
+%
+% \soultest{Italic correction needs to be set manually}
+% |\ul{foo \emph{bar\/} baz}|
+% {\ul{foo \emph{bar\/} baz}}
+%
+% \end{examples}
+%^^A=====================================================
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+% \section{Customization}
+%
+% \subsection{Adding accents}
+% \label{sec:soulaccent}
+%
+% The \soul\ scanner generally sees every input token separately.
+% It has to be taught that some tokens belong together. For accents this is done
+% by registering them via the \describemacro{\soulaccent} macro.
+%
+% \begin{syntax}
+% |\soulaccent{|\<accent command>|}|
+% \end{syntax}
+%
+% The standard accents, however, are already pre-registered:
+% |\`|, |\'|, |\^|, |\"|, |\~|, |\=|, |\.|, |\u|, |\v|, |\H|, |\t|,
+% |\c|, |\d|, |\b|, and |\r|. If used together with the \package{german}
+% package, \soul\ automatically adds the |"| command.
+% Let's assume you have defined |\%| to put some weird accent on
+% the next character. Simply put the following line into your |soul.cfg|
+% file (see section~\ref{sec:config}):
+%
+% \begin{example}
+% |\soulaccent{\%}|
+% \end{example}
+%
+% Note that active characters like the |"| command have already
+% to be \cs{\active} when they are stored or they won't be recognized
+% later. This can be done temporarily, as in |{\catcode\`"\active\soulaccent{"}}|.
+%
+%
+%
+%
+% \subsection{Adding font commands}
+% \label{sec:soulregister}
+%
+% To convince \soul\ not to feed font switching (or other)
+% commands to the analyzer, but rather to execute them immediately,
+% they have to be registered, too. The \describemacro{\soulregister} macro
+% takes the name of a command name and either |0| or |1| for the number
+% of arguments:
+%
+% \begin{syntax}
+% |\soulregister{|\<command name>|}{|\<number of arguments>|}|
+% \end{syntax}
+%
+% If \cs{\bf} and \cs{\emph} weren't already registered, you would
+% write the following into your |soul.cfg| configuration file:
+%
+% \begin{example}
+% |\soulregister{\bf}{0} % {\bf foo}| \\
+% |\soulregister{\emph}{1} % \emph{bar}|\\
+% \end{example}
+%
+%
+% All standard \TeX\ and \LaTeX\ font commands, as well as the
+% \package{yfonts} commands are already pre-registered:
+%
+% \begin{example}
+% |\em, \rm, \bf, \it, \tt, \sc, \sl, \sf, \emph, \textrm,|\\
+% |\textsf, \texttt, \textmd, \textbf, \textup, \textsl,|\\
+% |\textit, \textsc, \textnormal, \rmfamily, \sffamily,|\\
+% |\ttfamily, \mdseries, \upshape, \slshape, \itshape,|\\
+% |\scshape, \normalfont, \tiny, \scriptsize, \footnotesize,|\\
+% |\small, \normalsize, \large, \Large, \LARGE, \huge, \Huge,|\\
+% |\MakeUppercase, \textsuperscript, \footnote,|\\
+% |\textfrak, \textswab, \textgoth, \frakfamily,|\\
+% |\swabfamily, \gothfamily|\\
+% \end{example}
+%
+% You can also register other commands as fonts, so the
+% analyzer won't see them. This may be necessary for some
+% macros that \soul\ refuses to typeset correctly.
+% But note, that \cs{\so} and \cs{\caps} won't put their
+% letter-skips around then.
+%
+%
+%
+%
+%
+%
+% \subsection{Changing the internal font}
+% \label{sec:internalfont}
+%
+% The \soul\ package uses the |ectt1000| font while it analyzes
+% the syllables. This font is used, because it
+% has 256~mono-spaced characters without any kerning.
+% It belongs to \person{J\"org Knappen'\textrm{s}}
+% \caps{EC}-fonts, which should be part of every modern \TeX\ installation.
+% If \TeX\ reports ``\texttt{I can't find file `ectt1000'}'' you don't
+% seem to have this font installed. It is recommended that
+% you install at least the file |ectt1000.tfm| which has less than 1.4\,kB\null.
+% Alternatively, you can let the \soul\ package use the |cmtt10| font that
+% is part of any installation, or some other mono-spaced font:
+%
+% \begin{example}
+% |\font\SOUL@tt=cmtt10|
+% \end{example}
+%
+% Note, however, that \soul\ does only handle characters,
+% for which the internal font has a character with the same
+% character code. As |cmtt10| contains only characters with codes
+% 0 to~127, you can't typeset characters with codes 128 to~255.
+% These 8-bit character codes are used by many fonts with non-ascii
+% glyphs. So the |cmtt10| font will, for example, not work for |T2A|
+% encoded cyrillic characters.
+%
+%
+%
+%
+%
+%
+%
+% \subsection{The configuration file}
+% \label{sec:config}
+%
+% If you want to change the predefined settings or add new features,
+% then create a file named `|soul.cfg|' and put it in a directory, where \TeX\
+% can find it. This configuration file will then be loaded
+% at the end of the |soul.sty| file, so you may redefine
+% any settings or commands therein, select package options and even
+% introduce new ones. But if you intend to give
+% your documents to others, don't forget to give them the
+% required configuration files, too! That's how such a file
+% could look like:
+%
+% \indent
+% \begin{example}
+% |% define macros for logical markup|\\
+% |\sodef\person{\scshape}{0.125em}{0.4583em}{0.5833em}|\\
+% \\
+% |\sodef\SOUL@@@versal{\upshape}{0.125em}{0.4583em}{0.5833em}|\\
+% |\DeclareRobustCommand*\versal[1]{%|\\
+% | \MakeUppercase{\SOUL@@@versal{#1}}%|\\
+% |}|\\
+% \end{example}
+%
+% \indent
+% \begin{example}
+% |% load the color package and set|\\
+% |% a different highlighting color|\\
+% |\RequirePackage{color}|\\
+% |\definecolor{lightblue}{rgb}{.90,.95,1}|\\
+% |\sethlcolor{lightblue}|\\
+% |\endinput|
+% \end{example}
+%
+% You can safely use the |\SOUL@@@| namespace for internal macros---it
+% won't be used by the \soul\ package in the future.
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+% \section{Miscellaneous}
+%
+% \subsection{Using \texorpdfstring{\soul\ }{soul }with other flavors of \texorpdfstring{\TeX}{TeX}}
+% \label{sec:plain}
+%
+% This documentation describes how to use \soul\ together
+% with \LaTeXe, for which it is optimized. It works, however, with
+% all other flavors of \TeX, too. There are just some minor restrictions
+% for Non-\LaTeX\ use:
+%
+% The \cs{\caps} command doesn't use a database, it is only a dumb
+% definition with fixed values. It switches to \cs{\capsfont}, which---unless
+% defined explicitly like in the following example---won't really change
+% the used font at all. The commands \cs{\capsreset} and \cs{\capssave}
+% do nothing.
+%
+% \begin{example}
+% |\font\capsfont=cmcsc10|\\
+% |\caps{Tschichold}|\\
+% \end{example}
+%
+% None of the commands are made `robust', so they have to be
+% explicitly protected in fragile environments like in \cs{\write}
+% statements.
+% To make use of colored underlines or highlighting you have to
+% use the \package{color} package wrapper from \caps{CTAN}^^A
+% \footnote{\texttt{CTAN:/macros/plain/graphics/\char`\{miniltx.tex,color.tex\char`\}}},
+% instead of the \package{color} package directly:
+%
+% \begin{example}
+% |\input color|\\
+% |\input soul.sty|\\
+% |\hl{highlighted}|\\
+% |\bye|\\
+% \end{example}
+%
+% The \option{capsdefault} package option is mapped to a simple command
+% \describemacro{\capsdefault}.
+%
+%
+%
+%
+%
+%
+%
+% \subsection{Using \texorpdfstring{\soul\ }{soul }commands for logical markup}
+% \label{sec:markup}
+%
+% It's generally a bad idea to use font style commands like \cs{\textsc}
+% in running text. There should always be some reasoning behind changing
+% the style, such as ``names of persons shall be typeset in a caps-and-small-caps
+% font''. So you declare in your text just that some words are the name of a
+% person, while you define in the preamble or, even better, in a separate
+% style file how to deal with persons:
+%
+% \begin{example}
+% |\newcommand*\person{\textsc}|\\
+% |...|\\
+% |``I think it's a beautiful day to go to the zoo and feed|\\
+% |the ducks. To the lions.'' --~\person{Brian Kantor}|\\
+% \end{example}
+%
+% It's quite simple to use \soul\ commands that way:
+%
+% \begin{example}
+% |\newcommand\comment*{\ul} % or \let\comment=\ul|\\
+% |\sodef\person{\scshape}{0.125em}{0.4583em}{0.5833em}|\\
+% \end{example}
+%
+% Letterspacing commands like \cs{\so} and \cs{\caps} have to
+% check whether they are followed by white space, in which case
+% they replace that space by \syn{outer space}. Note that \soul\
+% does look through closing braces. Hence you can conveniently bury
+% a \soul\ command within another macro like in the following
+% example. Use any other token to hide following space if necessary,
+% for example the \cs{\null} macro.
+%
+% \begin{example}
+% |\DeclareRobustCommand*\versal[1]{%|\\
+% | \MakeUppercase{\SOUL@@@versal{#1}}%|\\
+% |}|\\
+% |\sodef\SOUL@@@versal{\upshape}{0.125em}{0.4583em}{0.5833em}|\\
+% \end{example}
+%
+%
+% But what if the \soul\ command is for some reason not the last one
+% in that macro definition and thus cannot look ahead at the following token?
+%
+%
+% \begin{example}
+% |\newcommand*\somsg[1]{\so{#1}\message{#1}}|\\
+% |...|\\
+% |foo \somsg{bar} baz % wrong spacing after `bar'!|\\
+% \end{example}
+%
+% In this case you won't get the following space replaced by \emph{outer space}
+% because when \soul\ tries to look ahead, it only sees the token
+% \cs{\message} and consequently decides that there is no space to replace.
+% You can get around this by explicitly calling the space scanner again.
+%
+% \begin{example}
+% |\newcommand*\somsg[1]{{%|\\
+% | \so{#1}%|\\
+% | \message{bar}%|\\
+% | \let\\\SOUL@socheck|\\
+% | \\%|\\
+% |}}|\\
+% \end{example}
+%
+% However, \cs{\SOUL@socheck} can't be used directly, because it would discard
+% any normal space. \cs{\\} doesn't have this problem.
+% The additional pair of braces avoids that its definition leaks out
+% of this macro. In the example above you could, of course, simply
+% have put \cs{\message} in front, so you hadn't needed to
+% use the scanner macro \cs{\SOUL@socheck} at all.
+%
+% Many packages do already offer logical markup commands that default
+% to some standard \LaTeX\ font commands or to \cs{\relax}. One example
+% is the \package{jurabib} package~\cite{jurabib}, which makes the use of
+% \soul\ a challenge. This package implements lots of
+% formatting macros. Let's have a look at one of them, \cs{\jbauthorfont},
+% which is used to typeset author names in citations.
+% The attempt to simply
+% define |\let\jbauthorfont\caps| fails, because the macro isn't directly
+% applied to the author name as in |\jbauthorfont{Don Knuth}|, but
+% to another command sequence: |\jbauthorfont{\jb@@author}|. Not even
+% \cs{\jb@@author} contains the name, but instead further commands that
+% at last yield the requested name. That's why we have to expand
+% the contents first. This is quite tricky, because we must not
+% expand too much, either. Fortunately, we can offer the contents
+% wrapped up in yet another macro, so that \soul\ knows that it has to
+% use its own macro expansion mechanism:
+%
+% \begin{example}
+% |\renewcommand*\jbauthorfont[1]{{%|\\
+% | \def\x{#1}%|\\
+% | \caps\x|\\
+% |}}|\\
+% \end{example}
+%
+% Some additional kerning after |\caps\x| wouldn't hurt, because
+% the look-ahead scanner is blinded by further commands that follow
+% in the \package{jurabib} package. Now we run into the next problem:
+% cited names may contain commands
+% that must not get expanded. We have to register them as special
+% command:
+%
+% \begin{example}
+% |\soulregister\jbbtasep{0}|\\
+% |...|\\
+% \end{example}
+%
+% But such registered commands bypass \soul's kernel and we don't
+% get the correct spacing before and afterwards. So we end up
+% redefining \cs{\jbbtasep}, whereby you should, of course, use
+% variables instead of numbers:
+%
+% \begin{example}
+% |\renewcommand*\jbbtasep{%|\\
+% | \kern.06em|\\
+% | \slash|\\
+% | \hskip.06em|\\
+% | \allowbreak|\\
+% |}|\\
+% \end{example}
+%
+% Another problem arises: bibliography entries that must not get
+% teared apart are supposed to be enclosed in additional braces.
+% This, however, won't work with \soul\ because of
+% \ref{par:Grouping hyphenatable material}. A simple trick will
+% get you around that problem: define a dummy command that only
+% outputs its argument, and register that command:
+%
+% \begin{example}
+% |\newcommand*\together[1]{#1}|\\
+% |\soulregister\together{1}|\\
+% \end{example}
+%
+% Now you can write ``|Author = {\together{Don Knuth}}|'' and
+% \package{jurabib} won't dare to reorder the parts of the name.
+% And what if some name shouldn't get letterspaced at all? Overriding
+% a conventional font style like \cs{\textbf} that was globally
+% set is trivial, you just have to specify the style that you
+% prefer in that very bibliography entry. In our example, if we
+% wanted to keep \soul\ from letterspacing a particular entry,
+% although they are all formatted by our \cs{\jbauthorfont}
+% and hence fed to \cs{\caps}, we'd use the following construction:
+%
+% \begin{example}
+% |Author = {\soulomit{\normalfont\huge Donald E. Knuth}}|\\
+% \end{example}
+%
+% The \package{jurabib} package is probably one of the more
+% demanding packages to collaborate with \soul. Everything else
+% can just become easier.
+%
+%
+%
+%
+%
+%
+%
+%
+% \subsection{Typesetting long words in narrow columns}
+% \label{sec:sloppyword}
+%
+% Narrow columns are best set |flushleft|, because not even the best
+% hyphenation algorithm can guarantee acceptable line breaks without
+% overly stretched spaces.
+% However, in some rare cases one may be \emph{forced} to typeset
+% block aligned. When typesetting in languages like German, where
+% there are really long words, the \describemacro{\sloppyword} macro
+% might help a little bit. It adds enough stretchability between the
+% single characters to make the hyphenation algorithm happy, but
+% is still not as ugly as the example in section~\ref{sec:dirtytricks}
+% demonstrates. In the following example the left column was typeset
+% as ``|Die \sloppyword{Donau...novelle} wird ...|'':
+%
+% \begin{center}
+% \def\word{Do\-nau\-dampf\-schiff\-fahrts\-ge\-sell\-schafts\-^^A
+% ka\-pi\-t\"ans\-wit\-wen\-pen\-si\-ons\-ge\-setz\-no\-vel\-le}
+% \begin{minipage}{1.5in}
+% \plainsetup
+% Die
+% \expandafter\sloppyword\expandafter{\word}
+% wird mit sofortiger Wirkung au\ss er Kraft gesetzt.
+% \end{minipage}
+% \hspace{1em}
+% \batchmode
+% \begin{minipage}{1.5in}
+% \plainsetup
+% Die \word\ wird mit sofortiger Wirkung au\ss er Kraft gesetzt.
+% \end{minipage}
+% \errorstopmode
+% \end{center}
+%
+%
+%
+%
+%
+%
+%
+% \subsection{Using \texorpdfstring{\soul\ }{soul }commands in section headings}
+%
+% Letterspacing was often used for section titles in the past,
+% mostly centered and with a closing period. The following example
+% shows how to achieve this using the \package{titlesec}
+% package \cite{titlesec}:
+%
+% \begin{example}
+% |\newcommand*\periodafter[2]{#1{#2}.}|\\
+% |\titleformat{\section}[block]|\\
+% | {\normalfont\centering}|\\
+% | {\thesection.}|\\
+% | {.66em}|\\
+% | {\periodafter\so}|\\
+% |...|\\
+% |\section{Von den Maassen und Maassst\"aben}|\\
+% \end{example}
+%
+% \bigbreak
+% This yields the following output:
+%
+% \bigskip
+% \newbox\examplebox
+% \sbox\examplebox{
+% \begin{minipage}{.9\textwidth}
+% \small
+% \bigskip
+% \begin{center}
+% \so{1\<. Von den Maassen und Maassst\"aben}.
+% \bigskip
+% \end{center}
+% \end{minipage}}
+% \fbox{\usebox\examplebox}
+% \bigbreak
+%
+% \noindent
+% The \cs{\periodafter} macro adds a period to the title, but not to
+% the entry in the table of contents. It takes the name of a command as
+% argument, that shall be applied to the title, for example~\cs{\so}.
+% Here's a more complicated and complete example:
+%
+% \begin{example}
+% |\documentclass{article}|\\
+% |\usepackage[latin1]{inputenc}|\\
+% |\usepackage[T1]{fontenc}|\\
+% |\usepackage{german,soul}|\\
+% |\usepackage[indentfirst]{titlesec}|\\
+% \end{example}
+%
+% \indent
+% \begin{example}
+% |\newcommand*\sectitle[1]{%|\\
+% | \MakeUppercase{\so{#1}.}\\[.66ex]|\\
+% | \rule{13mm}{.4pt}}|\\
+% |\newcommand*\periodafter[2]{#1{#2.}}|\\
+% \end{example}
+%
+% \indent
+% \begin{example}
+% |\titleformat{\section}[display]|\\
+% | {\normalfont\centering}|\\
+% | {\S. \thesection.}|\\
+% | {2ex}|\\
+% | {\sectitle}|\\
+% \end{example}
+%
+% \indent
+% \begin{example}
+% |\titleformat{\subsection}[block]|\\
+% | {\normalfont\centering\bfseries}|\\
+% | {\thesection.}|\\
+% | {.66em}|\\
+% | {\periodafter\relax}|\\
+% \end{example}
+%
+% \indent
+% \begin{example}
+% |\begin{document}|\\
+% |\section{Von den Maassen und Maassst\"aben}|\\
+% |\subsection{Das L\"angenmaass im Allgemeinen}|\\
+% \\
+% |Um L\"angen genau messen und vergleichen zu k\"onnen,|\\
+% |bedarf es einer gewissen, bestimmten Einheit, mit der|\\
+% |man untersucht, wie oft sie selbst, oder ihre Theile,|\\
+% |in der zu bestimmenden L\"ange enthalten sind.|\\
+% |...|\\
+% |\end{document}|
+% \end{example}
+%
+% \bigbreak
+% This example gives you roughly the following output,
+% which is a facsimile from~\cite{Muszynski}.
+%
+% \bigskip
+% \sbox\examplebox{
+% \begin{minipage}{.9\textwidth}
+% \small
+% \bigskip
+% \begin{center}
+% \S. 1.\\[2ex]
+% \so{VON DEN MAASSEN UND MAASSST\"ABEN}.\\[.66ex]
+% \rule{12mm}{.4pt}\\[1.66ex]
+% \textbf{1. Das L\"angenmaass im Allgemeinen.}\\[.66em]
+% \end{center}
+% \leavevmode\qquad
+% Um L\"angen genau messen und vergleichen zu k\"onnen,
+% bedarf es einer gewissen, bestimmten Einheit, mit der
+% man untersucht, wie oft sie selbst, oder ihre Theile,
+% in der zu bestimmenden L\"ange enthalten sind.
+% \bigskip
+% \end{minipage}}
+% \fbox{\usebox\examplebox}
+% \bigbreak
+%
+% \noindent
+% Note that the definition of \cs{\periodafter} decides if
+% the closing period shall be spaced out with the title (1), or
+% follow without space (2):
+%
+% \begin{example}
+% 1.\qquad|\newcommand*\periodafter[2]{#1{#2.}}|\\
+% 2.\qquad|\newcommand*\periodafter[2]{#1{#2}.}|\\
+% \end{example}
+%
+%
+%
+% \noindent
+% If you need to underline section titles, you can easily
+% do it with the help of the \package{titlesec} package. The following
+% example underlines the section title, but not the section
+% number:
+%
+% \begin{example}
+% |\titleformat{\section}|\\
+% | {\LARGE\titlefont}|\\
+% | {\thesection}|\\
+% | {.66em}|\\
+% | {\ul}|\\
+% \end{example}
+%
+% \noindent
+% The \cs{\titlefont} command is provided by the \caps{``\small{KOMA}}~script''
+% package. You can write |\normalfont\sffamily\bfseries| instead.
+% The following example does additionally underline the section number:
+%
+% \begin{example}
+% |\titleformat{\section}|\\
+% | {\LARGE\titlefont}|\\
+% | {\ul{\thesection{\kern.66em}}}|\\
+% | {0pt}|\\
+% | {\ul}|\\
+% \end{example}
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+% \section{How the package works}
+%
+% \subsection{The kernel}
+% \so{Letterspacing,} \ul{underlining}, \st{striking out} and highlighting
+% use the same kernel. It lets a \emph{word scanner} run over the given argument,
+% which inspects every token. If a token is a command registered via \cs{\soulregister},
+% it is executed immediately. Other tokens are only counted and trigger some action
+% when a certain number is reached (quotes and dashes). Three subsequent `|-|', for example,
+% trigger |\SOUL@everyexhyphen{---}|. A third group leads to special actions,
+% like |\mbox| that starts reading-in a whole group to protect its contents and let them be
+% seen as one entity. All other tokens, mostly characters and digits, are collected in
+% a word register, which is passed to the analyzer, whenever a whole word was read in.
+%
+% The analyzer typesets the word in a 1\,sp ($=\frac1{65536}$\,pt) wide \cs{\vbox},
+% hence encouraging \TeX\ to break lines at every possible hyphenation point. It
+% uses the mono-spaced \cs{\SOUL@tt} font (|ectt1000|), so as to avoid any inter-character
+% kerning. Now the \cs{\vbox} is decomposed splitting off \cs{\hbox} after \cs{\hbox}
+% from the bottom. All boxes, each of which contains one syllable, are pushed onto a
+% stack, which is provided by \TeX's grouping mechanism. When returning from the
+% recursion, box after box is fetched from the stack, its width measured and fed to the
+%``reconstructor''.
+%
+% This reconstruction macro (\cs{\SOUL@dosyllable}) starts to read tokens
+% from the just analyzed word until the given syllable
+% width is obtained. This is repeated for each syllable. Every time the engine
+% reaches a relevant state, the corresponding driver macro is executed
+% and, if necessary, provided with some data. There is a macro that is
+% executed for each token, one for each syllable, one for each space etc\null.
+%
+% The engine itself doesn't know how to letterspace or to underline. It
+% just tells the selected driver about the structure of the given argument.
+% There's a default driver (\cs{\SOUL@setup}) that does only set the
+% interface macros to a reasonable default state, but doesn't really do anything.
+% Further drivers can safely inherit these settings and only need to
+% redefine what they want to change.
+%
+%
+%
+%
+%
+% \subsection{The interface}
+% \label{sec:interface}
+%
+% \subsubsection{The registers}
+%
+% The package offers eight interface macros that can be used to define
+% the required actions. Some of the macros receive data as macro parameter
+% or in special \emph{token} or \emph{dimen} registers. Here is a list of
+% all available registers:
+%
+% \begin{labeling}{\hspace{.36\hsize}}
+% \item[\texttt{\string\SOUL@token}]
+% This token register contains the current token. It has to be used as |\the\SOUL@token|.
+% The macro \cs{\SOUL@gettoken} reads the next token into \cs{\SOUL@token} and
+% can be used in any interface macro. If you don't want to lose the old meaning,
+% you have to save it explicitly. \cs{\SOUL@puttoken} pushes the token
+% back into the queue, without changing \cs{\SOUL@token}. You can only
+% put one token back, otherwise you get an error message.
+% \item[\texttt{\string\SOUL@lasttoken}]
+% This token register contains the last token.
+% \item[\texttt{\string\SOUL@syllable}]
+% This token register contains all tokens that were already collected for
+% the current syllable. When used in \cs{\SOUL@everysyllable}, it
+% contains the \emph{whole} syllable.
+% \item[\texttt{\string\SOUL@charkern}]
+% This dimen register contains the kerning value between the current and the next character.
+% Since most character pairs don't require a kerning value to be applied and the
+% output in the logfile shouldn't be cluttered with |\kern0pt| it is
+% recommended to write |\SOUL@setkern\SOUL@charkern|, which sets
+% kerning for non-zero values only.
+% \item[\texttt{\string\SOUL@hyphkern}]
+% This dimen register contains the kerning value between the current character
+% and the hyphen character or, when used in \cs{\SOUL@everyexhyphen}, the
+% kerning between the last character and the explicit hyphen.
+% \end{labeling}
+%
+%
+%
+%
+%
+%
+% \subsubsection{The interface macros}
+%
+% The following list describes each of the interface macros and which
+% registers it can rely on. The mark between label and description
+% will be used in section \ref{sec:interfaceexamples} to show when
+% the macros are executed. The addition |#1| means that the macro
+% takes one argument.
+%
+% \begin{labeling}{\hspace{.36\hsize}}
+% \def\m#1{\leavevmode\llap{\hbox to1em{\hss#1\hss}\hskip.7em}}
+% \item[\texttt{\string\SOUL@preamble}]\m{$P$}^^A
+% executed once at the beginning
+% \item[\texttt{\string\SOUL@postamble}]\m{$E$}^^A
+% executed once at the end
+% \item[\texttt{\string\SOUL@everytoken}]\m{$T$}^^A
+% executed after scanning a token; It gets that
+% token in \cs{\SOUL@token} and has to care for inserting
+% the kerning value \cs{\SOUL@charkern} between this and the next character.
+% To look at the next character, execute \cs{\SOUL@gettoken}, which
+% replaces \cs{\SOUL@token} by the next token. This token has to
+% be put back into the queue using \cs{\SOUL@puttoken}.
+% \item[\texttt{\string\SOUL@everysyllable}]\m{$S$}^^A
+% This macro is executed after scanning a whole syllable. It gets the
+% syllable in \cs{\SOUL@syllable}.
+% \item[\texttt{\string\SOUL@everyhyphen}]\m{$-$}^^A
+% This macro is executed at every implicit hyphenation point.
+% It is responsible for setting the hyphen and will likely do this
+% in a \cs{\discretionary} statement. It has to care about the
+% kerning values. The registers \cs{\SOUL@lasttoken}, \cs{\SOUL@syllable},
+% \cs{\SOUL@charkern} and \cs{\SOUL@hyphkern} contain useful information.
+% Note that \cs{\discretionary} inserts \cs{\exhyphenpenalty}
+% if the first part of the discretionary is empty, and
+% \cs{\hyphenpenalty} else.
+% \item[\texttt{\string\SOUL@everyexhyphen\#1}]\m{$=$}^^A
+% This macro is executed at every explicit hyphenation point. The
+% hyphen `character' (one of hyphen, en-dash, em-dash or \cs{\slash})
+% is passed as parameter |#1|. A minimal implementation
+% would be |{#1\penalty\exhyphenpenalty}|. The kerning value
+% between the last character and the hyphen is passed in \cs{\SOUL@hyphkern},
+% that between the hyphen and the next character in \cs{\SOUL@charkern}.
+% The last syllable can be found in \cs{\SOUL@syllable}, the last
+% character in \cs{\SOUL@lasttoken}.
+% \item[\texttt{\string\SOUL@everyspace\#1}]\m{\texttt{\char`\ }}^^A
+% This macro is executed between every two words. It is responsible for
+% setting the space. The engine submits a \cs{\penalty} setting as
+% parameter |#1| that should be put in front of the space. The
+% macro should at least do |{#1\space}|. Further information can be found in
+% \cs{\SOUL@lasttoken} and \cs{\SOUL@syllable}. Note that this macro does not
+% care for the leading and trailing space. This is the job of
+% \cs{\SOUL@preamble} and \cs{\SOUL@postamble}.
+% \end{labeling}
+%
+%
+%
+%
+%
+%
+% \subsubsection{Some examples}
+% \label{sec:interfaceexamples}
+%
+% The above list's middle column shows a mark that indicates in the
+% following examples, when the respective macros are executed:\nopagebreak
+%
+% \begin{labeling}{\hspace{.36\hsize}}
+% \item[\normalfont\an{word}]
+% \cs{\SOUL@everytoken}$^T$ is executed for every token. \cs{\SOUL@everysyllable}$^S$
+% is \emph{additionally} executed for every syllable. You will mostly just
+% want to use either of them.
+% \item[\normalfont\an{one two}]
+% The macro |\SOUL@everyspace| is executed at every space within
+% the \soul\ argument. It has to take one argument, that can either
+% be empty or contain a penalty, that should be applied to the space.
+% \item[\normalfont\an{example}\kern-1em]
+% The macro |\SOUL@everyhyphen| is executed at every possible
+% implicit hyphenation point.
+% \item[\normalfont\an{beta-test}]
+% Explicit hyphens trigger \cs{\SOUL@everyexhyphen}.
+% \end{labeling}
+%
+%
+%
+% \bigbreak
+% \noindent
+% It's only natural that these examples, too,
+% were automatically typeset by the |soul| package
+% using a special driver:
+%
+% \begin{example}
+% |\DeclareRobustCommand*\an{%|\\
+% | \def\SOUL@preamble{$^{^P}$}%|\\
+% | \def\SOUL@everyspace##1{##1\texttt{\char`\ }}%|\\
+% | \def\SOUL@postamble{$^{^E}$}%|\\
+% | \def\SOUL@everyhyphen{$^{^-}$}%|\\
+% | \def\SOUL@everyexhyphen##1{##1$^{^=}$}%|\\
+% | \def\SOUL@everysyllable{$^{^S}$}%|\\
+% | \def\SOUL@everytoken{\the\SOUL@token$^{^T}$}%|\\
+% | \def\SOUL@everylowerthan{$^{^L}$}%|\\
+% | \SOUL@}|\\
+% \end{example}
+%
+%
+%
+%
+%
+%
+%
+%
+% \subsection{A driver example}
+%
+% Let's define a \soul\ driver that allows to typeset text
+% with a \cs{\cdot} at every potential hyphenation point. The name of
+% the macro shall be \cs{\sy} (for \emph{syllables}).
+% Since the \soul\ mechanism is highly fragile, we use the \LaTeX\
+% command \cs{\DeclareRobustCommand}, so that the \cs{\sy} macro
+% can be used even in section headings etc. The \cs{\SOUL@setup}
+% macro sets all interface macros to reasonable default definitions.
+% This could of course be done manually, too. As we won't
+% make use of \cs{\SOUL@everytoken} and \cs{\SOUL@postamble}
+% and both default to \cs{\relax}, anyway, we don't have to
+% define them here.
+%
+% \begin{example}
+% |\DeclareRobustCommand*\sy{%|\\
+% | \SOUL@setup|\\
+% \end{example}
+%
+% We only set \cs{\lefthyphenmin} and \cs{\righthyphenmin} to zero
+% at the beginning. All changes are restored automatically,
+% so there's nothing to do at the end.
+%
+% \begin{example}
+% | \def\SOUL@preamble{\lefthyphenmin=0 \righthyphenmin=0 }%|\\
+% \end{example}
+%
+% We only want simple spaces. Note that these are not provided
+% by default! \cs{\SOUL@everyspace} may get a penalty to be
+% applied to that space, so we set it before.
+%
+% \begin{example}
+% | \def\SOUL@everyspace##1{##1\space}%|\\
+% \end{example}
+%
+% There's nothing to do for \cs{\SOUL@everytoken}, we rather let
+% \cs{\SOUL@everysyllable} handle a whole syllable at once.
+% This has the advantage, that we don't have to deal with
+% kerning values, because \TeX\ takes care of that.
+%
+% \begin{example}
+% | \def\SOUL@everysyllable{\the\SOUL@syllable}|\\
+% \end{example}
+%
+% The \TeX\ primitive \cs{\discretionary}
+% takes three arguments: 1.~pre-hyphen material
+% 2.~post-hyphen material, and 3.~no-hyphenation material.
+%
+% \begin{example}
+% | \def\SOUL@everyhyphen{%|\\
+% | \discretionary{%|\\
+% | \SOUL@setkern\SOUL@hyphkern|\\
+% | \SOUL@sethyphenchar|\\
+% | }{}{%|\\
+% | \hbox{\kern1pt$\cdot$}%|\\
+% | }%|\\
+% | }%|\\
+%\end{example}
+%
+% Explicit hyphens like dashes and slashes shall be set normally.
+% We just have to care for kerning. The hyphen has to be put in
+% a box, because, as \cs{\hyphenchar}, it would yield its own, internal
+% \cs{\discretionary}. We need to set ours instead, though.
+%
+% \begin{example}
+% | \def\SOUL@everyexhyphen##1{%|\\
+% | \SOUL@setkern\SOUL@hyphkern|\\
+% | \hbox{##1}%|\\
+% | \discretionary{}{}{%|\\
+% | \SOUL@setkern\SOUL@charkern|\\
+% | }%|\\
+% | }|%\\
+% \end{example}
+%
+% Now that the interface macros are defined, we can start the scanner.
+%
+% \begin{example}
+% | \SOUL@|\\
+% |}|\\
+% \end{example}
+%
+% \hyphenation{al-go-rithm lin-guists ex-cel-lent} ^^A correct?
+% \noindent
+% \emph{\sy{This little macro will hardly be good enough
+% for linguists, although it uses {\TeX's} excellent hyphenation algorithm,
+% but it is at least a nice alternative to the}} \cs{\showhyphens} \emph{\sy{command}.}
+%
+%
+%
+%
+%
+%
+%
+% \section*{Acknowledgements}
+%
+% A big thank you goes to \person{Stefan Ulrich} for his tips and bug reports
+% during the development of versions 1.\lower2pt\hbox{*} and for his lessons on high quality
+% typesetting. The \cs{\caps} mechanism was very much influenced by his
+% suggestions. Thanks to \person{Alexander Shibakov} and \person{Frank Mittelbach,}
+% who sent me a couple of bug reports and feature requests, and finally encouraged
+% me to (almost) completely rewrite \soul. \person{Thorsten Manegold} contributed
+% a series of bug reports, helping to fix \soul's macro expander and hence making
+% it work together with the \package{jurabib} package.
+% Thanks to \person{Axel Reichert, Anshuman Pandey,} and \person{Peter Kreynin} for
+% detailed bug reports.
+% \person{Rowland McDonnel} gave useful hints for how to improve the documentation,
+% but I'm afraid he will still not be satisfied, and rightfully so. If only documentation
+% writing weren't that boring.~~\texttt{;-)}
+%
+%
+%
+%
+%
+%
+%
+% \begin{thebibliography}{00}
+% \raggedright
+%
+% \bibitem{jurabib}{\person{Berger, Jens:} \bibtitle{The jurabib package.} \CTAN-Archive, 2002, v0.52h.}
+%
+% \bibitem{titlesec}{\person{Bezos, Javier:} \bibtitle{The titlesec and titletoc package.}
+% \CTAN-Archive, 1999, v2.1.}
+%
+% \bibitem{color}{\person{Carlisle, D. P.:} \bibtitle{The color package.} \CTAN-Archive, 1997, v1.0d.}
+%
+% \bibitem{Duden}{Duden, Volume 1. \bibtitle{Die Rechtschreibung.} Bibliographisches Institut,
+% Mann\-heim--\hskip0pt Wien--Z\"urich, 1986, 19th~edition.}
+%
+% \bibitem{DEK}{\person{Knuth, Donald E.:} \bibtitle{The \TeX book.}
+% Addison--Wesley Publishing Company, Reading/Massachusetts, 1989, 16th~edition.}
+%
+% \bibitem{Muszynski}{\person{Muszynski, Carl} and \person{P\v rihoda, Eduard:}
+% \bibtitle{Die Terrainlehre in Verbindung mit der Darstellung, Beurtheilung und
+% Beschreibung des Terrains vom milit\"arischen
+% Standpunkte.}
+% L.\,W.~Seidel \&\ Sohn, Wien, 1872.}
+%
+% \bibitem{Reglement}{Normalverordnungsblatt f\"ur das k.\,u.\,k.~Heer.
+% \bibtitle{Exercier-Reglement f\"ur die k.\,u.\,k.~Cavallerie, I. Theil.}
+% Wien, k.\,k.~Hof- und Staatsdruckerei, 1898, 4th~edition.}
+%
+% \bibitem{german}{\person{Raichle, Bernd:} \bibtitle{The german package.} \CTAN-Archive, 1998, v2.5e.}
+%
+% \bibitem{yfonts}{\person{Schmidt, Walter:} \bibtitle{Ein Makropaket f\"ur die gebrochenen
+% Schriften.} \CTAN-Archive, 1998, v1.2.}
+%
+% \bibitem{Tschichold}{\person{Tschichold, Jan:} \bibtitle{Ausgew\"ahlte Aufs\"atze \"uber Fragen
+% der Gestalt des Buches und der Typographie.} Birkh\"auser, Basel,
+% 1987, 2nd~edition.}
+%
+% \bibitem{Willberg}{\person{Willberg, Hans Peter} and \person{Forssmann, Friedrich:}
+% \bibtitle{Lesetypographie.} H. Schmidt, Mainz, 1997.}
+%
+% \end{thebibliography}
+%
+%
+% \StopEventually{\addtocontents{toc}{\protect\end{multicols}}}
+%
+%
+%
+%
+%
+%
+%
+%
+%^^A max 72 columns
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \section{The implementation}
+%
+% \subsection*{The package preamble}
+%
+% This piece of code makes sure that the package is only loaded
+% once. While this is guaranteed by \LaTeX, we have to do it
+% manually for all other flavors of \TeX.
+%
+% \begin{macrocode}
+\expandafter\ifx\csname SOUL@\endcsname\relax\else
+ \expandafter\endinput
+\fi
+% \end{macrocode}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \noindent
+% Fake some of the \LaTeX\ commands if we were loaded by another flavor
+% of \TeX. This might break some previously loaded packages, though,
+% if e.\,g.~\cs{\mbox} was already in use. But we don't care \dots
+%
+% \begin{macrocode}
+\ifx\documentclass\SOULundefined
+ \chardef\atcode=\catcode`@
+ \catcode`\@=11
+ \def\DeclareRobustCommand*{\def}
+ \let\newcommand\DeclareRobustCommand
+ \def\DeclareOption#1#2{\expandafter\def\csname#1\endcsname{#2}}
+ \def\PackageError#1#2#3{{%
+ \newlinechar`^^J%
+ \errorcontextlines\z@
+ \edef\\{\errhelp{#3}}\\%
+ \errmessage{Package #1 error: #2}%
+ }}
+ \def\@height{height}
+ \def\@depth{depth}
+ \def\@width{width}
+ \def\@plus{plus}
+ \def\@minus{minus}
+ \font\SOUL@tt=ectt1000
+ \let\@xobeysp\space
+ \let\linebreak\break
+ \let\mbox\hbox
+% \end{macrocode}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \noindent
+% \soul\ tries to be a good \LaTeX\ citizen if used under \LaTeX\ and
+% declares itself properly. Most command sequences in the package
+% are protected by the |SOUL@| namespace, all other macros are first
+% defined to be empty. This will give us an error message \emph{now}
+% if one of those was already used by another package.
+%
+% \begin{macrocode}
+\else
+ \NeedsTeXFormat{LaTeX2e}
+ \ProvidesPackage{soul}
+ [2003/11/17 v2.4 letterspacing/underlining (mf)]
+ \newfont\SOUL@tt{ectt1000}
+ \newcommand*\sodef{}
+ \newcommand*\resetso{}
+ \newcommand*\capsdef{}
+ \newcommand*\capsfont{}
+ \newcommand*\setulcolor{}
+ \newcommand*\setuloverlap{}
+ \newcommand*\setul{}
+ \newcommand*\resetul{}
+ \newcommand*\setuldepth{}
+ \newcommand*\setstcolor{}
+ \newcommand*\sethlcolor{}
+ \newcommand*\so{}
+ \newcommand*\ul{}
+ \newcommand*\st{}
+ \newcommand*\hl{}
+ \newcommand*\caps{}
+ \newcommand*\soulaccent{}
+ \newcommand*\soulregister{}
+ \newcommand*\soulfont{}
+ \newcommand*\soulomit{}
+\fi
+% \end{macrocode}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \noindent
+% Other packages wouldn't be happy if we reserved piles of \cs{\newtoks} and
+% \cs{\newdimen}, so we try to get away with their \cs{\...def} counterparts
+% where possible.
+% Local registers are always even, while global ones are odd---this is a
+% \TeX\ convention.
+%
+% \begin{macrocode}
+\newtoks\SOUL@word
+\newtoks\SOUL@lasttoken
+\toksdef\SOUL@syllable\z@
+\newtoks\SOUL@cmds
+\newtoks\SOUL@buffer
+\newtoks\SOUL@token
+\dimendef\SOUL@syllgoal\z@
+\dimendef\SOUL@syllwidth\tw@
+\dimendef\SOUL@charkern=4
+\dimendef\SOUL@hyphkern=6
+\countdef\SOUL@minus\z@
+\countdef\SOUL@comma\tw@
+\countdef\SOUL@apo=4
+\countdef\SOUL@grave=6
+\newskip\SOUL@spaceskip
+\newif\ifSOUL@ignorespaces
+% \end{macrocode}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% ^^A\FIXME{\newpage}
+% \begin{macro}{\soulomit}
+% \begin{macro}{\SOUL@ignorem}
+% \begin{macro}{\SOUL@ignore}
+% \begin{macro}{\SOUL@stopm}
+% \begin{macro}{\SOUL@stop}
+% \begin{macro}{\SOUL@relaxm}
+% \begin{macro}{\SOUL@lowerthanm}
+% \begin{macro}{\SOUL@hyphenhintm}
+% These macros are used as markers. To be able to check for such a
+% marker with \cs{\ifx} we have also to create a macro that contains
+% the marker. \cs{\SOUL@spc} shall contain a normal space with a
+% \cs{\catcode} of~10.
+%
+% \begin{macrocode}
+\def\soulomit#1{#1}
+\def\SOUL@stopM{\SOUL@stop}
+\let\SOUL@stop\relax
+\def\SOUL@lowerthan{}
+\def\SOUL@lowerthanM{\<}
+\def\SOUL@hyphenhintM{\-}
+\def\SOUL@n*{\let\SOUL@spc= }\SOUL@n* %
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \subsection{The kernel}
+%
+% \begin{macro}{\SOUL@}
+% This macro is the entry to \soul. Using it does only make
+% sense after setting up a \soul\ driver. The next token after
+% the \soul\ command will be assigned to \cs{\SOUL@@}. This can be
+% some text enclosed in braces, or the name of a macro that contains text.
+%
+% \begin{macrocode}
+\def\SOUL@{%
+ \futurelet\SOUL@@\SOUL@expand
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@expand}
+% If the first token after the \soul\ command was an opening
+% brace we start scanning. Otherwise,
+% if the first token was a macro name, we expand that macro and
+% call \cs{\SOUL@} with its contents again. Unfortunately, we have to
+% exclude some macros therein from expansion.
+%
+% \begin{macrocode}
+\def\SOUL@expand{%
+ \ifcat\bgroup\noexpand\SOUL@@
+ \let\SOUL@n\SOUL@start
+ \else
+ \bgroup
+ \def\\##1##2{\def##2{\noexpand##2}}%
+ \the\SOUL@cmds
+ \SOUL@buffer={%
+ \\\TeX\\\LaTeX\\\soulomit\\\mbox\\\hbox\\\textregistered
+ \\\slash\\\textcircled\\\copyright\\\S\\\,\\\<\\\>\\~%
+ \\\\%
+ }%
+ \def\\##1{\def##1{\noexpand##1}}%
+ \the\SOUL@buffer
+ \let\protect\noexpand
+ \xdef\SOUL@n##1{\noexpand\SOUL@start{\SOUL@@}}%
+ \egroup
+ \fi
+ \SOUL@n
+}
+\long\def\SOUL@start#1{{%
+ \let\<\SOUL@lowerthan
+ \let\>\empty
+ \def\soulomit{\noexpand\soulomit}%
+ \gdef\SOUL@eventuallyexhyphen##1{}%
+ \let\SOUL@soeventuallyskip\relax
+ \SOUL@spaceskip=\fontdimen\tw@\font\@plus\fontdimen\thr@@\font
+ \@minus\fontdimen4\font
+ \SOUL@ignorespacesfalse
+ \leavevmode
+ \SOUL@preamble
+ \SOUL@lasttoken={}%
+ \SOUL@word={}%
+ \SOUL@minus\z@
+ \SOUL@comma\z@
+ \SOUL@apo\z@
+ \SOUL@grave\z@
+ \SOUL@do{#1}%
+ \SOUL@postamble
+}}
+\long\def\SOUL@do#1{%
+ \SOUL@scan#1\SOUL@stop
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \subsection{The scanner}
+%
+% \begin{macro}{\SOUL@scan}
+% This is the entry point for the scanner. It calls \cs{\SOUL@eval}
+% and will in turn be called by \cs{\SOUL@eval} again for every
+% new token to be scanned.
+%
+% \begin{macrocode}
+\def\SOUL@scan{%
+ \futurelet\SOUL@@\SOUL@eval
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@eval}
+% And here it is: the scanner's heart. It cares for quotes and dashes
+% ligatures and handles all commands that must not be fed to the
+% analyzer.
+%
+% \begin{macrocode}
+\def\SOUL@eval{%
+ \def\SOUL@n*##1{\SOUL@scan}%
+ \if\noexpand\SOUL@@\SOUL@spc
+ \else
+ \SOUL@ignorespacesfalse
+ \fi
+ \ifnum\SOUL@minus=\thr@@
+ \SOUL@flushminus
+ \else\ifnum\SOUL@comma=\tw@
+ \SOUL@flushcomma
+ \else\ifnum\SOUL@apo=\tw@
+ \SOUL@flushapo
+ \else\ifnum\SOUL@grave=\tw@
+ \SOUL@flushgrave
+ \fi\fi\fi\fi
+ \ifx\SOUL@@-\else\SOUL@flushminus\fi
+ \ifx\SOUL@@,\else\SOUL@flushcomma\fi
+ \ifx\SOUL@@'\else\SOUL@flushapo\fi
+ \ifx\SOUL@@`\else\SOUL@flushgrave\fi
+ \ifx\SOUL@@-%
+ \advance\SOUL@minus\@ne
+ \else\ifx\SOUL@@,%
+ \advance\SOUL@comma\@ne
+ \else\ifx\SOUL@@'%
+ \advance\SOUL@apo\@ne
+ \else\ifx\SOUL@@`%
+ \advance\SOUL@grave\@ne
+ \else
+ \SOUL@flushminus
+ \SOUL@flushcomma
+ \SOUL@flushapo
+ \SOUL@flushgrave
+ \ifx\SOUL@@\SOUL@stop
+ \def\SOUL@n*{%
+ \SOUL@doword
+ \SOUL@eventuallyexhyphen\null
+ }%
+ \else\ifx\SOUL@@\par
+ \def\SOUL@n*\par{\par\leavevmode\SOUL@scan}%
+ \else\if\noexpand\SOUL@@\SOUL@spc
+ \SOUL@doword
+ \SOUL@eventuallyexhyphen\null
+ \ifSOUL@ignorespaces
+ \else
+ \SOUL@everyspace{}%
+ \fi
+ \def\SOUL@n* {\SOUL@scan}%
+ \else\ifx\SOUL@@\\%
+ \SOUL@doword
+ \SOUL@eventuallyexhyphen\null
+ \SOUL@everyspace{\unskip\nobreak\hfil\break}%
+ \SOUL@ignorespacestrue
+ \else\ifx\SOUL@@~%
+ \SOUL@doword
+ \SOUL@eventuallyexhyphen\null
+ \SOUL@everyspace{\nobreak}%
+ \else\ifx\SOUL@@\slash
+ \SOUL@doword
+ \SOUL@eventuallyexhyphen{/}%
+ \SOUL@exhyphen{/}%
+ \else\ifx\SOUL@@\mbox
+ \def\SOUL@n*{\SOUL@addprotect}%
+ \else\ifx\SOUL@@\hbox
+ \def\SOUL@n*{\SOUL@addprotect}%
+ \else\ifx\SOUL@@\soulomit
+ \def\SOUL@n*\soulomit##1{%
+ \SOUL@doword
+ {\spaceskip\SOUL@spaceskip##1}%
+ \SOUL@scan
+ }%
+ \else\ifx\SOUL@@\break
+ \SOUL@doword
+ \break
+ \else\ifx\SOUL@@\linebreak
+ \SOUL@doword
+ \SOUL@everyspace{\linebreak}%
+ \else\ifcat\bgroup\noexpand\SOUL@@
+ \def\SOUL@n*{\SOUL@addgroup{}}%
+ \else\ifcat$\noexpand\SOUL@@
+ \def\SOUL@n*{\SOUL@addmath}%
+ \else
+ \def\SOUL@n*{\SOUL@dotoken}%
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+ \fi\fi\fi\fi
+ \SOUL@n*%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@flushminus}
+% \begin{macro}{\SOUL@flushcomma}
+% \begin{macro}{\SOUL@flushapo}
+% \begin{macro}{\SOUL@flushgrave}
+% As their names imply, these macros flush special tokens or token
+% groups to the word register. They don't do anything if the respective
+% counter equals zero. \cs{\SOUL@minus} does also flush the word
+% register, because hyphens disturb the analyzer.
+%
+% \begin{macrocode}
+\def\SOUL@flushminus{%
+ \ifcase\SOUL@minus
+ \else
+ \SOUL@doword
+ \SOUL@eventuallyexhyphen{-}%
+ \ifcase\SOUL@minus
+ \or
+ \SOUL@exhyphen{-}%
+ \or
+ \SOUL@exhyphen{--}%
+ \or
+ \SOUL@exhyphen{---}%
+ \fi
+ \SOUL@minus\z@
+ \fi
+}
+\def\SOUL@flushcomma{%
+ \ifcase\SOUL@comma
+ \or
+ \edef\x{\SOUL@word={\the\SOUL@word,}}\x
+ \or
+ \edef\x{\SOUL@word={\the\SOUL@word{{,,}}}}\x
+ \fi
+ \SOUL@comma\z@
+}
+\def\SOUL@flushapo{%
+ \ifcase\SOUL@apo
+ \or
+ \edef\x{\SOUL@word={\the\SOUL@word'}}\x
+ \or
+ \edef\x{\SOUL@word={\the\SOUL@word{{''}}}}\x
+ \fi
+ \SOUL@apo\z@
+}
+\def\SOUL@flushgrave{%
+ \ifcase\SOUL@grave
+ \or
+ \edef\x{\SOUL@word={\the\SOUL@word`}}\x
+ \or
+ \edef\x{\SOUL@word={\the\SOUL@word{{``}}}}\x
+ \fi
+ \SOUL@grave\z@
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@dotoken}
+% Command sequences from the \cs{\SOUL@cmds} list are handed over
+% to \cs{\SOUL@docmd}, everything else is added to \cs{\SOUL@word},
+% which will be fed to the analyzer every time a word is completed.
+% Since \emph{robust} commands come with an additional space, we
+% have also to examine if there's a space variant. Otherwise we
+% couldn't detect pre-expanded formerly robust commands.
+%
+% \begin{macrocode}
+\def\SOUL@dotoken#1{%
+ \def\SOUL@@{\SOUL@addtoken{#1}}%
+ \def\\##1##2{%
+ \edef\SOUL@x{\string#1}%
+ \edef\SOUL@n{\string##2}%
+ \ifx\SOUL@x\SOUL@n
+ \def\SOUL@@{\SOUL@docmd{##1}{#1}}%
+ \else
+ \edef\SOUL@n{\string##2\space}%
+ \ifx\SOUL@x\SOUL@n
+ \def\SOUL@@{\SOUL@docmd{##1}{#1}}%
+ \fi
+ \fi
+ }%
+ \the\SOUL@cmds
+ \SOUL@@
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@docmd}
+% Here we deal with commands that were registered with \cs{\soulregister}
+% or \cs{\soulaccent} or were already predefined in \cs{\SOUL@cmds}.
+% Commands with identifier |9| are accents that are put in a
+% group with their argument. Identifier |8| is reserved for the \cs{\footnote}
+% command, and |7| for the \cs{\textsuperscript} or similar commands.
+% The others are mostly (but not necessarily)
+% font switching commands, which may (|1|) or may not (|0|) take
+% an argument. A registered command leads to the current word
+% buffer being flushed to the analyzer, after which the command
+% itself is executed.
+%
+% Font switching commands which take an argument need special
+% treatment: They need to increment the level counter, so that
+% \cs{\SOUL@eval} knows where to stop scanning. Furthermore the
+% scanner has to be enabled to see the next token after the opening
+% brace.
+%
+%
+% \begin{macrocode}
+\def\SOUL@docmd#1#2{%
+ \ifx9#1%
+ \def\SOUL@@{\SOUL@addgroup{#2}}%
+ \else\ifx8#1%
+ \SOUL@doword
+ \def\SOUL@@##1{%
+ \SOUL@token={\footnotemark}%
+ \SOUL@everytoken
+ \SOUL@syllable={\footnotemark}%
+ \SOUL@everysyllable
+ \footnotetext{##1}%
+ \SOUL@doword
+ \SOUL@scan
+ }%
+ \else\ifx7#1%
+ \SOUL@doword
+ \def\SOUL@@##1{%
+ \SOUL@token={#2{##1}}%
+ \SOUL@everytoken
+ \SOUL@syllable={#2{##1}}%
+ \SOUL@everysyllable
+ \SOUL@doword
+ \SOUL@scan
+ }%
+ \else\ifx1#1%
+ \SOUL@doword
+ \def\SOUL@@##1{%
+ #2{\protect\SOUL@do{##1}}%
+ \SOUL@scan
+ }%
+ \else
+ \SOUL@doword
+ #2%
+ \let\SOUL@@\SOUL@scan
+ \fi\fi\fi\fi
+ \SOUL@@
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@addgroup}
+% \begin{macro}{\SOUL@addmath}
+% \begin{macro}{\SOUL@addprotect}
+% \begin{macro}{\SOUL@addtoken}
+% The macro names say it all. Each of these macros adds some
+% token to the word buffer \cs{\SOUL@word}. Setting \cs{\protect}
+% is necessary to make things like |\so{{a\itshape b}}| work.
+%
+% \begin{macrocode}
+\def\SOUL@addgroup#1#2{%
+ {\let\protect\noexpand
+ \edef\x{\global\SOUL@word={\the\SOUL@word{{\noexpand#1#2}}}}\x}%
+ \SOUL@scan
+}
+\def\SOUL@addmath$#1${%
+ {\let\protect\noexpand
+ \edef\x{\global\SOUL@word={\the\SOUL@word{{\hbox{$#1$}}}}}\x}%
+ \SOUL@scan
+}
+\def\SOUL@addprotect#1#2{%
+ {\let\protect\noexpand
+ \edef\x{\global\SOUL@word={\the\SOUL@word{{\hbox{#2}}}}}\x}%
+ \SOUL@scan
+}
+\def\SOUL@addtoken#1{%
+ \edef\x{\SOUL@word={\the\SOUL@word\noexpand#1}}\x
+ \SOUL@scan
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@exhyphen}
+% Dealing with explicit hyphens can't be done before we know the
+% following character, because we need to know if a kerning value
+% has to be inserted, hence we delay the \cs{\SOUL@everyexhyphen} call.
+% Unfortunately, the word scanner has no look-ahead mechanism.
+%
+% \begin{macrocode}
+\def\SOUL@exhyphen#1{%
+ \SOUL@getkern{\the\SOUL@lasttoken}{\SOUL@hyphkern}{#1}%
+ \gdef\SOUL@eventuallyexhyphen##1{%
+ \SOUL@getkern{#1}{\SOUL@charkern}{##1}%
+ \SOUL@everyexhyphen{#1}%
+ \gdef\SOUL@eventuallyexhyphen####1{}%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@cmds}
+% Here is a list of pre-registered commands that the analyzer
+% cannot handle, so the scanner has to look after them. Every
+% entry consists of a handle (\cs{\\}), an identifier and the
+% macro name. The class identifier can be |9| for accents,
+% |8| for the \cs{\footnote} command, |7| for the
+% \cs{\textsuperscript} command,
+% |0| for commands without arguments and |1| for commands that
+% take one argument. Commands with two or more arguments are
+% not supported.
+%
+% \begin{macrocode}
+\SOUL@cmds={%
+ \\9\`\\9\'\\9\^\\9\"\\9\~\\9\=\\9\.%
+ \\9\u\\9\v\\9\H\\9\t\\9\c\\9\d\\9\b\\9\r
+ \\1\emph\\1\textrm\\1\textsf\\1\texttt\\1\textmd\\1\textbf
+ \\1\textup\\1\textsl\\1\textit\\1\textsc\\1\textnormal
+ \\0\rmfamily\\0\sffamily\\0\ttfamily\\0\mdseries\\0\upshape
+ \\0\slshape\\0\itshape\\0\scshape\\0\normalfont
+ \\0\em\\0\rm\\0\bf\\0\it\\0\tt\\0\sc\\0\sl\\0\sf
+ \\0\tiny\\0\scriptsize\\0\footnotesize\\0\small
+ \\0\normalsize\\0\large\\0\Large\\0\LARGE\\0\huge\\0\Huge
+ \\1\MakeUppercase\\7\textsuperscript\\8\footnote
+ \\1\textfrak\\1\textswab\\1\textgoth
+ \\0\frakfamily\\0\swabfamily\\0\gothfamily
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\soulregister}
+% \begin{macro}{\soulfont}
+% \begin{macro}{\soulaccent}
+% Register a font switching command (or some other command) for the
+% scanner. The first argument is the macro name, the second is
+% the number of arguments (|0|~or~|1|). Example: |\soulregister{\bold}{0}|.
+% \cs{\soulaccent} has only one argument---the accent macro name.
+% Example: |\soulaccent{\~}|. It is a shortcut for |\soulregister{\~}{9}|.
+% The \cs{\soulfont} command is a synonym for \cs{\soulregister}
+% and is kept for compatibility reasons.
+%
+% \begin{macrocode}
+\def\soulregister#1#2{{%
+ \edef\x{\global\SOUL@cmds={\the\SOUL@cmds
+ \noexpand\\#2\noexpand#1}}\x
+}}
+\def\soulaccent#1{\soulregister{#1}9}
+\let\soulfont\soulregister
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \subsection{The analyzer}
+%
+% \begin{macro}{\SOUL@doword}
+% The only way to find out, where a given word can be broken into
+% syllables, is to let \TeX\ actually typeset the word under conditions
+% that enforce every possible hyphenation. The result is a paragraph with one
+% line for every syllable.
+%
+% \begin{macrocode}
+\def\SOUL@doword{%
+ \edef\x{\the\SOUL@word}%
+ \ifx\x\empty
+ \else
+ \SOUL@buffer={}%
+ \setbox\z@\vbox{%
+ \SOUL@tt
+ \hyphenchar\font`\-
+ \hfuzz\maxdimen
+ \hbadness\@M
+ \pretolerance\m@ne
+ \tolerance\@M
+ \leftskip\z@
+ \rightskip\z@
+ \hsize1sp
+ \everypar{}%
+ \parfillskip\z@\@plus1fil
+ \hyphenpenalty-\@M
+ \noindent
+ \hskip\z@
+ \relax
+ \the\SOUL@word}%
+ \let\SOUL@errmsg\SOUL@error
+ \let\-\relax
+ \count@\m@ne
+ \SOUL@analyze
+ \SOUL@word={}%
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \noindent
+% We store the hyphen width of the |ectt1000| font,
+% because we will need it in |\SOUL@doword|. (|ectt1000| is a mono-spaced
+% font, so every other character would have worked, too.)
+%
+% \begin{macrocode}
+\setbox\z@\hbox{\SOUL@tt-}
+\newdimen\SOUL@ttwidth
+\SOUL@ttwidth\wd\z@
+\def\SOUL@sethyphenchar{%
+ \ifnum\hyphenchar\font=\m@ne
+ \else
+ \char\hyphenchar\font
+ \fi
+}
+% \end{macrocode}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@analyze}
+% This macro decomposes the box that |\SOUL@doword| has built.
+% Because we have to start at the bottom, we put every
+% syllable onto the stack and execute ourselves recursively. If there
+% are no syllables left, we return from the recursion and pick syllable
+% after syllable from the stack again---this time from top to bottom---and
+% hand the syllable width |\SOUL@syllgoal| over to |\SOUL@dosyllable|.
+% All but the last syllable end with the hyphen character, hence
+% we subtract the hyphen width accordingly. After processing a
+% syllable we calculate the hyphen kern (i.\,e.~the kerning amount
+% between the last character and the hyphen). This might be needed
+% by \cs{\SOUL@everyhyphen}, which we call now.
+%
+% \begin{macrocode}
+\def\SOUL@analyze{{%
+ \setbox\z@\vbox{%
+ \unvcopy\z@
+ \unskip
+ \unpenalty
+ \global\setbox\@ne=\lastbox}%
+ \ifvoid\@ne
+ \else
+ \setbox\@ne\hbox{\unhbox\@ne}%
+ \SOUL@syllgoal=\wd\@ne
+ \advance\count@\@ne
+ \SOUL@analyze
+ \SOUL@syllwidth\z@
+ \SOUL@syllable={}%
+ \ifnum\count@>\z@
+ \advance\SOUL@syllgoal-\SOUL@ttwidth
+ \SOUL@dosyllable
+ \SOUL@getkern{\the\SOUL@lasttoken}{\SOUL@hyphkern}%
+ {\SOUL@sethyphenchar}%
+ \SOUL@everyhyphen
+ \else
+ \SOUL@dosyllable
+ \fi
+ \fi
+}}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@dosyllable}
+% This macro typesets token after token from \cs{\SOUL@word}
+% until \cs{\SOUL@syllwidth} has reached
+% the requested width \cs{\SOUL@syllgoal}. Furthermore the kerning
+% values are prepared in case \cs{\SOUL@everytoken} needs them.
+% The \cs{\<} command used by \cs{\so} and \cs{\caps} needs some
+% special treatment: It has to be checked for, even before
+% we can end a syllable.
+%
+% \begin{macrocode}
+\def\SOUL@dosyllable{%
+ \SOUL@gettoken
+ \SOUL@eventuallyexhyphen{\the\SOUL@token}%
+ \edef\x{\the\SOUL@token}%
+ \ifx\x\SOUL@hyphenhintM
+ \let\SOUL@n\SOUL@dosyllable
+ \else\ifx\x\SOUL@lowerthanM
+ \SOUL@gettoken
+ \SOUL@getkern{\the\SOUL@lasttoken}{\SOUL@charkern}
+ {\the\SOUL@token}%
+ \SOUL@everylowerthan
+ \SOUL@puttoken
+ \let\SOUL@n\SOUL@dosyllable
+ \else\ifdim\SOUL@syllwidth=\SOUL@syllgoal
+ \SOUL@everysyllable
+ \SOUL@puttoken
+ \let\SOUL@n\relax
+ \else\ifx\x\SOUL@stopM
+ \SOUL@errmsg
+ \global\let\SOUL@errmsg\relax
+ \let\SOUL@n\relax
+ \else
+ \setbox\tw@\hbox{\SOUL@tt\the\SOUL@token}%
+ \advance\SOUL@syllwidth\wd\tw@
+ \global\SOUL@lasttoken=\SOUL@token
+ \SOUL@gettoken
+ \SOUL@getkern{\the\SOUL@lasttoken}{\SOUL@charkern}
+ {\the\SOUL@token}%
+ \SOUL@puttoken
+ \global\SOUL@token=\SOUL@lasttoken
+ \SOUL@everytoken
+ \edef\x{\SOUL@syllable={\the\SOUL@syllable\the\SOUL@token}}\x
+ \let\SOUL@n\SOUL@dosyllable
+ \fi\fi\fi\fi
+ \SOUL@n
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@gettoken}
+% Provide the next token in \cs{\SOUL@token}. If there's already one
+% in the buffer, use that one first.
+%
+% \begin{macrocode}
+\def\SOUL@gettoken{%
+ \edef\x{\the\SOUL@buffer}%
+ \ifx\x\empty
+ \SOUL@nexttoken
+ \else
+ \global\SOUL@token=\SOUL@buffer
+ \global\SOUL@buffer={}%
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@puttoken}
+% The possibility to put tokens back makes the scanner design much
+% cleaner. There's only room for one token, though, so we issue
+% an error message if \cs{\SOUL@puttoken} is told to put a token
+% back while the buffer is still in use. Note that \cs{\SOUL@debug}
+% is actually undefined. This won't hurt as it can only happen
+% during driver design. No user will ever see this message.
+%
+% \begin{macrocode}
+\def\SOUL@puttoken{%
+ \edef\x{\the\SOUL@buffer}%
+ \ifx\x\empty
+ \global\SOUL@buffer=\SOUL@token
+ \global\SOUL@token={}%
+ \else
+ \SOUL@debug{puttoken called twice}%
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@nexttoken}
+% \begin{macro}{\SOUL@splittoken}
+% If the word buffer \cs{\SOUL@word} is empty, deliver a \cs{\SOUL@stop},
+% otherwise take the next token.
+%
+% \begin{macrocode}
+\def\SOUL@nexttoken{%
+ \edef\x{\the\SOUL@word}%
+ \ifx\x\empty
+ \SOUL@token={\SOUL@stop}%
+ \else
+ \expandafter\SOUL@splittoken\the\SOUL@word\SOUL@stop
+ \fi
+}
+\def\SOUL@splittoken#1#2\SOUL@stop{%
+ \global\SOUL@token={#1}%
+ \global\SOUL@word={#2}%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@getkern}
+% Assign the kerning value between the first and the third argument
+% to the second, which has to be a \cs{\dimen} register.
+% |\SOUL@getkern{A}{\dimen0}{V}| will assign the kerning value
+% between `A' and `V' to |\dimen0|.
+%
+% \begin{macrocode}
+\def\SOUL@getkern#1#2#3{%
+ \setbox\tw@\hbox{#1#3}%
+ #2\wd\tw@
+ \setbox\tw@\hbox{#1\null#3}%
+ \advance#2-\wd\tw@
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@setkern}
+% Set a kerning value if it doesn't equal 0\,pt. Of course, we could
+% also set a zero value, but that would needlessly clutter the
+% logfile.
+%
+% \begin{macrocode}
+\def\SOUL@setkern#1{\ifdim#1=\z@\else\kern#1\fi}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@error}
+% This error message will be shown once for every word that couldn't
+% be reconstructed by \cs{\SOUL@dosyllable}.
+%
+% \begin{macrocode}
+\def\SOUL@error{%
+ \vrule\@height.8em\@depth.2em\@width1em
+ \PackageError{soul}{Reconstruction failed}{%
+ I came across hyphenatable material enclosed in group
+ braces,^^Jwhich I can't handle. Either drop the braces or
+ make the material^^Junbreakable using an \string\mbox\space
+ (\string\hbox). Note that a space^^Jalso counts as possible
+ hyphenation point. See page 4 of the manual.^^JI'm leaving
+ a black square so that you can see where I am right now.%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@setup}
+% This is a null driver, that will be used as the basis for
+% other drivers. These have then to redefine only interface commands
+% that shall differ from the default.
+%
+% \begin{macrocode}
+\def\SOUL@setup{%
+ \let\SOUL@preamble\relax
+ \let\SOUL@postamble\relax
+ \let\SOUL@everytoken\relax
+ \let\SOUL@everysyllable\relax
+ \def\SOUL@everyspace##1{##1\space}%
+ \let\SOUL@everyhyphen\relax
+ \def\SOUL@everyexhyphen##1{##1}%
+ \let\SOUL@everylowerthan\relax
+}
+\SOUL@setup
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \subsection{The \texorpdfstring{\so{letterspacing}}{letterspacing} driver}
+%
+% \begin{macro}{\SOUL@sosetletterskip}
+% A handy helper macro that sets the inter-letter skip with a
+% draconian \cs{\penalty}.
+%
+% \begin{macrocode}
+\def\SOUL@sosetletterskip{\nobreak\hskip\SOUL@soletterskip}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@sopreamble}
+% If letterspacing (\cs{\so} or \cs{\caps}) follows a white space, we
+% replace it with our \syn{outer space}. \LaTeX\ uses |\hskip1sp| as
+% marker in tabular entries, so we ignore tiny skips.
+%
+% \begin{macrocode}
+\def\SOUL@sopreamble{%
+ \ifdim\lastskip>5sp
+ \unskip
+ \hskip\SOUL@soouterskip
+ \fi
+ \spaceskip\SOUL@soinnerskip
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@sopostamble}
+% Start the look-ahead scanner \cs{\SOUL@socheck} outside the \cs{\SOUL@}
+% scope. That's why we make the \syn{outer space} globally available in
+% \cs{\skip@}.
+%
+% \begin{macrocode}
+\def\SOUL@sopostamble{%
+ \global\skip@=\SOUL@soouterskip
+ \aftergroup\SOUL@socheck
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@socheck}
+% \begin{macro}{\SOUL@sodoouter}
+% Read the next token after the \soul\ command into \cs{\SOUL@@}
+% and examine it. If it's some kind of space, replace it with
+% \syn{outer space} and the appropriate penalty, else if it's
+% a closing brace, continue scanning. If it is neither: do nothing.
+%
+% \begin{macrocode}
+\def\SOUL@socheck{%
+ \futurelet\SOUL@@\SOUL@sodoouter
+}
+\def\SOUL@sodoouter{%
+ \def\SOUL@n*##1{\hskip\skip@}%
+ \ifcat\egroup\noexpand\SOUL@@
+ \unkern
+ \egroup
+ \def\SOUL@n*{\afterassignment\SOUL@socheck\let\SOUL@x=}%
+ \else\ifx\SOUL@spc\SOUL@@
+ \def\SOUL@n* {\hskip\skip@}%
+ \else\ifx~\SOUL@@
+ \def\SOUL@n*~{\nobreak\hskip\skip@}%
+ \else\ifx\ \SOUL@@
+ \else\ifx\space\SOUL@@
+ \else\ifx\@xobeysp\SOUL@@
+ \else
+ \def\SOUL@n*{}%
+ \let\SOUL@@\relax
+ \fi\fi\fi\fi\fi\fi
+ \SOUL@n*%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@soeverytoken}
+% Typeset the token and put an unbreakable inter-letter skip
+% thereafter. If the token is \cs{\<} then remove the last skip instead.
+% Gets the character kerning value between the actual and the
+% next token in \cs{\SOUL@charkern}.
+%
+% \begin{macrocode}
+\def\SOUL@soeverytoken{%
+ \edef\x{\the\SOUL@token}%
+ \ifx\x\SOUL@lowerthanM
+ \else
+ \global\let\SOUL@soeventuallyskip\SOUL@sosetletterskip
+ \the\SOUL@token
+ \SOUL@gettoken
+ \edef\x{\the\SOUL@token}%
+ \ifx\x\SOUL@stopM
+ \else
+ \SOUL@setkern\SOUL@charkern
+ \SOUL@sosetletterskip
+ \SOUL@puttoken
+ \fi
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@soeveryspace}
+% This macro sets an \syn{inner space}. The argument may contain
+% penalties and is used for the |~| command. This construction was
+% needed to make colored underlines work, without having to put
+% any of the coloring commands into the core. |\kern\z@| prevents
+% in subsequent \cs{\so} commands that the second discards the
+% \syn{outer space} of the first. To remove the space simply
+% use |\unkern\unskip|.
+%
+% \begin{macrocode}
+\def\SOUL@soeveryspace#1{#1\space\kern\z@}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@soeveryhyphen}
+% Sets implicit hyphens. The kerning value between the current token
+% and the hyphen character is passed in \cs{\SOUL@hyphkern}.
+%
+% \begin{macrocode}
+\def\SOUL@soeveryhyphen{%
+ \discretionary{%
+ \unkern
+ \SOUL@setkern\SOUL@hyphkern
+ \SOUL@sethyphenchar
+ }{}{}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@soeveryexhyphen}
+% Sets the explicit hyphen that is passed as argument.
+% \cs{\SOUL@soeventuallyskip} equals \cs{\SOUL@sosetletterskip},
+% except when a \cs{\<} had been detected. This is necessary because
+% \cs{\SOUL@soeveryexhyphen} wouldn't know otherwise, that it
+% follows a~\cs{\<}.
+%
+% \begin{macrocode}
+\def\SOUL@soeveryexhyphen#1{%
+ \SOUL@setkern\SOUL@hyphkern
+ \SOUL@soeventuallyskip
+ \hbox{#1}%
+ \discretionary{}{}{%
+ \SOUL@setkern\SOUL@charkern
+ }%
+ \SOUL@sosetletterskip
+ \global\let\SOUL@soeventuallyskip\relax
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@soeverylowerthan}
+% Let \cs{\<} remove the last inter-letter skip. Set the kerning value
+% between the token before and that after the \cs{\<} command.
+%
+%
+% \begin{macrocode}
+\def\SOUL@soeverylowerthan{%
+ \unskip
+ \unpenalty
+ \global\let\SOUL@soeventuallyskip\relax
+ \SOUL@setkern\SOUL@charkern
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@sosetup}
+% Override all interface macros by our letterspacing versions. The
+% only unused macro is \cs{\SOUL@everysyllable}.
+%
+% \begin{macrocode}
+\def\SOUL@sosetup{%
+ \SOUL@setup
+ \let\SOUL@preamble\SOUL@sopreamble
+ \let\SOUL@postamble\SOUL@sopostamble
+ \let\SOUL@everytoken\SOUL@soeverytoken
+ \let\SOUL@everyspace\SOUL@soeveryspace
+ \let\SOUL@everyhyphen\SOUL@soeveryhyphen
+ \let\SOUL@everyexhyphen\SOUL@soeveryexhyphen
+ \let\SOUL@everylowerthan\SOUL@soeverylowerthan
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@setso}
+% A handy macro for internal use.
+%
+% \begin{macrocode}
+\def\SOUL@setso#1#2#3{%
+ \def\SOUL@soletterskip{#1}%
+ \def\SOUL@soinnerskip{#2}%
+ \def\SOUL@soouterskip{#3}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\sodef}
+% This macro assigns the letterspacing skips as well as an optional
+% font switching command to a command sequence name. \cs{\so} itself
+% will be defined using this macro.
+%
+% \begin{macrocode}
+\def\sodef#1#2#3#4#5{%
+ \DeclareRobustCommand*#1{\SOUL@sosetup
+ \def\SOUL@preamble{%
+ \SOUL@setso{#3}{#4}{#5}%
+ #2%
+ \SOUL@sopreamble
+ }%
+ \SOUL@
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\resetso}
+% Let \cs{\resetso} define reasonable default values for letterspacing.
+%
+% \begin{macrocode}
+\def\resetso{%
+ \sodef\textso{}{.25em}{.65em\@plus.08em\@minus.06em}%
+ {.55em\@plus.275em\@minus.183em}%
+}
+\resetso
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\sloppyword}
+% Set up a letterspacing macro that inserts slightly stretchable
+% space between the characters. This can be used to typeset long
+% words in narrow columns, where ragged paragraphs are undesirable.
+% See section~\ref{sec:sloppyword}.
+%
+% \begin{macrocode}
+\sodef\sloppyword{%
+ \linepenalty10
+ \hyphenpenalty10
+ \adjdemerits\z@
+ \doublehyphendemerits\z@
+ \finalhyphendemerits\z@
+ \emergencystretch.1em}%
+ {\z@\@plus.1em}%
+ {.33em\@plus.11em\@minus.11em}%
+ {.33em\@plus.11em\@minus.11em}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \subsection[The \texorpdfstring{\caps{caps}}{caps} driver]{The caps driver}
+%
+% \begin{macro}{\caps}
+% Unless run under \LaTeX, make \cs{\caps} just another simple letterspacing
+% macro that selects a font \cs{\capsfont} (defaulting to \cs{\relax}) but
+% doesn't have any special capabilities.
+%
+% \begin{macrocode}
+\ifx\documentclass\@undefined
+\let\capsfont\relax
+\let\capsreset\relax
+\def\capsdef#1#2#3#4#5{}
+\def\capssave#1{}
+\def\capsselect#1{}
+\sodef\textcaps{\capsfont}
+ {.028em\@plus.005em\@minus.01em}%
+ {.37em\@plus.1667em\@minus.111em}%
+ {.37em\@plus.1em\@minus.14em}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\capsreset}
+% \dots\ else, if run under \LaTeX\ prepare a set of macros that
+% maintain a database with certain letterspacing values for different
+% fonts. \cs{\capsreset} clears the database and inserts a default rule.
+%
+% \begin{macrocode}
+\else
+\DeclareRobustCommand*\capsreset{%
+ \let\SOUL@capsbase\empty
+ \SOUL@capsdefault
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\capsdef}
+% Add an entry to the database, which is of course nothing else than
+% a \TeX\ macro. See section ``List macros'' of appendix~D in the
+% \TeX{}book~\cite{DEK} for details.
+%
+% \begin{macrocode}
+\def\capsdef#1#2#3#4#5{{%
+ \toks\z@{\\{#1/#2/#3/#4/#5}}%
+ \toks\tw@=\expandafter{\SOUL@capsbase}%
+ \xdef\SOUL@capsbase{\the\toks\z@\the\toks\tw@}%
+}}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\capssave}
+% \begin{macro}{\capsselect}
+% Save the current database in a macro within the |SOUL@| namespace
+% and let |\capsselect| restore this database.
+%
+% \begin{macrocode}
+\DeclareRobustCommand*\capssave[1]{%
+ \expandafter\global\expandafter\let
+ \csname SOUL@db@#1\endcsname\SOUL@capsbase
+}
+\DeclareRobustCommand*\capsselect[1]{%
+ \expandafter\let\expandafter\SOUL@capsbase
+ \csname SOUL@db@#1\endcsname
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@capsfind}
+% \begin{macro}{\SOUL@caps}
+% Go through the database entries and pick the first entry that matches
+% the currently active font. Then define an internal macro that uses
+% the respective spacing values in a macro that is equivalent to the
+% \cs{\textso} command.
+%
+% \begin{macrocode}
+\def\SOUL@capsfind#1/#2/#3/#4/#5/#6/#7/#8/#9/{%
+ \let\SOUL@match=1%
+ \SOUL@chk{#1}\f@encoding
+ \SOUL@chk{#2}\f@family
+ \SOUL@chk{#3}\f@series
+ \SOUL@chk{#4}\f@shape
+ \SOUL@dimchk{#5}\f@size
+ \if\SOUL@match1%
+ \let\\\@gobble
+ \gdef\SOUL@caps{%
+ \SOUL@sosetup
+ \def\SOUL@preamble{\SOUL@setso{#7}{#8}{#9}#6%
+ \SOUL@sopreamble}%
+ \SOUL@}%
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@chk}
+% Sets the \cs{\SOUL@match} flag if both parameters are equal.
+% This is used for all \caps{\small NFSS} elements except the font size.
+%
+% \begin{macrocode}
+\def\SOUL@chk#1#2{%
+ \if$#1$%
+ \else
+ \def\SOUL@n{#1}%
+ \ifx#2\SOUL@n\else\let\SOUL@match=0\fi
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@dimchk}
+% \begin{macro}{\SOUL@rangechk}
+% We do not only want to check if a given font size |#1| matches |#2|,
+% but also if it fits into a given range. An omitted lower boundary
+% is replaced by \cs{\z@} and an omitted upper boundary by \cs{\maxdimen}.
+% The first of a series of \cs{\SOUL@chk} and \cs{\SOUL@dimchk}
+% statements, which detects that the arguments don't match, sets the
+% \cs{\SOUL@match} flag to zero. A value of~1 indicates that an
+% entry in the font database matches the currently used font.
+%
+% \begin{macrocode}
+\def\SOUL@dimchk#1#2{\if$#1$\else\SOUL@rangechk{#2}#1--\@ne\@@\fi}
+\def\SOUL@rangechk#1#2-#3-#4\@@{%
+ \count@=#4%
+ \ifnum\count@>\z@
+ \ifdim#1\p@=#2\p@\else\let\SOUL@match=0\fi
+ \else
+ \dimen@=\if$#2$\z@\else#2\p@\fi
+ \ifdim#1\p@<\dimen@\let\SOUL@match=0\fi
+ \dimen@=\if$#3$\maxdimen\else#3\p@\fi
+ \ifdim#1\p@<\dimen@\else\let\SOUL@match=0\fi
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\textcaps}
+% Find a matching entry in the database and start the letterspacing
+% mechanism with the given spacing values.
+%
+% \begin{macrocode}
+\DeclareRobustCommand*\textcaps{{%
+ \def\\##1{\expandafter\SOUL@capsfind##1/}%
+ \SOUL@capsbase
+ \aftergroup\SOUL@caps
+}}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@capsdefault}
+% Define a default database entry and a default font.
+%
+% \begin{macrocode}
+\def\SOUL@capsdefault{%
+ \capsdef{////}%
+ \SOUL@capsdfltfnt
+ {.028em\@plus.005em\@minus.01em}%
+ {.37em\@plus.1667em\@minus.1em}%
+ {.37em\@plus.111em\@minus.14em}%
+}
+\let\SOUL@capsdfltfnt\scshape
+\capsreset
+\fi
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \subsection{The \texorpdfstring{\ul{underlining}}{underlining} driver}
+%
+% \begin{macro}{\SOUL@ulleaders}
+% This macro sets the underline under the following \cs{\hskip}.
+%
+% \begin{macrocode}
+\newdimen\SOUL@uldp
+\newdimen\SOUL@ulht
+\def\SOUL@ulleaders{%
+ \leaders\hrule\@depth\SOUL@uldp\@height\SOUL@ulht\relax
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@ulunderline}
+% Set an underline under the given material. It draws the line first,
+% and the given material afterwards. This is needed for highlighting,
+% but gives less than optimal results for colored overstriking, which,
+% however, will hardly ever be used, anyway.
+%
+% \begin{macrocode}
+\def\SOUL@ulunderline#1{{%
+ \setbox\z@\hbox{#1}%
+ \dimen@=\wd\z@
+ \dimen@i=\SOUL@uloverlap
+ \advance\dimen@2\dimen@i
+ \rlap{%
+ \null
+ \kern-\dimen@i
+ \SOUL@ulcolor{\SOUL@ulleaders\hskip\dimen@}%
+ }%
+ \unhcopy\z@
+}}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@ulpreamble}
+% Just set up the line dimensions and the space skip. Normally,
+% \cs{\spaceskip} is unset and not used by \TeX. We need it, though,
+% because we feed it to the \cs{\leaders} primitive.
+%
+% \begin{macrocode}
+\def\SOUL@ulpreamble{%
+ \SOUL@uldp=\SOUL@uldepth
+ \SOUL@ulht=-\SOUL@uldp
+ \advance\SOUL@uldp\SOUL@ulthickness
+ \spaceskip\SOUL@spaceskip
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@uleverysyllable}
+% By using \cs{\SOUL@everysyllable} we don't have to care about
+% kerning values and get better results for highlighting, where
+% negative kerning values would otherwise cut off characters.
+%
+% \begin{macrocode}
+\def\SOUL@uleverysyllable{%
+ \SOUL@ulunderline{%
+ \the\SOUL@syllable
+ \SOUL@setkern\SOUL@charkern
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@uleveryspace}
+% Set a given penalty and an underlined \cs{\space} equivalent.
+% The \cs{\null} prevents a nasty gap in |\textfrak| |{a \textswab{b}}|,
+% while it doesn't seem to hurt in all other cases. I didn't investigate
+% this.
+%
+% \begin{macrocode}
+\def\SOUL@uleveryspace#1{%
+ \SOUL@ulcolor{%
+ #1%
+ \SOUL@ulleaders
+ \hskip\spaceskip
+ }%
+ \null
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@uleveryhyphen}
+% If hyphenation takes place, output an underlined hyphen with the
+% required hyphen kerning value.
+%
+% \begin{macrocode}
+\def\SOUL@uleveryhyphen{%
+ \discretionary{%
+ \unkern
+ \SOUL@ulunderline{%
+ \SOUL@setkern\SOUL@hyphkern
+ \SOUL@sethyphenchar
+ }%
+ }{}{}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@uleveryexhyphen}
+% Underline the given hyphen, en-dash, em-dash or \cs{\slash} and care
+% for kerning.
+%
+% \begin{macrocode}
+\def\SOUL@uleveryexhyphen#1{%
+ \SOUL@setkern\SOUL@hyphkern
+ \SOUL@ulunderline{#1}%
+ \discretionary{}{}{%
+ \SOUL@setkern\SOUL@charkern
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@ulcolor}
+% \begin{macro}{\setulcolor}
+% Define the underline color or turn off coloring, in which case the lines are not
+% just colored black, but remain uncolored. This makes them appear
+% black, nevertheless, and has the advantage, that no Postscript
+% \cs{\specials} are cluttering the output.
+%
+% \begin{macrocode}
+\let\SOUL@ulcolor\relax
+\def\setulcolor#1{%
+ \if$#1$
+ \let\SOUL@ulcolor\relax
+ \else
+ \def\SOUL@ulcolor{\textcolor{#1}}%
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\setuloverlap}
+% \begin{macro}{\SOUL@uloverlap}
+% Set the overlap amount, that helps to avoid gaps on sloppy output
+% devices.
+%
+% \begin{macrocode}
+\def\setuloverlap#1{\def\SOUL@uloverlap{#1}}
+\setuloverlap{.25pt}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@ulsetup}
+% The underlining driver is quite simple. No need for \cs{\SOUL@postamble}
+% and \cs{\SOUL@everytoken}.
+%
+% \begin{macrocode}
+\def\SOUL@ulsetup{%
+ \SOUL@setup
+ \let\SOUL@preamble\SOUL@ulpreamble
+ \let\SOUL@everysyllable\SOUL@uleverysyllable
+ \let\SOUL@everyspace\SOUL@uleveryspace
+ \let\SOUL@everyhyphen\SOUL@uleveryhyphen
+ \let\SOUL@everyexhyphen\SOUL@uleveryexhyphen
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@textul}
+% Describing self-explanatory macros is \emph{so} boring!
+%
+% \begin{macrocode}
+\DeclareRobustCommand*\textul{\SOUL@ulsetup\SOUL@}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\setul}
+% \begin{macro}{\SOUL@uldepth}
+% \begin{macro}{\SOUL@ulthickness}
+% Set the underlining dimensions. Either value may be omitted and
+% lets the respective macro keep its current contents.
+%
+% \begin{macrocode}
+\def\setul#1#2{%
+ \if$#1$\else\def\SOUL@uldepth{#1}\fi
+ \if$#2$\else\def\SOUL@ulthickness{#2}\fi
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\resetul}
+% Set reasonable default values that fit most latin fonts.
+%
+% \begin{macrocode}
+\def\resetul{\setul{.65ex}{.1ex}}
+\resetul
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\setuldepth}
+% This macro sets all designated ``letters'' (\cs{\catcode=11}) or the
+% given material in a box and sets the underlining dimensions according
+% to the box depth.
+%
+% \begin{macrocode}
+\def\setuldepth#1{{%
+ \def\SOUL@n{#1}%
+ \setbox\z@\hbox{%
+ \tracinglostchars\z@
+ \ifx\SOUL@n\empty
+ \count@\z@
+ \loop
+ \ifnum\catcode\count@=11\char\count@\fi
+ \ifnum\count@<\@cclv
+ \advance\count@\@ne
+ \repeat
+ \else
+ #1%
+ \fi
+ }%
+ \dimen@\dp\z@
+ \advance\dimen@\p@
+ \xdef\SOUL@uldepth{\the\dimen@}%
+}}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \subsection{The \texorpdfstring{\st{overstriking}}{overstriking} driver}
+%
+% \begin{macro}{\SOUL@stpreamble}
+% Striking out is just underlining with a raised line of a different
+% color. Hence we only need to define the preamble accordingly and
+% let the underlining preamble finally do its job. Not that colored
+% overstriking was especially useful, but we want at least to keep
+% it black while we might want to set underlines in some fancy color.
+%
+% \begin{macrocode}
+\def\SOUL@stpreamble{%
+ \dimen@\SOUL@ulthickness
+ \dimen@i=-.5ex
+ \advance\dimen@i-.5\dimen@
+ \edef\SOUL@uldepth{\the\dimen@i}%
+ \let\SOUL@ulcolor\SOUL@stcolor
+ \SOUL@ulpreamble
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@stsetup}
+% We re-use the whole underlining setup and just replace the preamble
+% with our modified version.
+%
+% \begin{macrocode}
+\def\SOUL@stsetup{%
+ \SOUL@ulsetup
+ \let\SOUL@preamble\SOUL@stpreamble
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\textst}
+% These pretzels are making me thirsty \dots
+%
+% \begin{macrocode}
+\DeclareRobustCommand*\textst{\SOUL@stsetup\SOUL@}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@stcolor}
+% \begin{macro}{\setstcolor}
+% Set the overstriking color. This won't be used often, but is required
+% in cases, where the underlines are colored. You wouldn't want to
+% overstrike in the same color. Note that overstriking lines are
+% drawn \emph{beneath} the text, hence bright colors won't look good.
+%
+% \begin{macrocode}
+\let\SOUL@stcolor\relax
+\def\setstcolor#1{%
+ \if$#1$
+ \let\SOUL@stcolor\relax
+ \else
+ \def\SOUL@stcolor{\textcolor{#1}}%
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \subsection{The highlighting driver}
+%
+% \begin{macro}{\SOUL@hlpreamble}
+% This is nothing else than overstriking with very thick lines.
+%
+% \begin{macrocode}
+\def\SOUL@hlpreamble{%
+ \setul{}{2.5ex}%
+ \let\SOUL@stcolor\SOUL@hlcolor
+ \SOUL@stpreamble
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\SOUL@hlsetup}
+% No need to re-invent the wheel. Just use the overstriking setup
+% with a different preamble.
+%
+% \begin{macrocode}
+\def\SOUL@hlsetup{%
+ \SOUL@stsetup
+ \let\SOUL@preamble\SOUL@hlpreamble
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \begin{macro}{\texthl}
+% \begin{macro}{\sethlcolor}
+% \begin{macro}{\SOUL@hlcolor}
+% Define the highlighting macro and the color setting macro with a
+% simple default color. Yellow isn't really pleasing, but it's already
+% predefined by the \package{color} package.
+%
+% \begin{macrocode}
+\DeclareRobustCommand*\texthl{\SOUL@hlsetup\SOUL@}
+\def\sethlcolor#1{\if$#1$\else\def\SOUL@hlcolor{\textcolor{#1}}\fi}
+\sethlcolor{yellow}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \subsection*{The package postamble}
+%
+% \begin{macro}{\so}
+% \begin{macro}{\ul}
+% \begin{macro}{\st}
+% \begin{macro}{\hl}
+% \begin{macro}{\caps}
+% OK, I lied. The short macro names are just abbreviations for their
+% longer counterpart. Some people might be used to |\text*| style commands
+% to select a certain font. And then it doesn't hurt to reserve
+% these early enough.
+%
+% \begin{macrocode}
+\let\so\textso
+\let\ul\textul
+\let\st\textst
+\let\hl\texthl
+\let\caps\textcaps
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \noindent
+% When used in an environment other than \LaTeX\ and the \package{german}
+% package was already loaded, define the double quotes as accent.
+%
+% \begin{macrocode}
+\ifx\documentclass\@undefined
+ \ifx\mdqoff\@undefined
+ \else
+ \soulaccent{"}%
+ \fi
+ \catcode`\@=\atcode
+% \end{macrocode}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \noindent
+% If we have been loaded by a \LaTeX\ environment and the \package{color}
+% package wasn't also loaded, we disable all colors. Then we add the umlaut accent
+% |"| if the \package{german} package is present. The quotes character has to
+% be \cs{\catcode}'d \cs{\active} now, or it won't get recognized later.
+% The \option{capsdefault}
+% option overrides the \cs{\caps} driver and lets \cs{\SOUL@} set an underline.
+% Finally load the local configuration, process the |capsdefault|
+% option and exit.
+%
+% \begin{macrocode}
+\else
+ \bgroup
+ \catcode`\"\active
+ \AtBeginDocument{%
+ \@ifundefined{color}{%
+ \let\SOUL@color\relax
+ \let\setulcolor\@gobble
+ \let\setstcolor\@gobble
+ \let\sethlcolor\@gobble
+ \let\hl\ul
+ }{}
+ \@ifundefined{mdqoff}{}{\soulaccent{"}}
+ }
+ \egroup
+ \DeclareOption{capsdefault}{%
+ \AtBeginDocument{%
+ \def\SOUL@capsdfltfnt#1{%
+ \SOUL@ulsetup
+ \SOUL@ulpreamble
+ \scshape
+ }%
+ }%
+ }
+ \InputIfFileExists{soul.cfg}%
+ {\PackageInfo{soul}{Local config file soul.cfg used}}{}
+ \ProcessOptions
+\fi
+\endinput
+% \end{macrocode}
+%
+%
+%
+%
+%^^A--------------------------------------------------------------------
+%
+%
+%
+%
+% \vspace{2explus1fill}
+%\begin{verbatim}
+%$Id: soul.dtx,v 1.128 2003/11/17 22:57:24 m Rel $
+%\end{verbatim}
+% \Finale
+%
+%
+% ^^A.E.I.O.U.^^
+%^^A vim:ts=4:sw=4:et
diff --git a/macros/generic/soul/soul.ins b/macros/generic/soul/soul.ins
new file mode 100644
index 0000000000..451343f7df
--- /dev/null
+++ b/macros/generic/soul/soul.ins
@@ -0,0 +1,10 @@
+%% LaTeX2e file `soul.ins'
+%% generated by the `filecontents' environment
+%% from source `soul' on 2003/11/17.
+%%
+\def\batchfile{soul.ins}
+\input docstrip.tex
+\askforoverwritefalse
+\keepsilent % <-- this is for you, Christina ;-)
+\generate{\file{soul.sty}{\from{soul.dtx}{package}}}
+\endbatchfile
diff --git a/macros/generic/soul/soul.pdf b/macros/generic/soul/soul.pdf
new file mode 100644
index 0000000000..d60e6ba326
--- /dev/null
+++ b/macros/generic/soul/soul.pdf
Binary files differ
diff --git a/macros/generic/soul/soul.txt b/macros/generic/soul/soul.txt
new file mode 100644
index 0000000000..c44b4100fd
--- /dev/null
+++ b/macros/generic/soul/soul.txt
@@ -0,0 +1,59 @@
+soul.sty
+========
+
+This article describes the `soul' package, which
+provides hyphenatable letterspacing (spacing out),
+underlining, and some derivatives.
+All features are based upon a common mechanism
+that allows to typeset text syllable by syllable,
+where the excellent TeX hyphenation algorithm is
+used to find the proper hyphenation points.
+Two examples show how to use the provided interface to
+implement things such as `an-a-lyz-ing syl-la-bles'.
+Although the package is optimized for LaTeX2e,
+it works with Plain TeX and with other
+packages, too.
+
+author = "Melchior FRANZ"
+version = "2.4"
+date = "17 November 2002"
+address = "Melchior FRANZ
+ Rieder Hauptstrasse 52
+ A-5212 SCHNEEGATTERN
+ AUSTRIA"
+telephone = "++43 7746 3109"
+URL = "http://www.unet.univie.ac.at/~a8603365/"
+email = "a8603365@unet.univie.ac.at"
+codetable = "ISO/ASCII"
+keywords = "spacing out, letterspacing, underlining, striking out,
+ highlighting"
+supported = "yes"
+
+
+
+COPYRIGHT NOTICE
+================
+This package is free software that can be redistributed and/or modified
+under the terms of the LaTeX Project Public License as specified
+in the file macros/latex/base/lppl.txt on any CTAN archive server,
+such as ftp://ftp.dante.de/.
+
+
+
+Extracting the package & processing the documentation
+=====================================================
+
+on Unix/Linux just run "make" to get the style file and the documentation;
+else generate the driver soul.ins (if you don't already have it):
+
+ $ latex soul.dtx
+
+You'll probably get an error message that you may ignore. Now generate
+the style file:
+
+ $ tex soul.ins
+
+And finally to produce the documentation run LaTeX three times:
+
+ $ latex soul.dtx
+
diff --git a/macros/generic/youngtab/README b/macros/generic/youngtab/README
new file mode 100644
index 0000000000..5facde72a0
--- /dev/null
+++ b/macros/generic/youngtab/README
@@ -0,0 +1,94 @@
+YOUNGTAB-Package
+================
+-----------------------------------------------------------------------
+Authors:
+-----------------------------------------------------------------------
+
+Volker B"orchers (email: boercher@physik.uni-bremen.de)
+and Stefan Gieseke (email: gieseke@physik.uni-bremen.de)
+
+-----------------------------------------------------------------------
+Legal stuff:
+-----------------------------------------------------------------------
+Copyright (C) 1996,98,99 Volker B"orchers and Stefan Gieseke,
+This program can be redistributed and/or modified under the terms
+of the LaTeX Project Public License Distributed from CTAN
+archives in directory macros/latex/base/lppl.txt; either
+version 1 of the License, or any later version.
+
+-----------------------------------------------------------------------
+FILES:
+-----------------------------------------------------------------------
+
+README
+---------------- the file you're reading now
+
+youngtab.dtx
+---------------- a documentated version of the package. From it you can
+generate both a documentation and the .sty file without most comments
+using the docstrip utility.
+
+youngtab.ins
+---------------- run TeX on it to generate the youngtab.sty in your
+current working directory (from the .dtx file)
+
+makeydoc
+---------------- this (unix-) script generates youngtab.dvi, the
+documentation for the package.
+
+makeydoc.bat
+---------------- same as makeydoc but for MSDOS (may need some editing).
+
+gind.ist
+---------------- You need it to generate the index for the
+documentation. (gind.ist is a official part of doc/docstrip
+package. Just in the case this is not installed...)
+
+youngtab.tex
+---------------- For thoose who don't use LaTeX but TeX.
+
+youngtab.el
+---------------- Only for thoose who use Emacs in connection with
+AUC-TeX, the best TeX-shell i can imagine.. Makes life with
+Young-Tableaux even easier (autocompletion, syntax help).
+
+
+-----------------------------------------------------------------------
+INSTALL:
+-----------------------------------------------------------------------
+1) `tex youngtab.ins' (alternatively: `latex youngtab.ins')
+2) `makeydoc'
+ * if you don't want any macrocode listings, uncomment the line
+ containing ``\OnlyDescription'' (remove the `#')
+3) put `youngtab.sty' to a path where LaTeX can find it.
+
+-----------------------------------------------------------------------
+For TeX-users:
+-----------------------------------------------------------------------
+follow the instructions in the documentation. (You must have
+LaTeX2e to produce a .dvi file from youngtab.dtx -- Try to read the
+.dtx file instead if you don't have!)
+However there is a file already prepared for use with TeX:
+`youngtab.tex' - try this and install in a directory where TeX will
+find it.
+
+-----------------------------------------------------------------------
+For AUC-TeX-users:
+-----------------------------------------------------------------------
+. to install it once and for all, copy `youngtab.el' to the AUC-TeX
+style-directory, e.g. /usr/lib/emacs/site-lisp/auctex/style/.
+. to install it locally: do `mkdir style; cp youngtab.el style' in the
+directory where your .tex files, using youngtab, reside (or in each if
+you have more).
+. Provides autocompletion and syntax checks for the switches and
+dimensions "Y.*" and \young and \yng if you type `C-c RET' in emacs.
+
+-----------------------------------------------------------------------
+Date:
+-----------------------------------------------------------------------
+05/05/98
+
+-----------------------------------------------------------------------
+Version:
+-----------------------------------------------------------------------
+1.1
diff --git a/macros/generic/youngtab/makeydoc b/macros/generic/youngtab/makeydoc
new file mode 100755
index 0000000000..d0fda75af8
--- /dev/null
+++ b/macros/generic/youngtab/makeydoc
@@ -0,0 +1,59 @@
+#!/bin/sh
+#
+# Everything after a `#' is ignored (in this shell script)
+#
+# remove the string `> /dev/null' if you want more log-output
+# remove the line containing `batchmode' if you want even more
+# log-information while running LaTeX
+#
+#----------------- create a `ltxdoc.cfg': --------------------------
+
+# Put here a list of options to pass to the class:
+OPT=a4paper
+
+echo "Generating configuration file ltxdoc.cfg for youngtab.dtx"
+
+# Write the file in one pass:
+cat > ltxdoc.cfg <<EOF
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% ltxdoc.cfg for youngtab.dtx, generated by makeydoc %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\PassOptionsToClass{$OPT}{article}
+\batchmode
+
+%% Do not uncomment the next 2 lines
+%\AtBeginDocument{\RecordChanges}
+%\AtEndDocument{\PrintChanges}
+
+%% The next 3 lines produce full indexes and change logs
+%% - you may not want those (commented out by default).
+\AtBeginDocument{\CodelineIndex\EnableCrossrefs}
+\AtEndDocument{\PrintIndex}
+\AtEndDocument{\addcontentsline{toc}{section}{Index}}
+
+%% If you do not want any code listings, just documentation, then instead
+%% of the lines above, uncomment the following:
+%\AtBeginDocument{\OnlyDescription}
+EOF
+#---------- latex the documentation using `ltxdoc.cfg': --------------
+
+ThisDoc=youngtab.dtx
+Base=youngtab
+
+echo;echo "1st latex $ThisDoc"
+if (latex $ThisDoc > /dev/null)
+then
+ echo;echo "2nd latex $ThisDoc"
+ latex $ThisDoc > /dev/null
+
+ echo;echo "makeindex -s gind.ist $Base.idx"
+ makeindex -s gind.ist $Base.idx
+ echo;echo "3rd latex $ThisDoc"
+ latex $ThisDoc > /dev/null
+else
+ echo;cat <<EOF
+ !!! LaTeX ERROR: $ThisDoc. (See $Base.log.)
+ Perhaps a new version of youngtab.sty is missing?
+ (Then, generate it by "tex youngtab.ins")
+EOF
+fi
diff --git a/macros/generic/youngtab/makeydoc.bat b/macros/generic/youngtab/makeydoc.bat
new file mode 100644
index 0000000000..da46a730a8
--- /dev/null
+++ b/macros/generic/youngtab/makeydoc.bat
@@ -0,0 +1,45 @@
+@echo off
+rem MAKEYDOC.BAT (FOR MSDOS)
+
+rem Everything after a `rem' is ignored
+
+
+rem ----------------- create a `ltxdoc.cfg': --------------------------
+
+rem Edit the next line for options to pass to the class:
+echo \PassOptionsToClass{a4paper}{article} > ltxdoc.cfg
+echo \batchmode >> ltxdoc.cfg
+
+rem The next lines produce full indexes and change logs
+rem you may not want those:
+
+rem echo \AtBeginDocument{\RecordChanges} >> ltxdoc.cfg
+rem echo \AtEndDocument{\PrintChanges} >> ltxdoc.cfg
+echo \AtBeginDocument{\CodelineIndex\EnableCrossrefs} >> ltxdoc.cfg
+echo \AtEndDocument{\PrintIndex} >> ltxdoc.cfg
+echo \AtEndDocument{\addcontentsline{toc}{section}{Index}} >> ltxdoc.cfg
+
+rem If you do not want any code listings, just documentation, then instead
+rem of the lines above, uncomment the following:
+
+rem echo \AtBeginDocument{\OnlyDescription} >> ltxdoc.cfg
+
+rem ---------- latex the documentation using `ltxdoc.cfg': --------------
+
+echo 1st latex youngtab.dtx
+latex youngtab.dtx
+
+echo 2nd latex youngtab.dtx
+latex youngtab.dtx
+
+echo If you don't have Makeindex, exit now!
+echo makeindx -s gind.ist youngtab.idx
+makeindx -s gind.ist youngtab.idx
+rem or: echo makeidx -s gind.ist youngtab.idx
+rem or: makeidx -s gind.ist youngtab.idx
+
+echo 3rd latex youngtab.dtx
+latex youngtab.dtx
+
+echo +++++++++++++ all done! ++++++++++++
+
diff --git a/macros/generic/youngtab/youngtab.dtx b/macros/generic/youngtab/youngtab.dtx
new file mode 100644
index 0000000000..8db18c88c6
--- /dev/null
+++ b/macros/generic/youngtab/youngtab.dtx
@@ -0,0 +1,842 @@
+% \iffalse
+%% File: youngtab.dtx
+%% Copyright (C) 1996,98,99 Volker B"orchers and Stefan Gieseke,
+%% This program can be redistributed and/or modified under the terms
+%% of the LaTeX Project Public License Distributed from CTAN
+%% archives in directory macros/latex/base/lppl.txt; either
+%% version 1 of the License, or any later version.
+%
+%<package>\NeedsTeXFormat{LaTeX2e}
+%<package>\ProvidesPackage{youngtab}
+%<package>[1999/05/19 v1.1; Macros for Young-Tableaux]
+%
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage[enableskew]{youngtab}
+\GetFileInfo{youngtab.sty}
+\begin{document}
+\title{The \textsf{youngtab} package\thanks{This file has version number
+ \fileversion, dated \filedate.}}
+\author{Volker B\"orchers\thanks{email: boercher@physik.uni-bremen.de}
+ \\Stefan Gieseke\\
+ Universit\"at Bremen}
+\date{\filedate}
+ \maketitle
+ \DocInput{youngtab.dtx}
+\end{document}
+%</driver>
+% \fi
+%\iffalse
+%
+%% Package `youngtab' to use with TeX, LaTeX209 or LaTeX2e
+%% (You will need LaTeX2e to extract the documentation and a STY-file
+%% without comments from the .dtx file)
+%
+% Version: Date: Changes:
+%
+% 1.0 1996/03/25 First working version. (After much
+% frustrating tries to teach TeX accept
+% indefinite count of arguments - lerning TeX
+% in the meanwhile)
+% 1.1 1998/05/05 Added possibility to typeset ``skew''
+% tableaux (package option `enableskew')
+% suggested by Andrew Mathas
+% <mathas@maths.usyd.edu.au>. Added AUC-TeX
+% support for the youngtab macros (youngtab.el).
+% 1999/05/19 Only change: added licence informations
+%\fi
+%
+%
+% \DoNotIndex{\advance,\box,\CurrentOption,\DeclareOption,\def}
+% \DoNotIndex{\else,\fi,\hbox,\hfil,\hrule,\hspace,\ht,\ifcat}
+% \DoNotIndex{\ifmmode,\ifnum,\ifvoid,\loop,\MessageBreak,\newcount}
+% \DoNotIndex{\newdimen,\newif,\newskip,\offinterlineskip}
+% \DoNotIndex{\PackageWarning,\ProcessOptions,\relax,\repeat,\setbox}
+% \DoNotIndex{\space,\typeout,\unskip,\vbox,\vcenter,\vrule,\vspace}
+%
+% \CheckSum{322}
+%
+% \newcommand{\yt}{Young-Tableau}
+% \newcommand{\yts}{Young-Tableaux}
+% \newcommand{\newfeature}[1]{\leavevmode%
+% \marginpar{\small\sffamily\begin{center}
+% New feature\\#1\end{center}}}
+%
+% \begin{abstract}
+% This package provides two macros for typesetting
+% \yts\ with \TeX\ or \LaTeX. We use 2 macros, the first for empty
+% boxes (|\yng|), and the second for labelled boxes (|\young|). The
+% syntax of the macros is simple to avoid spelling-mistakes.
+% \end{abstract}
+%
+% \tableofcontents
+%
+% \section{Introduction}
+% The \yt-formalism is a strong algrebraic tool in group theory. Of course
+% we will deal here only with the problems of \emph{typesetting} \yts.
+% They are mathematical objects, so they usually occur in mathematical
+% environments. On the surface \yts\ consist of boxes like this:
+% \yng(1) --- or optionally labelled (usually with letters): \young(a).
+%
+% There is already one \LaTeX-package for typesetting \yts, the
+% \texttt{young.sty} by J\"org Knappen (based on |young.tex| by P. E. S.
+% Wormer). It provides a \texttt{Young}-environment with a syntax
+% similar to the \texttt{tabular}-environment.
+%
+% An Example for the usage of \texttt{Young}:
+%
+% \begin{minipage}[t]{5cm}
+% \begin{verbatim}
+% \begin{Young}
+% $a$&&\cr
+% &\cr
+% \cr
+% \end{Young}
+% \end{verbatim}
+% \end{minipage}
+% \parbox[t]{4cm}{ \young(a\hfil\hfil,\hfil\hfil,\hfil) }
+%
+% \iffalse
+% COMMENT: Maybe that's not the correct way to pretend the use of the
+% |Young|-environment, but otherwise we had to use |young.sty| only
+% for this tableau!
+% \fi
+%
+% This way of implementing \yts\ has one big advantage: It can deal with
+% an indefinite number of rows and columns (of course this is needed!).
+% A second argument for using a \texttt{tabular}-like environment might
+% be it's simple encoding.
+%
+% Nevertheless we wanted a simpler user-interface, for the use of |&| and
+% |\cr| is usually a very good source of typing mistakes (e.g. you
+% have to type \emph{three} |&|'s to get \emph{four} boxes in one
+% row). In addition the \TeX-code for mathematical relations with more
+% than two or three \yts\ becomes unreadable.
+%
+% The cure would be of course a \emph{macro} with a compact, intuitive
+% syntax. But there is the above mentioned problem: \TeX\ is not made to
+% handle an indefinite number of arguments. For \yts\ composed of empty
+% boxes we would like to have a macro with one argument for each row
+% (counting the number of boxes per row) for example this way:
+% |\thisdoesnotwork{5}{3}{1}|\dots. For \yts\ composed of labelled
+% boxes the problem is even worse since we have one letter
+% \emph{per box}!
+%
+% So we had to hide the fact of having an indefinite number of arguments
+% from \TeX. The macros in this package have --- as \TeX\ sees it ---
+% only one argument; this is parsed for the necessary information
+% by the macros themselves. Whereas, for the user, the number of rows and
+% number of boxes per row are plain to see.
+%
+% \section{Using the youngtab package}
+% Invoke the |youngtab| package by
+% requesting it in the preamble:\footnote{Of course this does not work
+% if you use the |youngtab|-package with \TeX\ instead of \LaTeX. For
+% compatibility-questions see section \ref{compat}}
+%
+% |\usepackage[...]{youngtab}|
+%
+% The package has four options (increasing)\DescribeMacro{Options}.
+% The \emph{first option}, |vcentermath|\DescribeMacro{vcentermath},
+% \emph{turns on} the vertical centering of the tableaux in math mode. The
+% \emph{second option}, |noautoscale|\DescribeMacro{noautoscale}, \emph{turns
+% off} the automatic scaling of the boxes according to the actual font.
+% The \emph{third one}, |stdtext|\DescribeMacro{stdtext}, switches
+% to text mode in the inside of labelled boxes. Choosing one of this
+% options does not mean that you have, for example, to stick to
+% |noautoscale| till the end of your days. You may change this
+% settings as often as you like.\\
+% The \emph{fourth option},
+% |enableskew|\DescribeMacro{enableskew}\newfeature{1998/05/05}
+% enables typesetting of skew \yts\ (tableaux that are not
+% left-aligned). This option is different from the other in the way
+% that there is no command to enable this feature after the package is
+% loaded.
+%
+% \yts\ usually have more than one row, so the vertical alignment is a
+% problem\DescribeMacro{vcentermath}. You can turn on vertical centering
+% (only) in mathmode either by choosing the option |vcentermath| with
+% |\usepackage| or later with the command
+% |\Yvcentermath|\meta{num}. Say |\Yvcentermath1| if you want
+% vertical centering and |\Yvcentermath0| to switch it off. Without
+% vcentering the tableaux are standing on the baseline.
+%
+% Since the boxes are quadratic (if you do not want want this,
+% complain!), there is only one dimension to determine: the length and
+% height of the boxes. Usually the macros determine this for
+% themselves,\footnote{So that a \yt\ e.g.\ \texttt{\bslash young(ab)}
+% \young(ab) appears smaller in a footnote than in normal text!} but
+% you can change this behavior by calling the macro
+% |\Yautoscale|\meta{num}\DescribeMacro{\Yautoscale}. Call it with
+% an argument of |1| if you want autoscaling after this, or with
+% the argument |0| if you want to adjust the box dimensions
+% yourself.
+%
+% \DescribeMacro{\Yboxdim}If you switch off autoscaling and
+% want to change the box dimensions, you have to call the macro
+% |\Yboxdim|\meta{dim} with a usual \TeX--dimension.
+% The argument has to be appended to the macro: |\Yboxdim13pt|. This
+% dimension is the \emph{total} height and width of the boxes --
+% \emph{including the lines.} (For small linethicknesses this
+% makes of course only a small difference.) Note that the use of |\Yboxdim|
+% \emph{implies} |noautoscale|! So to switch from |autoscale| to
+% |noautoscale| one call to |\Yboxdim| is sufficient.
+%
+% There is only one more parameter which determines the appearance of
+% the \yt\DescribeMacro{\Ylinethick}: the lines' thickness. This is
+% set by |\Ylinethick|\meta{dim}. (The default is $0.3pt$).
+%
+% You may add space between a tableau and surrounding stuff by
+% invoking the macro
+% |\Yinterspace|\meta{skip}\DescribeMacro{\Yinterspace}. The advantage
+% of using a \emph{skip} is that this helps \TeX\ to avoid |Over|-
+% or |Underful \hbox|es. The default value is |0ex plus 0.3ex|\,.
+% (Better take |ex| or |em| for the tableaux are scaleable.)
+%
+% \subsection{Empty boxes: \texttt{\protect\bslash yng}}
+% \DescribeMacro\yng
+% The most used variant of \yts\ are those consisting of empty boxes.
+% For the tableau \yng(2,1) you have to type
+% |\yng(2,1)|. If you want it to appear smaller, change the
+% fontsize: |{\tiny\yng(2,1)}| gives \Yautoscale1
+% {\tiny\yng(2,1)}; but remember, this only works if |autoscale|
+% is turned on (default). (If you are in |noautoscale|-mode, restore
+% autoscaling with |\Yautoscale1|.)
+%
+% Some notes on the usage of |\yng| and |\young| in math or
+% text mode\DescribeMacro{math or text?}: You can generate \yts\ in both
+% modes, but differences arise from \emph{vertical centering}.
+% This only works in math mode (if you have chosen it with
+% |\Yvcentermath1|) or |usepackage| option |vcentermath|.
+%
+% The difference is to be seen here:
+% {\tiny\Yvcentermath1 $\yng(1,1)\oplus\yng(1)=$
+% \yng(2,1)}$\oplus$ \dots, which has been generated by
+% \begin{verbatim}
+% {\tiny\Yvcentermath1 $\yng(1,1)\oplus\yng(1)=$
+% \yng(2,1)}$\oplus$ \dots
+% \end{verbatim}
+%
+% Here the tableau in math are centered with respect to the axis of
+% the formula while the one in text mode isn't. Note the
+% dimensions of the tableau on the one hand and the |\oplus| on the
+% other: The dimensions of the \yts\ are determined by the actual
+% text's fontsize (while autoscaling!)\DescribeMacro{sizing}. Try to
+% understand what happens in the following example. --- Do you
+% understand the sizes of the math symbols? (Compare to the example
+% above and have look up the \texttt{.log} file. Don't let \TeX\ fool
+% you by messages about invalid |\normalsize|!)
+% \begin{verbatim}
+% {\tiny\begin{equation}
+% \Yvcentermath1
+% \yng(1,1)\oplus\yng(1)= \Yboxdim{12pt}
+% \yng(2,1)\normalsize\oplus\dots
+% \end{equation}}
+% \end{verbatim}
+% {\tiny\begin{equation}
+% \Yvcentermath1 \yng(1,1)\oplus\yng(1)=
+% \Yboxdim{12pt}\yng(2,1)\normalsize\oplus\dots
+% \end{equation}}
+% \Yautoscale1
+%
+% \subsection{Labelled boxes: \texttt{\protect\bslash young}}
+% \DescribeMacro\young
+% While the sizing of the boxes and the behavior in math/text mode are
+% exactly the same as with |\yng|, we have of course a different syntax:\\
+% |{\scriptsize\young(aa,b)}| results in
+% {\scriptsize\young(aa,b)}. Each line of the tableau is represented
+% by a row of single letters (exactly: ``tokens''). The lines
+% are separated by commas.
+%
+% As you see from the example above the letters |a| and |b| come out in
+% math italics. This does \emph{not} depend on the \yt\ appearing in
+% math or text surround. \emph{The label within a tableau-box is math -- no
+% matter if the tableau is used in text or math mode!} But this is
+% only the default setting. Use either the option |stdtext| to the
+% |\usepackage| command to switch to roman letters or use the macro
+% |\Ystdtext| with an argument of |1|: |\Ystdtext1|. To switch to math
+% again use |\Ystdtext0|.
+%
+% What to do if you don't want to use single letters, but symbols or
+% perhaps some white boxes? There are no limits but it's a bit
+% complicated. The |\young| algorithm for parsing his argument depends
+% strongly on that every label of \emph{one} box,
+% \begin{enumerate}
+% \item consists of only \emph{one token}. Assume first you had
+% \emph{not} said |\Ystdtext1|. To get a single roman `a' then you
+% must not say |\mbox{a}|, because this makes \emph{four} tokens (1st
+% is |\mbox|, 2nd is |{|, 3rd is |a|, 4th is |}|). The cure is
+% simply making one token out of |\mbox{a}| by saying
+% |\newcommand{\rma}{\mbox{a}}| and everything is OK:\footnote{Note
+% that the space after \texttt{\bslash rma} belongs to the token itself.}
+% \newcommand{\rma}{\mbox{a}} |\young(\rma lright\bullet)| = \young(\rma
+% lright\bullet)\\
+% After |\Ystdtext1| it is an error to say |$\bullet$|, since the
+% two math delimiters are single tokens. Do it as described above:
+% \Ystdtext1\\ |\newcommand{\ybullet}{$\bullet$}|\\ and
+% everything is OK: \newcommand{\ybullet}{$\bullet$}
+% |\young(\ybullet works)| = \young(\ybullet works)\,.\Ystdtext0\\
+% To use a symbol or special letter in both modes (|\Ystdtext 0 or 1|)
+% put it in a box (here with an extra tuning):\\
+% |\renewcommand{\ybullet}{\raise1.5pt \hbox{$\bullet$}}|
+% \item Some characters and macros are not allowed: commas (guess why)
+% and the other punctuation marks, spaces, the macro |\space| and also
+% skips like |\,| and |\:|.\footnote{Write to us if you find more.} If
+% you want to have single empty boxes use (\TeX\ primitive) |\hfil|
+% (For understanding this limitations see also |\y@lastargtest| and
+% |\y@nelettertest| in macro section).
+% \end{enumerate}
+%
+%
+% \subsubsection{Skew \yts\ with \texttt{\protect\bslash young}}
+% \newfeature{1998/05/05}
+% As far as described above, the rows of a \yt\ are left-aligned. Since
+% some authors also assigned a meaning to \emph{``skew''} tableaux, this
+% package also supports such along with |\young|. If you want to typeset
+% skew tableaux, you have to enable this via the package option
+% |enableskew|\DescribeMacro{enableskew}. The default behavior of this
+% package is to \emph{dis\/}able skew boxes in order to save \TeX's
+% time, however, it's save to include this option even if you do not use
+% it.
+%
+% Here is an example:
+% |\young(abcd,:bc,::c)|: \raisebox{-1.9\baselineskip}{\young(abcd,:bc,::c)}
+%
+% As you see, the Option |enableskew| makes the colon a special
+% character (only inside the argument of |\young|). \footnote{If you
+% want a colon to appear as it is (do you??), you have to do the same
+% trick as above with an unpleasant extra: define a macro for the
+% colon using the \TeX-primitive \texttt{\bslash char} like this:
+% \texttt{\bslash newcommand{\bslash mycolon}{\bslash char58}}.} In
+% fact all other than the leading colons in a row will simply be
+% ignored, while the first will move the row to the right.
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \Yboxdim.4ex
+% \raisebox{-1pt}{\young(:\hfil,\hfil,\hfil,\hfil,\hfil,:\hfil)}
+% This is a\,
+% \young(\hfil,\hfil,\hfil,\hfil,\hfil\hfil\hfil)
+% \young(\hfil,\hfil,\hfil,\hfil,\hfil)
+% \young(\hfil\hfil\hfil,:\hfil,:\hfil,:\hfil,:\hfil)
+% \young(\hfil\hfil\hfil,:\hfil,:\hfil,:\hfil,:\hfil)
+% \young(\hfil,\hfil,\hfil,\hfil,\hfil\hfil\hfil)
+% \young(\hfil\hfil\hfil,\hfil,\hfil\hfil,\hfil,\hfil\hfil\hfil)
+% \hspace{.7ex}
+% \young(\hfil\hfil\hfil,:\hfil,:\hfil,:\hfil,:\hfil)
+% \young(\hfil\hfil\hfil,\hfil,\hfil\hfil,\hfil,\hfil\hfil\hfil)
+% \young(:\hfil\hfil\hfil,\hfil,:\hfil\hfil,:::\hfil,\hfil\hfil\hfil)
+% \young(\hfil\hfil\hfil,:\hfil,:\hfil,:\hfil,:\hfil)
+% of skew tableaux.
+% \raisebox{-1pt}{\young(\hfil,:\hfil,:\hfil,:\hfil,:\hfil,\hfil)}
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \Yautoscale1
+%
+%
+% \subsection{The \texttt{youngtab} package and \TeX}\label{compat}
+% \DescribeMacro{Compatibility}Because we do not use \PlainTeX, the
+% compatibility of this package and \TeX\ is not sufficiently tested.
+% However there are some changes necessary in |youngtab.sty| (see file
+% \texttt{youngtab.tex}, part of the distribution):
+% \begin{itemize}
+% \item The macros themselves only use two \LaTeX-commands,
+% |\vspace{|\meta{dim}|}| and |\hspace{|\meta{dim}|}|. One has to
+% replace them with `|\vskip |\meta{dim}' resp.\ `|\hskip|
+% \meta{dim}'\,. (The braces also have to get removed) The
+% \LaTeX-counterparts may be better but no problems should arise
+% from this replacement (we found none).
+% \item One has to remove all lines containing \LaTeXe-commands in the
+% preamble of the |.sty| file, e.g.\ comment out every line that
+% contains the following commands: |\DeclareOption|,
+% |\ProcessOptions|, |\NeedsTeXFormat| and |\ProvidesPackage|.
+% \item Since \TeX-input files must not contain a |@|,
+% |\catcode`\@11\relax| has to be added to the begin of the |.sty| file to
+% make |@| a |letter| and |\catcode`\@12\relax| at the end right
+% before the |\endinput|, to make it |other| again afterwards.
+% \item \textbf{Skew:}\hspace{1em} \TeX\ knows nothing about
+% style-options, we have to find a way to enable skew
+% \yts. (|enableskew| is the only package option that can \emph{not}
+% be accessed by a macro \emph{after loading} the package since
+% almost all according actions will be done at loading time).\\
+% Therefore, we will check if a macro |\enableskew| is defined at loading
+% time:\\[.3ex]
+% | \expandafter\ifx\csname enableskew\endcsname\relax|\\
+% | \y@enable@skewfalse \else \y@enable@skewtrue\fi|\\[.3ex]
+% (excerpt from |youngtab.tex|) Then this will enable printing of
+% skew tableaux: \hfil|\def\enableskew{1} \input youngtab|
+% \item The autoscaling doesn't work as nice as with \LaTeX\ since if
+% you lower the text's fontsize (which determines the boxsize), you
+% have to lower also the math fontsize. Otherwise the letters in
+% labelled boxes (math!) are too big for the box.
+% \end{itemize}
+%
+% \subsection{To do}
+% We have a \textbf{wish list}, things we think the package should be
+% capable of:
+% \begin{itemize}
+% \item A vertical alignment, in the way that the \emph{top}line of the
+% \yts\ and the mathsymbols are on the same height (perhaps using
+% |\vtop|?).
+% \item The macros should take notice of math fontsize changes e.g.\ with
+% \texttt{\bslash dis\-play\-style}. (This puts a focus on the autoscale
+% mechanism -- see |\y@setdim| in the macro section.)
+% \end{itemize}
+% \textbf{If You} have any problems, suggestions, critical remarks -- or
+% whatever according this package write to Volker B\"orchers
+% (email-adress see title).\\
+% {\tiny\yng(61)}
+%
+% \StopEventually{}
+%
+% \section{The Macros}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macro}{\Yautoscale}
+% \begin{macro}{\ify@autoscale}
+% If autoscaling is active, the size of the boxes (|\y@boxdim|) is
+% determined by the package itselve. The default setting is to
+% allow autoscale. |\Yautoscale|\meta{num} serves as the user
+% interface.\footnote{I know - it's against the \LaTeXe naming
+% conventions, but it is nicer\dots} We made an option to |\usepackage|
+% out of that (see below).
+% \begin{macrocode}
+\newif\ify@autoscale \y@autoscaletrue \def\Yautoscale#1{\ifnum #1=0
+ \y@autoscalefalse\else\y@autoscaletrue\fi}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\Yboxdim}
+% \begin{macro}{\y@b@xdim}
+% \begin{macro}{\y@boxdim}
+% The parameters determining the size of the single boxes and the macro
+% to set them. |\Yboxdim|\meta{dim} sets |\y@boxdim| (only used, when
+% autoscaling is turned off) and sets |y@autoscale| to
+% |false|. |\y@boxdim| is the \emph{total} size of the box (including
+% the delimiting lines) while |\y@b@xdim| (to be set in |\y@setdim|) is
+% the height and width of the inner of the box.
+% \begin{macrocode}
+\newdimen\y@b@xdim
+\newdimen\y@boxdim \y@boxdim=13pt
+\def\Yboxdim#1{\y@autoscalefalse\y@boxdim=#1}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\Ylinethick}
+% \begin{macro}{\y@linethick}
+% The line thickness and |\Ylinethick|\meta{dim} as user interface to it.
+% \begin{macrocode}
+\newdimen\y@linethick \y@linethick=.3pt
+\def\Ylinethick#1{\y@linethick=#1}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\Yinterspace}
+% \begin{macro}{\y@interspace}
+% To give the \yts\ extra-space (before and after) |\y@interspace| can
+% be set to more than |0pt| by calling |\Yinterspace|. (See |\yng| and
+% |\young|.) Note that this is a \emph{skip} and no \emph{dimemsion}.
+% \begin{macrocode}
+\newskip\y@interspace \y@interspace=0ex plus 0.3ex
+\def\Yinterspace#1{\y@interspace=#1}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\Yvcentermath}
+% \begin{macro}{\ify@vcenter}
+% The switch to turn vertical centering in math on or off. The default
+% is |\y@vcenterfalse|. The second option to |\usepackage|.
+% \begin{macrocode}
+\newif\ify@vcenter \y@vcenterfalse
+\def\Yvcentermath#1{\ifnum #1=0 \y@vcenterfalse\else\y@vcentertrue\fi}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\Ystdtext}
+% \begin{macro}{\ify@stdtext}
+% Normally the inside of the boxes (|\young|) is in math mode. This code
+% allows to switch to text mode.
+% \begin{macrocode}
+\newif\ify@stdtext \y@stdtextfalse
+\def\Ystdtext#1{\ifnum #1=0 \y@stdtextfalse\else\y@stdtexttrue\fi}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\ify@enable@skew}
+% In contrast to the other this \texttt{if} may be set only via the
+% package option |enableskew|.
+% \begin{macrocode}
+\newif\ify@enable@skew \y@enable@skewfalse
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{noautoscale}
+% \begin{macro}{vcentermath}
+% \begin{macro}{stdtext}
+% \begin{macro}{enableskew}
+% Declaration and processing of the options for use with
+% \LaTeXe. (For \TeX-users: Comment the following 8 lines out).
+% \begin{macrocode}
+\DeclareOption{noautoscale}{\y@autoscalefalse}
+\DeclareOption{vcentermath}{\y@vcentertrue}
+\DeclareOption{stdtext}{\y@vcentertrue}
+\DeclareOption{enableskew}{\y@enable@skewtrue}
+\DeclareOption*{\PackageWarning{youngtab}{%
+ Unknown option `\CurrentOption' (Known:\MessageBreak
+ `vcentermath', `noautoscale', `stdtext', `enableskew'.)}}
+\ProcessOptions\relax
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\y@vr}
+% A single vertical line to build the boxes. The reason for the depht of
+% the line should be clear. (The values for the depth maybe something
+% you want to tune)
+% \begin{macrocode}
+\def\y@vr{\vrule height0.8\y@b@xdim width\y@linethick depth 0.2\y@b@xdim}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\y@emptybox}
+% This macro does less than its name pretend: It only makes one vertical
+% line followed by a empty box (width: |\y@boxdim| -- 2|\y@linethick|).
+% \begin{macrocode}
+\def\y@emptybox{\y@vr\hbox to \y@b@xdim{\hfil}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\y@abcbox}
+% \begin{macro}{\y@mathabcbox}
+% If |enableskew| is not choosen (the package options have been
+% parsed now), a |\y@abcbox| or a |\y@mathabcbox| is the simple
+% analogue to |\y@emptybox| but it has a \emph{text-font} letter
+% centered in it.\\
+% For |\y@mathabcbox| the inside is math. We rather want an
+% easier access to math italics and symbols than to normal text; so we
+% usually use |\y@mathabcbox| instead of |\y@abcbox|.
+%
+% Skew \yts\ can only be used with |\young|. Then a colon is used to
+% \emph{shift} the row to the \emph{right} -- instead of ``inserting
+% a box without border'' -- so the colon boxes must be ignored.
+% \begin{macrocode}
+\ify@enable@skew
+ \def\y@abcbox#1{\if :#1\else
+ \y@vr\hbox to \y@b@xdim{\hfil#1\hfil}\fi}
+ \def\y@mathabcbox#1{\if :#1\else
+ \y@vr\hbox to \y@b@xdim{\hfil$#1$\hfil}\fi}
+\else
+ \def\y@abcbox#1{\y@vr\hbox to \y@b@xdim{\hfil#1\hfil}}
+ \def\y@mathabcbox#1{\y@vr\hbox to \y@b@xdim{\hfil$#1$\hfil}}
+\fi
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\y@setdim}
+% This macro is called at the beginning of the macros |\yng| and
+% |\young|. If |autoscale| is deactivated the box height and width is
+% |\y@boxdim| - 2|\y@linethick|. If not we save a box for temporary
+% usage, use the height of it to find a good size of the box, fill the
+% boxregister with a empty box, and clear the box again by using it.
+%
+% That's not elegant but I didn't know better\dots How can I determine
+% the height of the font in an other way? (I tried it with the \TeX-measure
+% |ex| -- but this did not seem to work in any case.) Or -- if I have
+% to use setbox -- which boxregister should I use? Is the |\ifvoid| test
+% obsolete? (First I used |\box0| -- till I found me competing with
+% \AmSTeX\ for this box.)
+% \begin{macrocode}
+\def\y@setdim{%
+ \ify@autoscale%
+ \ifvoid1\else\typeout{Package youngtab: box1 not free! Expect an
+ error!}\fi%
+ \setbox1=\hbox{A}\y@b@xdim=1.6\ht1 \setbox1=\hbox{}\box1%
+ \else\y@b@xdim=\y@boxdim \advance\y@b@xdim by -2\y@linethick
+ \fi}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\y@counter}
+% A counter for loops.
+% \begin{macrocode}
+\newcount\y@counter
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\y@lastargtest}
+% This macro is a hack to get \TeX\ to accept a indefinite number of
+% arguments (here: the number of \emph{lines} separated by commas). It
+% does nothing with its arguments but to see if the second is a space,
+% and, if it is to set |\y@islastargtrue|.\footnote{The
+% \texttt{islastarg} conditions are also used if the end of one line
+% of labelled boxes is reached.}
+% \begin{macrocode}
+\newif\ify@islastarg
+\def\y@lastargtest#1,#2 {\if\space #2 \y@islastargtrue
+ \else\y@islastargfalse\fi}
+% \end{macrocode}
+% How does it work? An Example:
+%
+% \verb*+\y@lastargtest first,second +\\
+% Here |#1| is |first| and |#2| is |second|. The |\if| construction
+% tests if the (expanded) \emph{first} token of |#2| and |\space|
+% (here: |s|) are equal. -- They are not. In the next example the
+% condition is |true|:
+%
+% \verb*+\y@lastargtest first, +\\
+% Here |#1| is again |first| but |\y@lastargtest| catches the blank
+% after the comma to be |#2|. The |\if| condition now is true and
+% |\y@islastargtrue| is set. Remember: the blank is essential!
+% \end{macro}
+%
+% \begin{macro}{\y@emptyboxes}
+% This macro draws |#1| (this is a number) empty boxes (|\y@emptybox|)
+% -- without a top or bottom line:
+%
+% |:\y@emptyboxes3:| \hspace{0.5em} is
+% :$\mid$\hspace{0.8em}$\mid$\hspace{0.8em}$\mid$\hspace{0.8em}:
+% \begin{macrocode}
+\def\y@emptyboxes#1{\y@counter=#1\loop\ifnum\y@counter>0
+ \advance\y@counter by -1 \y@emptybox\repeat}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\y@nelineemptyboxes}
+% This calls |\y@emptyboxes| and adds the top and bottom lines (I think
+% this is faster than draw single, complete boxes) and a right closing
+% vertical line. Because of the |\vspace| command the top line of the
+% eventually following next box-row will be drawn over the bottom line of
+% this box-row.
+% \begin{macrocode}
+\def\y@nelineemptyboxes#1{%
+ \vbox{%
+ \hrule height\y@linethick%
+ \hbox{\y@emptyboxes{#1}\y@vr}
+ \hrule height\y@linethick}\vspace{-\y@linethick}}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\yng}
+% The user-macro for empty \yts. As mentioned above it has only one
+% argument, enclosed in brackets. It first calls |\y@setdim| to
+% determine the size of the boxes and opens a |\vcenter| if in math mode
+% and |vcentermath| is set. Otherwise only a (then obsolet) |{| is
+% opened. |\y@lastargtest| determines if the tableau should have only
+% one line, setting |\y@islastargtrue| or -|false|. If there is only one
+% line, |\yng| does the whole job in calling
+% |\y@nelineemptyboxes| once. Otherwise it calls |\y@ungempty| to do the
+% real thing. Note the spacing before and after the tableau using
+% |\hspace|.
+% \begin{macrocode}
+\def\yng(#1){%
+ \y@setdim%
+ \hspace{\y@interspace}%
+ \ifmmode\ify@vcenter\vcenter\fi\fi{%
+ \y@lastargtest#1,
+ \vbox{\offinterlineskip
+ \ify@islastarg
+ \y@nelineemptyboxes{#1}
+ \else
+ \y@ungempty(#1)
+ \fi}}\hspace{\y@interspace}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\y@ungempty}
+% It is called with |\y@ungempty(#1)| from |\yng|. Now the parsing of
+% the arguments starts! As we know from |\y@lastargtest| in
+% |\yng|, there really are two arguments left. Explicitely: Let the
+% the initial command (given by the user) be |\yng(3,2,1)|; then
+% |\yng| calls |\y@ungempty(3,2,1)|. But |\y@ungempty| sees two
+% arguments: |#1| is |3| and |#2| is |2,1|! (Note the importance of the
+% brackets). |\y@ungempty| then processes the first argument immediately,
+% calling |\y@nelineemptyboxes|. (The braces protect numbers with more
+% than one digit.)
+%
+% The next step is to check if |#2| is the last line. If it is, it calls
+% \texttt{\bslash y@ne\-line\-empty\-boxes} again. Otherwise it calls
+% \emph{recursively itselve}, till all lines are processed.
+% \begin{macrocode}
+\def\y@ungempty(#1,#2){%
+ \y@nelineemptyboxes{#1}
+ \y@lastargtest#2,
+ \ify@islastarg
+ \y@nelineemptyboxes{#2}
+ \else
+ \y@ungempty(#2)
+ \fi}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\y@nelettertest}
+% The first macro especially for labelled boxes, that is, for
+% |\young|. Like \texttt{\bslash y@last\-arg\-test} it is used for
+% handling a indefinite number of arguments. (As mentioned before
+% \yts\ with labelled boxes have problem double.) |\y@nelettertest|
+% determines if the last box of the line has been reached.
+%
+% Again we will examine it's working method by examples:
+%
+% |\y@nelettertest ab.|\\
+% The period after the argument |ab| (and in the definition of
+% |\y@nelettertest|) is merely a mark for the end of the
+% arguments. (Otherwise \TeX\ would complain about missing arguments.)
+% Here |a| is |#1| and |#2| is |b| -- the |\if|-condition is |false|
+% and so |\y@islastargfalse| is set. Now a little miracle:
+%
+% |\y@nelettertest a.|\\
+% In the opposite to the case of |\y@lastargtest| it's not
+% understandable for me, why |#2| now is a space -- but it is! (Do
+% \emph{you} know the reason why?)
+% The rest is known from |\y@lastargtest|.
+% \begin{macrocode}
+\def\y@nelettertest#1#2. {\if\space #2 \y@islastargtrue
+ \else\y@islastargfalse\fi}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\y@abcboxes}
+% Again we use a period to mark the end of arguments. Compare to
+% |\y@emptyboxes| -- Now it is more strenuous! The |\y@nelettertest|
+% macro makes sure that |\y@abcboxes| is called with at least two boxes
+% to process. If there are only two boxes |\y@abcboxes| calls
+% |\y@abcbox| two times, otherwise it calls itselve recursively again.
+% (The argument-splitting works as in |\y@ungempty|.)
+% \begin{macrocode}
+\def\y@abcboxes#1#2.{%
+ \ify@stdtext\y@abcbox#1\else\y@mathabcbox#1\fi%
+ \y@nelettertest #2.
+% \end{macrocode}
+% There must be a space or (equivalently) a carriage return after this
+% line!
+% \begin{macrocode}
+ \ify@islastarg\unskip%
+ \ify@stdtext\y@abcbox{#2}\else\y@mathabcbox{#2}\fi%
+ \else\y@abcboxes#2.\fi}
+% \end{macrocode}
+% The |\unskip| is needed for the case that |#2| is only one token. Then
+% a space appears between two boxes. (I do not understand really what
+% happens -- see |\y@nelettertest|.) The |\unskip| resolves this problem.
+% \end{macro}
+%
+% \begin{macro}{\ify@enable@skew}
+% \begin{macro}{\y@full@b@xdim}
+% \begin{macro}{\y@m@veright@cnt}
+% Most of the skew boxes stuff can be found here along the definition
+% of \texttt{\bslash y@ne\-line\-abc\-boxes}. We need a further dimension,
+% for the effective lenght of one box in a row, |\y@full@b@xdim| =
+% |\y@b@xdim| + |1\y@linethick| and one counter for the number of
+% boxes to be left out on the left side of the tableau (determined by
+% the number of colons at the beginning of a row), |\y@m@veright@cnt|.
+% \begin{macrocode}
+\ify@enable@skew
+ \newdimen\y@full@b@xdim
+ \newcount\y@m@veright@cnt
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\y@get@m@veright@cnt}
+% To find out the number of leading colons in a row we have the macro
+% \texttt{\bslash y@get@\-m@ve\-right@\-cnt}. Here we use exactly the same
+% trick as in |\y@nelettertest|.
+% \begin{macrocode}
+ \def\y@get@m@veright@cnt#1#2.{%
+ \if :#1 \advance\y@m@veright@cnt by 1\y@get@m@veright@cnt#2.\fi}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\y@setdim}
+% Since we now have another dimension that depends on |\y@b@xdim|,
+% the dimension of the boxes, we have to extend |\y@setdim| to
+% calculate |\y@full@b@xdim| too. (The dummy |\y@setdim@| is used to
+% avoid a recursion.)
+% \begin{macrocode}
+ \let\y@setdim@=\y@setdim
+ \def\y@setdim{%
+ \y@setdim@ \y@full@b@xdim=\y@b@xdim
+ \advance\y@full@b@xdim by 1\y@linethick}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\y@m@veright@ifskew}
+% Now we put it all into the following macro that computes the offset
+% and moves the tableau to the right if necessary. If skew \yts\ are
+% not enabled, |\y@m@veright@ifskew| will be a null-command (but
+% catches the argument).
+% \begin{macrocode}
+ \def\y@m@veright@ifskew#1{
+ \y@m@veright@cnt=0 \y@get@m@veright@cnt#1.
+ \moveright \y@m@veright@cnt\y@full@b@xdim}
+\else
+ \def\y@m@veright@ifskew#1{}
+\fi
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\y@nelineabcboxes}
+% This is the counterpart of |\y@nelineemptyboxes|. The difference
+% is the treatment of the case of a row of only one box -- Then only
+% |\y@abcbox| is called and not |\y@abcboxes|. If this row must be
+% moved to the right, this is done by |\y@m@veright@ifskew|.
+% \begin{macrocode}
+\def\y@nelineabcboxes#1{%
+ \y@nelettertest #1.
+ \ify@islastarg
+ \y@m@veright@ifskew{#1}
+ \vbox{
+ \hrule height\y@linethick%
+ \hbox{\ify@stdtext\y@abcbox#1\else\y@mathabcbox#1\fi\y@vr}
+ \hrule height\y@linethick}\vspace{-\y@linethick}
+ \else
+ \y@m@veright@ifskew{#1}
+ \vbox{
+ \hrule height\y@linethick%
+ \hbox{\y@abcboxes #1.\y@vr}%
+ \hrule height\y@linethick}\vspace{-\y@linethick}
+ \fi}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\young}
+% The user-macro for labelled \yts. It has one argument as |\yng|,
+% enclosed in brackets. Everything is identical as in the emptybox case
+% (sizing, vcentering, treatment of multiple rows, \dots).
+% \begin{macrocode}
+\def\young(#1){%
+ \y@setdim%
+ \hspace{\y@interspace}%
+ \y@lastargtest#1,
+ \ifmmode\ify@vcenter\vcenter\fi\fi{%
+ \vbox{\offinterlineskip
+ \ify@islastarg\y@nelineabcboxes{#1}%
+ \else\y@ungabc(#1)%
+ \fi}}\hspace{\y@interspace}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\y@ungabc}
+% Again nothing new -- see |\y@ungempty|
+% \begin{macrocode}
+\def\y@ungabc(#1,#2){%
+ \y@nelineabcboxes{#1}%
+ \y@lastargtest#2,
+ \ify@islastarg\y@nelineabcboxes{#2}%
+ \else\y@ungabc(#2)%
+ \fi}
+% \end{macrocode}
+% \end{macro}
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \Finale
+\endinput
diff --git a/macros/generic/youngtab/youngtab.el b/macros/generic/youngtab/youngtab.el
new file mode 100644
index 0000000000..458049e8e2
--- /dev/null
+++ b/macros/generic/youngtab/youngtab.el
@@ -0,0 +1,42 @@
+;;; youngtab.el - Support for the user macros of the youngtab package
+;; by Volker B"orchers, <boercher@physik.uni-bremen.de>
+;; This program can be redistributed and/or modified under the terms
+;; of the LaTeX Project Public License Distributed from CTAN
+;; archives in directory macros/latex/base/lppl.txt; either
+;; version 1 of the License, or any later version.
+
+;;-((and (not( = elisp favorite-language)) (concat "lucky" "it" "works" (!))))
+
+(TeX-add-style-hook "youngtab"
+ (function
+ (lambda ()
+ (TeX-add-symbols
+ '("Yboxdim" "Box Dimension")
+ '("Ylinethick" "Line Thickness")
+ '("Yinterspace" "Space between 2 Tableaux")
+ '("Yvcentermath" TeX-arg-young-bool)
+ '("Ystdtext" TeX-arg-young-bool)
+ '("yng" (TeX-arg-young t))
+ '("young" TeX-arg-young)
+ ))))
+
+(defun TeX-arg-young (optional &optional isyng)
+ "Insert macros young and yng.
+Ask for the rows of a tableau.
+Do not accept non-numbers for yng."
+ (let ((num 0))
+ (insert "(")
+ (while (>= num 0)
+ (setq num (1+ num))
+ (setq row (read-input (concat (int-to-string num) ". Row: ")))
+ (if (zerop (length row))
+ (setq num -1)
+ (if (and isyng (<= (string-to-int row) 0))
+ (setq num (- num 1))
+ (insert (if (> num 1) "," "") row)))))
+ (insert ")"))
+
+(defun TeX-arg-young-bool (optional)
+ "To handle the switches Yvcentermath and Ystdtext"
+ (insert (if (y-or-n-p "true(y) or false(n)? ") "1" "0")))
+
diff --git a/macros/generic/youngtab/youngtab.ins b/macros/generic/youngtab/youngtab.ins
new file mode 100644
index 0000000000..a58ace3a9e
--- /dev/null
+++ b/macros/generic/youngtab/youngtab.ins
@@ -0,0 +1,36 @@
+%%
+%% --------------- start of docstrip commands ------------------
+%%
+\def\batchfile{youngtab.ins}
+\input docstrip.tex
+\preamble
+
+Copyright (C) 1996,98,99 Volker B"orchers and Stefan Gieseke,
+This program can be redistributed and/or modified under the terms
+of the LaTeX Project Public License Distributed from CTAN
+archives in directory macros/latex/base/lppl.txt; either
+version 1 of the License, or any later version.
+
+\endpreamble
+\def\filedate{1999/05/19}
+\input docstrip
+\keepsilent
+
+\generateFile{youngtab.sty}{t}{\from{youngtab.dtx}{package}}
+
+\ifToplevel{
+\Msg{***********************************************************}
+\Msg{*}
+\Msg{* To finish the installation you have to move}
+\Msg{* \space\space youngtab.sty}
+\Msg{* into a directory searched by TeX:}
+\Msg{*}
+\Msg{* To produce the documentation run}
+\Msg{* \space\space youngtab.dtx}
+\Msg{* through LaTeX.}
+\Msg{*}
+\Msg{***********************************************************}
+}
+
+
+
diff --git a/macros/generic/youngtab/youngtab.pdf b/macros/generic/youngtab/youngtab.pdf
new file mode 100644
index 0000000000..b91f4ae4e9
--- /dev/null
+++ b/macros/generic/youngtab/youngtab.pdf
Binary files differ
diff --git a/macros/generic/youngtab/youngtab.tex b/macros/generic/youngtab/youngtab.tex
new file mode 100644
index 0000000000..895a7c3267
--- /dev/null
+++ b/macros/generic/youngtab/youngtab.tex
@@ -0,0 +1,146 @@
+%%
+%% This is file `youngtab.tex',
+%% (manually) generated from `youngtab.sty'
+%% (For use with TeX)
+%%
+%% The original source files were:
+%%
+%% youngtab.dtx (with options: `package')
+%%
+%% Copyright (C) 1996,98,99 Volker B"orchers and Stefan Gieseke,
+%% This program can be redistributed and/or modified under the terms
+%% of the LaTeX Project Public License Distributed from CTAN
+%% archives in directory macros/latex/base/lppl.txt; either
+%% version 1 of the License, or any later version.
+\catcode`\@11\relax
+\newif\ify@autoscale \y@autoscaletrue \def\Yautoscale#1{\ifnum #1=0
+ \y@autoscalefalse\else\y@autoscaletrue\fi}
+\newdimen\y@b@xdim
+\newdimen\y@boxdim \y@boxdim=13pt
+\def\Yboxdim#1{\y@autoscalefalse\y@boxdim=#1}
+\newdimen\y@linethick \y@linethick=.3pt
+\def\Ylinethick#1{\y@linethick=#1}
+\newskip\y@interspace \y@interspace=0ex plus 0.3ex
+\def\Yinterspace#1{\y@interspace=#1}
+\newif\ify@vcenter \y@vcenterfalse
+\def\Yvcentermath#1{\ifnum #1=0 \y@vcenterfalse\else\y@vcentertrue\fi}
+\newif\ify@stdtext \y@stdtextfalse
+\def\Ystdtext#1{\ifnum #1=0 \y@stdtextfalse\else\y@stdtexttrue\fi}
+\newif\ify@enable@skew \y@enable@skewfalse
+%% To use skew tableaux, define a macro \enableskew
+%% right before loading this file: \def\enableskew{1}
+\expandafter\ifx\csname enableskew\endcsname\relax
+ \y@enable@skewfalse \else \y@enable@skewtrue\fi
+%% \DeclareOption{noautoscale}{\y@autoscalefalse}
+%% \DeclareOption{vcentermath}{\y@vcentertrue}
+%% \DeclareOption{stdtext}{\y@vcentertrue}
+%% \DeclareOption{enableskew}{\y@enable@skewtrue}
+%% \DeclareOption*{\PackageWarning{youngtab}{%
+%% Unknown option `\CurrentOption' (Known:\MessageBreak
+%% `vcentermath', `noautoscale', `stdtext', `enableskew'.)}}
+%% \ProcessOptions\relax
+\def\y@vr{\vrule height0.8\y@b@xdim width\y@linethick depth 0.2\y@b@xdim}
+\def\y@emptybox{\y@vr\hbox to \y@b@xdim{\hfil}}
+\ify@enable@skew
+ \def\y@abcbox#1{\if :#1\else
+ \y@vr\hbox to \y@b@xdim{\hfil#1\hfil}\fi}
+ \def\y@mathabcbox#1{\if :#1\else
+ \y@vr\hbox to \y@b@xdim{\hfil$#1$\hfil}\fi}
+\else
+ \def\y@abcbox#1{\y@vr\hbox to \y@b@xdim{\hfil#1\hfil}}
+ \def\y@mathabcbox#1{\y@vr\hbox to \y@b@xdim{\hfil$#1$\hfil}}
+\fi
+\def\y@setdim{%
+ \ify@autoscale%
+ \ifvoid1\else\typeout{Package youngtab: box1 not free! Expect an
+ error!}\fi%
+ \setbox1=\hbox{A}\y@b@xdim=1.6\ht1 \setbox1=\hbox{}\box1%
+ \else\y@b@xdim=\y@boxdim \advance\y@b@xdim by -2\y@linethick
+ \fi}
+\newcount\y@counter
+\newif\ify@islastarg
+\def\y@lastargtest#1,#2 {\if\space #2 \y@islastargtrue
+ \else\y@islastargfalse\fi}
+\def\y@emptyboxes#1{\y@counter=#1\loop\ifnum\y@counter>0
+ \advance\y@counter by -1 \y@emptybox\repeat}
+\def\y@nelineemptyboxes#1{%
+ \vbox{%
+ \hrule height\y@linethick%
+ \hbox{\y@emptyboxes{#1}\y@vr}
+ \hrule height\y@linethick}\vskip-\y@linethick}
+\def\yng(#1){%
+ \y@setdim%
+ \hskip\y@interspace%
+ \ifmmode\ify@vcenter\vcenter\fi\fi{%
+ \y@lastargtest#1,
+ \vbox{\offinterlineskip
+ \ify@islastarg
+ \y@nelineemptyboxes{#1}
+ \else
+ \y@ungempty(#1)
+ \fi}}\hskip\y@interspace}
+\def\y@ungempty(#1,#2){%
+ \y@nelineemptyboxes{#1}
+ \y@lastargtest#2,
+ \ify@islastarg
+ \y@nelineemptyboxes{#2}
+ \else
+ \y@ungempty(#2)
+ \fi}
+\def\y@nelettertest#1#2. {\if\space #2 \y@islastargtrue
+ \else\y@islastargfalse\fi}
+\def\y@abcboxes#1#2.{%
+ \ify@stdtext\y@abcbox#1\else\y@mathabcbox#1\fi%
+ \y@nelettertest #2.
+ \ify@islastarg\unskip%
+ \ify@stdtext\y@abcbox{#2}\else\y@mathabcbox{#2}\fi%
+ \else\y@abcboxes#2.\fi}
+ \newdimen\y@full@b@xdim
+ \newcount\y@m@veright@cnt
+\ify@enable@skew
+ \def\y@get@m@veright@cnt#1#2.{%
+ \if :#1 \advance\y@m@veright@cnt by 1\y@get@m@veright@cnt#2.\fi}
+ \let\y@setdim@=\y@setdim
+ \def\y@setdim{%
+ \y@setdim@ \y@full@b@xdim=\y@b@xdim
+ \advance\y@full@b@xdim by 1\y@linethick}
+ \def\y@m@veright@ifskew#1{
+ \y@m@veright@cnt=0 \y@get@m@veright@cnt#1.
+ \moveright \y@m@veright@cnt\y@full@b@xdim}
+\else
+ \def\y@m@veright@ifskew#1{}
+\fi
+\def\y@nelineabcboxes#1{%
+ \y@nelettertest #1.
+ \ify@islastarg
+ \y@m@veright@ifskew{#1}
+ \vbox{
+ \hrule height\y@linethick%
+ \hbox{\ify@stdtext\y@abcbox#1\else\y@mathabcbox#1\fi\y@vr}
+ \hrule height\y@linethick}\vskip-\y@linethick
+ \else
+ \y@m@veright@ifskew{#1}
+ \vbox{
+ \hrule height\y@linethick%
+ \hbox{\y@abcboxes #1.\y@vr}%
+ \hrule height\y@linethick}\vskip-\y@linethick
+ \fi}
+\def\young(#1){%
+ \y@setdim%
+ \hskip\y@interspace%
+ \y@lastargtest#1,
+ \ifmmode\ify@vcenter\vcenter\fi\fi{%
+ \vbox{\offinterlineskip
+ \ify@islastarg\y@nelineabcboxes{#1}%
+ \else\y@ungabc(#1)%
+ \fi}}\hskip\y@interspace}
+\def\y@ungabc(#1,#2){%
+ \y@nelineabcboxes{#1}%
+ \y@lastargtest#2,
+ \ify@islastarg\y@nelineabcboxes{#2}%
+ \else\y@ungabc(#2)%
+ \fi}
+\catcode`\@12\relax
+\endinput
+%%
+%% End of file `youngtab.tex'.