From d85f248e3b38ea0ecda38c5340e3cadd08d65346 Mon Sep 17 00:00:00 2001
From: Karl Berry <karl@freefriends.org>
Date: Sun, 16 Sep 2007 00:07:34 +0000
Subject: oberdiek update (14sep07)

git-svn-id: svn://tug.org/texlive/trunk@4947 c570f23f-e606-0410-a88d-b1316a301751
---
 .../texmf-dist/source/latex/oberdiek/alphalph.dtx  | 1602 ++++++++++++++------
 1 file changed, 1169 insertions(+), 433 deletions(-)

(limited to 'Master/texmf-dist/source/latex/oberdiek/alphalph.dtx')

diff --git a/Master/texmf-dist/source/latex/oberdiek/alphalph.dtx b/Master/texmf-dist/source/latex/oberdiek/alphalph.dtx
index 7fba92f4829..3a3d117ec0b 100644
--- a/Master/texmf-dist/source/latex/oberdiek/alphalph.dtx
+++ b/Master/texmf-dist/source/latex/oberdiek/alphalph.dtx
@@ -17,7 +17,8 @@
 %
 % This work consists of the main source file alphalph.dtx
 % and the derived files
-%    alphalph.sty, alphalph.pdf, alphalph.ins, alphalph.drv.
+%    alphalph.sty, alphalph.pdf, alphalph.ins, alphalph.drv,
+%    alphalph-test1.tex, alphalph-test2.tex, alphalph-test3.tex.
 %
 % Distribution:
 %    CTAN:macros/latex/contrib/oberdiek/alphalph.dtx
@@ -52,6 +53,9 @@
 % Installation:
 %    TDS:tex/generic/oberdiek/alphalph.sty
 %    TDS:doc/latex/oberdiek/alphalph.pdf
+%    TDS:doc/latex/oberdiek/alphalph-test1.tex
+%    TDS:doc/latex/oberdiek/alphalph-test2.tex
+%    TDS:doc/latex/oberdiek/alphalph-test3.tex
 %    TDS:source/latex/oberdiek/alphalph.dtx
 %
 %<*ignore>
@@ -67,7 +71,7 @@
 \input docstrip.tex
 \Msg{************************************************************************}
 \Msg{* Installation}
-\Msg{* Package: alphalph 2007/04/11 v1.5 Converting numbers to letters (HO)}
+\Msg{* Package: alphalph 2007/04/11 v2.0 Converting numbers to letters (HO)}
 \Msg{************************************************************************}
 
 \keepsilent
@@ -94,7 +98,8 @@ This Current Maintainer of this work is Heiko Oberdiek.
 
 This work consists of the main source file alphalph.dtx
 and the derived files
-   alphalph.sty, alphalph.pdf, alphalph.ins, alphalph.drv.
+   alphalph.sty, alphalph.pdf, alphalph.ins, alphalph.drv,
+   alphalph-test1.tex, alphalph-test2.tex, alphalph-test3.tex.
 
 \endpreamble
 
@@ -103,6 +108,10 @@ and the derived files
   \file{alphalph.drv}{\from{alphalph.dtx}{driver}}%
   \usedir{tex/generic/oberdiek}%
   \file{alphalph.sty}{\from{alphalph.dtx}{package}}%
+  \usedir{doc/latex/oberdiek}%
+  \file{alphalph-test1.tex}{\from{alphalph.dtx}{test1}}%
+  \file{alphalph-test2.tex}{\from{alphalph.dtx}{test2,etex}}%
+  \file{alphalph-test3.tex}{\from{alphalph.dtx}{test2,noetex}}%
 }
 
 \obeyspaces
@@ -128,17 +137,42 @@ and the derived files
 %<*driver>
 \NeedsTeXFormat{LaTeX2e}
 \ProvidesFile{alphalph.drv}%
-  [2007/04/11 v1.5 Converting numbers to letters (HO)]%
+  [2007/04/11 v2.0 Converting numbers to letters (HO)]%
 \documentclass{ltxdoc}
 \usepackage{holtxdoc}
-\usepackage{alphalph}
+\usepackage{alphalph}[2007/04/11]
+\makeatletter
+\newalphalph{\fnsymbolwrap}[wrap]{\@fnsymbol}{}
+\newcommand*{\fnsymbolsingle}[1]{%
+  \ensuremath{%
+    \ifcase#1%
+    \or *%
+    \or \dagger
+    \or \ddagger
+    \or \mathsection
+    \or \mathparagraph
+    \else
+      \@ctrerr
+    \fi
+  }%
+}
+\makeatother
+\newalphalph{\fnsymbolmult}[mult]{\fnsymbolsingle}{}
+\usepackage{amsmath}
+\DeclareMathOperator{\opDiv}{div}
+\DeclareMathOperator{\opMod}{mod}
+\newcommand*{\Def}{%
+  \ensuremath{%
+    \mathrel{\mathop{:}}=%
+  }%
+}
 \begin{document}
   \DocInput{alphalph.dtx}%
 \end{document}
 %</driver>
 % \fi
 %
-% \CheckSum{406}
+% \CheckSum{1035}
 %
 % \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
@@ -159,100 +193,352 @@ and the derived files
 % \GetFileInfo{alphalph.drv}
 %
 % \title{The \xpackage{alphalph} package}
-% \date{2007/04/11 v1.5}
+% \date{2007/04/11 v2.0}
 % \author{Heiko Oberdiek\\\xemail{oberdiek@uni-freiburg.de}}
 %
 % \maketitle
 %
 % \begin{abstract}
-% The package provides the new expandable commands \cs{alphalph}
-% and \cs{AlphAlph}. They are like \cs{number}, but the expansion
-% consists of lowercase and uppercase letters respectively.
+% The package provides methods to represent numbers with a limited
+% set of symbols. Both \LaTeX\ and \plainTeX are supported.
 % \end{abstract}
 %
 % \tableofcontents
 %
