summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/sauerj/zahl2string.dtx
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/zahl2string.dtx
Initial commit
Diffstat (limited to 'macros/latex/contrib/sauerj/zahl2string.dtx')
-rw-r--r--macros/latex/contrib/sauerj/zahl2string.dtx1044
1 files changed, 1044 insertions, 0 deletions
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