% \iffalse meta-comment
%
% alphalph.dtx
%
% This file is part of the package `alphalph' for use with LaTeX2e.
%
% Function: Selecting shipout output pages.
%
% Copyright (C) 1999 Heiko Oberdiek.
%
% This program can be redistributed and/or modified
% under the terms of the LaTeX Project Public License
% distributed from CTAN archives in directory
% macros/latex/base/lppl.txt; either version 1 of
% the License, or (at your option) any later version.
%
% Please send error reports and suggestions for improvements to
%   Heiko Oberdiek <oberdiek@ruf.uni-freiburg.de>.
%
% This is the desperate try to use only one identification string
% with the verion info:
%<*dtx>
          \ProvidesFile{alphalph.dtx}
%</dtx>
%<package>\ifx\ProvidesPackage\UnDeFiNeD
%<package>\begingroup\def\x#1#2#3[#4]#5{\endgroup\csname fi\endcsname
%<package>\immediate\write-1{Package: #3 #4 }}\x
%<package>\else
%<package>\ProvidesPackage{alphalph}%
%<driver>\ProvidesFile{alphalph.drv}
% \fi
%         \ProvidesFile{alphalph.dtx}
  [1999/04/13 v1.1 Converting numbers to letters (HO)]
%
% \iffalse
%<package>\fi
% \fi
% \GetFileInfo{alphalph.dtx}
%
% \CheckSum{268}
%
%% \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         \~}
%%
% \iffalse
%<*driver>
\documentclass{ltxdoc}
\usepackage{holtxdoc,alphalph}
\begin{document}
   \DocInput{alphalph.dtx}
\end{document}
%</driver>
% \fi
%
% ^^A\DoNotIndex{\ifnum,\ifx,\ifcase}
% \DoNotIndex{\or,\else,\fi,\csname,\endcsname}
% \DoNotIndex{\def,\edef,\long,\begingroup,\endgroup}
% \DoNotIndex{\@,\\}
% \DoNotIndex{\the,\relax,\expandafter}
%
% \newenvironment{param}{^^A
%   \newcommand{\entry}[1]{\meta{\###1}:&}^^A
%   \begin{tabular}[t]{@{}l@{ }l@{}}^^A
% }{^^A
%   \end{tabular}^^A
% }
%
% \SetupTitle{number,count,alph,TeX}
% \maketitle
%
% \begin{abstract}
%    The package provides the new expandable commands \cmd{\alphalph}
%    and \cmd{\AlphAlph}.
%    They are like \cmd{\number}, but the expansion consists of
%    lowercase and uppercase letters respectively.
% \end{abstract}
%
% \tableofcontents
%
% \section{Usage}
%    The package \Package{alphalph} can used with both plain\TeX\
%    and \LaTeX:
%    \begin{description}
%    \item[plain\TeX:] |\input alphalph.sty|
%    \item[\LaTeXe:]   |\usepackage{alphalph}|\\
%         There aren't any options.
%    \end{description}
%
% \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}
%
% \section{Installation}
% \InstallPackage
%    Or for use with TeX:
%    \begin{quote}
%      \Verb{texmf/tex/generic/misc/alphalph.sty}
%    \end{quote}
% \newcommand*{\ExtraDocumentation}{%
%    For generating the documentation the \eTeX-extension is recommended,
%    because it works faster with \Package{alphalph}.
% }
% \InstallDocumentation
%
% \StopEventually{}
%
% \section{Implementation}
% \subsection{Begin\texorpdfstring{ of package}{}}
%    \begin{macrocode}
%<*package>
%    \end{macrocode}
%    The package identification is done at the top of the |.dtx| file
%    in order to use only one identification string.
%
%    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.
%    \begin{macrocode}
\expandafter\edef\csname aa@atcode\endcsname{\the\catcode`\@ }
\catcode`\@=11
%    \end{macrocode}
%
% \subsection{Help macros}
%    \begin{macro}{\@ReturnAfterElseFi}
%    \begin{macro}{\@ReturnAfterFi}
%    The following commands moves the `then' and `else' part respectively
%    behind the |\if|-construct. This prevents a too deep |\if|-nesting
%    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).
%    \begin{macrocode}
\long\def\@ReturnAfterElseFi#1\else#2\fi{\fi#1}
\long\def\@ReturnAfterFi#1\fi{\fi#1}
%    \end{macrocode}
%    \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).
%    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.
%    \begin{macrocode}
\def\aa@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%
  \else
    @%
  \fi
}
\def\aa@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%
  \else
    @%
  \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{macrocode}