-% \newenvironment{param}{^^A
-%   \newcommand{\entry}[1]{\meta{\###1}:&}^^A
-%   \begin{tabular}[t]{@{}l@{ }l@{}}^^A
-% }{^^A
-%   \end{tabular}^^A
-% }
+% \section{Documentation}
 %
-% \section{Usage}
-%    The package \Package{alphalph} can be used with both \plainTeX\
-%    and \LaTeX:
-%    \begin{description}
-%    \item[\plainTeX:] |\input alphalph.sty|
-%    \item[\LaTeXe:]   |\usepackage{alphalph}|\\
-%         There aren't any options.
-%    \end{description}
+% \subsection{Introduction}
+% \LaTeX\ counter can be represented in different ways
+% by using presentation commands:
+% \begin{quote}
+%   \cs{arabic}, \cs{roman}, \cs{Roman},\\
+%   \cs{alph}, \cs{Alph}, \cs{fnsymbol}
+% \end{quote}
+% The ranges of supported counter values are more or less
+% restricted. Only \cs{arabic} can be used with any counter
+% value \TeX\ supports.
+% \begin{quote}
+% \catcode`\|=12 %
+% \begin{tabular}{@{}l|l|l|l@{}}
+% Presentation & Supported & Ignored & Error message\\
+% command      & domain    & values  & ``Counter too large''\\
+% \hline
+% \cs{arabic}
+%   & \ttfamily -MAX..MAX & &\\
+% \cs{roman}, \cs{Roman}
+%   & \ttfamily 1..MAX & \ttfamily MAX..0 &\\
+% \cs{alph}, \cs{Alph}
+%   & \ttfamily 1..26 & 0 & \ttfamily MAX..-1, 27..MAX\\
+% \cs{fnsymbol}
+%   & \ttfamily 1..9 & 0 & \ttfamily -MAX..-1, 10..MAX\\
+% \hline
+% \end{tabular}\\[1ex]
+% \texttt{MAX} = \texttt{2147483647}
+% \end{quote}
+% Ordinal numbers are often used in documents: numbering
+% of chapters, sections, figures, footnotes and so on.
+% The layouter chooses \cs{Alph} for chapter numbers
+% and \cs{fnsymbol} for footnotes. But what can be done
+% if there are more than 26 chapters or more than 10 footnotes?
+% This package \xpackage{alphalph} allows to define new
+% presentation commands. They rely on a existing command
+% and define presentations for values greater the limits.
+% Three different methods are provided by the package.
+% In the following use cases they are presentated.
+%
+% \subsection{Use cases}
+%
+% \subsubsection{Number system based on symbols}
+%
+% Asume you are writing a book and your lecturer demands
+% that chapter numbers must be letters. But you have already
+% 30 chapters and you have only 26 letters?
+%
+% In the decimal system the situation would be clear.
+% If you run out of digits, you are using more digits
+% to represent a number. This method can be also be used
+% for letters. After chapter 26 with |Z| we us |AA|, |AB|, |AC|, and |AD|
+% for the remaining chapters.
+%
+% Happily this package already defines this presentation command:
+%\begin{quote}
+%\begin{verbatim}
+%\usepackage{alphalph}
+%\renewcommand*{\thechapter}{%
+%  \AlphAlph{\value{chapter}}%
+%}
+%\end{verbatim}
+%\end{quote}
+% \cs{AlphAlph} generates:
+%   \AlphAlph{1}, \AlphAlph{2}, \AlphAlph{3}, \dots,
+%   \AlphAlph{26}, \AlphAlph{27}, \AlphAlph{28}, \dots
+%
+% The other presentation command is \cs{alphalph} for lowercase letters.
+%
+% \subsubsection{Wrap symbols around}
+%
+% Nine footnote symbols are quite a few.
+% Too soon the symbols are consumed
+% and \LaTeX\ complains with the error ``Counter too large''.
+% However, it could be acceptable to start again with the symbols
+% from the beginning, especially if there are less than nine symbols
+% on a page.
+% This could be achieved by a counter reset.
+% But finding the right place can be difficult or needs manual
+% actions. Also a
+% unique counter value can be desirable (e.g. for generating
+% unique anchor/link names).
+% Package \xpackage{alphalph} allows you to define
+% a macro that implements a ``wrap around'', but letting
+% the value of the counter untouched:
+%\begin{quote}
+%\begin{verbatim}
+%\usepackage{alphalph}
+%\makeatletter
+%\newalphalph{\fnsymbolwrap}[wrap]{\@fnsymbol}{}
+%\makeatother
+%\renewcommand*{\thefootnote}{%
+%  \fnsymbolwrap{\value{footnote}}%
+%}
+%\end{verbatim}
+%\end{quote}
+% \cs{fnsymbolwrap} generates:
+% \fnsymbolwrap{1}~(1), \fnsymbolwrap{2}~(2), \fnsymbolwrap{3}~(3), \dots,
+% \fnsymbolwrap{9}~(9), \fnsymbolwrap{10}~(10), \fnsymbolwrap{11}~11, \dots
 %
-% \subsection{User commands}
-%    \begin{description}
-%    \item[\cmd{\alphalph}:]\DescribeMacro{\alphalph}
-%      This works like \cmd{\number}, but the expansion consists of
-%      lowercase letters.
-%    \item[\cmd{\AlphAlph}:]\DescribeMacro{\AlphAlph}
-%      It converts a number into uppercase letters.
-%    \end{description}
-%    Both commands have following properties:
-%    \begin{itemize}
-%    \item They are fully expandable. This means that they can safely
-%          \begin{itemize}
-%          \item be written to a file,
-%          \item used in moving arguments (\LaTeX: they are \emph{robust}),
-%          \item used in a \cmd{\csname}-\cmd{\endcsname} pair.
-%          \end{itemize}
-%    \item If the argument is zero or negative, the commands expand
-%          to nothing like \cmd{\romannumeral}.
-%    \item As argument is allowed all that can be used after a \cmd{\number}:
-%          \begin{itemize}
-%          \item explicite constants,
-%          \item macros that expand to a number,
-%          \item count registers, \LaTeX\ counter can used
-%                via \cmd{\value}, e.\,g.:\\
-%                |\alphalph{\value{page}}|
-%          \end{itemize}
-%    \end{itemize}
-%
-%    The following table shows, how the conversion is made:
-%    \begin{center}
-%      \catcode`\|=12
-%      \catcode`\+\active
-%      \def+#1&{\alphalph{#1}&}%
-%      \begin{tabular}{@{}l|*{14}{r@{, }}r@{}}
-%      number         & 1& 2&\dots& 26& 27&\dots& 52& 53&
-%                     \dots& 78& 79&\dots& 702& 703&\dots
-%      \\\hline
-%      \cmd{\alphalph}&+1&+2&\dots&+26&+27&\dots&+52&+53&
-%                     \dots&+78&+79&\dots&+702&+703&\dots
-%      \end{tabular}
-%    \end{center}
-%
-% \subsubsection{New commands like \cs{alphalph}}
-%   \begin{description}
-%   \item[\cmd{\newalphalph}:]\DescribeMacro{\newalphalph}
-%     This macro defines a new command that acts like \cs{alphalph}.
-%     The use of \eTeX is required.
-%     The macro has three arguments:
-%     \begin{itemize}
-%     \item[\texttt{\#1}:] The command to be defined.
-%     \item[\texttt{\#2}:] A macro that converts a positive number
-%                         to a symbol.
-%     \item[\texttt{\#3}:] The number of available symbols.
-%     \end{itemize}
-%   \end{description}
-%
-%   Example:
+% \subsubsection{Multiple symbols}
+%
+% \LaTeX's standard set of footnote symbols contains doubled
+% symbols at the higher positions. Could this principle
+% be generalized?
+% Yes, but first we need a clean footnote symbol list without
+% doubled entries, example:
+%\begin{quote}
+%\begin{verbatim}
+%\usepackage{alphalph}
+%\makeatletter
+%\newcommand*{\fnsymbolsingle}[1]{%
+%  \ensuremath{%
+%    \ifcase#1%
+%    \or *%
+%    \or \dagger
+%    \or \ddagger
+%    \or \mathsection
+%    \or \mathparagraph
+%    \else
+%      \@ctrerr
+%    \fi
+%  }%
+%}
+%\makeatother
+%\newalphalph{\fnsymbolmult}[mult]{\fnsymbolsingle}{}
+%\renewcommand*{\thefootnote}{%
+%  \fnsymbolmult{\value{footnote}}%
+%}
+%\end{verbatim}
+%\end{quote}
+% The own definition of \cs{fnsymbolsingle} has the
+% advantage that this list can easily modified.
+% Otherwise you can use \cs{@fnsymbol} directly,
+% because it uses the same first five symbols.
 %\begin{quote}
 %\begin{verbatim}
-%\newcommand*{\myvocals}[1]{%
-%  \ifcase#1\or A\or E\or I\or O\or U\fi
+%\usepackage{alphalph}
+%\makeatletter
+%\newalphalph{\fnsymbolmult}[mult]{\@fnsymbol}{5}
+%\makeatother
+%\renewcommand*{\thefootnote}{%
+%  \fnsymbolmult{\value{footnote}}%
 %}
-%\newalphalph{\vocalsvocals}{\myvocals}{5}
 %\end{verbatim}
 %\end{quote}
+% \cs{fnsymbolmult} generates:
+% \fnsymbolmult{1}~(1), \fnsymbolmult{2}~(2), \fnsymbolmult{3}~(3),
+% \fnsymbolmult{4}~(4), \fnsymbolmult{5}~(5), \fnsymbolmult{6}~(6),
+% \dots, \fnsymbolmult{16}~16, \fnsymbolmult{17}~17, \dots
+%
+% \bigskip
+% The same method can also be used for the chapter problem
+% in the first discussed use case:
+%\begin{quote}
+%\begin{verbatim}
+%\usepackage{alphalph}
+%\makeatletter
+%\newalphalph{\AlphMult}[mult]{\@Alph}{26}
+%\makeatother
+%\renewcommand*{\chapter}{%
+%  \AlphMult{\value{chapter}}%
+%}
+%\end{verbatim}
+%\end{quote}
+% \cs{AlphMult} then generates AA, BB, CC, and DD for chapters 27--30.
+%
+% \subsection{Glossary}
+%
+% \begin{description}
+% \item[Counter presentation command] is a macro that
+%   expects a \LaTeX\ counter name as argument.
+%   Numbers cannot be used. Examples:
+%   \cs{arabic}, \cs{alph}, \cs{fnsymbol}.
+% \item[Number presentation command] is a macro that
+%   expects a number as argument. A number is anything
+%   that \TeX\ accepts as number including \cs{value}.
+%   Examples: \cs{alphalph}, \cs{AlphAlph}, \cs{alphalph@alph}
+%
+%   However, \cs{alph} or \cs{fnsymbol} are not number
+%   presentation commands because they expect a counter
+%   name as argument. Happily \LaTeX\ counter presentation
+%   commands internally uses number presentation commands
+%   with the same name, but prefixed by `@'. Thus
+%   \cs{@alph}, \cs{@fnsymbol} are number presentation commands.
+% \item[Symbols provider] is a command that can be used
+%   to get a list of symbols. For example, \cs{@Alph}
+%   provides the 26 uppercase letters from `A' to `Z'.
+%   Basically a symbol provider is a number presentation
+%   command, usually with a limited range.
+% \item[Number of symbols] is the number of the
+%   last symbol slot of a symbol provider. Thus \cs{@Alph}
+%   generates 26 symbols, \cs{@fnsymbol} provides 9 symbols.
+% \end{description}
+%
+% \subsection{Package usage}
+%
+% The package \Package{alphalph} can be used with both \plainTeX\
+% and \LaTeX:
+% \begin{description}
+% \item[\plainTeX:] |\input alphalph.sty|
+% \item[\LaTeXe:]   |\usepackage{alphalph}|\\
+%      There aren't any options.
+% \end{description}
+%
+% \subsection{User commands}
+%
+% \begin{declcs}{AlphAlph} \M{number}\\
+%   \cs{alphalph} \M{number}
+% \end{declcs}
+% Both macros are number presentation commands that
+% expects a number as argument. \LaTeX\ counters
+% are used with \cs{value}.
+%
+% The macros represents a number by letters.
+% First single letters |A..Z| are used, then
+% two letters |AA..ZZ|, three letters |AAA...ZZZ|, \dots
+% follow.
+%
+% Macro \cs{AlphAlph} uses uppercase letters,
+% \cs{alphalph} generates the lowercase variant.
+% \begin{quote}
+%   \catcode`\|=12
+%   \def\entry#1{
+%     \texttt{#1}
+%     & \texttt{\AlphAlph{#1}}
+%     & \texttt{\alphalph{#1}}
+%   }
+%   \begin{tabular}{@{}l|l|l@{}}
+%     \meta{number} & \verb|\AlphAlph{|\meta{number}\verb|}|
+%                   & \verb|\alphalph{|\meta{number}\verb|}|\\
+%     \hline
+%     \entry{1}\\
+%     \entry{2}\\
+%     \entry{26}\\
+%     \entry{27}\\
+%     \entry{30}\\
+%     \entry{2000}\\
+%     \entry{3752127}\\
+%     \entry{10786572}\\
+%     \entry{2147483647}\\
+%   \end{tabular}
+% \end{quote}
+%
+% \begin{declcs}{newalphalph}
+%   \M{cmd}
+%   |[|\meta{method}|]|
+%   \M{symbols provider}
+%   \M{number of symbols}
+% \end{declcs}
+% Macro \cs{newalphalph} defines \meta{cmd} as new
+% number presentation command. Like \cs{newcommand} an error
+% is thrown, if macro \meta{cmd} already exists.
+%
+% The \meta{method} is one of |alph|, |wrap|, or |mult|.
+% The default is |alph|.
+%
+% As symbol provider a number presentation command
+% can be used, e.g. \cs{@fnsymbol}, \cs{@Alph}, or
+% \cs{alphalph@alph}.
+%
+% The last argument is the number of symbols.
+% If the argument is empty, then \cs{newalphalph} tries
+% to find this number itself. \LaTeX's number presentation
+% commands throw an error message, if the number is too large.
+% This error message is put in a macro \cs{@ctrerr}.
+% Thus \cs{newalphalph} calls the symbol provider and tests
+% a number by typesetting it in a temporary box. The error
+% macro \cs{@ctrerr} is catched, it proofs that the number
+% is not supported. Also if the width of the result is zero
+% the number is considered as unavailable.
+%
+% The empty argument is useful for potentially variable lists.
+% However if the end cannot be detected, then the number of
+% symbols must be given. This is also a lot faster. Therefore don't
+% let the argument empty without reason.
+%
+% \subsection{Programmer commands}
+%
+% \begin{declcs}{alphalph@Alph} \M{number}\\
+%   \cs{alphalph@alph} \M{number}
+% \end{declcs}
+% They are basically the same as \cs{@Alph} and \cs{@alph}.
+% Some languages of package \xpackage{babel} redefine
+% \LaTeX's macros to include some font setup that
+% breaks expandibility. Therefore \cs{AlphAlph} and \cs{alphalph}
+% are based on \cs{alphalph@Alph} and \cs{alphalph@alph} to get
+% the letters. The behaviour of these symbol providers for numbers
+% outside the range |1..26| is undefined.
+%
+% \subsection{Design principles}
+%
+% \subsubsection{Number presentation commands}
+%
+% All number presentation commands that this package defines
+% (including \cs{alphalph} and \cs{AlphAlph}) have the following
+% properties:
+% \begin{itemize}
+% \item They are fully expandable. This means that they can safely
+%       \begin{itemize}
+%       \item be written to a file,
+%       \item used in moving arguments (\LaTeX: they are \emph{robust}),
+%       \item used in a \cmd{\csname}-\cmd{\endcsname} pair.
+%       \end{itemize}
+% \item If the argument is zero or negative, the commands expand
+%       to nothing like \cmd{\romannumeral}.
+% \item The argument is a \TeX\ number. Anything that would be
+%       accepted by \cmd{\number} is a valid argument:
+%       \begin{itemize}
+%       \item explicite constants,
+%       \item macros that expand to a number,
+%       \item count registers, \LaTeX\ counter can used
+%             via \cmd{\value}, e.\,g.:\\
+%             |\alphalph{\value{page}}|
+%       \item \dots
+%       \end{itemize}
+% \item \eTeX's numeric expressions are supported, if \eTeX\ is
+%       available. Then \cs{numexpr} is applied to the argument.
+%       Package \cs{calc}'s expressions are not supported.
+%       That would violate the expandibility.
+% \end{itemize}
+%
+% \subsubsection{General usability}
+%
+% \begin{description}
+% \item[\TeX\ format:]
+%   The package does not depend on \LaTeX, it can also be used
+%   by \plainTeX, for example.
+% \item[\eTeX:] \eTeX is supported, the macros are shorter and
+%   faster. But \eTeX's extensions are not requirements.
+%   Without \eTeX, just the implementation changes. The properties
+%   remain unchanged.
+% \end{description}
 %
 % \StopEventually{
 % }
@@ -319,18 +605,107 @@ and the derived files
   \fi
 \expandafter\x\csname ver@alphalph.sty\endcsname
 \ProvidesPackage{alphalph}%
-  [2007/04/11 v1.5 Converting numbers to letters (HO)]
+  [2007/04/11 v2.0 Converting numbers to letters (HO)]
 %    \end{macrocode}
 %
-%    For unique command names this package uses |aa@| as prefix
-%    for internal command names. Because we need |@| as a letter
-%    we save the current catcode value.
+% \subsection{Catcodes}
+%
 %    \begin{macrocode}
-\expandafter\edef\csname aa@atcode\endcsname{\the\catcode`\@ }
-\catcode`\@=11
+\expandafter\edef\csname AlPh@AtEnd\endcsname{%
+  \catcode64 \the\catcode64\relax
+}
+\catcode64 11 % @
+\def\TMP@EnsureCode#1#2{%
+  \edef\AlPh@AtEnd{%
+    \AlPh@AtEnd
+    \catcode#1 \the\catcode#1\relax
+  }%
+  \catcode#1 #2\relax
+}
+\TMP@EnsureCode{33}{12}% !
+\TMP@EnsureCode{39}{12}% '
+\TMP@EnsureCode{40}{12}% (
+\TMP@EnsureCode{41}{12}% )
+\TMP@EnsureCode{43}{12}% +
+\TMP@EnsureCode{44}{12}% ,
+\TMP@EnsureCode{46}{12}% .
+\TMP@EnsureCode{47}{12}% /
+\TMP@EnsureCode{59}{12}% ;
+\TMP@EnsureCode{60}{12}% <
+\TMP@EnsureCode{61}{12}% =
+\TMP@EnsureCode{62}{12}% >
+\TMP@EnsureCode{91}{12}% [
+\TMP@EnsureCode{93}{12}% ]
+\TMP@EnsureCode{96}{12}% `
+\TMP@EnsureCode{124}{12}% |
+%    \end{macrocode}
+%
+% \subsection{Package loading}
+%
+%    \begin{macrocode}
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname RequirePackage\endcsname\relax
+  \input infwarerr.sty\relax
+  \input intcalc.sty\relax
+\else
+  \RequirePackage{infwarerr}[2007/09/09]%
+  \RequirePackage{intcalc}[2007/09/09]%
+\fi
+%    \end{macrocode}
+%
+% \subsection{\eTeX\ detection}
+%
+%    \begin{macrocode}
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname numexpr\endcsname\relax
+  \catcode124=9 % '!': ignore
+  \catcode43=14 % '+': comment
+\else
+  \catcode124=14 % '!': comment
+  \catcode43=9   % '+': ignore
+\fi
 %    \end{macrocode}
 %
 % \subsection{Help macros}
+%
+%    \begin{macro}{\AlPh@Error}
+%    \begin{macrocode}
+\def\AlPh@Error#1{%
+  \begingroup
+    \escapechar=92 % backslash
+    \@PackageError{alphalph}{#1}\@ehc
+  \endgroup
+}
+%    \end{macrocode}
+%    \end{macro}
+%
+%    \begin{macro}{\AlPh@IfDefinable}
+%    \begin{macrocode}
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname @ifdefinable\endcsname\relax
+  \def\AlPh@IfDefinable#1#2{%
+    \ifcase\ifx#1\@undefined\else\ifx#1\relax\else1\fi\fi0 %
+      #2%
+    \else
+      \AlPh@Error{%
+        Command \string#1 already defined%
+      }%
+    \fi
+  }%
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macrocode}
+\else
+%    \end{macrocode}
+%    \begin{macro}{\AlPh@IfDefinable}
+%    \begin{macrocode}
+  \let\AlPh@IfDefinable\@ifdefinable
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macrocode}
+\fi
+%    \end{macrocode}
+%
 %    \begin{macro}{\@ReturnAfterElseFi}
 %    \begin{macro}{\@ReturnAfterFi}
 %    The following commands moves the `then' and `else' part respectively
