From d85f248e3b38ea0ecda38c5340e3cadd08d65346 Mon Sep 17 00:00:00 2001 From: Karl Berry 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} % % \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 +% % \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} -% +\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} +% % \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 +% +\usepackage{alphalph}[2007/04/11] +%\RestoreNumexpr +\usepackage{qstest} +\IncludeTests{*} +\LogTests{log}{*}{*} + +\newcommand*{\TestCmd}[3]{% + \setbox0=\hbox{% +% \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} +% +% \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