summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/sauerj
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/sauerj
Initial commit
Diffstat (limited to 'macros/latex/contrib/sauerj')
-rw-r--r--macros/latex/contrib/sauerj/README65
-rw-r--r--macros/latex/contrib/sauerj/collect.dtx815
-rw-r--r--macros/latex/contrib/sauerj/collect.ins19
-rw-r--r--macros/latex/contrib/sauerj/collect.pdfbin0 -> 174985 bytes
-rw-r--r--macros/latex/contrib/sauerj/metainfo.dtx1242
-rw-r--r--macros/latex/contrib/sauerj/metainfo.ins19
-rw-r--r--macros/latex/contrib/sauerj/metainfo.pdfbin0 -> 190365 bytes
-rw-r--r--macros/latex/contrib/sauerj/optparams.dtx327
-rw-r--r--macros/latex/contrib/sauerj/optparams.ins19
-rw-r--r--macros/latex/contrib/sauerj/optparams.pdfbin0 -> 141610 bytes
-rw-r--r--macros/latex/contrib/sauerj/parcolumns.dtx1090
-rw-r--r--macros/latex/contrib/sauerj/parcolumns.ins19
-rw-r--r--macros/latex/contrib/sauerj/parcolumns.pdfbin0 -> 198902 bytes
-rw-r--r--macros/latex/contrib/sauerj/processkv.dtx199
-rw-r--r--macros/latex/contrib/sauerj/processkv.ins19
-rw-r--r--macros/latex/contrib/sauerj/processkv.pdfbin0 -> 126376 bytes
-rw-r--r--macros/latex/contrib/sauerj/zahl2string.dtx1044
-rw-r--r--macros/latex/contrib/sauerj/zahl2string.ins19
-rw-r--r--macros/latex/contrib/sauerj/zahl2string.pdfbin0 -> 199022 bytes
19 files changed, 4896 insertions, 0 deletions
diff --git a/macros/latex/contrib/sauerj/README b/macros/latex/contrib/sauerj/README
new file mode 100644
index 0000000000..31b87d15f6
--- /dev/null
+++ b/macros/latex/contrib/sauerj/README
@@ -0,0 +1,65 @@
+README
+------
+
+These are a few LaTeX2e-packages for a variety of tasks:
+
+- collect provides several environment to collect text in a macro
+ or a file for later use.
+
+ Current version: 0.9
+
+
+- metainfo provides a macro for only typesetting specially formatted
+ comments of a document.
+
+ Current version: 0.9.1
+
+
+- optparams provides a small macro for creating macros with multiple
+ optional parameters.
+
+ Current version: 0.9
+
+
+- parcolumns provides an environment for typesetting text in two or
+ more columns in parallel.
+
+ Requires the processkv-package (below).
+
+ Current version: 1.2
+
+
+- processkv provides macros for processing of key-value-lists by
+ calling a user-defined macro for each key-value-pair.
+
+ Requires the keyval-package dated 1999/03/16 or later.
+
+ Current version: 1.0.1
+
+
+- zahl2string provides macros for formatting numbers as german words,
+ i.e. `1' gets formatted as `eins'.
+
+ Current version: 1.2.1
+
+
+Each package consists of an .ins-file containing the driver for
+installation, a .dtx-file containing the macros and documentation and
+a .pdf containing the typeset documentation.
+
+To install, run LaTeX on the .ins-file, then copy the resulting
+.sty-file somewhere LaTeX can find it. To typeset the documentation,
+run LaTeX on the .dtx-file, run MakeIndex using gind.ist as the index
+style file and then run LaTeX again.
+
+
+
+All packages may be distributed and/or modified under the conditions
+of the LaTeX Project Public License (lppl), either version 1.3 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.3 or later is part of all distributions of LaTeX version
+2003/12/01 or later.
diff --git a/macros/latex/contrib/sauerj/collect.dtx b/macros/latex/contrib/sauerj/collect.dtx
new file mode 100644
index 0000000000..05a8f50c76
--- /dev/null
+++ b/macros/latex/contrib/sauerj/collect.dtx
@@ -0,0 +1,815 @@
+% \iffalse meta-comment
+% Line endings: UNIX
+% Tab size: 4
+%
+% Copyright 2004 Jonathan Sauer
+%
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3
+% 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.3 or later is part of all distributions of LaTeX
+% version 2003/12/01 or later.
+%
+% This work has the LPPL maintenance status "maintained".
+%
+% The Current Maintainer of this work is Jonathan Sauer
+% (<jonathan.sauer@gmx.de>).
+%
+% This work consists of the files collect.dtx and collect.ins
+% and the derived file collect.sty.
+%
+% \fi
+%
+% \iffalse
+%
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage{collect}
+\EnableCrossrefs
+\CodelineIndex
+\RecordChanges
+% Modification of verbatim for tabs in listings
+\makeatletter
+{\catcode`\ =\active%
+\catcode`\^^I=\active%
+\gdef\@vobeyspaces{%
+\catcode`\ \active\let \@xobeysp%
+\catcode`\^^I\active\def^^I{~~}%
+}}%
+\makeatother
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+%
+%<package>\NeedsTeXFormat{LaTeX2e}
+%<package>\ProvidesPackage{collect}
+%<package> [2004/09/12 v0.9 collect the contents of an environment]
+%
+% \fi
+%
+% \CheckSum{256}
+% \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{\@currenvir,\@ehc,\@ifundefined,\@input}
+% \DoNotIndex{\@tempa,\@tempb,\bgroup,\catcode,\closeout,\csname}
+% \DoNotIndex{\def,\edef,\egroup,\else,\end,\endcsname,\expandafter}
+% \DoNotIndex{\fi,\futurelet,\gdef,\global,\ifx,\immediate,\jobname,\let,\long}
+% \DoNotIndex{\meaning,\newcommand,\newenvironment,\newif,\newwrite}
+% \DoNotIndex{\openout,\PackageError,\par,\strip@prefix,\the,\toks@}
+% \DoNotIndex{\write}
+%
+% \GetFileInfo{\jobname.sty}
+%
+% \title{The \textsf{collect} package\thanks{This document
+% corresponds to \textsf{\filename}~\fileversion, dated \filedate.}}
+%
+% \author{Jonathan Sauer \\ \texttt{jonathan.sauer@gmx.de}}
+%
+% \date{\filedate}
+%
+% \maketitle
+%
+% \begin{abstract}
+% This file describes the \textsf{collect} package that
+% makes it possible to collect text for later use.
+%
+% \end{abstract}
+%
+% \tableofcontents
+%
+% \section{Introduction}
+%
+% Suppose you are writing the specification of a programming language.
+% Then you will surely insert definitions of the grammar (i.e. using
+% the \textsf{syntax} package). Most likely you will insert the
+% grammar for i.e. loops, conditions et cetera in the appropriate
+% chapter, but for easy implementation of a parser, you will want to
+% include the complete grammar as an appendix, so that one does not
+% have to collect the complete grammar from the bits in each chapter.
+%
+% Of course you could do this by hand using the copy-and-paste
+% facility of your text editor. But this is cumbersome and errorprone
+% if you modify the grammar afterwards, i.e. for a second version.
+%
+% This package provides the |collect| environment that typesets
+% its contents and collects it for later use as well.
+%
+% In other situations you will want to save the contents of an
+% environment in a macro. Then the |collectinmacro| environment
+% should do the trick.
+%
+%
+%
+% \section{Usage}
+%
+% \paragraph{General note} If an environment exists in a normal and a
+% starred form (i.e. |collect| and |collect*|), then the former does
+% not typeset the environment contents, while the latter typesets it.
+% Note, too, that the normal and the starred version of an environment
+% often have a different number of parameters.
+%
+% \paragraph{Stripping of spaces} All environments strip any leading
+% space before the start of the text and any trailing space after the
+% end of the text. Trailing |\par|s (i.e. resulting from a blank line
+% at the end of the environment) are \emph{not} removed.
+%
+%
+%
+%
+% \subsection{\texttt{collect}}
+%
+% You can define several \emph{collections}. Each collection can be
+% used independently to collect text across the document. You define a
+% collection using |\definecollection|, use it in the |collect| and
+% |collect*| environment and typeset it using |\includecollection|.
+%
+% \paragraph{Note} The name of the collection is used as the suffix of
+% the file that stores the collection (the complete name is
+% \meta{jobname}|.|\meta{name)}. So you should not name a collection
+% |tex|, |log|, |dvi|, |pdf| and so on.
+%
+% \paragraph{Note} You can only include a collection after completely
+% collecting it. If you include it and continue to collect afterwards,
+% the collection will be cleared after its inclusion.
+%
+% This can be used to recycle a collection: Use it in the first part
+% of your document to collect text, typeset this text using
+% |\includecollection| and then reuse the collection in the second
+% part of your document to collect new text which will finally be
+% typeset using |\includecollection| a second time.
+%
+%
+% \DescribeMacro{\definecollection} Usage: |\definecollection|
+% \marg{name}.
+%
+% Defines a collection of the name \meta{name}.
+%
+%
+% \DescribeEnv{collect*} Usage: |\begin{collect*}|
+% \marg{name} \marg{before} \marg{after} \marg{beforecol}
+% \marg{aftercol} \ldots\ |\end{collect*}|.
+%
+% Collects the text inside the environment in the collection
+% \meta{name}. Then typesets the text. \meta{name} must have been
+% defined using |\definecollection|.
+%
+% \meta{before} and \meta{after} are tokens inserted before and after
+% the environment contents in the collection as well as the typeset
+% text.
+%
+% \meta{beforecol} and \meta{aftercol} are tokens inserted before and
+% after the environment contents only in the collection. This can be
+% used to insert a section heading (\meta{beforecol}) and a backref to
+% the section where the text has been collected (\meta{aftercol}).
+%
+% \paragraph{Note} The |collect*| environment uses a temporary file
+% \meta{jobname}|.tmp| to temporarily store the environment contents
+% and include it afterwards.\footnote{This way, catcode changes inside
+% the environment are honored.}
+%
+%
+% \DescribeEnv{collect} Usage: |\begin{collect}| \marg{name}
+% \marg{beforecol} \marg{aftercol} \ldots\ |\end{collect}|.
+%
+% Collects the text inside the environment in the collection
+% \meta{name}. \emph{Does not} typeset the text (therefore, the two
+% parameters \meta{before} and \meta{after} are missing); except for
+% that, this environment is identical to |collect*|.
+%
+%
+% \DescribeMacro{\includecollection} Usage: |\includecollection|
+% \marg{name}. Includes the collection \meta{name}. Afterwards, the
+% collection is reset.
+%
+% You can include the collection \emph{before} it is actually
+% collected in the same way you can include a table of contents at the
+% beginning of your document. Simply say |\includecollection| and then
+% use the |collect*| or |collect| environment to collect text. Then
+% run \LaTeX\ on your file \emph{twice}. (the first time to collect
+% the text, the second time to put it in the document using
+% |\includecollection|)
+%
+%
+%
+% \subsection{Other environments}
+%
+% \DescribeEnv{collectinmacro} Usage: |\begin{collectinmacro}|
+% \marg{macro} \marg{before} \marg{after} \ldots\
+% |\end{collectinmacro}|.
+%
+% Collects the contents of an environment inside a macro \meta{macro}
+% without typesetting it. If \meta{macro} has been defined prior to
+% using this environment, its previous meaning is lost. The new
+% definition is global.
+%
+% \meta{before} and \meta{after} are tokens inserted before and after
+% the environment contents in the macro.
+%
+% \paragraph{Important note} This environment differs slightly from
+% |collect| and |collect*|: Some macros, i.e. |\verb|, do not work
+% correctly when \meta{macro} is used later on.\footnote{As the
+% catcodes have already been set when collecting the contents and
+% cannot be changed afterwards, at least not without e\TeX.}
+%
+%
+%
+%
+% \section{Examples}
+%
+% \subsection{\texttt{collect}}
+%
+% \begin{verbatim}
+% \begin{collect*}{tst}{Before\par}{\par After}{Before file\par}{\par After file}
+% This is a test
+% \end{collect*}
+% \end{verbatim}
+%
+% \noindent This results in the following text typeset directly:
+%
+% \begin{verbatim}
+% Before
+% This is a test
+% After
+% \end{verbatim}
+%
+% \noindent And following text is typeset when the collection |tst| is
+% included using |\includecollection{tst}|:
+%
+% \begin{verbatim}
+% Before file
+% Before
+% This is a test
+% After
+% After file
+% \end{verbatim}
+%
+%
+%
+%
+% \subsection{Other environments}
+%
+% \begin{verbatim}
+% \begin{collectinmacro}{\collectedtext}{Before\par}{\par After}
+% This is a test
+% \end{collectinmacro}
+% \end{verbatim}
+%
+% \noindent This results in no text typeset directly and the following
+% text stored in the macro |\collectedtext|:
+%
+% \begin{verbatim}
+% Before\par This is a test\par After
+% \end{verbatim}
+%
+%
+%
+%
+% \section{Creating your own environment}
+%
+% You can create your own environment based on any of the environments
+% in this package, i.e. to create a |grammarpart| environment to
+% typeset part of a grammar.
+%
+% You can for example say:
+%
+% \begin{verbatim}
+% \definecollection{gra}
+%
+% \newenvironment{grammarpart}[1]{%
+% \@nameuse{collect*}{gra}{%
+% \emph{Start of grammar `#1'}\par%
+% }{%
+% \par\emph{End of grammar}\par%
+% }{%
+% \subsection{#1}%
+% }{%
+% \par See some section in the text.
+% }%
+% }{%
+% \@nameuse{endcollect*}%
+% }
+% \end{verbatim}
+%
+% \noindent This will create a |grammarpart| environment with one
+% parameter, the part of the grammar defined. (i.e. `Identifiers') At
+% the start of the environment the text `\emph{Start of grammar
+% \meta{part}}' will be typeset, followed by the grammar (the contents
+% of the environment), and finally a line `\emph{End of grammar}' will
+% be added.
+%
+% When including the collected grammar parts using
+% |\includecollection| each grammar part will be prefixed by a
+% subsection heading bearing the grammar part as its title and
+% suffixed by `See some section in the text.' (this could be extended
+% to include a backref using |\ref|\meta{label})
+%
+% \paragraph{Note} If you use any of the environments inside a custom
+% environment to afterwards collect text with this custom environment
+% (as in the example of the |grammarpart| environment above), you
+% \emph{must not} begin and end it using |\begin| and |\end|, or the
+% environment contents will not be collected correctly. You must use
+% |\@nameuse{|\meta{environment}|}| and
+% |\@nameuse{end|\meta{environment}|}| as in the example above, or, if
+% the environment is not starred, |\|\meta{environment} and
+% |\end|\meta{environment}.
+%
+% \paragraph{Note} You still can use the environments of this package
+% inside other environments (i.e. a |itemize| environment) without any
+% problems.
+%
+%
+%
+%
+% \section{Notes}
+%
+% \begin{itemize}
+% \item If you use any of the environments inside your own
+% environment, note that the end of the environment is
+% executed, but not included in the collected text! (that's
+% why the the environments |collect*| and |collectinmacro|
+% have two parameters for including text before and after
+% the environment, \meta{before} and \meta{after}).
+%
+% \end{itemize}
+%
+%
+%
+%
+% \StopEventually{}
+%
+% \section{Implementation}
+%
+% \subsection{Main environments and macros}
+%
+% \subsubsection{\texttt{collect}}
+%
+% \begin{macro}{\definecollection}
+%
+% Usage: |\definecollection| \marg{name}
+%
+% Defines a collection \meta{name}.
+%
+% This macro allocates a |\newwrite| |CE@@|\meta{name}|@out| and
+% defines a |\newif| |CE@@|\meta{name}|open|.
+%
+% \begin{macrocode}
+\newcommand{\definecollection}[1]{%
+ \@ifundefined{CE@@#1@out}{%
+ \expandafter\newwrite\csname CE@@#1@out\endcsname%
+ \expandafter\newif\csname ifCE@@#1@open\endcsname%
+ \csname CE@@#1@openfalse\endcsname%
+ }{%
+ \PackageError{collect}{Collection `#1' has already %
+ been defined}{\@ehc}%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{environment}{collect*}
+%
+% Usage: |\begin{collect*}| \marg{name} \marg{before}
+% \marg{after} \marg{beforecol} \marg{aftercol} \ldots\
+% |\end{collect*}|.
+%
+% \begin{macrocode}
+\newenvironment{collect*}[5]{%
+ \global\toks@{}%
+ \def\CE@file{#1}%
+ \def\CE@preenv{#2}%
+ \def\CE@postenv{#3}%
+ \def\CE@prefileenv{#4}%
+ \def\CE@postfileenv{#5}%
+ \CE@get@env@body@start%
+}{%
+% \end{macrocode}
+%
+% What are we doing? We make sure the collection is open, then we save
+% \meta{beforecol}, \meta{before}, the collected environment contents,
+% \meta{after} and \meta{aftercol} in the collection file.
+%
+% \begin{macrocode}
+ \CE@ensure@opened{\CE@file}%
+ \edef\@tempa{\csname CE@@\CE@file @out\endcsname}%
+ \immediate\write\@tempa{\CE@meaning\CE@prefileenv}%
+ \immediate\write\@tempa{\CE@meaning\CE@preenv}%
+ \immediate\write\@tempa{\the\toks@}%
+ \immediate\write\@tempa{\CE@meaning\CE@postenv}%
+ \immediate\write\@tempa{\CE@meaning\CE@postfileenv}%
+% \end{macrocode}
+%
+% Now we repeat the same thing, but with the temporary file and
+% writing only \meta{before}, the collected environment contents and
+% \meta{after}. Then we include the temporary file.
+%
+% Why so complicated, as we have the contents of the environment in
+% |\toks@|? Because the catcodes might not be correct, i.e. if |\verb|
+% is used inside the environment. So we have to read the environment
+% contents again, which without e\TeX\ is only possible using a
+% temporary file.
+%
+% \begin{macrocode}
+ \immediate\openout\CE@tmp@out=\jobname.tmp%
+ \immediate\write\CE@tmp@out{\CE@meaning\CE@preenv}%
+ \immediate\write\CE@tmp@out{\the\toks@}%
+ \immediate\write\CE@tmp@out{\CE@meaning\CE@postenv}%
+ \immediate\closeout\CE@tmp@out%
+ \@input{\jobname.tmp}%
+ \par%
+}
+% \end{macrocode}
+% \end{environment}
+%
+%
+% \begin{environment}{collect}
+%
+% Usage: |\begin{collect}| \marg{name} \marg{beforecol}
+% \marg{aftercol} \ldots\ |\end{collect}|.
+%
+% \begin{macrocode}
+\newenvironment{collect}[3]{%
+ \global\toks@{}%
+ \def\CE@file{#1}%
+ \def\CE@prefileenv{#2}%
+ \def\CE@postfileenv{#3}%
+ \CE@get@env@body@start%
+}{%
+% \end{macrocode}
+%
+% As this environment, contrary to |collect*|, does not typeset its
+% contents, we only write to the collection file:
+%
+% \begin{macrocode}
+ \CE@ensure@opened{\CE@file}%
+ \edef\@tempa{\csname CE@@\CE@file @out\endcsname}%
+ \immediate\write\@tempa{\CE@meaning\CE@prefileenv}%
+ \immediate\write\@tempa{\the\toks@}%
+ \immediate\write\@tempa{\CE@meaning\CE@postfileenv}%
+}
+% \end{macrocode}
+% \end{environment}
+%
+%
+% \begin{macro}{\includecollection}
+%
+% Usage: |\includecollection| \marg{name}.
+%
+% Includes the collection \meta{name} which must have been defined
+% previously using |\definecollection|. Afterwards, the collection is
+% cleared.
+%
+% \begin{macrocode}
+\newcommand{\includecollection}[1]{%
+ \CE@ensure@closed{#1}%
+ \@input{\jobname.#1}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \subsubsection{Other environments}
+%
+% \begin{environment}{collectinmacro}
+%
+% Usage: |\begin{collectinmacro}| \marg{macro} \marg{before}
+% \marg{after} \ldots\ |\end{collectinmacro}|.
+%
+% Collects the contents of an environment inside a macro.
+%
+% \begin{macrocode}
+\newenvironment{collectinmacro}[3]{%
+ \def\CE@destmacro{#1}%
+ \def\CE@postenv{#3}%
+% \end{macrocode}
+%
+% We initialize the result with \meta{before}:
+%
+% \begin{macrocode}
+ \toks@{#2}%
+ \CE@get@env@body@start%
+}{%
+% \end{macrocode}
+%
+% We add \meta{after}:
+%
+% \begin{macrocode}
+ \toks@\expandafter\expandafter\expandafter{%
+ \expandafter\the\expandafter\toks@\CE@postenv}%
+% \end{macrocode}
+%
+% Finally we globally define \meta{macro} to contain the collected
+% contents:
+%
+% \begin{macrocode}
+ \expandafter\expandafter\expandafter%
+ \gdef\expandafter\CE@destmacro\expandafter{\the\toks@}%
+ \toks@{}%
+}
+% \end{macrocode}
+% \end{environment}
+%
+%
+%
+%
+% \subsection{Internal environments and macros}
+%
+% We allocate a new |\newwrite| for the processing of a temporary
+% file:
+%
+% \begin{macrocode}
+\newwrite\CE@tmp@out
+% \end{macrocode}
+%
+%
+% \begin{macro}{\CE@get@env@body@start}
+%
+% Starts the collecting of the contents of an environment. (the
+% environment starts immediately after the macro)
+%
+% \begin{macrocode}
+\def\CE@get@env@body@start{%
+ \let\@tempa\CE@get@env@body%
+% \end{macrocode}
+%
+% We may have to gobble leading spaces, therefore we check the first
+% character in the environment:
+%
+% \begin{macrocode}
+ \futurelet\@tempb\CE@get@env@body@start@%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\CE@get@env@body@start@}
+%
+% Support macro for |\CE@get@env@body@start|. Checks if the next token
+% is a space, then calls |\CE@get@env@body@start@@|. Otherwise, the
+% collecting of the environment contents is started.
+%
+% \begin{macrocode}
+\def\CE@get@env@body@start@{%
+% \end{macrocode}
+%
+% |\@sptoken| contains a single space and is defined in
+% \textsf{ltdefns.dtx}:
+%
+% \begin{macrocode}
+ \ifx\@tempb\@sptoken%
+ \expandafter\CE@get@env@body@start@@%
+ \else%
+ \expandafter\CE@get@env@body%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\CE@get@env@body@start@@}
+%
+% Support macro for |\CE@get@env@body@start@|. Gobbles up any space
+% following the macro, then start the collecting of the environment
+% contents using |\CE@get@env@body|.
+%
+% \begin{macrocode}
+\def\CE@get@env@body@start@@{%
+ \afterassignment\CE@get@env@body%
+ \let\@tempb= %
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\CE@get@env@body}
+%
+% Usage: |\CE@get@env@body| \marg{body} |\end| \marg{envname}.
+%
+% To ensure proper initialization, this macro should not be called
+% directly; instead |\CE@get@env@body@start| should be called.
+%
+% First we change the catcode of |Q| to 3 (math switch) in order to
+% have a really unique character for parameter matching later
+% on.\footnote{Taken from `Around the bend 15'} We do this in a group
+% in order to easily restore the catcode later on and make all macro
+% definitions global:
+%
+% \begin{macrocode}
+\bgroup
+\catcode`\Q=3
+% \end{macrocode}
+%
+% Now we begin the macro:
+%
+% \begin{macrocode}
+\long\gdef\CE@get@env@body#1\end#2{%
+% \end{macrocode}
+%
+% Right at the beginning of the macro, we are at an |\end| (and |#1|
+% contains the contents prior to it). We check if it ends the current
+% environment (|#2| contains the name of the environment ended):
+%
+% \begin{macrocode}
+ \def\@tempb{#2}%
+ \ifx\@tempb\@currenvir%
+% \end{macrocode}
+%
+% \paragraph{Yes, it ends the current environment.} We add the
+% contents to |\toks@| and are done. But we do not add the contents
+% directly as there may be a trailing space left (multiple spaces have
+% been collapsed into one space by \TeX). So we call
+% |\CE@get@env@body@| using delimited parameters (note that |Q| has
+% catcode 3, therefore a normal |Q| is not matched).
+%
+% What exactly is going on here? Suppose we have the text
+%
+% \begin{verbatim}
+% Hello World_
+% \end{verbatim}
+% %
+% \noindent (the |_| denotes the trailing space). Then
+% |\CE@get@env@body@| is called like this:
+%
+% \begin{verbatim}
+% \CE@get@env@body@Hello World Q Q
+% \end{verbatim}
+% %
+% \noindent |\CE@get@env@body@| matches the parameters like this: |#1|
+% is `Hello World'; leaving |_Q| (added by the call from
+% |\CE@get@env@body|) in the input. |\CE@get@env@body@| then calls
+% |\CE@get@env@body@@| using |#1| and |Q|, resulting in the call:
+%
+% \begin{verbatim}
+% \CE@get@env@body@@Hello WorldQ Q
+% \end{verbatim}
+% %
+% \noindent |\CE@get@env@body@@| matches its parameter like this: |#1|
+% is `Hello World' again, and |#2| is the second |Q|.
+%
+% But what happened to the space between the two |Q|s? As |#2| is not
+% a delimited parameter, \TeX\ skips spaces after matching the first
+% |Q| until it reaches the second |Q|, thus gobbling up the space
+% inbetween.\footnote{c.f. \TeX book chapter 20.}
+%
+% \addvspace{\baselineskip}\noindent Now suppose we have the text
+% \begin{verbatim}
+% Hello World
+% \end{verbatim}
+% %
+% \noindent without any trailing space. Then |\CE@get@env@body@| is
+% called like this:
+%
+% \begin{verbatim}
+% \CE@get@env@body@Hello WorldQ Q
+% \end{verbatim}
+% %
+% \noindent |\CE@get@env@body@| matches its parameters like this: |#1|
+% is `Hello WorldQ'. |\CE@get@env@body@| then calls
+% |\CE@get@env@body@@| using |#1| and |Q|, resulting in the call:
+%
+% \begin{verbatim}
+% \CE@get@env@body@@Hello WorldQQ
+% \end{verbatim}
+% %
+% \noindent |\CE@get@env@body@@| matches its parameter like this: |#1|
+% is `Hello World' without the trailing `Q', and |#2| is the second
+% |Q|. The only difference to the situation described above is the
+% missing space between the two |Q|s.
+%
+% Remember that the `Q' is always `Q' with catcode 3, thus no `Q' in
+% the environment contents is matched.
+%
+% \begin{macrocode}
+ \CE@get@env@body@#1Q Q%
+ \def\@tempa{\end{#2}}%
+ \else
+% \end{macrocode}
+%
+% \paragraph{No, it ends another environment.} We add the contents as
+% well as the |\end|\meta{environment} to |\toks@|. Then we continue
+% collecting:
+%
+% \begin{macrocode}
+ \toks@\expandafter{\the\toks@#1\end{#2}}%
+ \fi%
+ \@tempa%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\CE@get@env@body@}
+%
+% Support macro for |\CE@get@env@body|. See |\CE@get@env@body| for
+% explanations.
+%
+% \begin{macrocode}
+\long\gdef\CE@get@env@body@#1 Q{%
+ \CE@get@env@body@@#1Q%
+}
+% \end{macrocode}
+% \end{macro}
+%
+
+% \begin{macro}{\CE@get@env@body@@}
+%
+% Support macro for |\CE@get@env@body@|. See |\CE@get@env@body| for
+% explanations.
+%
+% \begin{macrocode}
+\long\gdef\CE@get@env@body@@#1Q#2{%
+ \toks@\expandafter{\the\toks@#1}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% Finally we end the group, thus restoring the catcode of |Q|:
+%
+% \begin{macrocode}
+\egroup
+% \end{macrocode}
+%
+%
+% \begin{macro}{\CE@meaning}
+%
+% Usage: |\CE@meaning| \marg{macro}.
+%
+% Expands to the meaning of \meta{macro}.
+%
+% \begin{macrocode}
+\long\def\CE@meaning#1{%
+ \expandafter\strip@prefix\meaning#1%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\CE@ensure@opened}
+%
+% Usage: |\CE@ensure@opened| \marg{name}.
+%
+% Ensures that the file for collection \meta{name} is opened.
+%
+% \begin{macrocode}
+\def\CE@ensure@opened#1{%
+ \@ifundefined{ifCE@@#1@open}{%
+ \PackageError{collect}{Collection `#1' has not been defined}{\@ehc}%
+ }{%
+ \csname ifCE@@#1@open\endcsname\else%
+ \expandafter\immediate\expandafter\openout%
+ \csname CE@@#1@out\endcsname=\jobname.#1%
+ \expandafter\global\csname CE@@#1@opentrue\endcsname%
+ \fi%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\CE@ensure@closed}
+%
+% Usage: |\CE@ensure@closed| \marg{name}.
+%
+% Ensures that the file for collection \meta{name} is closed.
+%
+% \begin{macrocode}
+\def\CE@ensure@closed#1{%
+ \@ifundefined{ifCE@@#1@open}{%
+ \PackageError{collect}{Collection `#1' has not been defined}{\@ehc}%
+ }{%
+ \csname ifCE@@#1@open\endcsname%
+ \expandafter\immediate\expandafter\closeout%
+ \csname CE@@#1@out\endcsname%
+ \expandafter\global\csname CE@@#1@openfalse\endcsname%
+ \fi%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \Finale
+% \PrintChanges
+% \PrintIndex
+\endinput \ No newline at end of file
diff --git a/macros/latex/contrib/sauerj/collect.ins b/macros/latex/contrib/sauerj/collect.ins
new file mode 100644
index 0000000000..a03684bd8a
--- /dev/null
+++ b/macros/latex/contrib/sauerj/collect.ins
@@ -0,0 +1,19 @@
+\input docstrip
+\keepsilent
+\askforoverwritefalse
+
+\preamble
+\endpreamble
+\generate{%
+ \file{\jobname.sty}{\from{\jobname.dtx}{package}}
+}
+
+\Msg{***************************************************************}
+\Msg{*}
+\Msg{* \space To finish the installation you have to copy the files}
+\Msg{*}
+\Msg{* \space *.sty into a directory searched by TeX}
+\Msg{*}
+\Msg{***************************************************************}
+
+\endbatchfile \ No newline at end of file
diff --git a/macros/latex/contrib/sauerj/collect.pdf b/macros/latex/contrib/sauerj/collect.pdf
new file mode 100644
index 0000000000..e812f19e0f
--- /dev/null
+++ b/macros/latex/contrib/sauerj/collect.pdf
Binary files differ
diff --git a/macros/latex/contrib/sauerj/metainfo.dtx b/macros/latex/contrib/sauerj/metainfo.dtx
new file mode 100644
index 0000000000..b4941dbffd
--- /dev/null
+++ b/macros/latex/contrib/sauerj/metainfo.dtx
@@ -0,0 +1,1242 @@
+% \iffalse meta-comment
+% Line endings: UNIX
+% Tab size: 4
+%
+% Copyright 2004 Jonathan Sauer
+%
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3
+% 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.3 or later is part of all distributions of LaTeX
+% version 2003/12/01 or later.
+%
+% This work has the LPPL maintenance status "maintained".
+%
+% The Current Maintainer of this work is Jonathan Sauer
+% (<jonathan.sauer@gmx.de>).
+%
+% This work consists of the files metainfo.dtx and metainfo.ins
+% and the derived file metainfo.sty.
+%
+% \fi
+%
+% \iffalse
+%
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage{metainfo}
+\EnableCrossrefs
+\CodelineIndex
+\RecordChanges
+% Modification of verbatim for tabs in listings
+\makeatletter
+{\catcode`\ =\active%
+\catcode`\^^I=\active%
+\gdef\@vobeyspaces{%
+\catcode`\ \active\let \@xobeysp%
+\catcode`\^^I\active\def^^I{~~}%
+}}%
+\makeatother
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+%
+%<package>\NeedsTeXFormat{LaTeX2e}
+%<package>\ProvidesPackage{metainfo}
+%<package> [2004/11/25 v0.9.1 typeset document metainfo]
+%
+% \fi
+%
+% \CheckSum{386}
+% \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{\@@input,\|}
+% \DoNotIndex{\@ifundefined,\@ehc,\@empty,\@gobbletwo,\@nil}
+% \DoNotIndex{\@startsection,\@tempa,\active,\baselineskip}
+% \DoNotIndex{\begin,\bfseries,\bgroup,\catcode,\DeclareOption}
+% \DoNotIndex{\def,\egroup,\else,\end,\endinput,\expandafter}
+% \DoNotIndex{\fi,\futurelet,\gdef,\ifmmode,\ifcat,\ifx}
+% \DoNotIndex{\index,\item,\let,\long,\newcommand,\newif}
+% \DoNotIndex{\noexpand,\noindent,\normalfont,\normalsize}
+% \DoNotIndex{\PackageError,\par,\ProcessOptions,\relax,\space}
+% \DoNotIndex{\string,\textbf,\z@}
+%
+% \GetFileInfo{\jobname.sty}
+%
+% \title{The \textsf{metainfo} package\thanks{This document
+% corresponds to \textsf{\filename}~\fileversion, dated \filedate.}}
+%
+% \author{Jonathan Sauer \\ \texttt{jonathan.sauer@gmx.de}}
+%
+% \date{\filedate}
+%
+% \maketitle
+%
+% \begin{abstract}
+% This file describes the \textsf{metainfo} package that typesets only
+% special comments of a \TeX\ file.
+%
+% \end{abstract}
+%
+% \tableofcontents
+%
+% \section{Introduction}
+%
+% Suppose you write a text and include some annotations for yourself
+% that are not printed, i.e. an explanation of a pun or a short
+% summary of the current chapter in order to be able to later create a
+% summary of the whole text. Then it would be nice to be able to
+% extract these annotations and typeset them separately. This package
+% provides the macro |\typesetmetainfo| to typeset only these
+% annotations (herein called `metainfo', as they are information about
+% the information contained in the text).
+%
+%
+%
+%
+% \section{Macros}
+%
+% \DescribeMacro{\typesetmetainfo} Usage: |\typesetmetainfo|
+% \marg{file}.
+%
+% Typesets the metainfo of the \TeX\ file \meta{file}. Anything not a
+% metainfo---text, preamble---is skipped.
+%
+%
+%
+%
+% \section{Formatting}
+%
+% \subsection{Metainfo after a heading}
+%
+% Any comments following a line with a heading are considered a
+% metainfo and are typeset as if they were normal text. The first line
+% that does not begin with a percent sign finishes the metainfo.
+%
+% A heading is started by a macro defined in |\\mi@@MIbeginnings|.
+% Normally this macro contains |\chapter|, |\section|, |\subsection|,
+% and |\subsubsection|, but you can of course redefine it.
+%
+% The heading itself is typeset as well, before the metainfo,
+% resulting all metainfo being typeset using the outline of the normal
+% document. Note that when writing a heading, some restriction apply:
+%
+% \begin{enumerate}
+% \item The heading macro must be at the beginning of the line.
+%
+% \item Any parameters of the macro must be on the same line.
+% (parameters split over several lines might work, but they
+% are not guaranteed to)
+%
+% \end{enumerate}
+%
+%
+%
+%
+% \subsection{Local metainfo}
+%
+% There is another way to include metainfo in a document, that is as a
+% \emph{local metainfo}. A local metainfo is a metainfo not following
+% a heading; instead they can appear anywhere in the text. They start
+% with a double percent sign at the beginning of the line (|%%|); the
+% line itself is then typeset as a metainfo as well as all the
+% following lines beginning with a |%| (just as a metainfo following a
+% heading). The first line that does not begin with a percent sign
+% finishes the local metainfo.
+%
+% You can format a local metainfo using three macros. (see section
+% \ref{sec:ExLoMI} on page \pageref{sec:ExLoMI} for an example how to
+% customize them.)
+%
+% \begin{enumerate}
+% \item |\mi@@firstlocalMItext|: The contents of this macro is
+% inserted before the first local metainfo of a chapter.
+%
+% \item |\mi@@lastlocalMItext|: The contents of this macro is
+% inserted after the last local metainfo of a chapter.
+%
+% \item |\mi@@everylocalMItext|: The contents of this macro is
+% inserted before every local metainfo.
+%
+% \end{enumerate}
+%
+% \paragraph{Note} If you change these macros in your document
+% preamble or your main document opposed to a package file, you must
+% surround them with |\makeatletter| and |\makeatother|, as shown in
+% the example below.
+%
+%
+%
+%
+% \section{Package options}\label{sec:Options}
+%
+% The following package options exist:
+%
+% \begin{description}
+% \item[compactheadings] Changes the section headings to be more
+% compact in order to save some space.
+%
+% \item[indexshorthand] Provides shorthands for indexing.
+% |^|\marg{text} indexes and typesets \meta{text}, |^^|\marg{text}
+% only indexes it.\footnote{These shorthands have been inspired by
+% Donald E. Knuth's own index macros used for the \TeX book.}
+% For indexing, the standard index macro |\index| is used.
+%
+% These macros only work in text mode; in math mode, |^| is a
+% superscript as predefined in \LaTeX.
+%
+% \item[listlocalmetainfo] Changes the macros |\mi@@firstlocalMItext|,
+% |\mi@@lastlocalMItext| and |\mi@@everylocalMItext| (described in
+% the section above) to |itemize| the local metainfo.
+% \end{description}
+%
+%
+%
+%
+% \section{Driver files}
+%
+% In order to typeset only the metainfo of a document, a special
+% driver file is needed. This driver loads the packages necessary for
+% typesetting the metainfo (at least the package \textsf{metainfo})
+% and inputs the document to be typeset using |\typesetmetainfo|.
+%
+% \paragraph{Note} No package of the document processed using
+% |\typesetmetainfo| is loaded, as the |\usepackage| macros are
+% skipped. The same is true for any definitions in the document
+% preamble or elsewhere: They are skipped, so if the metainfo relies
+% on these definitions, they have to be included in the driver as
+% well.
+%
+%
+%
+%
+% \section{Examples}
+%
+% \subsection{Example driver file}
+%
+% The following driver file typesets the metainfo of the \TeX\ file
+% `example.tex' using compact headings:
+%
+% \begin{verbatim}
+% \documentclass{book}
+% \usepackage[compactheadings]{metainfo}
+%
+% \begin{document}
+% \typesetmetainfo{example}
+% \end{document}
+% \end{verbatim}
+%
+%
+%
+%
+% \subsection{Example document}
+%
+% If we save the following file as `example.tex' and process it using
+% the driver file in the example above \ldots
+%
+% \begin{verbatim}
+% \documentclass{minimal}
+% \usepackage{testpackage}
+%
+% \begin{document}
+%
+% \chapter{Chapter 1}
+% % Metainfo for chapter `Chapter 1'
+%
+% \section{Section 1}
+% % Metainfo for section `Section 1'
+%
+% This is some text.
+%
+% \chapter{Chapter 2}
+% \section{Section 2}
+% % Metainfo for section `Section 2'
+%
+% This is some more text.
+%
+% %% Local metainfo. This metainfo is a bit longer, but only
+% % a little bit.
+%
+% \section{Section 3}
+% % Metainfo for section `Section 3'
+% \end{document}
+% \end{verbatim}
+%
+% \ldots\ this results in:\footnote{Approximately, as the real
+% formatting will differ slightly from the text typeset here.}
+%
+% \addvspace{\baselineskip}
+% \textbf{Chapter 1}\par
+% Metainfo for chapter `Chapter 1'
+%
+% \addvspace{\baselineskip}
+% \textbf{Section 1}\par
+% Metainfo for section `Section 1'
+%
+% \addvspace{\baselineskip}
+% \textbf{Chapter 2}\par
+% \textbf{Section 2}\par
+% Metainfo for section `Section 2'
+%
+% \addvspace{\baselineskip}
+% Annotations:\par
+% Local metainfo. This metainfo is a bit longer, but only a little
+% bit.
+%
+% \addvspace{\baselineskip}
+% \textbf{Section 3}\par
+% Metainfo for section `Section 3'
+%
+%
+%
+%
+% \subsection{Example local metainfo formatting}\label{sec:ExLoMI}
+%
+% The following macros prefix local metainfo with `Annotations:' in
+% bold typeface and typesets the local metainfo in an |itemize|
+% environment:\footnote{Similar to the package option
+% \texttt{listlocalmetainfo}, described in section \ref{sec:Options}
+% on page \pageref{sec:Options} does.}
+%
+% \begin{verbatim}
+% \makeatletter
+% \def\mi@@firstlocalMItext{%
+% \addvspace{\baselineskip}%
+% \noindent\textbf{Annotations:}%
+% \begin{itemize}%
+% }
+% \def\mi@@lastlocalMItext{%
+% \end{itemize}%
+% }
+% \def\mi@@everylocalMItext{%
+% \item\relax%
+% }
+% \makeatother
+% \end{verbatim}
+%
+%
+%
+%
+% \section{Notes/Limitations}
+%
+% \begin{itemize}
+% \item Any text or macros on the same line as a heading are
+% processed as well, immediately after the heading. Thus
+% you can type |\section{foo}\label{sec:foo}| and refer
+% to this section inside a metainfo using the label
+% |sec:foo|.
+%
+% \item The document included using |\typesetmetainfo| must
+% be a valid \LaTeX\ document insofar as that it must
+% contain a |document| environment, because |\end{document}|
+% serves as the ending delimiter for typesetting the
+% metainfo.
+%
+% That also means that any metainfo following |\end{document}|
+% is \emph{not} typeset.
+%
+% \end{itemize}
+%
+%
+%
+%
+% \StopEventually{}
+%
+% \section{Implementation}
+%
+% \subsection{Main environments and macros}
+%
+% \begin{macro}{\typesetmetainfo}
+%
+% Usage: |\typesetmetainfo| \marg{file}.
+%
+% Typesets the metainfo of a document.
+%
+% \begin{macrocode}
+\newcommand{\typesetmetainfo}[1]{%
+ \bgroup%
+ \mi@activenewline%
+ \mi@emptyactivepercent%
+ \mi@otherbraces%
+ \ifmi@indexmacros\mi@activehat\fi%
+% \end{macrocode}
+%
+% We provide support for the standard \LaTeX\ |verbatim| environment:
+%
+% \begin{macrocode}
+ \let\mi@old@verbatim\@verbatim%
+ \def\@verbatim{%
+ \mi@old@verbatim%
+ \mi@verbatimnewline%
+ }%
+% \end{macrocode}
+%
+% We use the original \TeX\ definition of |\input| (saved by \LaTeX\
+% in |\@@input|), because we must continue with our special processing
+% immediately after \meta{file} has been opened. This is a job for the
+% original \TeX\ |\input|, as it simply switches the input stream to
+% \meta{file} and expands to nothing.
+%
+% The |\relax| delimits the filename.
+%
+% \begin{macrocode}
+ \expandafter\mi@skiplines\@@input#1\relax%
+ \egroup%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+% \subsection{Package customization}
+%
+% \begin{macro}{\mi@@MIbeginnings}
+%
+% Stores all the macros that can begin a metainfo.
+%
+% \begin{macrocode}
+\def\mi@@MIbeginnings{\chapter\section\subsection\subsubsection}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\mi@@firstlocalMItext}
+%
+% Stores the text inserted before the first local metainfo.
+%
+% \begin{macrocode}
+\def\mi@@firstlocalMItext{\textbf{Annotations:}\par\noindent}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\mi@@lastlocalMItext}
+%
+% Stores the text inserted after the last local metainfo.
+%
+% \begin{macrocode}
+\def\mi@@lastlocalMItext{}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\mi@@everylocalMItext}
+%
+% Stores the text inserted before every local metainfo.
+%
+% \begin{macrocode}
+\def\mi@@everylocalMItext{}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+% \subsection{Package options}
+%
+% \subsubsection{Headings}
+%
+% We provide the possibility of changing the headings to a more
+% compact formatting:
+%
+% \begin{macrocode}
+\DeclareOption{compactheadings}{%
+ \@ifundefined{thechapter}{}{%
+ \def\chapter{\@startsection{chapter}{0}{\z@}{-2\baselineskip}%
+ {\baselineskip}{\normalfont\normalsize\bfseries}}%
+ }%
+ \def\section{\@startsection{section}{1}{\z@}{-2\baselineskip}%
+ {\baselineskip}{\normalfont\normalsize\bfseries}}%
+ \def\subsection{\@startsection{subsection}{2}{\z@}{-2\baselineskip}%
+ {\baselineskip}{\normalfont\normalsize\bfseries}}%
+ \def\subsubsection{\@startsection{subsubsection}{3}{\z@}%
+ {-2\baselineskip}{\baselineskip}%
+ {\normalfont\normalsize\bfseries}}%
+}
+% \end{macrocode}
+%
+%
+%
+%
+% \subsubsection{Index shorthand}
+%
+% \begin{macro}{\ifmi@indexmacros}
+%
+% |true|, if index shorthands specified using the package option
+% |indexshorthand| are used, otherwise |false|:
+%
+% \begin{macrocode}
+\newif\ifmi@indexmacros
+\mi@indexmacrosfalse
+% \end{macrocode}
+% \end{macro}
+%
+% We provide the possibility of using the shorthand |^| for an index
+% entry that is typeset, and |^^| for an index entry that is not
+% typeset:
+%
+% \begin{macrocode}
+\DeclareOption{indexshorthand}{%
+ \mi@indexmacrostrue%
+% \end{macrocode}
+%
+%
+% \begin{macro}{\mi@hat}
+%
+% We save the original meaning of |^|. We do not simply use |^| in the
+% |\mi@hat|\ldots-macros, because then we would assume that |^| is not
+% already an active character before our catcode change (which we will
+% make in |\typesetmetainfo|). Normally, |^| has catcode 7
+% (superscript), but if is was active (i.e. because of another package
+% changing |^|), we would store an active |^| in the definition of the
+% |\mi@hat|\ldots-macros. When later used this |^| would point to our
+% macro |\mi@hat|, resulting in an endless loop. So we save the
+% original meaning of |^| instead using |\let|, which, if |^| is
+% active, would save the macro |^| would have been |\let| to.
+%
+% \begin{macrocode}
+ \let\mi@@@hat^%
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\mi@hat}
+%
+% Main macro for indexing and first step in deciding how to index:
+%
+% \begin{itemize}
+% \item Math mode: Expand to the original definition of |^|.
+%
+% \item Otherwise: Check the next token using |\mi@hat@|.
+%
+% \end{itemize}
+%
+% \begin{macrocode}
+ \def\mi@hat{%
+ \ifmmode%
+ \expandafter\mi@@@hat%
+ \else%
+ \expandafter\futurelet\expandafter\@tempa\expandafter\mi@hat@%
+ \fi%
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\mi@hat@}
+%
+% Second step in deciding how to index. We know that we are not in
+% math mode. The token following the hat has been prefetched and
+% stored in |\@tempa|. (it has not been read yet)
+%
+% \begin{itemize}
+% \item A second hat (|^|): Check the next token using |\mi@hat@twohats|.
+%
+% \item Opening brace: Typeset the index word and index it using
+% it |\mi@indextypeset|.
+%
+% \item Otherwise: Display an error, as |^^| must be followed by
+% a parameter in braces.
+%
+% \end{itemize}
+%
+% \begin{macrocode}
+ \def\mi@hat@{%
+ \ifx\@tempa\mi@hat%
+ \expandafter\mi@hat@twohats%
+ \else\ifx\@tempa\bgroup%
+ \expandafter\expandafter\expandafter\mi@indextypeset%
+ \else%
+ \mi@hat@errbrace%
+ \fi\fi%
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\mi@hat@twohats}
+%
+% First step in deciding how to index a word not typeset. We know we
+% have two hats in a row (|^^|), but the second hat is not read yet
+% (only prefetched using |\futurelet|). Therefore we gobble it using
+% |#1|.
+%
+% \begin{macrocode}
+ \def\mi@hat@twohats#1{%
+ \futurelet\@tempa\mi@hat@twohats@%
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\mi@hat@twohats}
+%
+% Second step in deciding how to index a word not typeset. We know we
+% have two hats in a row, both read. The token following the two hats
+% has been prefetched and stored in |\@tempa|.
+%
+% Note that we could skip this step and simpy expand to |\index|,
+% letting |\index| take care that a proper parameter follows.
+%
+% \begin{macrocode}
+ \def\mi@hat@twohats@{%
+ \ifx\@tempa\bgroup%
+ \expandafter\index%
+ \else%
+ \mi@hat@errbrace%
+ \fi%
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\mi@indextypeset}
+%
+% Usage: |\mi@indextypeset| \marg{word}. Typesets \meta{word} and
+% indexes it using |\index|.
+%
+% \begin{macrocode}
+ \def\mi@indextypeset#1{%
+ #1\index{#1}%
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\mi@hat@errbrace}
+%
+% Error handling when a |^| or |^^| is not followed by a left brace.
+%
+% \begin{macrocode}
+ \def\mi@hat@errbrace{%
+ \PackageError{metainfo}{`\string^' or `\string^\string^' not %
+ followed by a left brace}\@ehc%
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% End of |\DeclareOption{index}|:
+%
+% \begin{macrocode}
+}
+% \end{macrocode}
+%
+%
+%
+%
+% \subsubsection{Other options}
+%
+% \begin{macrocode}
+\DeclareOption{listlocalmetainfo}{%
+ \def\mi@@firstlocalMItext{%
+ \begin{itemize}%
+ }%
+ \def\mi@@lastlocalMItext{%
+ \end{itemize}%
+ }%
+ \def\mi@@everylocalMItext{%
+ \item\relax%
+ }%
+}
+% \end{macrocode}
+%
+%
+%
+%
+% \begin{macrocode}
+\ProcessOptions\relax
+% \end{macrocode}
+%
+%
+%
+%
+% \subsection{Internal environments and macros}
+%
+% \subsubsection{General definitions and flags}
+%
+% \paragraph{Strategy for dealing with catcode changes} At the
+% beginning of the processing, the catcodes are changed as follows:
+%
+% \begin{tabular}{cl}
+% |^^M| & 13 (active), set in |\mi@activenewline| \\
+% |%| & 13, set in |\mi@emptyactivepercent| \\
+% |{| & 12 (other), set in |\mi@otherbraces| \\
+% |}| & 12, set in |\mi@otherbraces| \\
+% |^| & 13, optionally set in |\mi@activehat| \\
+% \end{tabular}
+%
+% If any macro changes the catcodes of these characters, it must reset
+% them to these values after processing. If any macro needs the braces
+% |{| and |}| for parameter grouping, it should use the macro
+% |\mi@normalbraces| to change the catcodes accordingly.
+%
+%
+% \begin{macro}{\ifmi@firstlocalMI}
+%
+% |true| if this is the first local metainfo, otherwise |false|. Used
+% to insert |\mi@@firstlocalMItext| and |\mi@@lastlocalMItext|.
+%
+% \begin{macrocode}
+\newif\ifmi@firstlocalMI
+\mi@firstlocalMItrue
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+% \subsubsection{Modes}
+%
+% Three modes of processing exist:
+%
+% \begin{description}
+% \item[Skipping text] Text is skipped line after line. If two
+% percent signs are found at the beginning of a new line,
+% a local metainfo is begun and the mode changed to
+% `Typesetting a metainfo'.
+%
+% Main macro: |\mi@skiplines|.
+%
+% \item[Beginning metainfo] The appropriate heading is typeset
+% and the remaining line of text skipped. The mode is then
+% changed to `Typesetting a metainfo'.
+%
+% Main macro: |\mi@checkbeginMI|.
+%
+% \item[Typesetting a metainfo] The text is typeset. If a line does
+% not start with a percent sign, the metainfo is done. The
+% mode is then changed to `Skipping text'.
+%
+% Main macro: |\mi@typesetMI|.
+%
+% \end{description}
+%
+%
+% \begin{macro}{\mi@skiplines}
+%
+% Main macro. Skips lines and checks the first token of a line (stored
+% in |#1|) for two special cases:
+%
+% \begin{enumerate}
+% \item A percent sign |%|: We check if it starts a local metainfo
+% using |\mi@checkbeginlocalMI|.
+%
+% \item A control sequence: We check if it starts a new metainfo
+% using |\mi@checkbeginMI|.
+%
+% \end{enumerate}
+%
+% \begin{macrocode}
+\def\mi@skiplines#1{%
+ \ifx#1\mi@percentempty%
+% \end{macrocode}
+%
+% A percent sign: We check if it starts a local metainfo.
+%
+% \begin{macrocode}
+ \expandafter\mi@checkbeginlocalMI%
+ \else\ifcat\noexpand#1\relax%
+% \end{macrocode}
+%
+% A control sequence: We check if it starts a new metainfo.
+%
+% \begin{macrocode}
+ \expandafter\expandafter\expandafter\mi@checkbeginMI%
+ \else%
+% \end{macrocode}
+%
+% Anything else: We skip it and the remaining line of text. Note that
+% it could be a line ending (|^^M|), so it may be possible that we
+% gobble only |#1|, which will be re-inserted into the stream below.
+% That way we do not have to check if |#1| is a line ending.
+%
+% \begin{macrocode}
+ \expandafter\expandafter\expandafter\mi@gobbletolineend%
+ \fi\fi%
+% \end{macrocode}
+%
+% We always insert the first token of a line back into the stream,
+% even though it is not necessary for |\mi@checkbeginlocalMI|. But as
+% normally most of the lines of a text will be skipped, we optimize
+% for this case.
+%
+% \begin{macrocode}
+ #1%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% The following macros require |^^M| to be active:
+%
+% \begin{macrocode}
+\bgroup
+\catcode`\^^M=\active%
+% \end{macrocode}
+%
+%
+% \begin{macro}{\mi@typesetMI}
+%
+% Prepares the typesetting of a metainfo.
+%
+% \begin{macrocode}
+\gdef\mi@typesetMI{%
+ \mi@normalbraces%
+% \end{macrocode}
+%
+% Every CR we check if the next line continues the metainfo
+% using |\mi@typesetMI@checkend|.
+%
+% \begin{macrocode}
+ \let^^M\mi@typesetMI@checkend%
+% \end{macrocode}
+%
+% Now we start typesetting the text. We let \TeX\ take completely
+% control instead of reading one line after the other; we will regain
+% control at the end of each line using our redefinition of |^^M|.
+%
+% \begin{macrocode}
+ \ignorespaces%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\mi@typesetMI@checkend}
+%
+% Called at a carriage return. If the token after the CR is equals to
+% |\mi@percentempty|, the next line starts with a |%|, thus continuing
+% the metainfo. Otherwise, the metainfo is finished.
+%
+% \begin{macrocode}
+\long\gdef\mi@typesetMI@checkend#1{%
+ \ifx#1\mi@percentempty%
+% \end{macrocode}
+%
+% The next line continues the comment. We check for an empty line:
+%
+% \begin{macrocode}
+ \expandafter\mi@typesetMI@checkend@%
+ \else%
+% \end{macrocode}
+%
+% The next line finishes the comment:
+%
+% \begin{macrocode}
+ \mi@otherbraces%
+ \let^^M\@empty%
+ \expandafter\mi@skiplines\expandafter#1%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\mi@typesetMI@checkend@}
+%
+% Checks if a |^^M| (CR) follows immediately after the |%|. Then we
+% insert a |\par|. Note that any spaces between the |%| and the CR
+% are automatically skipped by using a non-delimited parameter.
+%
+% \begin{macrocode}
+\long\gdef\mi@typesetMI@checkend@#1{%
+ \ifx#1\mi@typesetMI@checkend%
+ \par\expandafter\mi@typesetMI@checkend%
+ \else%
+% \end{macrocode}
+%
+% We assume the line is |% |\meta{text} instead of |%|\meta{text},
+% thus we insert back a space that was skipped before:
+%
+% \begin{macrocode}
+ \space%
+ \expandafter#1%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\mi@checkbeginMI}
+%
+% Usage: |\mi@checkbeginMI|\meta{cs}.
+%
+% First step in the check for the begin of a metainfo: Checks if
+% \meta{cs} is a control sequence that can begin a metainfo.
+%
+% \begin{macrocode}
+\gdef\mi@checkbeginMI#1{%
+% \end{macrocode}
+%
+% Handle |\end|:
+%
+% \begin{macrocode}
+ \ifx#1\end%
+ \expandafter\mi@checkdocumentend%
+ \else%
+% \end{macrocode}
+%
+% We check if \meta{cs} is a relevant control sequence. (these are
+% stored in |\mi@@MIbeginnings|) Then we use |\mi@checkbeginMI@| to
+% evaluate the result:
+%
+% \begin{macrocode}
+ \def\@tempa##1#1##2\@nil{\mi@checkbeginMI@{##2}#1}%
+ \expandafter\expandafter\expandafter\@tempa%
+ \expandafter\mi@@MIbeginnings\expandafter#1%
+ \expandafter\@nil%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\mi@checkbeginMI@}
+%
+% Support macro for |\mi@checkbeginMI|. Checks if |#2| is a relevant
+% control sequence by checking if |#1| is empty (|false|) or not
+% (|true|).
+%
+% \begin{macrocode}
+\gdef\mi@checkbeginMI@#1#2{%
+ \ifx^^M#1^^M%
+% \end{macrocode}
+%
+% Not a relevant control sequence: Skip till the end of the line.
+%
+% \begin{macrocode}
+ \expandafter\mi@gobbletolineend%
+ \else%
+% \end{macrocode}
+%
+% A relevant control sequence. If there has been any local metainfo
+% before this macro, we finish it by inserting |\mi@@lastlocalMItext|:
+%
+% \begin{macrocode}
+ \ifmi@firstlocalMI\else\mi@@lastlocalMItext\fi%
+% \end{macrocode}
+%
+% We restore all character catcodes except for |^^M|, which we use to
+% continue processing after the control sequence in question has been
+% executed: (this is the reason a heading must appear on a single
+% line, as otherweise |^^M| is executed more than once)
+%
+% \begin{macrocode}
+ \let^^M\mi@checkbeginMI@@%
+ \mi@normalbraces%
+ \mi@normalpercent%
+% \end{macrocode}
+%
+% In any case, a local metainfo following this macro is the first, so
+% we set the flag accordingly:
+%
+% \begin{macrocode}
+ \mi@firstlocalMItrue%
+ \expandafter#2%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\mi@checkbeginMI@@}
+%
+% Support macro for |\mi@checkbeginMI@|. Is called via |^^M| at the end
+% of a line.
+%
+% \begin{macrocode}
+\gdef\mi@checkbeginMI@@{%
+ \let^^M\@empty%
+ \mi@otherbraces%
+ \mi@emptyactivepercent%
+ \mi@checkbeginMI@@@%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\egroup
+% \end{macrocode}
+%
+%
+% \begin{macro}{\mi@checkbeginMI@@@}
+%
+% Support macro for |\mi@checkbeginMI| and the second step in the
+% check for the begin of a metainfo: Checks if the line after the
+% control sequence begins with a percent sign.
+%
+% \begin{macrocode}
+\def\mi@checkbeginMI@@@#1{%
+ \ifx#1\mi@percentempty%
+% \end{macrocode}
+%
+% A percent sign: It starts a metainfo. Change to metainfo.
+%
+% \begin{macrocode}
+ \par%
+ \expandafter\mi@typesetMI%
+ \else%
+% \end{macrocode}
+%
+% Anything else: No metainfo follows. Ignore it.
+%
+% \begin{macrocode}
+ \expandafter\mi@skiplines\expandafter#1%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\mi@checkbeginlocalMI}
+%
+% Usage: |\mi@checkbeginlocalMI|\meta{dummy}\meta{next token}.
+%
+% \meta{dummy} is the result of an optimization of |\mi@skiplines|.
+% (see above)
+%
+% \begin{macrocode}
+\def\mi@checkbeginlocalMI#1#2{%
+ \ifx#2\mi@percentempty%
+% \end{macrocode}
+%
+% A percent sign: It starts a local metainfo. Change to metainfo.
+%
+% \begin{macrocode}
+ \par%
+ \ifmi@firstlocalMI\mi@@firstlocalMItext\fi%
+ \mi@@everylocalMItext%
+% \end{macrocode}
+%
+% We have begun to typeset the local metainfo, therefore we take note
+% that any local metainfo following this one is not the first.
+%
+% \begin{macrocode}
+ \mi@firstlocalMIfalse%
+ \expandafter\mi@typesetMI%
+ \else%
+% \end{macrocode}
+%
+% Anything else: No, it is just a simple comment. Ignore it.
+%
+% \begin{macrocode}
+ \expandafter\mi@gobbletolineend\expandafter#2%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\mi@checkdocumentend}
+%
+% Checks if the |\end| just read ends the |document| environment.
+%
+% \begin{macrocode}
+\def\mi@checkdocumentend{%
+% \end{macrocode}
+%
+% We change the catcodes of braces back to normal in order to get the
+% name of the environment as the only parameter of |\mi@checkdocumentend@|
+% and not only the opening brace.
+%
+% \begin{macrocode}
+ \mi@normalbraces%
+ \mi@checkdocumentend@%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\mi@checkdocumentend@}
+%
+% Support macro for |\mi@checkdocumentend|.
+%
+% \begin{macrocode}
+\def\mi@checkdocumentend@#1{%
+ \def\@tempa{#1}%
+ \ifx\@tempa\mi@textdocument%
+% \end{macrocode}
+%
+% If there has been any local metainfo before this macro, we finish it
+% by inserting |\mi@@lastlocalMItext|:
+%
+% \begin{macrocode}
+ \ifmi@firstlocalMI\else\mi@@lastlocalMItext\fi%
+ \expandafter\mi@gobbletolineend@any\expandafter\endinput%
+ \else%
+% \end{macrocode}
+%
+% As are not done yet, we better set the catcode of braces to
+% `letter':
+%
+% \begin{macrocode}
+ \mi@otherbraces%
+ \expandafter\mi@skiplines%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\mi@textdocument}
+%
+% The text `document' for |\mi@checkdocumentend|.
+%
+% \begin{macrocode}
+\def\mi@textdocument{document}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\mi@percentempty}
+%
+% \begin{macrocode}
+\def\mi@percentempty{\@empty}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+% \subsubsection{Gobbling text}
+%
+% \begin{macrocode}
+\bgroup
+\catcode`\^^M=\active%
+% \end{macrocode}
+%
+%
+% \begin{macro}{\mi@gobbletolineend}
+%
+% Gobbles up any text till the end of the line. Continues with
+% |\mi@skiplines|. (specialization of |\mi@gobbletolineend@any|)
+%
+% \begin{macrocode}
+\gdef\mi@gobbletolineend{%
+ \mi@gobbletolineend@any\mi@skiplines%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\mi@gobbletolineend@any}
+%
+% Usage: |\mi@gobbletolineend@any| \marg{macro}.
+%
+% Gobbles up any text till the end of the line. Continues with
+% \meta{macro}. The macro is |long| in case the line (stored in |#2|)
+% contains a |\par|.
+%
+% \begin{macrocode}
+\long\gdef\mi@gobbletolineend@any#1#2^^M{%
+ #1%
+}
+\egroup
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \subsubsection{Catcode changes}
+%
+% We define the macros for changing catcodes:
+%
+% \begin{macro}{\mi@activenewline}
+% \begin{macro}{\mi@verbatimnewline}
+% \begin{macro}{\mi@emptyactivepercent}
+% \begin{macro}{\mi@activehat}
+%
+% \begin{macrocode}
+\bgroup
+% \end{macrocode}
+%
+% We use \verb+|+ as the comment character as we make |%| active:
+%
+% \begin{macrocode}
+\catcode`\|=14 %
+\catcode`\^^M=\active%
+\catcode`\%=\active|
+\gdef\mi@activenewline{|
+ \catcode`\^^M=\active|
+ \let^^M\@empty|
+}|
+\gdef\mi@verbatimnewline{|
+ \catcode`\^^M=\active|
+ \def^^M{\par\@gobbletwo}|
+}|
+\gdef\mi@emptyactivepercent{|
+ \catcode`\%=\active|
+ \let%\mi@percentempty|
+}|
+\catcode`\^=\active|
+\gdef\mi@activehat{|
+ \catcode`\^\active|
+ \let^\mi@hat|
+}|
+\egroup
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{\mi@normalpercent}
+%
+% \begin{macrocode}
+\def\mi@normalpercent{%
+ \catcode`\%=14 %
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\mi@otherbraces}
+%
+% \begin{macrocode}
+\def\mi@otherbraces{%
+ \catcode`\{=12 %
+ \catcode`\}=12 %
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\mi@normalbraces}
+%
+% \begin{macrocode}
+\def\mi@normalbraces{%
+ \catcode`\{=1 %
+ \catcode`\}=2 %
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \Finale
+% \PrintChanges
+% \PrintIndex
+\endinput \ No newline at end of file
diff --git a/macros/latex/contrib/sauerj/metainfo.ins b/macros/latex/contrib/sauerj/metainfo.ins
new file mode 100644
index 0000000000..a03684bd8a
--- /dev/null
+++ b/macros/latex/contrib/sauerj/metainfo.ins
@@ -0,0 +1,19 @@
+\input docstrip
+\keepsilent
+\askforoverwritefalse
+
+\preamble
+\endpreamble
+\generate{%
+ \file{\jobname.sty}{\from{\jobname.dtx}{package}}
+}
+
+\Msg{***************************************************************}
+\Msg{*}
+\Msg{* \space To finish the installation you have to copy the files}
+\Msg{*}
+\Msg{* \space *.sty into a directory searched by TeX}
+\Msg{*}
+\Msg{***************************************************************}
+
+\endbatchfile \ No newline at end of file
diff --git a/macros/latex/contrib/sauerj/metainfo.pdf b/macros/latex/contrib/sauerj/metainfo.pdf
new file mode 100644
index 0000000000..6fd43c7090
--- /dev/null
+++ b/macros/latex/contrib/sauerj/metainfo.pdf
Binary files differ
diff --git a/macros/latex/contrib/sauerj/optparams.dtx b/macros/latex/contrib/sauerj/optparams.dtx
new file mode 100644
index 0000000000..99c4880441
--- /dev/null
+++ b/macros/latex/contrib/sauerj/optparams.dtx
@@ -0,0 +1,327 @@
+% \iffalse meta-comment
+% Line endings: UNIX
+% Tab size: 4
+%
+% Copyright 2004 Jonathan Sauer
+%
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3
+% 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.3 or later is part of all distributions of LaTeX
+% version 2003/12/01 or later.
+%
+% This work has the LPPL maintenance status "maintained".
+%
+% The Current Maintainer of this work is Jonathan Sauer
+% (<jonathan.sauer@gmx.de>).
+%
+% This work consists of the files optparams.dtx and optparams.ins
+% and the derived file optparams.sty.
+%
+% \fi
+%
+% \iffalse
+%
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage{optparams}
+\EnableCrossrefs
+\CodelineIndex
+\RecordChanges
+% Modification of verbatim for tabs in listings
+\makeatletter
+{\catcode`\ =\active%
+\catcode`\^^I=\active%
+\gdef\@vobeyspaces{%
+\catcode`\ \active\let \@xobeysp%
+\catcode`\^^I\active\def^^I{~~}%
+}}%
+\makeatother
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+%
+%<package>\NeedsTeXFormat{LaTeX2e}
+%<package>\ProvidesPackage{optparams}
+%<package> [2004/08/14 v0.9 multiple optional parameters in macros]
+%
+% \fi
+%
+% \CheckSum{12}
+% \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{\@ifnextchar,\@nil,\def,\newcommand}
+%
+% \GetFileInfo{\jobname.sty}
+%
+% \title{The \textsf{optparams} package\thanks{This document
+% corresponds to \textsf{\filename}~\fileversion, dated \filedate. The
+% package is based on David Kastrup's macros for `Around the Bend
+% 21'.}}
+%
+% \author{Jonathan Sauer \\ \texttt{jonathan.sauer@gmx.de}}
+%
+% \date{\filedate}
+%
+% \maketitle
+%
+% \begin{abstract}
+% This file describes the \textsf{optparams} package that provides a
+% small macro for creating macros with multiple optional parameters.
+%
+% \end{abstract}
+%
+% \tableofcontents
+%
+%
+%
+% \section{Introduction}
+%
+% The \LaTeX\ macro |\newcommand| is used to define macros that may
+% have one optional parameter (the first one). However, there is no
+% easy way of defining macros having several optional parameters. This
+% package provides the macro |\optparams| to simplify the creation of
+% macros with multiple optional parameters (or optional parameters
+% only).
+%
+%
+%
+% \section{Examples}
+%
+% \subsection{Example one}
+%
+% \begin{verbatim}
+% \long\def\test@[#1][#2][#3][#4]{%
+% (#1) (#2) (#3) (#4)
+% }
+%
+% \newcommand{\test}{%
+% \optparams{\test@}{[one][two][three][four]}%
+% }
+% \end{verbatim}
+% You have now defined a macro |\test| that takes up to four optional
+% parameters (|#1| to |#4|). You can call this macro as:
+%
+% \begin{itemize}
+% \item |\test[this]|, resulting in |(this) (two) (three) (four)|.
+%
+% \item |\test[this][is]|, resulting in |(this) (is) (three) (four)|.
+%
+% \item |\test[this][is][a]|, resulting in |(this) (is) (a) (four)|.
+%
+% \item |\test[this][is][a][test]|, resulting in |(this) (is) (a) (test)|.
+%
+% \end{itemize}
+% You see that the default parameters defined in |\test| are replaced
+% one by one by the parameters given when |\test| is called.
+%
+%
+%
+% \subsection{Example two}
+%
+% \begin{verbatim}
+% \long\def\test@[#1][#2][#3][#4]#5{%
+% (#1) (#2) (#3) (#4) !#5!
+% }
+%
+% \newcommand{\test}{%
+% \optparams{\test@}{[one][two][three][four]}%
+% }
+% \end{verbatim}
+% You have now defined a macro |\test| that takes up to four optional
+% parameters (|#1| to |#4|) and one mandatory parameter (|#5)|. You
+% can call this macro as:
+%
+% \begin{itemize}
+% \item |\test[this]{foo}|, resulting in
+% |(this) (two) (three) (four) !foo!|.
+%
+% \item |\test[this][is]{foo}|, resulting in
+% |(this) (is) (three) (four) !foo!|.
+%
+% \item |\test[this][is][a]{foo}|, resulting in
+% |(this) (is) (a) (four) !foo!|.
+%
+% \item |\test[this][is][a][test]{foo}|, resulting in
+% |(this) (is) (a) (test) !foo!|.
+%
+% \end{itemize}
+%
+%
+%
+% \section{Description of the macros}
+%
+% \DescribeMacro{\optparams} Usage: |\optparams| \marg{macro}
+% \marg{default parameters}.
+%
+% This macro reads any optional parameters from the input and finally
+% calls your macro with the optional parameters as well as the
+% remaining default parameters.
+%
+% Each default parameter must have the form |[|\meta{value}|]|. As all
+% default parameters are passed as one parameter to |\optparams|, they
+% must be enclosed in braces (|{|\meta{default parameters}|}|).
+%
+% The macro that is finally called must have as many optional
+% parameters as have been defined in the call of |\optparams|; their
+% form must be |[|\meta{parameter}|]|, where \meta{parameter} is a
+% number beginning with one and ending with nine.\footnote{This is a
+% general restriction of \TeX: A macro cannot have more than nine
+% parameters.} The parameter numbers must be numbered consecutively,
+% i.e. |[#1][#2][#3]| instead of |[#1][#2][#4]|.
+%
+% Because of this special way of declaring macro parameters, you
+% cannot use |\newcommand| but have to use the \TeX\ primitiv |\def|.
+% As |\def|, contrary to |\newcommand|, does not warn you when you
+% overwrite an already existing macro, you first should define the
+% macro as a dummy using |\newcommand| and then correctly using
+% |\def|, i.e.:
+%
+% \begin{verbatim}
+% \newcommand{\test@}{}
+% \long\def\test@[#1][#2][#3][#4]{%
+% <macro>
+% }
+% \end{verbatim}
+% This way you do not accidentally overwrite an existing macro.
+%
+% What does the |\long| do? In \TeX, in order to quicker capture
+% errors such as missing right braces |}|, parameters of macros
+% defined using |\def| cannot contain a |\par|, or \TeX\ will complain
+% (`runaway argument?'). This makes it easier for the user to spot
+% mistakes, as in that case \TeX\ will stop processing immediately at
+% the end of the current paragraph and not continue until i.e. the end
+% of the file before realizing that a macro parameter has not been
+% closed via |}|.
+%
+% But there is a way to make the usage of |\par| as a macro parameter
+% possible: Using |\long| in front of the |\def|. In \LaTeX,
+% |\newcommand| defines macros as |\long| by default, and its variant
+% |\newcommand*| defines macros restricted to `short' parameters. So
+% as demonstrated in the examples, you should either use |\newcommand|
+% and |\long\def| together or |\newcommand*| and |\def| in order to
+% make your macros behave correctly.
+%
+%
+%
+% \section{Notes}
+%
+% \begin{itemize}
+% \item If you use the notation used in the examples above,
+% \meta{macroname} for the main macro and
+% \meta{macroname}|@| for the macro finally called by
+% |\optparams|, and if you define these macros not in a
+% package or class, but in your document preamble, you have
+% to enclose the definitions in |\makeatletter| \ldots\
+% |\makeatother|, otherwise you cannot use |@| in macro
+% names.
+%
+% \item If you define a macro having only optional parameters (as
+% in the first example above), you have to make sure the
+% macro is not called in a context where a |[| follows not
+% as a parameter, but simply as an opening bracket, i.e.
+% |\test[foo] [as a side note| \ldots, where the call of
+% |\test| should have only |[foo]| as its only
+% parameter. In this case |\optparams| will think that
+% another optional parameter follows, resulting in chaos.
+%
+% To prevent this from happening, insert a |\relax| after
+% the last optional parameter of the macro call, i.e.
+% |\test[foo]\relax [as a side note| \ldots\ Then
+% |\optparams| will stop looking for more optional
+% parameters.
+%
+% \end{itemize}
+%
+% \StopEventually{}
+%
+%
+%
+% \section{Implementation}
+%
+% \subsection{Main macros}
+%
+% \begin{macro}{\optparams}
+%
+% Calls |#1| using a variable number of parameters. Default parameters
+% are provided in |#2| in the form |[|\meta{param one}|]| |[|\meta{param
+% two}|]| \ldots
+%
+% \begin{macrocode}
+\newcommand{\optparams}[2]{%
+ \optparams@{#1}{}{#2}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \subsection{Internal macros}
+%
+% \begin{macro}{\optparams@}
+%
+% Checks if the next character from the input is a |[|. If true calls
+% |\optparams@@|, as there are still optional parameters left. Otherwise
+% calls \meta{macro} with \meta{parameters read} and \meta{remaining
+% default parameters}.
+%
+% Usage: |\optparams@| \marg{macro} \marg{parameters read}
+% \marg{remaining default parameters}.
+%
+% \begin{macrocode}
+\def\optparams@#1#2#3{%
+ \@ifnextchar[{%
+ \optparams@@{#1}{#2}#3\@nil%
+ }{%
+ #1#2#3%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\optparams@@}
+%
+% Reads the next optional parameter from the input (as |#5| or
+% \meta{new parameter}). Then gobbles up the corresponding default
+% parameter (as |#3| or \meta{default for parameter read}, appends the
+% parameter read to \meta{parameters read} and calls |\optparams@|
+% again to check for more optional parameters.
+%
+% Usage: |\optparams@@| \marg{macro} \marg{parameters read}
+% \marg{default for parameter read} \marg{remaining default
+% parameters} \marg{new parameter}.
+%
+% \begin{macrocode}
+\def\optparams@@#1#2[#3]#4\@nil[#5]{%
+ \optparams@{#1}{#2[#5]}{#4}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% Now this is quite a coincidence: Thirteen lines of code, and this
+% package was begun on Friday, 13th \ldots
+%
+% \Finale
+% \PrintChanges
+% \PrintIndex
+\endinput \ No newline at end of file
diff --git a/macros/latex/contrib/sauerj/optparams.ins b/macros/latex/contrib/sauerj/optparams.ins
new file mode 100644
index 0000000000..a03684bd8a
--- /dev/null
+++ b/macros/latex/contrib/sauerj/optparams.ins
@@ -0,0 +1,19 @@
+\input docstrip
+\keepsilent
+\askforoverwritefalse
+
+\preamble
+\endpreamble
+\generate{%
+ \file{\jobname.sty}{\from{\jobname.dtx}{package}}
+}
+
+\Msg{***************************************************************}
+\Msg{*}
+\Msg{* \space To finish the installation you have to copy the files}
+\Msg{*}
+\Msg{* \space *.sty into a directory searched by TeX}
+\Msg{*}
+\Msg{***************************************************************}
+
+\endbatchfile \ No newline at end of file
diff --git a/macros/latex/contrib/sauerj/optparams.pdf b/macros/latex/contrib/sauerj/optparams.pdf
new file mode 100644
index 0000000000..e3ed25d776
--- /dev/null
+++ b/macros/latex/contrib/sauerj/optparams.pdf
Binary files differ
diff --git a/macros/latex/contrib/sauerj/parcolumns.dtx b/macros/latex/contrib/sauerj/parcolumns.dtx
new file mode 100644
index 0000000000..f898e43aae
--- /dev/null
+++ b/macros/latex/contrib/sauerj/parcolumns.dtx
@@ -0,0 +1,1090 @@
+% \iffalse meta-comment
+% Line endings: UNIX
+% Tab size: 4
+%
+% Copyright 2004 Jonathan Sauer
+%
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3
+% 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.3 or later is part of all distributions of LaTeX
+% version 2003/12/01 or later.
+%
+% This work has the LPPL maintenance status "maintained".
+%
+% The Current Maintainer of this work is Jonathan Sauer
+% (<jonathan.sauer@gmx.de>).
+%
+% This work consists of the files parcolumns.dtx and parcolumns.ins
+% and the derived file parcolumns.sty.
+%
+% \fi
+%
+% \iffalse
+%
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage{parcolumns}
+\EnableCrossrefs
+\CodelineIndex
+\RecordChanges
+% Modification of verbatim for tabs in listings
+\makeatletter
+{\catcode`\ =\active%
+\catcode`\^^I=\active%
+\gdef\@vobeyspaces{%
+\catcode`\ \active\let \@xobeysp%
+\catcode`\^^I\active\def^^I{~~}%
+}}%
+\makeatother
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+%
+%<package>\NeedsTeXFormat{LaTeX2e}
+%<package>\ProvidesPackage{parcolumns}
+%<package> [2004/11/25 v1.2 Typeset multiple parallel columns]
+%<package>\RequirePackage{processkv}[2004/08/05]
+%
+% \fi
+%
+% \CheckSum{368}
+% \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{\@clubpenalty,\@doendpe,\@ehc,\@ifundefined,\@M,\@ne}
+% \DoNotIndex{\@one,\@nobreakfalse,\@plus,\@tempa,\@tempb,\@tempboxa}
+% \DoNotIndex{\@tempcnta,\@tempdima,\@tempdimb,\@tempdimc}
+% \DoNotIndex{\@tempswafalse,\@testopt,\advance,\afterassignment}
+% \DoNotIndex{\box,\brokenpenalty,\clubpenalty,\count@,\csname}
+% \DoNotIndex{\def,\define@key,\displaywidowpenalty,\divide,\dp,\edef}
+% \DoNotIndex{\else,\endcsname,\endgraf,\everypar,\expandafter}
+% \DoNotIndex{\fi,\global,\hbadness,\hb@xt@,\hfill,\hsize,\hskip}
+% \DoNotIndex{\if@tempswa,\ifnum,\ifvoid,\ifx,\interlinepenalty}
+% \DoNotIndex{\lastbox,\leavevmode,\let,\linewidth,\long,\loop}
+% \DoNotIndex{\m@ne,\multiply,\newbox,\newcommand,\newcount}
+% \DoNotIndex{\newdimen,\newenvironment,\newif,\newtoks}
+% \DoNotIndex{\number,\PackageError,\PackageInfo,\processkeyvalues}
+% \DoNotIndex{\relax,\repeat,\setbox,\setkeys,\space,\spaceskip}
+% \DoNotIndex{\splittopsep,\splittopskip,\strut,\strutbox,\the}
+% \DoNotIndex{\toks@,\tolerance,\unvbox,\vbadness,\vbox,\vfuzz}
+% \DoNotIndex{\vrule,\vsplit,\widowpenalty,\z@,\z@skip,\\}
+%
+% \GetFileInfo{\jobname.sty}
+%
+% \title{The \textsf{parcolumns} package\thanks{This document
+% corresponds to \textsf{\filename}~\fileversion, dated \filedate.}}
+%
+% \author{Jonathan Sauer \\ \texttt{jonathan.sauer@gmx.de}}
+%
+% \date{\filedate}
+%
+% \maketitle
+%
+% \begin{abstract}
+% This file describes the \textsf{parcolumns} package that provides an
+% environment for typesetting text in two or more columns columns in
+% parallel.
+%
+% \end{abstract}
+%
+% \tableofcontents
+%
+% \section{Introduction}
+%
+% Sometimes it is necessary to typeset text in two or more columns in
+% parallel, i.e. when typesetting a text in its original language and
+% in its translation(s). This package provides the \verb|parcolumns|
+% environment for typesetting text in several columns, where the text
+% of all columns is aligned vertically.
+%
+% Text in the |parcolums| environment is typeset in chunks, where the
+% chunks of one row are aligned vertically. A chunk consists of one or
+% more paragraphs of text, including \TeX\ macros.
+%
+%
+% \section{Usage}\label{sec:Usage}
+%
+% \DescribeEnv{parcolumns} Usage: |parcolumns| \oarg{options}
+% \marg{number of colums}.
+%
+% Inside the |parcolumns| environment text can be typeset in two or
+% more columns in parallel via the |\parchunk| macro. Normal text can
+% also be included.
+%
+% The \verb|parcolumns| environment takes an optional parameter that
+% specifies the options for the environment using the \textsf{keyval}
+% and \textsf{processkv} packages. The following options exist:
+%
+% \begin{description}
+% \item[\emph{colwidths}] Sets the widths of the columns. The
+% widths are specified as key-values,
+% \meta{columnnumber}=\meta{width}.
+% Columns start at `1'. Note that in
+% order to be ignored by the
+% \textsf{keyval} package, the complete
+% value has to be surrounded by braces,
+% i.e. `|colwidths={1=2cm,3=5cm,4=2cm}|'
+% to set the first column to a width of
+% 2~cm, the third to 5~cm and the fourth
+% to 2~cm. (the second column is
+% calculated)
+%
+% Columns not set this way will be
+% distributed evenly across the remaining
+% horizontal space of the page.
+%
+% \item[distance] Sets the distance between two columns.
+% If omitted set to \verb|2em|.
+%
+% \item[rulebetween] (Flag)\footnote{Meaning that if you
+% just say \texttt{rulebetween}, you set the
+% flag, as well as when you say
+% \texttt{rulebetween=true}. Saying
+% \texttt{rulebetween=false} clears the flag,
+% even though this does not make much sense,
+% as it is the default.}
+% Typeset a vertical bar between two
+% columns.
+%
+% |false| if omitted.
+%
+% \item[nofirstindent] (Flag) Suppress the indentation of the first
+% paragraph in the environment.
+%
+% |false| if omitted.
+%
+% \item[sloppy] (Flag) Typeset text in the columns in a
+% more sloppy way, preventing overfull
+% hboxes at the cost of larger
+% interword spacing.
+%
+% |false| if omitted.
+%
+% \item[sloppyspaces] (Flag) Makes spaces in the columns
+% stretchable, preventing overfull
+% hboxes at the cost of even larger
+% interword spacing that |sloppy|.
+%
+% |false| if omitted.
+%
+% \end{description}
+%
+%
+% \DescribeMacro{\colchunk} Usage: |\colchunk| \oarg{column}
+% \marg{chunk}.
+%
+% The macro |\colchunk| sets a chunk of text for the next column. You
+% don't have to set chunks for all columns; the colums not set remain
+% empty. However, the columns are filled from left to right, so if a
+% column inbetween should remain empty, you must say |\colchunk{}| or
+% specify the column to set using the optional parameter (columns
+% start at 1): |\colchunk[2]{|\ldots|}| sets the text of the second
+% column. Following calls to |\colchunk| without optional parameter
+% fill the third, fourth et cetera column.
+%
+% After a call to |\colplacechunks|, the column number is reset to
+% one.
+%
+%
+%
+% \DescribeMacro{\colplacechunks} Usage: |\colplacechunks|.
+%
+% The macro |\colplacechunks| places the chunks added with |\colchunk|
+% on the page. If there are no chunks to place, it does nothing.
+%
+%
+%
+% \section{Examples}
+%
+% Two columns, option |rulebetween=true| (which is the same as
+% just saying |rulebetween|):
+%
+% \addvspace{\baselineskip}
+% \begin{parcolumns}[rulebetween=true]{2}
+% \colchunk{Erwarten Sie von mir, dass ich rede? -- Nein, Mister
+% Bond, ich erwarte von Ihnen, dass Sie sterben!}
+%
+% \colchunk{Do you expect me to talk? -- No, Mister Bond, I expect you
+% to die!}
+%
+% \colplacechunks
+%
+% \colchunk{Erwarten Sie von mir, dass ich rede? -- Nein, Mister
+% Bond, ich erwarte von Ihnen, dass Sie sterben!}
+%
+% \colchunk{Do you expect me to talk? -- No, Mister Bond, I expect you
+% to die!}
+%
+% \colplacechunks
+%
+% \end{parcolumns}
+% \addvspace{\baselineskip}
+% As the german text is slightly longer, let's make the left column
+% alittle bit larger using |colwidths={1=.55\linewidth}|:
+%
+% \addvspace{\baselineskip}
+% \begin{parcolumns}[rulebetween=true,colwidths={1=.55\linewidth}]{2}
+% \colchunk{Erwarten Sie von mir, dass ich rede? -- Nein, Mister
+% Bond, ich erwarte von Ihnen, dass Sie sterben!}
+%
+% \colchunk{Do you expect me to talk? -- No, Mister Bond, I expect you
+% to die!}
+%
+% \colplacechunks
+%
+% \colchunk{Erwarten Sie von mir, dass ich rede? -- Nein, Mister
+% Bond, ich erwarte von Ihnen, dass Sie sterben!}
+%
+% \colchunk{Do you expect me to talk? -- No, Mister Bond, I expect you
+% to die!}
+%
+% \colplacechunks
+%
+% \end{parcolumns}
+% \addvspace{\baselineskip}
+% Three columns, option |nofirstindent=true|:
+%
+% \addvspace{\baselineskip}
+% \begin{parcolumns}[nofirstindent]{3}
+% \colchunk{This is just a short english text, just long enough to fill
+% a few lines.}
+%
+% \colchunk{Dies ist nur ein kurzer deutscher Text, gerade lang genug,
+% um ein paar Zeilen zu fuellen.}
+%
+% \colchunk{This is another short english text, as my french is not
+% that good anymore.}
+%
+% \colplacechunks
+%
+% \end{parcolumns}
+% \addvspace{\baselineskip}
+% There was an overfull |\hbox| in the previous text. Let's
+% try that again with the option |sloppy|:
+%
+% \addvspace{\baselineskip}
+% \begin{parcolumns}[nofirstindent,sloppy]{3}
+% \colchunk{This is just a short english text, just long enough to fill
+% a few lines.}
+%
+% \colchunk{Dies ist nur ein kurzer deutscher Text, gerade lang genug,
+% um ein paar Zeilen zu fuellen.}
+%
+% \colchunk{This is another short english text, as my french is not
+% that good anymore.}
+%
+% \colplacechunks
+%
+% \end{parcolumns}
+% \addvspace{\baselineskip}
+% No overfull hbox this time, but the spacing in the first column
+% is not optimal. You just have to pick what's better. Or you could
+% try the interword spacing provided by the \textsf{soul} package.
+%
+% \addvspace{\baselineskip}\noindent Maybe we do not want to fill the
+% first column, but do not want to type |\colchunk{}| either. Then we
+% can say |\colchunk[2]| to directly start with the second column
+% (note that we are using the option |sloppy|, too):
+%
+% \addvspace{\baselineskip}
+% \begin{parcolumns}[nofirstindent,sloppy]{3}
+% \colchunk[2]{This is just a short english text, just long enough to fill
+% a few lines.}
+%
+% \colchunk{Dies ist nur ein kurzer deutscher Text, gerade lang genug,
+% um ein paar Zeilen zu fuellen.}
+%
+% \colplacechunks
+%
+% \end{parcolumns}
+% \addvspace{\baselineskip}
+% Note that \texttt{parcolumns} does not insert vertical space
+% before or after the environment! In these examples, the space has
+% manually been added with |\addvspace|.
+%
+%
+%
+% \section{Notes}\label{sec:Notes}
+%
+% \begin{itemize}
+% \item The columns will always fill the complete width of the
+% page by stretching or shrinking the space between the columns.
+% That means that if the total width of all columns is set
+% to about half the page width, the space between the columns
+% will take up the rest, ignoring whatever was set with the
+% key |distance|.\footnote{The key \texttt{distance} is only
+% used for calculating the width of the columns and is ignored
+% afterwards.}
+%
+% \item Footnotes are not set in columns.
+%
+% \item \textsf{parcolumns} does not work very well with displayed
+% formula. The best way to typeset a |displaymath| et.al.
+% environment is to include it in separate |\colchunk|
+% commands, i.e. (assuming two columns and the same formula
+% in both):
+%
+% \begin{verbatim}
+% ... some text placed using \colchunk ...
+% \colchunk{ % Left column
+% \begin{displaymath}
+% x^2 + y^2 = z^2
+% \end{displaymath}
+% }
+% \colchunk{ % Right column
+% \begin{displaymath}
+% x^2 + y^2 = z^2
+% \end{displaymath}
+% }
+% \colplacechunks
+% ... some more text placed using \colchunk ...
+% \end{verbatim}
+%
+% \end{itemize}
+%
+%
+%
+% \StopEventually{}
+%
+% \section{Implementation}
+%
+% \subsection{Allocation}
+%
+% The current column (starting with one):
+%
+% \begin{macrocode}
+\newcount\pc@columnctr
+% \end{macrocode}
+%
+% The total number of columns in the current |parcolums| environment.
+%
+% \begin{macrocode}
+\newcount\pc@columncount
+% \end{macrocode}
+%
+% Place a vertical rule between two columns?
+%
+% \begin{macrocode}
+\newif\ifpc@rulebetween
+% \end{macrocode}
+%
+% Stores |\everypar| for use in |\parparagraphs|.
+%
+% \begin{macrocode}
+\newtoks\pc@everypar
+% \end{macrocode}
+%
+% Note that additional allocations are performed later on-demand in
+% |\pc@alloccolumns|.
+%
+%
+%
+% \subsection{\textsf{keyvalue} keys}
+%
+% \begin{macro}{\pc@boolkey}
+%
+% Sets an \verb|if|-condition in \marg{\#1} to the value passed as
+% \marg{\#2}. If \verb|#2| is \verb|false|, set \verb|if#1| to
+% \verb|false|, else (any other value) to \verb|true|.
+%
+% Usage: |\pc@boolkey| \marg{ifcondition} \marg{value}
+%
+% \begin{macrocode}
+\def\pc@boolkey#1#2{%
+ \edef\@tempa{#2}%
+ \edef\@tempb{false}%
+ \ifx\@tempa\@tempb%
+ \csname #1false\endcsname%
+ \else%
+ \csname #1true\endcsname%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% Define the keys for the options of |parcolumns|.
+%
+% \begin{macrocode}
+\define@key{parcolumns}{distance}{%
+ \@tempdimc#1\relax%
+}
+\define@key{parcolumns}{rulebetween}[true]{%
+ \pc@boolkey{pc@rulebetween}{#1}%
+}
+\define@key{parcolumns}{nofirstindent}[true]{%
+ \pc@boolkey{@tempswa}{#1}%
+% \end{macrocode}
+%
+% If the indentation of the first line of the first paragraph should
+% be suppressed, change |\pc@everypar| accordingly. The token register
+% is reset after the placing of the first row of chunks in
+% |\colplacechunks|.
+%
+% What exactly are we doing? First we assign box 0 the contents of
+% |\lastbox|. At the beginning of a paragraph |\lastbox| contains
+% the glue inserted for the indentation of the first line. By
+% assigning this box to box 0, we remove the indentation. We do
+% this in a group as not to change the contents of box 0.
+%
+% Afterwards we set |\everypar| to nothing. This is necessary because
+% we only want to suppress the indentation for the first paragraph of
+% the |parcolumns| environment, not every paragraph. We set
+% |\everypar| and not |\pc@everypar| to nothing, because
+% |\pc@everypar| is only a temporary storage that will be assigned to
+% |\everypar| when used.
+%
+% \begin{macrocode}
+ \if@tempswa\pc@everypar{{\setbox\z@\lastbox}\everypar{}}\fi%
+}
+\define@key{parcolumns}{sloppy}[true]{%
+ \pc@boolkey{@tempswa}{#1}%
+% \end{macrocode}
+%
+% If sloppy typesetting is asked for, we set |\hbadness| and
+% |\tolerance| to 10000, so that \TeX\ breaks lines whenever possible,
+% even if this means high interword spacing.
+%
+% \begin{macrocode}
+ \if@tempswa%
+ \hbadness\@M%
+ \tolerance\@M%
+ \fi%
+}
+\define@key{parcolumns}{sloppyspaces}[true]{%
+ \pc@boolkey{@tempswa}{#1}%
+% \end{macrocode}
+%
+% If sloppy spaces are asked for, we make the space stretchable:
+%
+% \begin{macrocode}
+ \if@tempswa%
+ \spaceskip.3333em\@plus1em %
+ \fi%
+}
+% \end{macrocode}
+%
+%
+% We save the key-value-list containing widths of the columns in
+% |\toks@| for later use in |\pc@setcolumnwidths|.
+%
+% \begin{macrocode}
+\define@key{parcolumns}{colwidths}{%
+ \toks@{#1}%
+}
+% \end{macrocode}
+%
+%
+% \subsection{Main environments and macros}
+%
+% \begin{environment}{parcolumns}
+%
+% Environment for a number of columns of text set in parallel (see
+% section \ref{sec:Usage} on page \pageref{sec:Usage} for the possible
+% options)
+%
+% Usage: |\begin{parcolumns}| \oarg{options} \marg{number of columns}
+% \ldots\ |\end{parcolums}|
+%
+% \begin{macrocode}
+\newenvironment{parcolumns}[2][]{%
+ \pc@rulebetweenfalse%
+% \end{macrocode}
+%
+% |\if@tempswa| is |true|, if the indentation of the first line
+% should be suppressed, otherwise |false|. Default is |false|:
+%
+% \begin{macrocode}
+ \@tempswafalse%
+% \end{macrocode}
+%
+% |\@tempdimc| contains the space between two columns. Default
+% is |2em|:
+%
+% \begin{macrocode}
+ \@tempdimc2em\relax%
+% \end{macrocode}
+%
+% We set the options:
+%
+% \begin{macrocode}
+ \toks@{}%
+ \setkeys{parcolumns}{#1}%
+% \end{macrocode}
+%
+% We store the total number of columns and reset the counter for
+% the current column:
+%
+% \begin{macrocode}
+ \pc@columncount#2 %
+ \pc@columnctr\z@%
+% \end{macrocode}
+%
+% We allocate the columns and set their widths:
+%
+% \begin{macrocode}
+ \pc@alloccolumns%
+ \pc@setcolumnwidths%
+% \end{macrocode}
+%
+% We switch to vertical mode:
+%
+% \begin{macrocode}
+ \endgraf%
+% \end{macrocode}
+%
+% As we are changing |\everypar|, we need to make sure that the most
+% important flag is reset, which normally happens in the |\everypar|
+% of a |\section|-command: |\if@nobreak|. (otherwise the next section
+% is typeset directly after the text of the previous section instead
+% of leaving some space)\footnote{I discovered this the hard way,
+% spending one or two hours wondering why the spacing between two
+% sections was much too small.}
+%
+% \begin{macrocode}
+ \@nobreakfalse%
+% \end{macrocode}
+%
+% We reset |\everypar|, as it is of no use for us and can only screw
+% up things badly:
+%
+% \begin{macrocode}
+ \global\everypar{}%
+}{%
+% \end{macrocode}
+%
+% At the end of the |parcolumns|-environment \ldots\ just in case, we
+% place the last chunks, if not already done so:
+%
+% \begin{macrocode}
+ \colplacechunks%
+ \endgraf%
+% \end{macrocode}
+%
+% We reset |\clubpenalty| globally to its normal value (the |\global|
+% makes sure that if |\everypar| should have reset |\clubpenalty|, it
+% is reset now).
+%
+% \begin{macrocode}
+ \global\clubpenalty\@clubpenalty%
+% \end{macrocode}
+%
+% We suppress the indentation of the next paragraph immediately
+% following the environment:
+%
+% \begin{macrocode}
+ \@doendpe%
+}
+% \end{macrocode}
+% \end{environment}
+%
+%
+% \begin{macro}{\colchunk}
+%
+% Sets the text for the next chunk of the next column.
+%
+% Usage: |\colchunk| \oarg{column} \marg{chunk}. (note that the |{|
+% and |}| are \emph{not} optional, even if the chunk consists of only
+% one token!)
+%
+% We need two macros for handling the optional parameter
+% \meta{column}, |\colchunk| and |\colchunk@|. First we define
+% |\colchunk|:
+%
+% \changes{1.1}{2004/08/22}{Optional parameter added.}
+%
+% \begin{macrocode}
+\newcommand{\colchunk}{\@testopt\colchunk@{}}%
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\colchunk@}
+%
+% What are we doing now? By suffixing the last (optional) parameter by
+% |#|, we tell \TeX\ that the last parameter of |\colchunk| is to be
+% delimited by a right brace |{|, or \TeX\ will complain with a more
+% comprehensible message that without the |#|: `Use of |\colchunk|
+% doesn't match its definition.' instead of `Missing |{| inserted.'
+%
+% \changes{1.0.1}{2004/08/10}{Parameter added.}
+% \changes{1.1}{2004/08/22}{Optional parameter added.}
+%
+% \begin{macrocode}
+\long\def\colchunk@[#1]#{%
+% \end{macrocode}
+%
+% We check if the optional parameter is not empty. Then we use it as
+% the column number, otherwise we simply pick the next column:
+%
+% \begin{macrocode}
+ \ifx\\#1\\%
+ \advance\pc@columnctr\@ne%
+ \else%
+ \pc@columnctr#1\relax%
+ \fi%
+% \end{macrocode}
+%
+% If we try to add a column past the last one, we display an error
+% message:
+%
+% \begin{macrocode}
+ \ifnum\pc@columnctr>\pc@columncount%
+ \PackageError{parcolumns}{The column \number\pc@columnctr\space%
+ is too large}{Only \number\pc@columncount\space columns are%
+ \space allowed.}
+% \end{macrocode}
+%
+% As we cannot simply skip the chunk (we could gobble what follows
+% after the macro, but this would require a lot of jumping, and just
+% for handling a small mistake \ldots), we simply set the last column:
+%
+% \changes{1.0.1}{2004/08/10}{Error handling somewhat improved.}
+%
+% \begin{macrocode}
+ \pc@columnctr\pc@columncount%
+ \fi%
+% \end{macrocode}
+%
+% We zero the |\clubpenalty| that could have been changed, i.e. by
+% |\everypar| of a |\section|-command: |\section| changes the
+% clubpenalty to prevent a break between the first two lines of the
+% paragraph following immediately after the section; as we split off
+% line after line when typesetting the two columns, this would make
+% splitting of a single line impossible (|\vsplit| uses the same logic
+% as page-breaking), thus resulting in a lot of overfull vboxes and
+% weird spacing inbetween, as \emph{two} lines would be split off.
+%
+% We do this every time we add chunks just in case some macro in the
+% chunks has changed |\clubpenalty|. Note that we cannot prevent a
+% macro in the text of the chunk to change the
+% |\clubpenalty|.\footnote{Well we could, by redefining the
+% clubpenalty to be a macro that simply throws its parameter away, and
+% using some tricks to make this macro behave like a register,
+% therefore completely ignoring any change of the clubpenalty.} But if
+% it is changed, at least it will not stay changed (though the typeset
+% columns will still look bad).
+%
+% \changes{1.0.1}{2004/08/09}{clubpenalty is always reset before
+% adding chunks}
+%
+% \begin{macrocode}
+ \clubpenalty\z@%
+% \end{macrocode}
+%
+% The same goes for the other penalties \TeX\ will insert between two
+% lines, as we absolutely, positively \emph{must} be able to break
+% between any two lines:\footnote{C.f. chapter 14 of the \TeX book}
+%
+% \changes{1.2}{2004/11/25}{other penalties added}
+%
+% \begin{macrocode}
+ \interlinepenalty\z@%
+ \displaywidowpenalty\z@%
+ \widowpenalty\z@%
+ \brokenpenalty\z@%
+% \end{macrocode}
+%
+% We set |\everypar| to our self-defined |\pc@everypar| to suppress
+% the indentation of the first paragraph if so desired:
+%
+% \begin{macrocode}
+ \everypar\expandafter{\the\pc@everypar}%
+% \end{macrocode}
+%
+% After the next assignment, insert the width of the column:
+%
+% \begin{macrocode}
+ \afterassignment\pc@setcolumnwidth%
+% \end{macrocode}
+%
+% We typeset the chunk's text into the box |\pc@column@|\meta{column
+% counter}. The text of the chunk follows the macro, meaning that the
+% last line looks like this: |\vbox{|\meta{chunk text}|}|.
+%
+% But what about the width of the box? |\hsize| must be set in the
+% vbox in order to make it the correct width! We achieve this using
+% the |\afterassignment| above: After the assignment of the chunk's
+% text to the box, we are inside the box, therefore the contents of
+% |\pc@setcolumnwidth| is inserted at the very beginning of the vbox,
+% setting the correct width.
+%
+% Why don't we simply make |\colchunk| take one parameter that
+% contains the text of the chunk? Because in that case, macros that
+% change catcodes like |\verb| would be prohibited, which would
+% restrict this package somewhat. Also it would be slower and would
+% use more memory.
+%
+% \begin{macrocode}
+ \expandafter\setbox\csname pc@column@\number\pc@columnctr\endcsname%
+ \vbox%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\colplacechunks}
+%
+% Places all chunks set with |\colchunk|.
+%
+% \begin{macrocode}
+\newcommand{\colplacechunks}{%
+% \end{macrocode}
+%
+% If there are any chunks to place:
+%
+% \begin{macrocode}
+ \ifnum\pc@columnctr>\z@%
+% \end{macrocode}
+%
+% We place them:
+%
+% \begin{macrocode}
+ \pc@placeboxes%
+% \end{macrocode}
+%
+% We reset the column counter:
+%
+% \begin{macrocode}
+ \pc@columnctr\z@%
+% \end{macrocode}
+%
+% We clear |\pc@everypar|, because we only want to suppress the
+% indentation of the first paragraph of each column at the very top of
+% the |parcolumns| environment, not of the first paragraph of every
+% call to |\colchunk|.
+%
+% \begin{macrocode}
+ \pc@everypar{}%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+% \subsection{Internal environments and macros}
+%
+% \begin{macro}{\pc@placeboxes}
+%
+% Places the prepared boxes (containing the chunks) on the page.
+%
+% \begin{macrocode}
+\def\pc@placeboxes{%
+% \end{macrocode}
+%
+% We assume we don't have to perform another line (|\@tempa| contains
+% what we have to to after we are finished with this macro). The
+% assignment is global because later on when changing |\@tempa| we are
+% in a group:
+%
+% \begin{macrocode}
+ \global\let\@tempa\relax%
+ \count@\z@%
+% \end{macrocode}
+%
+% We create a hbox. Inside a hbox, vboxes are put horizontally
+% next to each other and are aligned on their baseline:
+%
+% \begin{macrocode}
+ \hb@xt@\linewidth{%
+% \end{macrocode}
+%
+% Before doing any work, we change a few parameters:
+%
+% \changes{1.2}{2004/11/22}{moved parameter changes from begin of
+% environment}
+%
+% We prevent warnings of overfull and underfull vboxes as they can
+% happen, but we do not really care (happens when we |\vsplit| the top
+% off the chunks, this is okay):
+%
+% \changes{1.2}{2004/11/22}{vfuzz increased to prevent warnings with
+% math}
+%
+% \changes{1.2}{2004/11/22}{vbadness set}
+%
+% \begin{macrocode}
+ \vfuzz30ex %
+ \vbadness\@M%
+% \end{macrocode}
+%
+% We prevent vertical glue to be insert when |vsplit|ting a vbox
+% (otherwise it screws up the spacing).
+%
+% \begin{macrocode}
+ \splittopskip\z@skip%
+% \end{macrocode}
+%
+% Now we loop over all the prepared boxes. We can use |\loop| here as
+% we are in a group (begun by |\hbox|). Otherwise we would have to
+% open a group manually or loop manually, as to not screw up a |\loop|
+% outside the macro:
+%
+% \begin{macrocode}
+ \loop\ifnum\count@<\pc@columncount%
+ \advance\count@\@ne%
+% \end{macrocode}
+%
+% If the box |\pc@column@|\meta{counter} is empty, we simply insert a
+% hskip the width of the box (saved in
+% |\pc@column@width@|\meta{counter}):
+%
+% \begin{macrocode}
+ \expandafter\ifvoid\csname pc@column@\number\count@%
+ \endcsname%
+ \hskip\csname pc@column@width@\number\count@\endcsname%
+ \else%
+% \end{macrocode}
+%
+% Otherwise we |\vsplit| the first line of the box (at the same time
+% removing it from |\pc@column@|\meta{counter}) and save it in
+% |\@tempboxa|. Then, we strip this resulting box of its enclosing
+% vbox and put it into another vbox, which we put into the hbox begun
+% a few lines ago.
+%
+% Why is this so complicated? To ensure that proper vertical glue is
+% inserted (otherwise the spacing between the lines would be wrong).
+%
+% \begin{macrocode}
+ \expandafter\setbox\expandafter\@tempboxa\expandafter%
+ \vsplit\csname pc@column@\number\count@\endcsname%
+ to \dp\strutbox%
+ \vbox{\unvbox\@tempboxa}%
+ \fi%
+% \end{macrocode}
+%
+% If the remaining box is not empty, we have to perform at least
+% another line:
+%
+% \begin{macrocode}
+ \expandafter\ifvoid\csname pc@column@\number\count@%
+ \endcsname\else%
+ \global\let\@tempa\pc@placeboxes%
+ \fi%
+% \end{macrocode}
+%
+% If this is not the last column, we put a strut into the hbox to
+% ensure propery vertical spacing:
+%
+% \begin{macrocode}
+ \ifnum\count@<\pc@columncount%
+ \strut%
+% \end{macrocode}
+%
+% If a vertical line should be placed between two columns, we insert
+% it now, centering it between two |\hfill|s. Otherwise, we simply
+% insert a |\hfill| that stretches as much as possible, pushing the
+% right column to the right margin. (see also section \ref{sec:Notes}
+% on page \pageref{sec:Notes})
+%
+% \begin{macrocode}
+ \hfill%
+ \ifpc@rulebetween%
+ \vrule%
+ \hfill%
+ \fi%
+ \fi%
+ \repeat%
+ }%
+% \end{macrocode}
+%
+% If necessary, we perform another line:
+%
+% \begin{macrocode}
+ \@tempa%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\pc@alloccolumns}
+%
+% Allocates a number of |\box|es, named |\pc@column@1|, |\pc@column@2|
+% et cetera, if not already allocated.
+%
+% Also allocates a number of |\dimen|s, named |\pc@column@width@1| et
+% cetera.
+%
+% If the |\box|es and |\dimen|s are already allocated, they are
+% cleared (|\box|es) or set to zero (|\dimen|s).
+%
+% \begin{macrocode}
+\def\pc@alloccolumns{%
+ \count@\z@%
+ \loop\ifnum\count@<\pc@columncount%
+ \advance\count@\@ne%
+ \@ifundefined{pc@column@\number\count@}{%
+ \expandafter\newbox\csname pc@column@\number\count@%
+ \endcsname%
+ \expandafter\newdimen\csname pc@column@width@\number%
+ \count@\endcsname%
+ }{%
+ \setbox0\box\csname pc@column@\number\count@\endcsname%
+ \csname pc@column@width@\number\count@\endcsname\z@%
+ }%
+ \repeat%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\pc@setcolumnwidths}
+%
+% Sets the widths of all columns. The defined widths have been
+% temporarily stored in |\toks@|. |\@tempdimc| contains the space
+% between two columns.
+%
+% \begin{macrocode}
+\def\pc@setcolumnwidths{%
+ \expandafter\processkeyvalues\expandafter{\the\toks@}%
+ \pc@setsinglecolwidth%
+% \end{macrocode}
+%
+% |\@tempdima| will contain the total width of all columns that have a
+% known width (read: have had their width set via the parameter
+% |colwidths|)
+%
+% \begin{macrocode}
+ \@tempdima\z@%
+% \end{macrocode}
+%
+% |\@tempcnta| will contain the count of columns that an unknown width
+% (read: have had their width \emph{not} set via the parameter
+% |colwidths|, thus now having a width of zero points, as the widths
+% of all columns have been reset in |\pc@alloccolumns|):
+%
+% \begin{macrocode}
+ \@tempcnta\z@%
+% \end{macrocode}
+%
+% We calculate the total width of all columns known. We count how many
+% columns have an unknown width:
+%
+% \begin{macrocode}
+ \count@\z@%
+ \loop\ifnum\count@<\pc@columncount%
+ \advance\count@\@ne%
+ \@tempdimb\csname pc@column@width@\number\count@\endcsname%
+ \advance\@tempdima\@tempdimb%
+ \ifnum\@tempdimb=\z@%
+ \advance\@tempcnta\@ne%
+ \else%
+ \PackageInfo{parcolumns}{Width of column \number\count@%
+ \space set to \the\@tempdimb}
+ \fi%
+ \repeat%
+% \end{macrocode}
+%
+% If at least one column has an unknown width:
+%
+% \begin{macrocode}
+ \ifnum\@tempcnta>\z@%
+% \end{macrocode}
+%
+% |\@tempdimc| contains the distance between columns. We calculate the
+% space left for the columns with an unknown width.
+%
+% |\@tempdimb| will contain the sum of the space between all the
+% columns \ldots
+%
+% \begin{macrocode}
+ \@tempdimb\@tempdimc%
+ \multiply\@tempdimb\pc@columncount%
+ \advance\@tempdimb-\@tempdimc%
+% \end{macrocode}
+%
+% \ldots\ plus the sum of the width of all columns with a known width:
+%
+% \begin{macrocode}
+ \advance\@tempdimb\@tempdima%
+% \end{macrocode}
+%
+% |\@tempdima| will contain the space for each column with an unknown
+% width:
+%
+% \begin{macrocode}
+ \@tempdima\linewidth%
+ \advance\@tempdima-\@tempdimb%
+ \divide\@tempdima\@tempcnta%
+% \end{macrocode}
+%
+% We set the widths of the colums with an unknown width:
+%
+% \begin{macrocode}
+ \count@\z@%
+ \loop\ifnum\count@<\pc@columncount%
+ \advance\count@\@ne%
+ \ifnum\csname pc@column@width@\number\count@\endcsname=\z@%
+ \csname pc@column@width@\number\count@\endcsname\@tempdima%
+ \PackageInfo{parcolumns}{Width of column \number\count@%
+ \space calculated as \the\@tempdima}
+ \fi%
+ \repeat%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\pc@setsinglecolwidth}
+%
+% Usage: |\pc@setsinglecolwidth| \marg{column} \marg{width}.
+%
+% Sets the width of the column \meta{column} to the width
+% \meta{width}. Displays an error message if the column is not valid.
+%
+% \begin{macrocode}
+\def\pc@setsinglecolwidth#1#2{%
+ \@ifundefined{pc@column@width@\number#1}{
+ \PackageError{parcolumns}{`#1' is not a valid column number!}%
+ {\@ehc}%
+ }{%
+ \csname pc@column@width@\number#1\endcsname=#2\relax%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\pc@setcolumnwidth}
+%
+% Sets |\hsize| to the width of a column (stored in
+% |\pc@column@width@|\meta{pc@columnctr}) and enters horizonal mode.
+%
+% \changes{1.2}{2004/11/22}{linewidth set, too}
+%
+% \begin{macrocode}
+\def\pc@setcolumnwidth{%
+ \hsize\csname pc@column@width@\number\pc@columnctr\endcsname%
+ \linewidth\hsize%
+ \leavevmode%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \Finale
+% \PrintChanges
+% \PrintIndex
+\endinput \ No newline at end of file
diff --git a/macros/latex/contrib/sauerj/parcolumns.ins b/macros/latex/contrib/sauerj/parcolumns.ins
new file mode 100644
index 0000000000..a03684bd8a
--- /dev/null
+++ b/macros/latex/contrib/sauerj/parcolumns.ins
@@ -0,0 +1,19 @@
+\input docstrip
+\keepsilent
+\askforoverwritefalse
+
+\preamble
+\endpreamble
+\generate{%
+ \file{\jobname.sty}{\from{\jobname.dtx}{package}}
+}
+
+\Msg{***************************************************************}
+\Msg{*}
+\Msg{* \space To finish the installation you have to copy the files}
+\Msg{*}
+\Msg{* \space *.sty into a directory searched by TeX}
+\Msg{*}
+\Msg{***************************************************************}
+
+\endbatchfile \ No newline at end of file
diff --git a/macros/latex/contrib/sauerj/parcolumns.pdf b/macros/latex/contrib/sauerj/parcolumns.pdf
new file mode 100644
index 0000000000..c500dd4c2b
--- /dev/null
+++ b/macros/latex/contrib/sauerj/parcolumns.pdf
Binary files differ
diff --git a/macros/latex/contrib/sauerj/processkv.dtx b/macros/latex/contrib/sauerj/processkv.dtx
new file mode 100644
index 0000000000..520853917f
--- /dev/null
+++ b/macros/latex/contrib/sauerj/processkv.dtx
@@ -0,0 +1,199 @@
+% \iffalse meta-comment
+% Line endings: UNIX
+% Tab size: 4
+%
+% Copyright 2004 Jonathan Sauer
+%
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3
+% 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.3 or later is part of all distributions of LaTeX
+% version 2003/12/01 or later.
+%
+% This work has the LPPL maintenance status "maintained".
+%
+% The Current Maintainer of this work is Jonathan Sauer
+% (<jonathan.sauer@gmx.de>).
+%
+% This work consists of the files processkv.dtx and processkv.ins and
+% the derived file processkv.sty.
+%
+% This work is based on the package keyval.
+%
+% \fi
+%
+% \iffalse
+%
+%<*driver>
+\documentclass{ltxdoc}
+\IfFileExists{processkv.sty}{\usepackage{processkv}}{}
+\EnableCrossrefs
+\CodelineIndex
+\RecordChanges
+% Modification of verbatim for tabs in listings
+\makeatletter
+{\catcode`\ =\active%
+\catcode`\^^I=\active%
+\gdef\@vobeyspaces{%
+\catcode`\ \active\let \@xobeysp%
+\catcode`\^^I\active\def^^I{~~}%
+}}%
+\makeatother
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+%
+%<package>\NeedsTeXFormat{LaTeX2e}
+%<package>\ProvidesPackage{processkv}
+%<package> [2004/08/09 v1.0.1 process key=value lists]
+%<package>\RequirePackage{keyval}[1999/03/16]
+%
+% \fi
+%
+% \CheckSum{41}
+% \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{\@empty,\@tempa,\@tempb,\def,\else,\empty,\expandafter}
+% \DoNotIndex{\fi,\ifx,\relax}
+%
+% \changes{1.0.1}{2004/08/09}{Mangled macronames corrected.}
+%
+% \GetFileInfo{\jobname.sty}
+%
+% \title{The \textsf{processkv} package\thanks{This document
+% corresponds to \textsf{\filename}~\fileversion, dated \filedate.}}
+%
+% \author{Jonathan Sauer \\ \texttt{jonathan.sauer@gmx.de}}
+%
+% \date{\filedate}
+%
+% \maketitle
+%
+% \begin{abstract}
+% This file describes the \textsf{processkv} package that provides
+% macros for processing of key-value-lists by calling a user-defined
+% macro for each key-value-pair.
+%
+% \end{abstract}
+%
+% \tableofcontents
+%
+% \section{Introduction}
+%
+% The \textsf{keyval} package provides the possibility of specifying
+% macro arguments as |key=value|, where |key| is one of previously
+% defined keys. Sometimes it is necessary not to have to define the
+% keys in advance, but to specify arbitrary keys which are then
+% processed.
+%
+% This package provides the macro |\processkeyvalues| that calls a
+% user-defined macro for each key-value-pair.
+%
+% This package makes use of some internal macros of the package
+% \textsf{keyval}. I hope this will not break someday \ldots
+%
+%
+% \section{Using the package}
+%
+% \DescribeMacro{\processkeyvalues} Usage: |\processkeyvalues|
+% \marg{keyvalue-list} \marg{macro}.
+%
+% The main macro of this package. It calls \meta{macro} for each
+% key-value-pair in \meta{keyvalue-list}. Macros in the list are not
+% expanded.
+%
+% \meta{macro} can be any macro with two parameters, i.e:
+%
+% \begin{verbatim}
+% \def\testmacro#1#2{%
+% \message{Key = `#1', value = `#2'}%
+% }
+% \end{verbatim}
+% Or
+%
+% \begin{verbatim}
+% \newcommand{\testmacro}[2]{%
+% \message{Key = `#1', value = `#2'}%
+% }
+% \end{verbatim}
+%
+%
+% \StopEventually{}
+%
+% \section{Implementation}
+%
+% \subsection{Main macros}
+%
+% \begin{macro}{\processkeyvalues}
+%
+% Usage: |\processkeyvalues| \marg{keyvalue-list} \marg{macro}.
+%
+% Calls \meta{macro} for each key-value-pair in the list. \meta{macro}
+% must have two parameters, \meta{key} and \meta{value}.
+%
+% \begin{macrocode}
+\def\processkeyvalues#1#2{%
+ \def\PKV@process{#2}%
+ \PKV@do#1,\relax,%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{Internal macros}
+%
+% \begin{macro}{\PKV@do}
+%
+% Processes the list.
+%
+% \begin{macrocode}
+\def\PKV@do#1,{%
+ \ifx\relax#1\empty\else%
+ \PKV@split#1==\relax%
+ \expandafter\PKV@do\fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\PKV@split}
+%
+% Processes a key-value-pair of the list. Uses some macros of the
+% \textsf{keyval} package.
+%
+% \begin{macrocode}
+\def\PKV@split#1=#2=#3\relax{%
+ \KV@@sp@def\@tempa{#1}%
+ \ifx\@tempa\@empty\else%
+ \KV@@sp@def\@tempb{#2}%
+ \expandafter\expandafter\expandafter\PKV@process%
+ \expandafter\expandafter\expandafter{\expandafter\@tempa%
+ \expandafter}\expandafter{\@tempb}%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \Finale
+% \PrintChanges
+% \PrintIndex
+\endinput \ No newline at end of file
diff --git a/macros/latex/contrib/sauerj/processkv.ins b/macros/latex/contrib/sauerj/processkv.ins
new file mode 100644
index 0000000000..a03684bd8a
--- /dev/null
+++ b/macros/latex/contrib/sauerj/processkv.ins
@@ -0,0 +1,19 @@
+\input docstrip
+\keepsilent
+\askforoverwritefalse
+
+\preamble
+\endpreamble
+\generate{%
+ \file{\jobname.sty}{\from{\jobname.dtx}{package}}
+}
+
+\Msg{***************************************************************}
+\Msg{*}
+\Msg{* \space To finish the installation you have to copy the files}
+\Msg{*}
+\Msg{* \space *.sty into a directory searched by TeX}
+\Msg{*}
+\Msg{***************************************************************}
+
+\endbatchfile \ No newline at end of file
diff --git a/macros/latex/contrib/sauerj/processkv.pdf b/macros/latex/contrib/sauerj/processkv.pdf
new file mode 100644
index 0000000000..c85bb6b52a
--- /dev/null
+++ b/macros/latex/contrib/sauerj/processkv.pdf
Binary files differ
diff --git a/macros/latex/contrib/sauerj/zahl2string.dtx b/macros/latex/contrib/sauerj/zahl2string.dtx
new file mode 100644
index 0000000000..c332c1d087
--- /dev/null
+++ b/macros/latex/contrib/sauerj/zahl2string.dtx
@@ -0,0 +1,1044 @@
+% \iffalse meta-comment
+% Line endings: UNIX
+% Tab size: 4
+%
+% Copyright 2004 Jonathan Sauer
+%
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3
+% 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.3 or later is part of all distributions of LaTeX
+% version 2003/12/01 or later.
+%
+% This work has the LPPL maintenance status "maintained".
+%
+% The Current Maintainer of this work is Jonathan Sauer
+% (<jonathan.sauer@gmx.de>).
+%
+% This work consists of the files zahl2string.dtx and zahl2string.ins
+% and the derived file zahl2string.sty.
+%
+% \fi
+%
+% \iffalse
+%
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage{zahl2string}
+\EnableCrossrefs
+\CodelineIndex
+\RecordChanges
+% Modification of verbatim for tabs in listings
+\makeatletter
+{\catcode`\ =\active%
+\catcode`\^^I=\active%
+\gdef\@vobeyspaces{%
+\catcode`\ \active\let \@xobeysp%
+\catcode`\^^I\active\def^^I{~~}%
+}}%
+\makeatother
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+%
+%<package>\NeedsTeXFormat{LaTeX2e}
+%<package>\ProvidesPackage{zahl2string}
+%<package> [2004/11/25 v1.2.1 format a number as german words]
+%
+% \fi
+%
+% \CheckSum{331}
+% \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{\",\@empty,\@M,\@m,\@tempa,\csname,\DeclareOption}
+% \DoNotIndex{\DeclareRobustCommand,\def}
+% \DoNotIndex{\else,\endcsname,\expandafter,\fi,\if,\ifcase}
+% \DoNotIndex{\ifnum,\let,\MakeUppercase,\newcommand,\number,\or}
+% \DoNotIndex{\PackageError,\PackageWarning,\ProcessOptions}
+% \DoNotIndex{\protected@edef,\relax,\space,\ss,\string,\z@}
+% \DoNotIndex{\@ne,\@nil,\-}
+%
+% \GetFileInfo{\jobname.sty}
+%
+% \changes{1.1}{2004/08/08}{Range expanded to 999,999,999.}
+% \changes{1.2.1}{2004/10/20}{@Numstring and @Ordstring made robust.}
+%
+% \title{The \textsf{zahl2string} package\thanks{This document
+% corresponds to \textsf{\filename}~\fileversion, dated \filedate.}}
+%
+% \author{Jonathan Sauer \\ \texttt{jonathan.sauer@gmx.de}}
+%
+% \date{\filedate}
+%
+% \maketitle
+%
+% \begin{abstract}
+% This file describes the \textsf{zahl2string} package that provides
+% macros for formatting numbers as german words, i.e. `1' gets
+% formatted as `eins'.
+%
+% \end{abstract}
+%
+% \tableofcontents
+%
+% \section{Introduction}
+%
+% Sometimes, for example when formatting a chapter title, you do not
+% want to say `Kapitel 1' (`Chapter 1') but `Kapitel eins' (`Chapter
+% one') or `Erstes Kapitel' (`First chapter'). This package provides
+% macros to format a \LaTeX-counter or more generally speaking a
+% number as a german word.
+%
+%
+% \section{Description of the macros}
+%
+% All macros format numbers in the range 0 to 999,999,999. Larger
+% numbers are formatted as an arabic number, smaller numbers are
+% formatted as zero. This can be changed using the package options
+% described on page \pageref{sec:Options}.
+%
+% \subsection{\LaTeX\ macros}
+%
+% The four macros |\numstring|, |\Numstring|, |\ordstring| and
+% |\Ordstring| are macros taking a \LaTeX-counter as their only
+% argument.
+%
+% \DescribeMacro{\numstring} Usage: |\numstring| \marg{LaTeX counter}.
+%
+% Formats a \LaTeX\ counter in the range of 0 to 999,999,999 as a
+% word.
+%
+% \DescribeMacro{\Numstring} Usage: |\Numstring| \marg{LaTeX counter}.
+%
+% Formats a \LaTeX\ counter in the range of 0 to 999,999,999 as words,
+% where the first letter is a capital letter.
+%
+% \DescribeMacro{\ordstring} Usage: |\ordstring| \marg{LaTeX counter}.
+%
+% Formats a \LaTeX\ counter in the range of 0 to 999,999,999 as an ordinal
+% word.
+%
+% \DescribeMacro{\Ordstring} Usage: |\Ordstring| \marg{LaTeX counter}.
+%
+% Formats a \LaTeX\ counter in the range of 0 to 999,999,999 as an ordinal
+% word, where the first letter is a capital letter.
+%
+%
+%
+% \subsection{General macros}
+%
+% The four macros |\@numstring|, |\@Numstring|, |\@ordstring| and
+% |\@Ordstring| as well as their aliases |\numstr|, |\Numstr|,
+% |\ordstr| and |\Ordstr| are macros taking a number or a \TeX\ count
+% register as their only argument.
+%
+% \DescribeMacro{\@numstring} \DescribeMacro{\numstr} Usage:
+% |\@numstring| \marg{number} / |\numstr| \marg{number}.
+%
+% Formats a number or a \TeX\ count register in the range of 0 to
+% 999,999,999 as words.
+%
+% \DescribeMacro{\@Numstring} \DescribeMacro{\Numstr} Usage:
+% |\@Numstring| \marg{number} / |\Numstr| \marg{number}.
+%
+% Formats a number or a \TeX\ count register in the range of 0 to
+% 999,999,999 as words, where the first letter is a capital letter.
+%
+% \DescribeMacro{\@ordstring} \DescribeMacro{\ordstr} Usage:
+% |\@ordstring| \marg{number} / |\ordstr| \marg{number}.
+%
+% Formats a number or a \TeX\ count register in the range of 0 to
+% 999,999,999 as an ordinal word.
+%
+% \DescribeMacro{\@Ordstring} \DescribeMacro{\Ordstr} Usage:
+% |\@Ordstring| \marg{number} / |\Ordstr| \marg{number}.
+%
+% Formats a number or a \TeX\ count register in the range of 0 to
+% 999,999,999 as an ordinal word, where the first letter is a capital
+% letter.
+%
+% ^^A For debugging discretionary hyphens:
+% ^^A\def\-{.\discretionary{}{}{}}
+%
+%
+%
+% \section{Examples}
+%
+% \newcommand{\zahlexamples}[1]{
+% 0 $\Longrightarrow$ #1{0}
+%
+% 7 $\Longrightarrow$ #1{7}
+%
+% 13 $\Longrightarrow$ #1{13}
+%
+% 23 $\Longrightarrow$ #1{23}
+%
+% 42 $\Longrightarrow$ #1{42}
+%
+% 99 $\Longrightarrow$ #1{99}
+%
+% 127 $\Longrightarrow$ #1{127}
+%
+% 999 $\Longrightarrow$ #1{999}
+%
+% 1000 $\Longrightarrow$ #1{1000}
+%
+% 1001 $\Longrightarrow$ #1{1001}
+%
+% 2004 $\Longrightarrow$ #1{2004}
+%
+% 2017 $\Longrightarrow$ #1{2017}
+%
+% 2029 $\Longrightarrow$ #1{2029}
+%
+% 9999 $\Longrightarrow$ #1{9999}
+%
+% 10000 $\Longrightarrow$ #1{10000}
+%
+% 101101 $\Longrightarrow$ #1{101101}
+%
+% 999999 $\Longrightarrow$ #1{999999}
+%
+% 1000000 $\Longrightarrow$ #1{1000000}
+%
+% 1234567 $\Longrightarrow$ #1{1234567}
+%
+% 123456789 $\Longrightarrow$ #1{123456789}
+%
+% 101101101 $\Longrightarrow$ #1{101101101}
+%
+% 999999999 $\Longrightarrow$ #1{999999999}
+% }
+%
+% \addvspace{\baselineskip}\noindent Some examples using |\numstring|,
+% |\numstr| and |\@numstring|:
+%
+% \zahlexamples{\numstr}
+%
+% \addvspace{\baselineskip}\noindent Some examples using |\ordstring|,
+% |\ordstr| and |\@ordstring|:
+%
+% \zahlexamples{\ordstr}
+%
+%
+% \addvspace{\baselineskip}\noindent Formatting the current page
+% number (a \LaTeX\ counter) results in: Dies ist Seite
+% \numstring{page} (|\numstring{page}|). Dies ist die \ordstring{page}
+% Seite (|\ordstring{page}|). Seite: \Numstring{page}
+% (|\Numstring{page}|). \Ordstring{page} Seite (|\Ordstring{page}|).
+%
+%
+%
+% \section{Options}\label{sec:Options}
+%
+% The package has the following option:
+%
+% \begin{description}
+% \item[showrangeerrors] If a number larger than 999,999,999
+% is to be formatted, normally the number
+% is not formatted as words, but using
+% arabic digits. This option changes this
+% behaviour to display an error instead,
+% thus notifying you when you format too
+% large a number
+%
+% \end{description}
+%
+%
+%
+% \section{Creating your own formatting}
+%
+% You can modify output of the \textsf{zahl2string} macros in a
+% limited way by providing your own macros for formatting the numbers
+% between `1' and `19. \emph{But note} that if you simply want to add
+% something to the suffix, , i.e. if you want to format numbers with
+% the suffix `tens' (`erstens', `zweitens' \ldots), then you can
+% simply say |\ordstr{|\meta{number}|}ns|, resulting in i.e.
+% `\ordstr{42}ns'.
+%
+%
+% If on the other hand you want to create a more complicated
+% formatting, then you have to do the following:
+%
+% \begin{itemize}
+% \item Create a macro for formatting the numbers `1' to `19',
+% i.e. |\my@neunzehnte|. See the predefined macros in
+% section \ref{sec:LabFor} on page \pageref{sec:LabFor},
+% |\ns@neunzehn|, |\ns@neunzehns|, |\ns@neunzehne| and
+% |\ns@neunzehnord| for examples and notes.
+%
+% This macro has one parameter, the number (up to two
+% digits, in the range of `0' to `19'. `0' must expand to the
+% generic suffix, i.e. `stens'; `19' to `19' simply format
+% the number.
+%
+% Do not forget to insert discretionary hyphens using |\-|,
+% or hyphenation will not be perfect!
+%
+% \item Create another macro you want to call, i.e. |\mynumstring|.
+% This macro takes one parameter, the number, and calls
+% |\ns@numstr| using the following parameters:
+%
+% \begin{enumerate}
+% \item The number to be formatted (the parameter to
+% |\mynumstring|).
+%
+% \item The macro for formatting numbers `1' to `19',
+% i.e. |\my@neunzehnte|.
+%
+% \item The value that represents the number zero,
+% i.e. `nulltens'.
+%
+% \item The suffix for numbers larger than 999,999,999,
+% i.e. `tens'.
+%
+% \end{enumerate}
+%
+% \item Call the macro |\mynumstring| with the number to format.
+%
+% \end{itemize}
+% If you want to create a macro to format a \LaTeX-counter, create an
+% additional macro, i.e. |\myLnumstring|, that calls |\mynumstring| by
+% saying:
+%
+% \begin{verbatim}
+% \newcommand{\myLnumstring}[1]{%
+% \expandafter\mynumstring\csname c@#1\endcsname%
+% }
+% \end{verbatim}
+% See also the notes and predefined macros in section \ref{sec:LabFor}
+% on page \pageref{sec:LabFor}.
+%
+%
+%
+% \section{Notes/Limitations}
+%
+% \begin{itemize}
+%
+% \item Ordinal numbers larger than 999999 do not look that
+% good, as i.e. 1000000 gets formatted as
+% `\ordstr{1000000}' instead of `einmillionste'.
+%
+% \end{itemize}
+%
+%
+%
+% \StopEventually{}
+%
+% \section{Implementation}
+%
+% \subsection{Main macros}
+%
+%
+% \begin{macro}{\numstring}
+%
+% Usage: |\numstring| \marg{LaTeX counter}.
+%
+% Formats a \LaTeX\ counter in the range of 0 to 999,999,999 as words.
+%
+% \begin{macrocode}
+\newcommand{\numstring}[1]{%
+ \expandafter\@numstring\csname c@#1\endcsname%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\Numstring}
+%
+% Usage: |\Numstring| \marg{LaTeX counter}.
+%
+% Formats a \LaTeX\ counter in the range of 0 to 999,999,999 as words. The
+% first letter is uppercase.
+%
+% \begin{macrocode}
+\newcommand{\Numstring}[1]{%
+ \expandafter\@Numstring\csname c@#1\endcsname%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\ordstring}
+%
+% Usage: |\ordstring| \marg{LaTeX counter}.
+%
+% Formats a \LaTeX\ counter in the range of 0 to 999,999,999 as an ordinal
+% word.
+%
+% \begin{macrocode}
+\newcommand{\ordstring}[1]{%
+ \expandafter\@ordstring\csname c@#1\endcsname%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\Ordstring}
+%
+% Usage: |\Ordstring| \marg{LaTeX counter}.
+%
+% Formats a \LaTeX\ counter in the range of 0 to 999,999,999 as an ordinal
+% word. The first letter is uppercase.
+%
+% \begin{macrocode}
+\newcommand{\Ordstring}[1]{%
+ \expandafter\@Ordstring\csname c@#1\endcsname%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@numstring}
+%
+% Usage: |\@numstring| \marg{number or \TeX\ count register}.
+%
+% Formats a number or a \TeX\ count register in the range of 0 to
+% 999,999,999 as words.
+%
+% \begin{macrocode}
+\newcommand{\@numstring}[1]{%
+ \ns@numstr{#1}\ns@neunzehns{null}{}%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+%
+% \begin{macro}{\@Numstring}
+%
+% Usage: |\@Numstring| \marg{number or \TeX\ count register}.
+%
+% Formats a number or a \TeX\ count register in the range of 0 to
+% 999,999,999 as words. The first letter is uppercase.
+%
+% \begin{macrocode}
+\newcommand\@Numstring[1]{%
+ \expandafter\@@Numstring\expandafter{\number#1}%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+%
+% \begin{macro}{\@@Numstring}
+%
+% Support macro for |\@Numstring| to make |\@Numstring| robust.
+%
+% \changes{1.2.1}{2004/10/20}{Added}
+%
+% \begin{macrocode}
+\DeclareRobustCommand{\@@Numstring}[1]{%
+ \protected@edef\@tempa{\@numstring{#1}}%
+ \expandafter\MakeUppercase\@tempa%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@ordstring}
+%
+% Usage: |\@ordstring| \marg{number or \TeX\ count register}.
+%
+% Formats a number or a \TeX\ count register in the range of 0 to
+% 999,999,999 as an ordinalword, i.e. `erste', `zweite' et cetera.
+%
+% \begin{macrocode}
+\newcommand{\@ordstring}[1]{%
+ \ns@numstr{#1}\ns@neunzehnord{null\-te}{te}%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+%
+% \begin{macro}{\@Ordstring}
+%
+% Usage: |\@Ordstring| \marg{number or \TeX\ count register}.
+%
+% Formats a number or a \TeX\ count register in the range of 0 to
+% 999,999,999 as an ordinalword, i.e. `Erste', `Zweite' et cetera. The
+% first letter is uppercase.
+%
+% \begin{macrocode}
+\newcommand{\@Ordstring}[1]{%
+ \expandafter\@@Ordstring\expandafter{\number#1}%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+%
+% \begin{macro}{\@@Ordstring}
+%
+% Support macro for |\@Ordstring| to make |\@Ordstring| robust.
+%
+% \changes{1.2.1}{2004/10/20}{Added}
+%
+% \begin{macrocode}
+\DeclareRobustCommand{\@@Ordstring}[1]{%
+ \protected@edef\@tempa{\@ordstring{#1}}%
+ \expandafter\MakeUppercase\@tempa%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% We provide public aliases for the macros. The macros beginning with
+% |@| are still necessary in order to be able to format the page
+% number as a string. (see \textsf{ltpageno.dtx})
+%
+% \changes{1.2}{2004/09/08}{Added}
+%
+% \begin{macrocode}
+\let\numstr\@numstring%
+\let\Numstr\@Numstring%
+\let\ordstr\@ordstring%
+\let\Ordstr\@Ordstring%
+% \end{macrocode}
+%
+%
+% \subsection{Option processing}
+%
+% \changes{1.1}{2004/08/13}{Options `publicnumstr' and `showrangeerrors'
+% added.}
+% \changes{1.2}{2004/09/08}{Option `publicnumstr' deprecated}
+%
+% \begin{macrocode}
+\DeclareOption{publicnumstr}{%
+ \PackageWarning{zahl2string}{Option `publicnumstr' is %
+ deprecated and will be removed in version 1.3}%
+}
+% \end{macrocode}
+%
+%
+% \begin{macro}{\ns@numoutofrange}
+%
+% Formats a number that is too large to be formatted as words.
+%
+% Usage: |\ns@numoutofrange| \marg{number} \marg{suffix}.
+%
+% This macro is redefined to show an error message using the package
+% option |showrangeerrors|.
+%
+% \begin{macrocode}
+\def\ns@numoutofrange#1#2{%
+ \number#1#2%
+}
+% \end{macrocode}
+% \end{macro}
+%
+
+% \begin{macrocode}
+\DeclareOption{showrangeerrors}{%
+ \def\ns@numoutofrange#1#2{%
+ \PackageError{zahl2string}{The number `#1' is too large %
+ to be formatted using zahl2string}{The largest possible %
+ number is 999,999,999.}
+ }%
+}
+% \end{macrocode}
+%
+%
+%
+% \begin{macrocode}
+\ProcessOptions\relax
+% \end{macrocode}
+%
+%
+%
+% \subsection{Internal macros}
+%
+% \subsubsection{Splitting and formatting a number}
+%
+% \begin{macro}{\ns@numstr}
+%
+% Base macro for formatting a number.
+%
+% Usage: |\ns@numstr| \marg{number} \marg{macro} \marg{nullvalue}
+% \marg{suffix}, where \meta{macro} is the macro to use for the
+% numbers between |1| and |19|, as these require some special
+% treatment, \meta{nullvalue} is the value this macro expands to when
+% \meta{number} is zero, and \meta{suffix} is text added as a suffix
+% to a number larger than 999,999,999.
+%
+% \changes{1.1}{2004/08/08}{Macro added}
+%
+% \begin{macrocode}
+\def\ns@numstr#1#2#3#4{%
+ \ifnum\number#1<\@ne%
+ #3%
+ \else\ifnum\number#1<1000000000 %
+ \expandafter\ns@numstring\expandafter{\number#1}#2%
+ \else%
+ \ns@numoutofrange{#1}{#4}%
+ \fi\fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\ns@numstring}
+%
+% \changes{1.1}{2004/08/14}{Reimplemented to avoid using up TeX's
+% space for control sequences}
+%
+% Formats a number as words.
+%
+% Usage: |\ns@numstring| \marg{number} \marg{macro}, where
+% \meta{macro} is the macro to use for the numbers between |1| and
+% |19|, as these require some special treatment.
+%
+% \emph{Note: \meta{number} must be a real number consisting of digits
+% in the range 0 to 9! It must not be a \TeX\ count register!}
+%
+% How does this work? Modulo operations are not trivial in \TeX\ as in
+% order to achieve $a \bmod b$ you have to calculate $a - (a \div b)
+% \times b$. This is complicated and also not expandable, so another
+% solution has to be found.
+%
+% \TeX's capabilities of parsing text using macro arguments are fairly
+% strong, so why not use them? It would be much easier if it would be
+% possible of defining a macro with, say, six parameters, where each
+% parameter is one digit of the number to be formatted. Then it would
+% be possible to directly access each digit (or several digits
+% combined by grouping several parameters) without having to perform
+% lengthy modulo calculations.
+%
+% Adding leading zeros to a number is easily done by comparing it
+% using |\ifnum| and adding zeros if the number is too small. However,
+% the macro must not receive the |\ifnum| et.al. tokens as a
+% parameter, but the result of the expansion, that is the number with
+% leading zeros.
+%
+% |\expandafter| would not suffice, as it expands a macro only once,
+% not fully. |\edef| would accomplish the task at hand, however
+% |\edef| is not fully expandable.
+%
+% So what do we do? We take advantage of the fact that when expanding
+% an |\ifcase|, \TeX\ goes on expanding until it has made sure that
+% the number for the |\ifcase| is complete. So immediately after the
+% |\ifcase| we launch into several nested |\ifnum|s, which \TeX\
+% expands dutifully in order to determine the number to use.
+%
+% What these nested |\ifnum|s do is the following: Depending on the
+% length of \meta{number}, they expand to a digit between one and
+% nine, one being the digit if \meta{number} is less than 10 and nine
+% being the digit if \meta{number} is larger than 99,999,999.
+%
+% Then \TeX\ uses this digit between one and nine to jump to the
+% appropriate part of the |\ifcase|-clause. There \meta{number} is
+% prefixed with the necessary amount of zeros to result in a number
+% exactly nine digits long: For the digit one (resulting from the
+% nested |\ifnum|s), eight leading zeros have to be prefixed, as
+% \meta{number} is only one digit long, for the digit two, seven zeros
+% are prefixed, as \meta{number} is less than 100 (but more than 9) et
+% cetera, until for digit nine no zeros have to be prefixed, as
+% \meta{number} is already nine digits long.
+%
+% Let's have an example: Suppose \meta{number} is 42. Then the result
+% of the nested |\ifnum|s is 2, as \meta{number} is not less than 10
+% but less than 100 (the second |\ifnum| is true). This 2 leads to
+% jumping to part after the second |\or| (before the first |\or| is
+% the part for the number 0, in this case left blank, and after the
+% first |\or| for the number 1), which is |0000000#1|. |#1| is 42. So
+% the result is: |000000042|, a number prefixed with leading zeros and
+% exactly nine digits long.
+%
+% Another example: Suppose \meta{number} is 12,345,678. Then the
+% result of the nested |\ifnum|s is 8, as the eigths |\ifnum| is true
+% (less than 100,000,000 but not less than 10,000,000). Then only one
+% zero is prefixed, resulting in |012345678|.
+%
+% However, we are not finished yet, as \TeX\ does not expand further.
+% So we are left (picking up the second example above) with this:
+% |012345678\or12345678\or| (the second incarnation of |12345678| is
+% due to the ninth part of the |\ifcase| clause, |\or#1|).
+%
+% We do not need all this |\or| baggage, we only want the number. But
+% \TeX\ is good at matching text using macros with delimited
+% parameters, so we just define |\ns@@numstring| in a way that gobbles
+% up the first |\or| and whatever follows.
+%
+% And we are done: We have a number padded perfectly with leading
+% zeros to a length of nine digits!
+%
+% \paragraph{Implementation note} In Version 1.0, we used |\csname|
+% \ldots\ |\endcsname| to add the leading zeros, as |\csname| \ldots\
+% |\endcsname| expands everything inbetween until only unexpandable
+% tokens remain, in this case digits (the |\ifnum|s are expanded).
+% Afterwards, the resulting control sequence was converted into
+% separate tokens using |\string| and finally, the backslash at the
+% beginning was gobbled by |\ns@@numstring| as its first (and unused)
+% argument.
+%
+% Unfortunately, this had its price: For every number we formatted
+% using |\ns@numstring| and that had not been formatted before, a new
+% entry was inserted into the hash table \TeX\ uses to store all
+% control sequences. So if you had a document where you formatted a
+% lot of numbers this way, you would run out of hash table space, and
+% \TeX\ would complain. (The number of hash table entries used is
+% indicated in the |log|-file as `multiletter control sequences'.)
+%
+% This was less than optimal, so we changed the implementation to this
+% |\ifcase|-|\ifnum| construct.
+%
+% \begin{macrocode}
+\def\ns@numstring#1#2{%
+ \expandafter\ns@@numstring%
+ \ifcase%
+ \ifnum#1<10 1%
+% \end{macrocode}
+%
+% Why are the constants predefined by the \LaTeX-kernel used instead
+% of numbers? Because they save tokens: |1000| are four tokens, |\@m|
+% is only one.
+%
+% \begin{macrocode}
+ \else\ifnum#1<100 2%
+ \else\ifnum#1<\@m 3%
+ \else\ifnum#1<\@M 4%
+ \else\ifnum#1<100000 5%
+ \else\ifnum#1<1000000 6%
+ \else\ifnum#1<10000000 7%
+ \else\ifnum#1<100000000 8%
+ \else9%
+ \fi\fi\fi\fi\fi\fi\fi\fi %
+ \or00000000#1% case 1: Add 8 leading zeros
+ \or0000000#1% case 2: Add 7 leading zeros
+ \or000000#1% case 3: Add 6 leading zeros
+ \or00000#1% case 4: Add 5 leading zeros
+ \or0000#1% case 5: Add 4 leading zeros
+ \or000#1% case 6: Add 3 leading zeros
+ \or00#1% case 7: Add 2 leading zeros
+ \or0#1% case 8: Add 1 leading zero
+ \or#1% case 9: Add no leading zeros
+% \end{macrocode}
+%
+% The next |\or| is only necessary because |\ns@@numstring| needs an
+% |\or| as a delimiter of the number:
+%
+% \begin{macrocode}
+ \or%
+% \end{macrocode}
+%
+% The last parameter to |\ns@@numstring| is \meta{macro}; we delimit
+% it using |\@nil|:
+%
+% \begin{macrocode}
+ \@nil#2%
+% \end{macrocode}
+%
+% Finally we end the |\ifcase| (note that this is \emph{after} the
+% number has been formatted):
+%
+% \begin{macrocode}
+ \fi%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+%
+% \begin{macro}{\ns@@numstring}
+%
+% Expands to a number in words between |1| and |999,999,999|.
+%
+% Usage: |\ns@@numstring| \marg{9. digit} \marg{8. digit} \marg{7.
+% digit} \marg{6. digit} \marg{5. digit} \marg{4. digit} \marg{3rd -
+% 1st digit} \marg{(ignored)} \marg{macro}, where \meta{macro} is, as
+% is the case with |\ns@numstring|, the macro to use for the numbers
+% between |1| and |19|, as these require some special treatment.
+%
+% |\or| and the following |#8| (\meta{ignored}) gobble up whatever was
+% left from the expansion of |\ifcase| in |\ns@numstring|. |\@nil|
+% acts as a delimiter for the last parameter, \meta{macro}.
+%
+% \changes{1.1}{2004/08/08}{Formatting of millions added.}
+% \changes{1.1}{2004/08/14}{Changed to match reeimplementation of
+% ns@numstring.}
+%
+% \begin{macrocode}
+\def\ns@@numstring#1#2#3#4#5#6#7\or#8\@nil#9{%
+ \ifnum#1#2#3>\z@
+ \ns@million#1#2#3%
+% \end{macrocode}
+%
+% We insert a space if a number follows:
+%
+% \begin{macrocode}
+ \ifnum#4#5#6>\z@\space\fi%
+ \fi%
+ \ifnum#4#5#6>\z@%
+ \ns@hundred#4#5#6{#1#2#3}{#4#5}\ns@neunzehn%
+% \end{macrocode}
+%
+% If there has been a number larger than one before the `tausend',
+% insert a discretionary hyphen before:
+%
+% \begin{macrocode}
+ \ifnum#4#5#6>\@ne\-\fi%
+ tau\-send%
+% \end{macrocode}
+%
+% If there will be a number after the `tausend', insert a
+% discretionary hyphen after:
+%
+% \begin{macrocode}
+ \ifnum#7>\z@\-\fi%
+ \fi%
+ \ns@hundred#7{#4#5#6}1#9%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+%
+% \begin{macro}{\ns@million}
+%
+% Expands to millions.
+%
+% Usage: |\ns@million| \marg{third digit} \marg{second digit}
+% \marg{first digit}.
+%
+% \changes{1.1}{2004/08/08}{Macro added.}
+%
+% \begin{macrocode}
+\def\ns@million#1#2#3{%
+ \ifnum#1#2#3=\@ne%
+ \ns@hundred#1#2#301\ns@neunzehne%
+ \space%
+ Mil\-lion%
+ \else%
+ \ns@hundred#1#2#301\ns@neunzehns%
+ \space%
+ Mil\-lio\-nen%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\ns@hundred}
+%
+% Expands to a number in words between |1| and |100|.
+%
+% Usage: |\ns@hundred| \marg{third digit} \marg{second digit}
+% \marg{first digit} \marg{shownumber} \marg{showone}
+% \marg{macro}.
+%
+% \meta{shownumber} defines if the number before the |hundert|
+% (`hundred') should be shown, i.e. |einhundert| (`onehundred')
+% instead of |hundert|. |0| is |false|, everything else |true|.
+% Can contain more than one digit.
+%
+% \meta{showone} defines if \meta{macro} should be called for the
+% number |1|. |0| is |false|, everything else |true|. Can contain more
+% than one digit.
+%
+% What does all this code do? First the third digit (`hundred'),
+% contained in |#1|, is expanded -- if it is not zero. However, there
+% is a catch: If the third digit is one, this digit is only included
+% in the result of this macro if |#4| says so. The reason is that
+% normally you would say |hunderteins| (`101') instead of
+% |einhunderteins| -- but not if there is a fourth digit. Then the
+% digit has to be included in the output of the macro, i.e.
+% |tausendeinhunderteins|
+%
+% So we want to include the digit in the output of the macro, if |#3|
+% is larger than one \emph{or} |#4| is larger than zero. We could use
+% two |\ifnum|s to accomplish this, but it can be combined into a
+% single |\ifnum|, saving tokens and time:
+%
+% We check if |#4#1| is larger than one. That means that if |#1|, the
+% third digit, is larger than one, it is included in the output. But
+% that also means that if |#4| is not zero, |#4#1| is always at least
+% |10|, which is also larger than one and exactly what we want.
+%
+% After successfully processing the third digit, the remaining last
+% two digits (|#2| and |#3|) are not really complicated anymore. We
+% perform some special treatment of the numbers between |1| and |19|
+% as these numbers are not constructed systematically. Here we have to
+% perform a check similar to the one performed for the third digit: We
+% have to check if we have to output the number if it is |1|, using
+% the same trick for a logical |or| as before, only this time with
+% |#5|, |#2| and |#3|.
+%
+% The macro to output |1| to |19| is parametrized as |#6| in order to
+% be able to use different macros for normal numbers and ordinal
+% numbers.
+%
+% If the last two digits are larger than |19|, we first output the
+% third digit using |\ns@neunzehn|, followed by |und| (`and') and then
+% the second digit. Here we don't have to use the parametrized macro
+% as before, as the ordinal suffix is appended at the end of the
+% number, not inbetween.
+%
+% But where to get the suffix from? We could pass it as a macro, but
+% that would be tedious. So we simply define the macro to output the
+% numbers |1| to |19| (|\ns@neunzehns| for normal numbers and
+% |\ns@neunzehnord| for ordinal numbers) to output the suffix if
+% called with |0| as its parameter.
+%
+% And we are done!
+%
+% \begin{macrocode}
+\def\ns@hundred#1#2#3#4#5#6{%
+% \end{macrocode}
+%
+% We expand the third digit:
+%
+% \begin{macrocode}
+ \ifnum#1>\z@%
+% \end{macrocode}
+%
+% Logical |OR| hidden in |#4#1| (see above):
+%
+% \begin{macrocode}
+ \ifnum#4#1>\@ne\ns@neunzehn#1\-\fi%
+ hun\-dert%
+% \end{macrocode}
+%
+% We insert a discretionary hyphen, if a number follows:
+%
+% \begin{macrocode}
+ \ifnum#2#3>\z@\-\fi%
+ \fi%
+% \end{macrocode}
+%
+% We expand the first an second digit:
+%
+% \begin{macrocode}
+ \ifnum#2#3<20 %
+% \end{macrocode}
+%
+% Again: Logical |OR| in |#5#2#3|:
+%
+% \begin{macrocode}
+ \ifnum#5#2#3>\@ne#6{#2#3}\fi%
+ \else%
+ \ifnum#3>\z@\ns@neunzehn#3\-und\-\fi%
+ \ns@neunzig#2%
+ #60%
+ \fi%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+%
+% \subsubsection{Macros for formatting `1' to `19'}\label{sec:LabFor}
+%
+% Very important: The position for |0| must expand to the suffix of
+% the number (\emph{any number}), see the explanations for
+% |\ns@hundred| above. If it expands to a text (as opposed to
+% |\@empty|), this text must be prefixed by a discretionary hyphen!
+%
+%
+% \begin{macro}{\ns@neunzehn}
+%
+% Expands to |ein| (`1') to |neunzehn| (`19').
+%
+% \changes{1.1}{2004/08/08}{Hyphenation added.}
+%
+% \begin{macrocode}
+\def\ns@neunzehn#1{%
+ \ifcase#1\@empty\or ein\or zwei\or drei\or vier\or f\"unf\or sechs\or%
+ sie\-ben\or acht\or neun\or zehn\or elf\or zw\"olf\or drei\-zehn\or%
+ vier\-zehn\or f\"unf\-zehn\or sech\-zehn\or sieb\-zehn\or%
+ acht\-zehn\or neun\-zehn\fi%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+%
+% \begin{macro}{\ns@neunzehns}
+%
+% Expands to |eins| (`1') to |neunzehn| (`19'). |0| expands to
+% |\@empty|.
+%
+% Why |\@empty| instead of nothing? Because then \TeX\ would insert a
+% |\relax| before the first |\or| in order to finish expansion of the
+% number. This |\relax| would remain in the output and would stay
+% there even when |\edef|ed, whereas |\@empty| expands to nothing.
+%
+% This is necessary for |\Numstring| and |\Ordstring|, as they convert
+% the first token of the |\edef|ed result of |\numstring| and
+% |\ordstring| to uppercase, and they need this token to be the first
+% letter of the number, not |\relax|.
+%
+% \begin{macrocode}
+\def\ns@neunzehns#1{%
+ \ifcase#1\@empty\or eins\else\ns@neunzehn{#1}\fi%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+%
+\def\ns@neunzehne#1{%
+ \ifcase#1\@empty\or ei\-ne\else\ns@neunzehn{#1}\fi%
+}
+%
+%
+% \begin{macro}{\ns@neunzehnord}
+%
+% Expands to |erste| (`1st') to |neunzehnte| (`19th'). |0| expands to
+% |ste|.
+%
+% \changes{1.1}{2004/08/08}{Hyphenation added.}
+%
+% \begin{macrocode}
+\def\ns@neunzehnord#1{%
+ \ifcase#1\-ste\or er\-ste\or zwei\-te\or drit\-te\or vier\-te\or%
+ f\"unf\-te\or sech\-ste\or sieb\-te\or ach\-te\or neun\-te\or%
+ zehn\-te\or elf\-te\or zw\"olf\-te\or drei\-zehn\-te\or%
+ vier\-zehn\-te\or f\"unf\-zehn\-te\or sech\-zehn\-te\or%
+ sieb\-zehn\-te\or acht\-zehn\-te\or neun\-zehn\-te\fi%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+%
+% \begin{macro}{\ns@neunzig}
+%
+% Expands to |zwanzig| (twenty) to |neunzig| (ninety) in steps of ten.
+%
+% \changes{1.1}{2004/08/08}{Hyphenation added.}
+%
+% \begin{macrocode}
+\def\ns@neunzig#1{%
+ \ifcase#1\or\or zwan\-zig\or drei\ss ig\or vier\-zig\or%
+ f\"unf\-zig\or sech\-zig\or sieb\-zig\or acht\-zig\or%
+ neun\-zig\fi%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \Finale
+% \PrintChanges
+% \PrintIndex
+\endinput \ No newline at end of file
diff --git a/macros/latex/contrib/sauerj/zahl2string.ins b/macros/latex/contrib/sauerj/zahl2string.ins
new file mode 100644
index 0000000000..a03684bd8a
--- /dev/null
+++ b/macros/latex/contrib/sauerj/zahl2string.ins
@@ -0,0 +1,19 @@
+\input docstrip
+\keepsilent
+\askforoverwritefalse
+
+\preamble
+\endpreamble
+\generate{%
+ \file{\jobname.sty}{\from{\jobname.dtx}{package}}
+}
+
+\Msg{***************************************************************}
+\Msg{*}
+\Msg{* \space To finish the installation you have to copy the files}
+\Msg{*}
+\Msg{* \space *.sty into a directory searched by TeX}
+\Msg{*}
+\Msg{***************************************************************}
+
+\endbatchfile \ No newline at end of file
diff --git a/macros/latex/contrib/sauerj/zahl2string.pdf b/macros/latex/contrib/sauerj/zahl2string.pdf
new file mode 100644
index 0000000000..0b45d8cf1b
--- /dev/null
+++ b/macros/latex/contrib/sauerj/zahl2string.pdf
Binary files differ