@@ -338,7 +713,7 @@ and the derived files
 %    and so a \TeX\ capacity error because of a limited input stack size.
 %    I use this trick in several packages, so I don't prefix these internal
 %    commands in order not to have the same macros with different names.
-%    (It saves memory).
+%    (It saves memory.)
 %    \begin{macrocode}
 \long\def\@ReturnAfterElseFi#1\else#2\fi{\fi#1}
 \long\def\@ReturnAfterFi#1\fi{\fi#1}
@@ -346,461 +721,810 @@ and the derived files
 %    \end{macro}
 %    \end{macro}
 %
-%    \begin{macro}{\aa@alph}
-%    \begin{macro}{\aa@Alph}
-%    The two commands \cmd{\aa@alph} and \cmd{\aa@Alph} convert a
-%    number into a letter (lowercase and uppercase respectivly).
+%    \begin{macro}{\@gobblefour}
+%    \LaTeX\ defines commands for eating arguments.
+%    Define \cs{@gobblefour} if it is not defined (\plainTeX).
+%    \begin{macrocode}
+\expandafter\ifx\csname @gobblefour\endcsname\relax
+  \long\def\@gobblefour#1#2#3#4{}%
+\fi
+%    \end{macrocode}
+%    \end{macro}
+%
+%    \begin{macro}{AlPh@IfOptArg}
+%    \begin{macrocode}
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname kernel@ifnextchar\endcsname\relax
+  \begingroup\expandafter\expandafter\expandafter\endgroup
+  \expandafter\ifx\csname @ifnextchar\endcsname\relax
+    \def\AlPh@IfOptArg#1#2{%
+      \def\AlPh@TempA{#1}%
+      \def\AlPh@TempB{#2}%
+      \futurelet\AlPh@Token\AlPh@IfOptArgNext
+    }%
+    \let\AlPh@BracketLeft=[%]
+    \def\AlPh@IfOptArgNext{%
+      \ifx\AlPh@Token\AlPh@BracketLeft
+        \expandafter\AlPh@TempA
+      \else
+        \expandafter\AlPh@TempB
+      \fi
+    }%
+  \else
+    \def\AlPh@IfOptArg{\@ifnextchar[}%]
+  \fi
+\else
+  \def\AlPh@IfOptArg{\kernel@ifnextchar[}%]
+\fi
+%    \end{macrocode}
+%    \end{macro}
+%
+% \subsection{Symbol provider}
+%
+% \subsubsection{Alphabet}
+%
+%    The output of \cs{alphalph} and \cs{AlphAlph} should be
+%    usable as part of command names (see \cs{@namedef}, \cs{csname}, \dots).
+%    Unhappily some languages of package \xpackage{babel}
+%    redefine \LaTeX's \cs{@alph} and \cs{@Alph} in a manner that
+%    they cannot be used in expandable context any more.
+%    Therefore package \xpackage{alphalph} provides its own
+%    commands.
+%
+%    \begin{macro}{\alphalph@Alph}
+%    \begin{macro}{\alphalph@alph}
+%    The two commands \cmd{\AlPh@Alph} and \cmd{\AlPh@alph} convert a
+%    number into a letter (uppercase and lowercase respectivly).
 %    The character |@| is used as an error symbol,
 %    if the number isn't in the range of 1 until 26.
 %    Here we need no space after the number |#1|, because the error
 %    symbol |@| for the zero case stops scanning the number.
+%    This error symbol should not appear anywhere (except for bugs).
 %    \begin{macrocode}
-\def\aa@alph#1{%
+\def\alphalph@Alph#1{%
   \ifcase#1%
     @%
-  \or a\or b\or c\or d\or e\or f\or g\or h\or i\or j\or k\or l\or m%
-  \or n\or o\or p\or q\or r\or s\or t\or u\or v\or w\or x\or y\or z%
+  \or A\or B\or C\or D\or E\or F\or G\or H\or I\or J\or K\or L\or M%
+  \or N\or O\or P\or Q\or R\or S\or T\or U\or V\or W\or X\or Y\or Z%
   \else
+    \AlPh@ctrerr
     @%
   \fi
 }