\def\alphalph{\aa@callmake\aa@alph}
\def\AlphAlph{\aa@callmake\aa@Alph}
%    \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.)
%    \begin{macrocode}
\def\aa@callmake#1#2{%
  \expandafter\aa@make\expandafter{\number#2}#1%
}
%    \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{macrocode}
\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname numexpr\endcsname\relax
%    \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}.
%    \begin{macrocode}
\def\aa@make#1#2{%
  \ifnum#1<1
  \else
    \@ReturnAfterFi{%
      \aa@process1;#1;1..#2%
    }%
  \fi
}
%    \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{macrocode}
\def\aa@process#1;#2;{%
  \ifnum#1=#2
    \expandafter\aa@getresult
  \else
    \@ReturnAfterFi{%
      \expandafter\aa@process\number\aa@inc{#1}\aa@alphinc{;#2;}%
    }%
  \fi
}
%    \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{macrocode}
\def\aa@getresult#1..#2{%
  \aa@@getresult!#2#1..%
}
%    \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{macrocode}
\def\aa@@getresult#1!#2#3.{%
  \ifx\\#3\\%
    \@ReturnAfterElseFi{#1}% ready
  \else
    \@ReturnAfterFi{%
      \expandafter\expandafter\expandafter\expandafter
      \expandafter\expandafter\expandafter
      \aa@@getresult
      \expandafter\expandafter\expandafter\expandafter
      #2{#3}#1!#2%
    }%
  \fi
}
%    \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.)
%    \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
}
%    \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''.
%    \begin{macrocode}
\def\aa@nextdigit#1{\ifcase#1 1\or2\or3\or4\or5\or6\or7\or8\or9\fi}
%    \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{macrocode}
\def\aa@reverse#1#2!#3!{%
  \ifx\\#2\\%
    \aa@addone#1#3!!%
  \else
    \@ReturnAfterFi{%
      \aa@reverse#2!#1#3!%
    }%
  \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{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
}
%    \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}.
%    \begin{macrocode}
\def\aa@lastreverse#1#2!#3!{%
  \ifx\\#2\\%
    #1#3%
  \else
    \@ReturnAfterFi{%
      \aa@lastreverse#2!#1#3!%
    }%
  \fi
}
%    \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{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
}
%    \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{macrocode}
\def\aa@alphinclast#1#2{#2#1.}
%    \end{macrocode}
%    \end{macro}
%
% \subsection{\texorpdfstring{Conversion with \eTeX\ features}{\eTeX}}
%    \label{sec:etex}
%    \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
}
%    \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{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
}
%    \end{macrocode}
%    \end{macro}
%
% \subsection{End\texorpdfstring{ of package}{}}
%    Now we can terminate the differentiation between \TeX\ and \eTeX.
%    \begin{macrocode}
\fi
%    \end{macrocode}
%
%    At the end the catcode of the character |@| is restored.
%    \begin{macrocode}
\catcode`\@=\aa@atcode
%    \end{macrocode}
%    \begin{macrocode}
%</package>
%    \end{macrocode}
%
% \StartHistory
% \HistVersion{1999/03/19 v0.1}
%   \begin{itemize}
%   \item The first version was built as a response to a
%         \URL{question}^^A
%           {http://www.dejanews.com/[ST_rn=ps]/getdoc.xp?AN=455791936}^^A
%         of \Email[Will Douglas]{william.douglas@wolfson.ox.ac.uk}
%         and the
%         \URL{request}^^A
%           {http://www.dejanews.com/[ST_rn=ps]/getdoc.xp?AN=456358639}^^A
%         of \Email[Donald Arsenau]{asnd@reg.triumf.ca},
%         published in the newsgroup
%         \href{news:comp.text.tex}{comp.text.tex}:
%         \URL{``Re: alph counters \textgreater\ 26''}^^A
%           {http://www.dejanews.com/[ST_rn=ps]/getdoc.xp?AN=456485421}
%   \item Copyright: LPPL (\CTAN{macros/latex/base/lppl.txt})
%   \end{itemize}
% \HistVersion{1999/04/12 v1.0}
%   \begin{itemize}
%   \item Documentation added in dtx format.
%   \item \eTeX\ support added.
%   \end{itemize}
% \HistVersion{1999/04/13 v1.1}
%   \begin{itemize}
%   \item Minor documentation change.
%   \item First CTAN release.
%   \end{itemize}
%
% \PrintIndex
%
% \Finale
\endinput