-\def\aa@Alph#1{%
+\def\alphalph@alph#1{%
   \ifcase#1%
     @%
-  \or A\or B\or C\or D\or E\or F\or G\or H\or I\or J\or K\or L\or M%
-  \or N\or O\or P\or Q\or R\or S\or T\or U\or V\or W\or X\or Y\or Z%
+  \or a\or b\or c\or d\or e\or f\or g\or h\or i\or j\or k\or l\or m%
+  \or n\or o\or p\or q\or r\or s\or t\or u\or v\or w\or x\or y\or z%
   \else
+    \AlPh@ctrerr
     @%
   \fi
 }
 %    \end{macrocode}
 %    \end{macro}
 %    \end{macro}
-%
-% \subsection{User commands}
-%    \begin{macro}{\alphalph}
-%    \begin{macro}{\AlphAlph}
-%    The whole difference between \cmd{\alphalph} and \cmd{\AlphAlph}
-%    is that the output consists of lowercase or uppercase letters.
+%    \begin{macro}{\AlPh@ctrerr}
+%    Macro \cs{AlPh@ctrerr} is used as hook for the algorithm
+%    to get the available number of symbols.
 %    \begin{macrocode}
-\def\alphalph{\aa@callmake\aa@alph}
-\def\AlphAlph{\aa@callmake\aa@Alph}
+\def\AlPh@ctrerr{}
 %    \end{macrocode}
 %    \end{macro}
-%    \end{macro}
 %
-%    \begin{macro}{\aa@callmake}
-%    \cmd{\aa@callmake} converts the number in
-%    the second argument |#2| into explicite decimal digits via
-%    the \TeX\ primitive \cmd{\number}. (The closing curly brace stops reading
-%    the number at the latest.)
+% \subsection{Finding number of symbols}
+%
+%    \begin{macro}{\AlPh@GetNumberOfSymbols}
+%    \noindent
+%    |#1|: symbols provider
 %    \begin{macrocode}
-\def\aa@callmake#1#2{%
-  \expandafter\aa@make\expandafter{\number#2}#1%
+\def\AlPh@GetNumberOfSymbols#1{%
+  \AlPh@TestNumber1!{#1}%
+  \ifAlPh@Unavailable
+    \def\AlPh@Number{0}%
+    \AlPh@Error{No symbols found}%
+  \else
+    \def\AlPh@Number{1}%
+    \AlPh@ExpSearch2!{#1}%
+  \fi
 }
 %    \end{macrocode}
 %    \end{macro}
-%
-%    \eTeX provides the new primitive \cmd{\numexpr}.
-%    With this command the implementation is very simple
-%    (see \ref{sec:etex}). Therefore the package provides two
-%    methods: a fast and simple one that uses the \eTeX\ extension
-%    and a method that is restricted to the standard \TeX\ means.
-%
-%    Now we distinguish between \TeX\ and \eTeX\ by checking
-%    whether \cmd{\numexpr} is defined or isn't.
-%    Because the \TeX\ primitive \cmd{\csname} defines an
-%    undefined command to be \cmd{\relax}, \cmd{\csname}
-%    is executed in a group.
+%    \begin{macro}{\ifAlPh@Unavailable}
 %    \begin{macrocode}
-\begingroup\expandafter\expandafter\expandafter\endgroup
-\expandafter\ifx\csname numexpr\endcsname\relax
+\newif\ifAlPh@Unavailable
+\def\AlPh@Unavailabletrue{%
+  \global\let\ifAlPh@Unavailable\iftrue
+}
+\def\AlPh@Unavailablefalse{%
+  \global\let\ifAlPh@Unavailable\iffalse
+}
 %    \end{macrocode}
-%
-% \subsection{\texorpdfstring{Conversion with standard \TeX\ means}{\TeX}}
-%    \begin{macro}{\aa@make}
-%    \cmd{\aa@make} catches the cases, if the number is zero or negative.
-%    Then it expands to nothing like \cmd{\romannumeral}.
+%    \end{macro}
+%    \begin{macro}{\AlPh@TestNumber}
+%    |#1|: number to be tested\\
+%    |#2|: symbols provider
 %    \begin{macrocode}
-  \def\aa@make#1#2{%
-    \ifnum#1<1 %
-    \else
-      \@ReturnAfterFi{%
-        \aa@process1;#1;1..#2%
-      }%
+\def\AlPh@TestNumber#1!#2{%
+  \AlPh@Unavailablefalse
+  \begingroup
+    \setbox0=\hbox{%
+      \begingroup % color
+        \let\@ctrerr\AlPh@Unavailabletrue
+        \let\AlPh@ctrerr\AlPh@Unavailabletrue
+        #2{#1}%
+      \endgroup
+    }%
+    \ifdim\wd0=0pt %
+      \AlPh@Unavailabletrue
     \fi
-  }%
+  \endgroup
+}
 %    \end{macrocode}
 %    \end{macro}
-%
-%    \begin{macro}{\aa@process}
-%    \cmd{\aa@process} contains the algorithm for the conversion.
-%    \TeX doesn't provide a simple method to divide or multiply
-%    numbers in a fully expandable way. An expandable addition by one
-%    is complicated enough. Therefore \cmd{\aa@process} uses
-%    only expandible versions of additions by one. The algorithm
-%    starts with one and increments it until the size of the wanted
-%    number is reached. The intermediate number that is incremented
-%    is present in two kinds:
-%    \begin{itemize}
-%    \item the normal decimal form for the \cs{ifnum}-comparison,
-%    \item a digit format: the end of each digit is marked by an dot,
-%          and the digits are in reserved order. An empty digit
-%          ends this format. The meaning of a digit is here the
-%          decimal representation of a letter, the range is
-%          from 1 until 26.
-%    \end{itemize}
-%    Example: The aim number is 100, the intermediate number 50, so
-%    following would be on the argument stack:
-%    \begin{quote}
-%      |50;100;24.1..\aa@alph|
-%    \end{quote}
-%    \cmd{\aa@process} increments the first argument |#1| (|50|),
-%    and calls \cmd{\aa@alphinc} to increment the digit form
-%    (|24.1..|). The middle part with the aim number |;#2;| (|;100;|)
-%    will not be changed. Neither \cmd{\aa@process} nor \cmd{\aa@alphinc}
-%    need the conversion command \cmd{\aa@alph} nor \cmd{\aa@Alph}.
-%    This command is read by \cmd{\aa@getresult}, if the digit form is
-%    ready.
-%
-%    The expansion motor is \cmd{\number}. It reads and expands token
-%    to get decimal numbers until a token is reached that isn't a
-%    decimal digit. So the expansion doesn't stop, if \cmd{\aa@inc}
-%    is ready, because \cmd{\aa@inc} produces only decimal digits.
-%    \cmd{\aa@alphinc} is expanded to look for further digits.
-%    Now \cmd{\aa@alphinc} makes its job and returns with its
-%    argument |;#2;|. At last the first character |;| finishes \cmd{\number}.
+%    \begin{macro}{\AlPh@ExpSearch}
+%    |#1|: number to be tested\\
+%    |#2|: symbols provider
 %    \begin{macrocode}
-  \def\aa@process#1;#2;{%
-    \ifnum#1=#2 %
-      \expandafter\aa@getresult
+\def\AlPh@ExpSearch#1!#2{%
+  \let\AlPh@Next\relax
+  \AlPh@TestNumber#1!{#2}%
+  \ifAlPh@Unavailable
+    \expandafter\AlPh@BinSearch\AlPh@Number!#1!{#2}%
+  \else
+    \def\AlPh@Number{#1}%
+    \ifnum#1>1073741823 %
+      \AlPh@TestNumber2147483647!{#2}%
+      \ifAlPh@Unavailable
+        \AlPh@BinSearch#1!2147483647!{#2}%
+      \else
+        \def\AlPh@Number{0}%
+        \AlPh@Error{%
+          Maximal symbol number not found%
+        }%
+      \fi
     \else
-      \@ReturnAfterFi{%
-        \expandafter\aa@process\number\aa@inc{#1}\aa@alphinc{;#2;}%
+      \def\AlPh@Next{%
+        \expandafter\AlPh@ExpSearch\number\intcalcShl{#1}!{#2}%
       }%
     \fi
-  }%
+  \fi
+  \AlPh@Next
+}
 %    \end{macrocode}
 %    \end{macro}
-%
-% \subsubsection{\texorpdfstring{^^A
-% Convert the separated digits to the letter result}{^^A
-% Digits to letter result}}\label{sec:form}
-%
-%    The single decimal digits of the final letter number are
-%    limited by a dot and come in reverse order. The end is
-%    marked by an empty digit.
-%    The next token is the command to convert a digit
-%    (\cmd{\aa@alph} or \cmd{\aa@Alph}), e.g.:
-%    \begin{quote}
-%      |11.3.1..\alph| $\Rightarrow$ |ack|
-%    \end{quote}
-%
-%    \begin{macro}{\aa@getresult}
-%    \cmd{\aa@getresult} reads the digits |#1| and the converting
-%    command |#2|. Then it
-%    calls \cmd{\aa@@getresult} with its arguments.
+%    \begin{macro}{\AlPh@BinSearch}
+%    |#1|: available number\\
+%    |#2|: unavailable number, |#2| $>$ |#1|\\
+%    |#3|: symbols provider
 %    \begin{macrocode}
-  \def\aa@getresult#1..#2{%
-    \aa@@getresult!#2#1..%
-  }%
+\def\AlPh@BinSearch#1!#2!#3{%
+  \expandafter\AlPh@ProcessBinSearch
+  \number\intcalcShr{\intcalcAdd{#1}{#2}}!%
+  #1!#2!{#3}%
+}
 %    \end{macrocode}
 %    \end{macro}
-%
-%    \begin{macro}{\aa@@getresult}
-%    In its first argument |#1| \cmd{\aa@@getresult} collects the
-%    converted letters in the correct order. Character |!| is used
-%    as a parameter separator. The next token |#2| is the converting
-%    command (\cmd{\aa@alph} or \cmd{\aa@Alph}). The next digit |#3|
-%    is read, converted, and |\aa@@getresult| is called again.
-%    If the digit |#3| is empty, the end of the digit form is reached
-%    and the process stops and the ready letter number is output.
+%    \begin{macro}{\AlPh@ProcessBinSearch}
+%    |#1|: number to be tested, |#2| $\leq$ |#1| $\leq$ |#3|\\
+%    |#2|: available number\\
+%    |#3|: unavailable number\\
+%    |#4|: symbols provider
 %    \begin{macrocode}
-  \def\aa@@getresult#1!#2#3.{%
-    \ifx\\#3\\%
-      \@ReturnAfterElseFi{#1}% ready
+\def\AlPh@ProcessBinSearch#1!#2!#3!#4{%
+  \let\AlPh@Next\relax
+  \ifnum#1>#2 %
+    \ifnum#1<#3 %
+      \AlPh@TestNumber#1!{#4}%
+      \ifAlPh@Unavailable
+        \def\AlPh@Next{%
+          \AlPh@BinSearch#2!#1!{#4}%
+        }%
+      \else
+        \def\AlPh@Next{%
+          \AlPh@BinSearch#1!#3!{#4}%
+        }%
+      \fi
     \else
-      \@ReturnAfterFi{%
-        \expandafter\expandafter\expandafter\expandafter
-        \expandafter\expandafter\expandafter
-        \aa@@getresult
-        \expandafter\expandafter\expandafter\expandafter
-        #2{#3}#1!#2%
-      }%
+      \def\AlPh@Number{#2}%
     \fi
-  }%
+  \else
+    \def\AlPh@Number{#2}%
+  \fi
+  \AlPh@Next
+}
 %    \end{macrocode}
 %    \end{macro}
 %
-% \subsubsection{Addition by one}
-%
-% \paragraph{Expandable addition of a decimal integer.}
-%    \begin{macro}{\aa@inc}
-%    \cmd{\aa@inc} increments its argument |#1| by one.
-%    The case, that the whole number is less than nine, is
-%    specially treated because of speed. (The space
-%    after |9| is neccessary.)
+% \subsection{Methods}
+%
+%    The names of method macros start with \cs{AlPh@Method}.
+%    These macros do the main job in converting a number to
+%    its representation.
+%    A method command is called with three arguments.
+%    The first argument is the number of symbols. The
+%    second argument is the basic macro for converting
+%    a number with limited number range. The last parameter
+%    is the number that needs converting.
+%
+% \subsubsection{Common methods}
+%
+%    \begin{macro}{\AlPh@CheckPositive}
+%    \noindent
+%    |#1|: number to be checked
+%    |#2|: continuation macro\\
+%    |#3|: number of symbols (hidden here)\\
+%    |#4|: symbol provider (hidden here)
 %    \begin{macrocode}
-% \aa@inc adds one to its argument #1.
-  \def\aa@inc#1{%
-    \ifnum#1<9 %
-      \aa@nextdigit{#1}%
-    \else
-      \aa@reverse#1!!%
-    \fi
-  }%
+\def\AlPh@CheckPositive#1!#2{%
+  \ifnum#1<1 %
+    \expandafter\@gobblefour
+  \fi
+  #2{#1}%
+}
 %    \end{macrocode}
 %    \end{macro}
-%    \begin{macro}{\aa@nextdigit}
-%    \cmd{\aa@nextdigit} increments the digit |#1|. The result
-%    is a digit again. \cmd{\aa@addone} works off the case ``9+1''.
+%
+% \subsubsection{Method `alph'}
+%
+%    \begin{macro}{\AlPh@Method@alph}
+%    \noindent
+%    |#1|: number of symbols\\
+%    |#2|: symbols provider\\
+%    |#3|: number to be converted
 %    \begin{macrocode}
-  \def\aa@nextdigit#1{\ifcase#1 1\or2\or3\or4\or5\or6\or7\or8\or9\fi}%
+\def\AlPh@Method@alph#1#2#3{%
+  \expandafter\AlPh@CheckPositive
+|   \number#3!%
++   \the\numexpr#3!%
+    \AlPh@ProcessAlph
+    {#1}{#2}%
+}
 %    \end{macrocode}
 %    \end{macro}
-%    \begin{macro}{\aa@reverse}
-%    Because the addition starts with the lowest significant digit
-%    of the number. But with the means of \TeX's macro expansion is
-%    the first digit of a number available. So \cmd{\aa@reverse}
-%    reverses the order of the digits and calls \cmd{\aa@addone},
-%    if it is ready.
+%    \begin{macro}{\AlPh@ProcessAlph}
+%    |#1|: current number\\
+%    |#2|: number of symbols\\
+%    |#3|: symbols provider
 %    \begin{macrocode}
-  \def\aa@reverse#1#2!#3!{%
-    \ifx\\#2\\%
-      \aa@addone#1#3!!%
-    \else
-      \@ReturnAfterFi{%
-        \aa@reverse#2!#1#3!%
-      }%
-    \fi
-  }%
+\def\AlPh@ProcessAlph#1#2#3{%
+  \ifnum#1>#2 %
+    \@ReturnAfterElseFi{%
+      \expandafter\AlPh@StepAlph\number
+        \intcalcInc{%
+          \intcalcMod{\intcalcDec{#1}}{#2}%
+        }%
+      \expandafter!\number
+        \intcalcDiv{\intcalcDec{#1}}{#2}%
+      !{#2}{#3}%
+    }%
+  \else
+    \@ReturnAfterFi{%
+      #3{#1}%
+    }%
+  \fi
+}
 %    \end{macrocode}
 %    \end{macro}
-%    \begin{macro}{\aa@addone}
-%    The addition is performed by the macro \cmd{\aa@addone}.
-%    The digits are in reversed order. The parameter text |#1#2|
-%    separates the next digit |#1| that have to be incremented.
-%    Already incremented digits are stored in |#3| in reversed order
-%    to take some work of \cmd{\aa@lastreverse}.
+%    \begin{macro}{\AlPh@StepAlph}
+%    |#1|: current last digit\\
+%    |#2|: new current number\\
+%    |#3|: number of symbols\\
+%    |#4|: symbols provider
 %    \begin{macrocode}
-  \def\aa@addone#1#2!#3!{%
-    \ifnum#1<9 %
-      \expandafter\aa@lastreverse\number\aa@nextdigit#1 #2!#3!%
-    \else
-      \@ReturnAfterFi{%
-        \ifx\\#2\\%
-          10#3%
-        \else
-          \@ReturnAfterFi{%
-            \aa@addone#2!0#3!%
-          }%
-        \fi
-      }%
-    \fi
-  }%
+\def\AlPh@StepAlph#1!#2!#3#4{%
+  \AlPh@ProcessAlph{#2}{#3}{#4}%
+  #4{#1}%
+}
 %    \end{macrocode}
 %    \end{macro}
-%    \begin{macro}{\aa@lastreverse}
-%    With \cmd{\aa@reverse} the order of the digits is changed to
-%    perform the addition in \cmd{\aa@addone}. Now we have to return
-%    to the original order that is done by \cmd{\aa@lastreverse}.
+%
+% \subsubsection{Method `wrap'}
+%
+%    \begin{macro}{\AlPh@Method@wrap}
+%    \noindent
+%    |#1|: number of symbols\\
+%    |#2|: symbols provider\\
+%    |#3|: number to be converted
 %    \begin{macrocode}
-  \def\aa@lastreverse#1#2!#3!{%
-    \ifx\\#2\\%
-      #1#3%
-    \else
-      \@ReturnAfterFi{%
-        \aa@lastreverse#2!#1#3!%
-      }%
-    \fi
-  }%
+\def\AlPh@Method@wrap#1#2#3{%
+  \expandafter\AlPh@CheckPositive
+|   \number#3!%
++   \the\numexpr#3!%
+    \AlPh@ProcessWrap
+    {#1}{#2}%
+}
 %    \end{macrocode}
 %    \end{macro}
 %
-% \paragraph{Increment of the decimal digit result form.}
-%    \begin{macro}{\aa@alphinc}
-%    \cmd{\aa@alphinc} adds one to the intermediate number in
-%    the decimal digit result form (see \ref{sec:form}).
-%    Parameter |#1| consists of the tokens that come before the
-%    addition result (see |;#2;| of \cmd{\aa@process}). Then
-%    it is also used to store already incremented digits.
-%    |#2| contains the next digit in the range of 1 until 26.
-%    An empty |#2| marks the end of the number.
+%    \begin{macro}{\AlPh@ProcessWrap}
+%    |#1|: number to be converted\\
+%    |#2|: number of symbols\\
+%    |#3|: symbols provider
 %    \begin{macrocode}
-  \def\aa@alphinc#1#2.{%
-    \ifx\\#2\\%
-      \@ReturnAfterElseFi{%
-        #11..% ready
-      }%
-    \else
-      \@ReturnAfterFi{%
-        \ifnum#2<26 %
-          \@ReturnAfterElseFi{%
-            \expandafter\aa@alphinclast\expandafter
-              {\number\aa@inc{#2}}{#1}%
-          }%
-        \else
-          \@ReturnAfterFi{%
-            \aa@alphinc{#11.}%
-          }%
-        \fi
-      }%
-    \fi
-  }%
+\def\AlPh@ProcessWrap#1#2#3{%
+  \ifnum#1>#2 %
+    \@ReturnAfterElseFi{%
+      \expandafter\AlPh@StepWrap\number
+        \intcalcInc{\intcalcMod{\intcalcDec{#1}}{#2}}%
+      !{#3}%
+    }%
+  \else
+    \@ReturnAfterFi{%
+      #3{#1}%
+    }%
+  \fi
+}
 %    \end{macrocode}
 %    \end{macro}
-%    \begin{macro}{\aa@alphinclast}
-%    \cmd{\aa@alphinclast} is a help macro. Because |#2| consists of
-%    several tokens (e.g. |;100;|), we cannot jump over it via
-%    \cmd{\expandafter} in \cmd{\aa@alphinc}.
+%    \begin{macro}{\AlPh@StepWrap}
+%    |#1|: final number\\
+%    |#2|: symbols provider
 %    \begin{macrocode}
-  \def\aa@alphinclast#1#2{#2#1.}%
+\def\AlPh@StepWrap#1!#2{%
+  #2{#1}%
+}
 %    \end{macrocode}
 %    \end{macro}
 %
-%    \begin{macro}{\newalphalph}
+% \subsubsection{Method `mult'}
+%
+%    After the number of symbols is exhausted,
+%    repetitions of the symbol are used.
+%    \begin{gather*}
+%      x \Def \text{number to be converted}\\
+%      n \Def \text{number of symbols}\\
+%      r \Def \text{repetition length}\\
+%      s \Def \text{symbol slot}\\
+%      r = ((x - 1) \div n) + 1\\
+%      s = ((x - 1) \mod n) + 1
+%    \end{gather*}
+%    \begin{macro}{\AlPh@Method@mult}
+%    \noindent
+%    |#1|: number of symbols\\
+%    |#2|: symbols provider\\
+%    |#3|: number to be converted
 %    \begin{macrocode}
-  \newcommand*{\newalphalph}[3]{%
-    \PackageError{alphalph}{%
-      \string\newalphalph\space requires e-TeX%
-    }\@ehc
+\def\AlPh@Method@mult#1#2#3{%
+  \expandafter\AlPh@CheckPositive
+|   \number#3!%
++   \the\numexpr#3!%
+    \AlPh@ProcessMult
+    {#1}{#2}%
+}
 %    \end{macrocode}
 %    \end{macro}
 %
-% \subsection{\texorpdfstring{Conversion with \eTeX\ features}{\eTeX}}
-%    \label{sec:etex}
+%    \begin{macro}{\AlPh@ProcessMult}
+%    |#1|: number to be converted\\
+%    |#2|: number of symbols\\
+%    |#3|: symbols provider
 %    \begin{macrocode}
-\else
-%    \end{macrocode}
-%
-%    \begin{macro}{\aa@make}
-%    \cmd{\aa@make} catches the cases, if the number is zero or negative.
-%    Then it expands to nothing like \cmd{\romannumeral}.
-%    \begin{macrocode}
-  \def\aa@make#1#2{%
-    \ifnum#1<1 %
-    \else
-      \@ReturnAfterFi{%
-        \aa@eprocess#1;#2%
-      }%
-    \fi
-  }%
+\def\AlPh@ProcessMult#1#2#3{%
+  \ifnum#1>#2 %
+    \@ReturnAfterElseFi{%
+      \expandafter\AlPh@StepMult\romannumeral
+        \intcalcInc{\intcalcDiv{\intcalcDec{#1}}{#2}}%
+        000%
+      \expandafter!\number
+        \intcalcInc{\intcalcMod{\intcalcDec{#1}}{#2}}%
+      !{#3}%
+    }%
+  \else
+    \@ReturnAfterFi{%
+      #3{#1}%
+    }%
+  \fi
+}
 %    \end{macrocode}
 %    \end{macro}
-%
-%    \begin{macro}{\aa@eprocess}
-%    The first argument |#1| contains the number that have to be
-%    converted yet, the next argument |#2| the command for making
-%    the conversion of a digit (\cmd{\aa@alph} or \cmd{\aa@Alph}).
-%    The number is divided by 26 to get the rest. Command
-%    |#2| converts the rest to a letter that is put after the arguments
-%    of the next call of \cmd{\aa@eprocess}.
-%
-%    The only feature of \eTeX\ we use the new primitive \cmd{\numexpr}.
-%    It provides expandible mathematical calculations.
+%    \begin{macro}{\AlPh@StepMult}
+%    |#1#2|: repetitions coded as list of character `m'\\
+%    |#3|: symbol slot\\
+%    |#4|: symbols provider
 %    \begin{macrocode}
-  \def\aa@eprocess#1;#2{%
-    \ifnum#1<27 %
-      \@ReturnAfterElseFi{%
-        #2{#1}%
-      }%
-    \else
-      \@ReturnAfterFi{%
-        \expandafter\aa@eprocess\number\numexpr(#1-14)/26%
-          \expandafter\expandafter\expandafter;%
-          \expandafter\expandafter\expandafter#2%
-          #2{\numexpr#1-((#1-14)/26)*26}%
-      }%
-    \fi
-  }%
+\def\AlPh@StepMult#1#2!#3!#4{%
+  \ifx\\#2\\%
+  \else
+    \@ReturnAfterFi{%
+      \AlPh@StepMult#2!#3!{#4}%
+    }%
+  \fi
+  #4{#3}%
+}
 %    \end{macrocode}
 %    \end{macro}
 %
-% \subsection{Generic version}
+% \subsection{User interface}
 %
-%    \begin{macro}{\aa@gen@callmake}
-%    See macro \cs{aa@callmake}. Argument |#3| holds the
-%    number of available symbols.
+%    \begin{macro}{\newalphalph}
+%    Macro \cs{newalphalph} had three arguments in versions below 2.0.
+%    For the new method argument we use an optional argument an first
+%    position.\\
+%    |#1|: cmd\\
+%    |[#2]|: method name: |alph| (default), |wrap|, |mult|\\ % hash-ok
+%    |#3|: symbols provider\\
+%    |#4|: number of symbols
 %    \begin{macrocode}
-  \def\aa@gen@callmake#1#2#3{%
-    \expandafter\aa@gen@make\expandafter{\number#3}#1{#2}%
+\AlPh@IfDefinable\newalphalph{%
+  \def\newalphalph#1{%
+    \AlPh@IfOptArg{%
+      \AlPh@newalphalph{#1}%
+    }{%
+      \AlPh@newalphalph{#1}[alph]%
+    }%
   }%
+}
 %    \end{macrocode}
 %    \end{macro}
-%    \begin{macro}{\aa@gen@make}
-%    See macro \cs{aa@make}. Argument |#3| holds the number of
-%    available symbols.
+%    \begin{macro}{\AlPh@newalphalph}
+%    |#1|: cmd
+%    |#2|: method name\\
+%    |#3|: symbols provider\\
+%    |#4|: number of symbols
 %    \begin{macrocode}
-  \def\aa@gen@make#1#2#3{%
-    \ifnum#1<1 %
+\def\AlPh@newalphalph#1[#2]#3#4{%
+  \begingroup\expandafter\expandafter\expandafter\endgroup
+  \expandafter\ifx\csname AlPh@Method@#2\endcsname\relax
+    \AlPh@Error{%
+      Unknown method %
+|     `#2'%
++     `\detokenize{#2}'%
+    }%
+  \else
+    \ifx\\#4\\%
+      \AlPh@GetNumberOfSymbols{#3}%
+      \ifcase\AlPh@Number
+      \else
+        \begingroup
+          \escapechar=92 % backslash
+          \@PackageInfo{alphalph}{%
+            Number of symbols for \string#1 is \AlPh@Number
+          }%
+        \endgroup
+        \expandafter\AlPh@NewAlphAlph
+        \csname AlPh@Method@#2\expandafter\endcsname
+        \AlPh@Number!{#1}{#3}%
+      \fi
     \else
-      \@ReturnAfterFi{%
-        \aa@gen@eprocess{#3}#1;#2%
-      }%
+      \expandafter\AlPh@NewAlphAlph
+      \csname AlPh@Method@#2\expandafter\endcsname
+|     \number#4!%
++     \the\numexpr#4!%
+      {#1}{#3}%
     \fi
-  }%
+  \fi
+}%
 %    \end{macrocode}
 %    \end{macro}
-%    \begin{macro}{\aa@gen@eprocess}
-%    See macro \cs{aa@eprocess}. Argument |#1| holds the number of
-%    available symbols.
+%    \begin{macro}{\AlPh@NewAlphAlph}
+%    |#1|: method macro\\
+%    |#2|: number of symbols\\
+%    |#3|: cmd\\
+%    |#4|: symbols provider
 %    \begin{macrocode}
-  \def\aa@gen@eprocess#1#2;#3{%
-    \ifnum#2>#1 %
-      \@ReturnAfterElseFi{%
-        \expandafter\aa@gen@eprocess\expandafter{%
-          \number#1\expandafter
-        }%
-        \number\numexpr(#2-(\aa@half{#1}+1))/#1%
-        \expandafter\expandafter\expandafter;%
-        \expandafter\expandafter\expandafter#3%
-        #3{\numexpr#2-((#2-(\aa@half{#1}+1))/#1)*#1\relax}%
-      }%
+\def\AlPh@NewAlphAlph#1#2!#3#4{%
+  \AlPh@IfDefinable#3{%
+    \ifnum#2>0 %
+      \def#3{#1{#2}{#4}}%
     \else
-      \@ReturnAfterFi{%
-        #3{#2}%
-      }%
+      \AlPh@Error{%
+          Definition of \string#3 failed,\MessageBreak
+          because number of symbols (#2) is not positive%
+        }%
     \fi
   }%
+}
 %    \end{macrocode}
 %    \end{macro}
-%    \begin{macro}{\aa@half}
-%    Macro \cs{aa@half} implements integer division by two
-%    without rounding.
+%
+%    \begin{macro}{\AlphAlph}
 %    \begin{macrocode}
-  \def\aa@half#1{%
-    \number\dimexpr.5\dimexpr #1sp\relax\relax
-  }%
+\newalphalph\AlphAlph\alphalph@Alph{26}
 %    \end{macrocode}
 %    \end{macro}
-%    \begin{macro}{\newalphalph}
-%    New macros are defined by \cs{newalphalph} that act like
-%    \cs{alphalph}. The macro to be defined is |#1|. Argument |#2|
-%    contains the macro that converts a number to a symbol and
-%    argument |#3| holds the number of available symbols.
+%    \begin{macro}{\alphalph}
 %    \begin{macrocode}
-  \newcommand*{\newalphalph}[3]{%
-    \newcommand*{#1}{}%
-    \edef#1{%
-      \noexpand\aa@gen@callmake\noexpand#2{\number\numexpr#3}%
-    }%
-  }%
+\newalphalph\alphalph\alphalph@alph{26}
 %    \end{macrocode}
 %    \end{macro}
 %
-% \subsection{End\texorpdfstring{ of package}{}}
-%    Now we can terminate the differentiation between \TeX\ and \eTeX.
 %    \begin{macrocode}
-\fi
+\AlPh@AtEnd
+%</package>
 %    \end{macrocode}
 %
-%    At the end the catcode of the character |@| is restored.
+% \section{Test}
+%
+% \subsection{Catcode checks for loading}
+%
 %    \begin{macrocode}
-\catcode`\@=\aa@atcode
+%<*test1>
 %    \end{macrocode}
 %    \begin{macrocode}
-%</package>
+\catcode`\@=11 %
+\def\RestoreCatcodes{}
+\count@=0 %
+\loop
+  \edef\RestoreCatcodes{%
+    \RestoreCatcodes
+    \catcode\the\count@=\the\catcode\count@\relax
+  }%
+\ifnum\count@<255 %
+  \advance\count@\@ne
+\repeat
+
+\def\RangeCatcodeInvalid#1#2{%
+  \count@=#1\relax
+  \loop
+    \catcode\count@=15 %
+  \ifnum\count@<#2\relax
+    \advance\count@\@ne
+  \repeat
+}
+\def\Test{%
+  \RangeCatcodeInvalid{0}{47}%
+  \RangeCatcodeInvalid{58}{64}%
+  \RangeCatcodeInvalid{91}{96}%
+  \RangeCatcodeInvalid{123}{255}%
+  \catcode`\@=12 %
+  \catcode`\\=0 %
+  \catcode`\{=1 %
+  \catcode`\}=2 %
+  \catcode`\#=6 %
+  \catcode`\[=12 %
+  \catcode`\]=12 %
+  \catcode`\%=14 %
+  \catcode`\ =10 %
+  \catcode13=5 %
+  \input alphalph.sty\relax
+  \RestoreCatcodes
+}
+\Test
+\csname @@end\endcsname
+\end
+%    \end{macrocode}
+%    \begin{macrocode}
+%</test1>
 %    \end{macrocode}
+%
+% \section{Macro tests}
+%
+%    \begin{macrocode}
+%<*test2>
+\NeedsTeXFormat{LaTeX2e}
+\nofiles
+\documentclass{article}
+%<*noetex>
+\makeatletter
+\let\saved@numexpr\numexpr
+\newcommand*{\DisableNumexpr}{%
+  \let\numexpr\@undefined
+}
+\newcommand*{\RestoreNumexpr}{%
+  \let\numexpr\saved@numexpr
+}
+\DisableNumexpr
+%</noetex>
+\usepackage{alphalph}[2007/04/11]
+%<noetex>\RestoreNumexpr
+\usepackage{qstest}
+\IncludeTests{*}
+\LogTests{log}{*}{*}
+
+\newcommand*{\TestCmd}[3]{%
+  \setbox0=\hbox{%
+%<noetex>    \DisableNumexpr
+    \edef\TestString{#1{#2}}%
+    \expandafter\Expect\expandafter{\TestString}{#3}%
+    \edef\TestString{#1{#2} }%
+    \expandafter\Expect\expandafter{\TestString}{#3 }%
+  }%
+  \Expect*{\the\wd0}{0.0pt}%
+}
+
+\makeatletter
+\newalphalph\LaTeXAlphAlph\@Alph{26}
+\newalphalph\LaTeXalphalph\@alph{26}
+\newalphalph\AlphWrap[wrap]\alphalph@Alph{26}
+\newalphalph\alphwrap[wrap]\alphalph@alph{26}
+\newalphalph\LaTeXAlphWrap[wrap]\@Alph{26}
+\newalphalph\LaTeXalphwrap[wrap]\@alph{26}
+\def\LastSymbol#1{%
+  \ifx\\#1\\%
+  \else
+    \@LastSymbol#1\@nil
+  \fi
+}
+\def\@LastSymbol#1#2\@nil{%
+  \ifx\\#2\\%
+    #1%
+  \else
+    \@LastSymbol#2\@nil
+  \fi
+}
+\makeatother
+\newcommand*{\TestAlph}[2]{%
+  \uppercase{\TestCallCmd\AlphAlph{#2}}{#1}%
+  \lowercase{\TestCallCmd\alphalph{#2}}{#1}%
+  \uppercase{\TestCallCmd\LaTeXAlphAlph{#2}}{#1}%
+  \lowercase{\TestCallCmd\LaTeXalphalph{#2}}{#1}%
+  \edef\WrapString{\LastSymbol{#2}}%
+  \expandafter\TestAlphWrap\expandafter{\WrapString}{#1}%
+}
+\newcommand*{\TestAlphWrap}[2]{%
+  \uppercase{\TestCallCmd\AlphWrap{#1}}{#2}%
+  \lowercase{\TestCallCmd\alphwrap{#1}}{#2}%
+  \uppercase{\TestCallCmd\LaTeXAlphWrap{#1}}{#2}%
+  \lowercase{\TestCallCmd\LaTeXalphwrap{#1}}{#2}%
+}
+\newcommand*{\TestCallCmd}[3]{%
+  \TestCmd#1{#3}{#2}%
+}
+\begin{qstest}{AlphSymbols}{alphalph, AlphAlph, symbols}
+  \TestAlph{1}{a}%
+  \TestAlph{2}{b}%
+  \TestAlph{3}{c}%
+  \TestAlph{4}{d}%
+  \TestAlph{5}{e}%
+  \TestAlph{6}{f}%
+  \TestAlph{7}{g}%
+  \TestAlph{8}{h}%
+  \TestAlph{9}{i}%
+  \TestAlph{10}{j}%
+  \TestAlph{11}{k}%
+  \TestAlph{12}{l}%
+  \TestAlph{13}{m}%
+  \TestAlph{14}{n}%
+  \TestAlph{15}{o}%
+  \TestAlph{16}{p}%
+  \TestAlph{17}{q}%
+  \TestAlph{18}{r}%
+  \TestAlph{19}{s}%
+  \TestAlph{20}{t}%
+  \TestAlph{21}{u}%
+  \TestAlph{22}{v}%
+  \TestAlph{23}{w}%
+  \TestAlph{24}{x}%
+  \TestAlph{25}{y}%
+  \TestAlph{26}{z}%
+\end{qstest}
+\begin{qstest}{AlphRange}{alphalph, range}
+  \TestAlph{0}{}%
+  \TestAlph{-1}{}%
+  \TestAlph{-2147483647}{}%
+  \TestAlph{27}{aa}%
+  \TestAlph{28}{ab}%
+  \TestAlph{52}{az}%
+  \TestAlph{53}{ba}%
+  \TestAlph{78}{bz}%
+  \TestAlph{79}{ca}%
+  \TestAlph{702}{zz}%
+  \TestAlph{703}{aaa}%
+  \TestAlph{2147483647}{fxshrxw}%
+\end{qstest}
+
+\makeatletter
+\newcommand*{\myvocals}[1]{%
+  \ifcase#1X\or A\or E\or I\or O\or U\else Y\fi
+}
+\makeatother
+\newalphalph\vocalsvocals\myvocals{5}
+\newcommand*{\TestVocals}{%
+  \TestCmd\vocalsvocals
+}
+\begin{qstest}{vocals}{vocals}
+  \TestVocals{0}{}%
+  \TestVocals{1}{A}%
+  \TestVocals{2}{E}%
+  \TestVocals{3}{I}%
+  \TestVocals{4}{O}%
+  \TestVocals{5}{U}%
+  \TestVocals{6}{AA}%
+  \TestVocals{7}{AE}%
+  \TestVocals{8}{AI}%
+  \TestVocals{9}{AO}%
+  \TestVocals{10}{AU}%
+  \TestVocals{11}{EA}%
+  \TestVocals{24}{OO}%
+  \TestVocals{25}{OU}%
+  \TestVocals{26}{UA}%
+  \TestVocals{29}{UO}%
+  \TestVocals{30}{UU}%
+  \TestVocals{31}{AAA}%
+  \TestVocals{155}{UUU}%
+  \TestVocals{156}{AAAA}%
+  \TestVocals{2147483647}{AIIOOEEIOIIUOE}%
+\end{qstest}
+
+\makeatletter
+\newalphalph\AlphMult[mult]{\alphalph@Alph}{26}
+\newalphalph\alphmult[mult]{\alphalph@alph}{26}
+\newalphalph\LaTeXAlphMult[mult]{\@Alph}{26}
+\newalphalph\LaTeXalphmult[mult]{\@alph}{26}
+\makeatother
+\newcommand*{\TestMult}[2]{%
+  \uppercase{\TestCallCmd\AlphMult{#2}}{#1}%
+  \lowercase{\TestCallCmd\alphmult{#2}}{#1}%
+  \uppercase{\TestCallCmd\LaTeXAlphMult{#2}}{#1}%
+  \lowercase{\TestCallCmd\LaTeXalphmult{#2}}{#1}%
+}
+\begin{qstest}{mult}{mult}
+  \TestMult{0}{}%
+  \TestMult{-1}{}%
+  \TestMult{-2147483647}{}%
+  \TestMult{1}{a}%
+  \TestMult{2}{b}%
+  \TestMult{26}{z}%
+  \TestMult{27}{aa}%
+  \TestMult{28}{bb}%
+  \TestMult{52}{zz}%
+  \TestMult{53}{aaa}%
+  \TestMult{54}{bbb}%
+  \TestMult{259}{yyyyyyyyyy}%
+  \TestMult{260}{zzzzzzzzzz}%
+  \TestMult{261}{aaaaaaaaaaa}%
+  \TestMult{262}{bbbbbbbbbbb}%
+\end{qstest}
+
+\def\myvocalsB#1{%
+  \ifcase#1\or A\or E\or I\or O\or U\fi
+}
+\begin{qstest}{symbolnum}{symbolnum}
+  \makeatletter
+  \def\Test#1#2{%
+    \let\TestCmd\relax
+    \newalphalph\TestCmd{#1}{}%
+    \Expect*{\AlPh@Number}{#2}%
+  }%
+  \Test\@alph{26}%
+  \Test\@Alph{26}%
+  \Test\@fnsymbol{9}%
+  \Test\myvocalsB{5}%
+  \Test\alphalph@alph{26}%
+  \Test\alphalph@Alph{26}%
+\end{qstest}
+
+\begin{qstest}{list}{list}
+  \makeatletter
+  \def\catch#1\relax{%
+    \def\FoundList{\catch#1}%
+  }%
+  \def\Test[#1]#2#3#4{%
+    \let\testcmd\relax
+    \newalphalph\testcmd[{#1}]{\catch}{#2}%
+    \testcmd{#3}|\relax
+    \expandafter\Expect\expandafter{\FoundList}{#4|}%
+    %
+    \let\SavedCatch\catch
+    \def\catch{\noexpand\catch\noexpand\foo}%
+    \edef\Result{#4|}%
+    \@onelevel@sanitize\Result
+    \let\catch\SavedCatch
+    \let\testcmd\relax
+    \newalphalph\testcmd[{#1}]{\catch\foo}{#2}%
+    \testcmd{#3}|\relax
+    \@onelevel@sanitize\FoundList
+    \Expect*{\FoundList}*{\Result}%
+  }%
+  \Test[alph]{26}{3}{\catch{3}}%
+  \Test[alph]{26}{12}{\catch{12}}%
+  \Test[alph]{26}{27}{\catch{1}\catch{1}}%
+  \Test[alph]{26}{78}{\catch{2}\catch{26}}%
+  \Test[wrap]{26}{7}{\catch{7}}%
+  \Test[wrap]{26}{14}{\catch{14}}%
+  \Test[wrap]{26}{80}{\catch{2}}%
+  \Test[wrap]{26}{700}{\catch{24}}%
+  \Test[mult]{26}{4}{\catch{4}}%
+  \Test[mult]{26}{17}{\catch{17}}%
+  \Test[mult]{26}{54}{\catch{2}\catch{2}\catch{2}}%
+\end{qstest}
+
+\begin{document}
+\end{document}
+%</test2>
+%    \end{macrocode}
+%
 % \section{Installation}
 %
 % \subsection{Download}
@@ -862,6 +1586,9 @@ and the derived files
 % \begin{tabular}{@{}>{\ttfamily}l@{ $\rightarrow$ }>{\ttfamily}l@{}}
 %   alphalph.sty & tex/generic/oberdiek/alphalph.sty\\
 %   alphalph.pdf & doc/latex/oberdiek/alphalph.pdf\\
+%   alphalph-test1.tex & doc/latex/oberdiek/alphalph-test1.tex\\
+%   alphalph-test2.tex & doc/latex/oberdiek/alphalph-test2.tex\\
+%   alphalph-test3.tex & doc/latex/oberdiek/alphalph-test3.tex\\
 %   alphalph.dtx & source/latex/oberdiek/alphalph.dtx\\
 % \end{tabular}^^A
 % }^^A
@@ -1034,6 +1761,15 @@ and the derived files
 %   \item
 %     Line ends sanitized.
 %   \end{Version}
+%   \begin{Version}{2007/09/09 v2.0}
+%   \item
+%     New implementation that uses package \cs{intcalc}.
+%     This removes the dependency on \eTeX.
+%   \item
+%     \cs{newalphalph} is extended to support new methods `wrap' and 'multi'.
+%   \item
+%     Documentation rewritten.
+%   \end{Version}
 % \end{History}
 %
 % \PrintIndex
-- 
cgit v1.2.3

