# Converting numbers to letters, but starting with 0=A instead of 1=A

As the title implies, essentially I want to convert a number to a letter, and this thread does a phenomenal job at solving that.

egreg gave a great solution that I've been tinkering with, but despite researching what documentation I could find around this, I can't seem to adapt his solution to output 0=A, instead of 1=A.

Here's one of egreg's solutions that I'm trying to work with:

\newcommand\makeAlph[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\fi}


Is it possible for me to easily adapt it this way, or is there a better solution for my particularly use-case? It feels like an absurdly simple thing, yet I can't seem to nail it down.

I'm happy to explore any other proposed routes, or provide more detail if that's needed (although this seems pretty straightforward).

Thanks!

(I also asked the opposite question later, regarding converting letters to numbers.)

The syntax for \ifcase is

\ifcase <number>
% case 0
\or % case 1
\or % case 2
...
\else % other cases
\fi


So the easiest change is to put a in case 0 rather than in case 1, so just remove the first \or (but use the next option):

\newcommand\makeAlph[1]{%
\ifcase #1 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\fi}


You could make that a bit safer and also accept a numerical expression (something like 2+2) as argument by using \numexpr:

\newcommand\makeAlph[1]{%
\ifcase\numexpr#1\relax 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\fi}

• Hi Phelype! This is exactly what I was missing, and solves my problem. I didn't thoroughly understand the logic and overlooked it, but it makes sense now. Cheers! Apr 30, 2021 at 1:42

You can do it in several ways. A “newer” one is with expl3, which has \int_to_alph:n, which accepts an expression in the argument.

However, this function returns combinations of letters for values greater than 26, which you don't want. Easy enough: add a test for the accepted range.

\documentclass{article}

\ExplSyntaxOn

\NewExpandableDocumentCommand{\makeAlph}{m}
{
\int_compare:nTF { 0 <= #1 <= 25 }
{
\int_to_alph:n { #1 + 1 }
}
{
Bummer!
}
}

\ExplSyntaxOff

\begin{document}

\makeAlph{0}--\makeAlph{25}

\makeAlph{26}

\end{document}


If you prefer that the command silently ignores out-of-range values,

\ExplSyntaxOn

\NewExpandableDocumentCommand{\makeAlph}{m}
{
\int_compare:nT { 0 <= #1 <= 25 } { \int_to_alph:n { #1 + 1 } }
}

\ExplSyntaxOff


which is essentially a one-liner.

• Definitely expressive and easy! I'm falling in love with LaTeX3. :-p Apr 30, 2021 at 7:39

Here is my LuaLaTeX-based solution. I like Lua because Python is my preferred scripting language, and it has a lot of similarities in syntax. It's easy for me to mentally separate and manage what is coded vs. what is typeset. The proposed solution should be straightforward to expand if you'd like to include error checking/throwing, for example, if the user passed -1, 28, or "alpha" to the function/command.

\documentclass{letter}
\usepackage{luacode}
\begin{luacode*}
function num2let(arg)
local argInt = tonumber(arg)
if argInt ~= nil then
if  (0 <= argInt) and (argInt <= 25) then
tex.print(string.char(65 + argInt))
end -- can put an else statement for error tracking
end -- can put an else statement for error tracking
end
\end{luacode*}
\newcommand{\NumToLet}[1]{\directlua{num2let(#1)}}

\begin{document}
Valid: \NumToLet{0}\NumToLet{1}...\NumToLet{25}

Invalid: \NumToLet{-1}, \NumToLet{26}, \NumToLet{alpha}
\end{document}



If you like, you can use a macro that processes a delimited argument for distingusihing the 28 cases 0..25, ⟨argument empty⟩, ⟨argument none of the further⟩ from each other.

With the example below the macro \makeAlph takes two arguments, the first argument being the TeX-⟨number⟩-quantity to convert to character, the second argument denoting tokens to be delivered in case of error, i.e., in case the first argument not being in range 0..25.

With the example below it is just relied on \makeAlph's 1st argument being a TeX-⟨number⟩-quantity. There is no checking if \makeAlph's 1st argument is a TeX-⟨number⟩-quantity: The 1st argument is a set of tokens, thus is something that might form an arbitrary (expansion-based) algorithm. Checking if the result of carrying out such an algorithm yields a TeX-⟨number⟩-quantity subsumes checking if such an algorithm terminates at all/terminates without error-message. This in turn reminds me of the halting-problem ...

Nonetheless there is a test for exclamation-mark so that you cannot outmaneuver the thing by arguments like 0!1!2!3!4!5!6!7!8!9!10!11!12!13!14!15!16!17!18!19!20!21!22!23!24!25! where applying \number to the 1st token will not trigger an error-message and which might erroneously match up \makeAlphfork's delimiter.

\errorcontextlines=10000
\documentclass{article}

\makeatletter
\@ifdefinable\gobbletoexclam{\long\def\gobbletoexclam#1!{}}%
\newcommand\makeAlph[1]{%
\expandafter\innermakeAlph\expandafter{\number#1}%
}
\newcommand\innermakeAlph[2]{%
% Test if #1 contains exclamation-mark:
\ifcat$\detokenize\expandafter{\gobbletoexclam#1!}$%
\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{%
% #1 does not contain exclamation-mark:
\makeAlphfork
!#1!0!1!2!3!4!5!6!7!8!9!10!11!12!13!14!15!16!17!18!19!20!21!22!23!24!25!{#2}% argument empty
!!#1!1!2!3!4!5!6!7!8!9!10!11!12!13!14!15!16!17!18!19!20!21!22!23!24!25!{a}%
!!0!#1!2!3!4!5!6!7!8!9!10!11!12!13!14!15!16!17!18!19!20!21!22!23!24!25!{b}%
!!0!1!#1!3!4!5!6!7!8!9!10!11!12!13!14!15!16!17!18!19!20!21!22!23!24!25!{c}%
!!0!1!2!#1!4!5!6!7!8!9!10!11!12!13!14!15!16!17!18!19!20!21!22!23!24!25!{d}%
!!0!1!2!3!#1!5!6!7!8!9!10!11!12!13!14!15!16!17!18!19!20!21!22!23!24!25!{e}%
!!0!1!2!3!4!#1!6!7!8!9!10!11!12!13!14!15!16!17!18!19!20!21!22!23!24!25!{f}%
!!0!1!2!3!4!5!#1!7!8!9!10!11!12!13!14!15!16!17!18!19!20!21!22!23!24!25!{g}%
!!0!1!2!3!4!5!6!#1!8!9!10!11!12!13!14!15!16!17!18!19!20!21!22!23!24!25!{h}%
!!0!1!2!3!4!5!6!7!#1!9!10!11!12!13!14!15!16!17!18!19!20!21!22!23!24!25!{i}%
!!0!1!2!3!4!5!6!7!8!#1!10!11!12!13!14!15!16!17!18!19!20!21!22!23!24!25!{j}%
!!0!1!2!3!4!5!6!7!8!9!#1!11!12!13!14!15!16!17!18!19!20!21!22!23!24!25!{k}%
!!0!1!2!3!4!5!6!7!8!9!10!#1!12!13!14!15!16!17!18!19!20!21!22!23!24!25!{l}%
!!0!1!2!3!4!5!6!7!8!9!10!11!#1!13!14!15!16!17!18!19!20!21!22!23!24!25!{m}%
!!0!1!2!3!4!5!6!7!8!9!10!11!12!#1!14!15!16!17!18!19!20!21!22!23!24!25!{n}%
!!0!1!2!3!4!5!6!7!8!9!10!11!12!13!#1!15!16!17!18!19!20!21!22!23!24!25!{o}%
!!0!1!2!3!4!5!6!7!8!9!10!11!12!13!14!#1!16!17!18!19!20!21!22!23!24!25!{p}%
!!0!1!2!3!4!5!6!7!8!9!10!11!12!13!14!15!#1!17!18!19!20!21!22!23!24!25!{q}%
!!0!1!2!3!4!5!6!7!8!9!10!11!12!13!14!15!16!#1!18!19!20!21!22!23!24!25!{r}%
!!0!1!2!3!4!5!6!7!8!9!10!11!12!13!14!15!16!17!#1!19!20!21!22!23!24!25!{s}%
!!0!1!2!3!4!5!6!7!8!9!10!11!12!13!14!15!16!17!18!#1!20!21!22!23!24!25!{t}%
!!0!1!2!3!4!5!6!7!8!9!10!11!12!13!14!15!16!17!18!19!#1!21!22!23!24!25!{u}%
!!0!1!2!3!4!5!6!7!8!9!10!11!12!13!14!15!16!17!18!19!20!#1!22!23!24!25!{v}%
!!0!1!2!3!4!5!6!7!8!9!10!11!12!13!14!15!16!17!18!19!20!21!#1!23!24!25!{w}%
!!0!1!2!3!4!5!6!7!8!9!10!11!12!13!14!15!16!17!18!19!20!21!22!#1!24!25!{x}%
!!0!1!2!3!4!5!6!7!8!9!10!11!12!13!14!15!16!17!18!19!20!21!22!23!#1!25!{y}%
!!0!1!2!3!4!5!6!7!8!9!10!11!12!13!14!15!16!17!18!19!20!21!22!23!24!#1!{z}%
!!0!1!2!3!4!5!6!7!8!9!10!11!12!13!14!15!16!17!18!19!20!21!22!23!24!25!{#2}% argument s.th. else without exclamation-mark
!!!!%
}{%
% #1 does contain exclamation-mark -> argument s.th. else with exclamation-mark:
#2%
}%
}%
\@ifdefinable\makeAlphfork{%
\long\def\makeAlphfork#1!!0!1!2!3!4!5!6!7!8!9!10!11!12!13!14!15!16!17!18!19!20!21!22!23!24!25!#2#3!!!!{#2}%
}%
% An error-message-command:
\newcommand\makeAlpherrordefault{%
%\PackageError{Package-Name}{Invalid argument for \string\makeAlph}{Only TeX-<number>-quantities in range 0..25 are allowed!}%
\GenericError{(macro \string\makeAlph)\@spaces \@spaces \@spaces \@spaces }%
{macro \string\makeAlph Error: Invalid argument for \string\makeAlph}%
{Only TeX-<number>-quantities in range 0..25 are allowed!}%
}%
\makeatother

\begin{document}

\noindent
\verb|\makeAlph{0}{\makeAlpherrordefault}| yields: \makeAlph{0}{\makeAlpherrordefault}\\
\verb|\makeAlph{1}{\makeAlpherrordefault}| yields: \makeAlph{1}{\makeAlpherrordefault}\\
\verb|\makeAlph{2}{\makeAlpherrordefault}| yields: \makeAlph{2}{\makeAlpherrordefault}\\
\verb|\makeAlph{3}{\makeAlpherrordefault}| yields: \makeAlph{3}{\makeAlpherrordefault}\\
\verb|\makeAlph{4}{\makeAlpherrordefault}| yields: \makeAlph{4}{\makeAlpherrordefault}\\
\verb|\makeAlph{5}{\makeAlpherrordefault}| yields: \makeAlph{5}{\makeAlpherrordefault}\\
\verb|\makeAlph{6}{\makeAlpherrordefault}| yields: \makeAlph{6}{\makeAlpherrordefault}\\
\verb|\makeAlph{7}{\makeAlpherrordefault}| yields: \makeAlph{7}{\makeAlpherrordefault}\\
\verb|\makeAlph{8}{\makeAlpherrordefault}| yields: \makeAlph{8}{\makeAlpherrordefault}\\
\verb|\makeAlph{9}{\makeAlpherrordefault}| yields: \makeAlph{9}{\makeAlpherrordefault}\\
\verb|\makeAlph{10}{\makeAlpherrordefault}| yields: \makeAlph{10}{\makeAlpherrordefault}\\
\verb|\makeAlph{11}{\makeAlpherrordefault}| yields: \makeAlph{11}{\makeAlpherrordefault}\\
\verb|\makeAlph{12}{\makeAlpherrordefault}| yields: \makeAlph{12}{\makeAlpherrordefault}\\
\verb|\makeAlph{13}{\makeAlpherrordefault}| yields: \makeAlph{13}{\makeAlpherrordefault}\\
\verb|\makeAlph{14}{\makeAlpherrordefault}| yields: \makeAlph{14}{\makeAlpherrordefault}\\
\verb|\makeAlph{15}{\makeAlpherrordefault}| yields: \makeAlph{15}{\makeAlpherrordefault}\\
\verb|\makeAlph{16}{\makeAlpherrordefault}| yields: \makeAlph{16}{\makeAlpherrordefault}\\
\verb|\makeAlph{17}{\makeAlpherrordefault}| yields: \makeAlph{17}{\makeAlpherrordefault}\\
\verb|\makeAlph{18}{\makeAlpherrordefault}| yields: \makeAlph{18}{\makeAlpherrordefault}\\
\verb|\makeAlph{19}{\makeAlpherrordefault}| yields: \makeAlph{19}{\makeAlpherrordefault}\\
\verb|\makeAlph{20}{\makeAlpherrordefault}| yields: \makeAlph{20}{\makeAlpherrordefault}\\
\verb|\makeAlph{21}{\makeAlpherrordefault}| yields: \makeAlph{21}{\makeAlpherrordefault}\\
\verb|\makeAlph{22}{\makeAlpherrordefault}| yields: \makeAlph{22}{\makeAlpherrordefault}\\
\verb|\makeAlph{23}{\makeAlpherrordefault}| yields: \makeAlph{23}{\makeAlpherrordefault}\\
\verb|\makeAlph{24}{\makeAlpherrordefault}| yields: \makeAlph{24}{\makeAlpherrordefault}\\
\verb|\makeAlph{25}{\makeAlpherrordefault}| yields: \makeAlph{25}{\makeAlpherrordefault}

\bigskip

\noindent
\verb|\newcounter{scratchcounter}|\newcounter{scratchcounter}\\
\verb|\setcounter{scratchcounter}{12}|\setcounter{scratchcounter}{12}\\
\verb|\makeAlph{\value{scratchcounter}}{\makeAlpherrordefault}| yields: \makeAlph{\value{scratchcounter}}{\makeAlpherrordefault}

\bigskip

\noindent
% \makeAlpherrordefault delivers an error-message. Instead we want the phrase "Error-Tokens".
% \verb|\makeAlph{-1}{\makeAlpherordefault}| yields: \makeAlph{-1}{\makeAlpherordefault}\\
\verb|\makeAlph{-1}{Error-Tokens.}| yields: \makeAlph{-1}{Error-Tokens.}\\
% \verb|\makeAlph{26}{\makeAlpherrordefault}| yields: \makeAlph{26}{\makeAlpherrordefault}\\
\verb|\makeAlph{26}{Error-Tokens.}| yields: \makeAlph{26}{Error-Tokens.}

\bigskip

\noindent
\verb|\setcounter{scratchcounter}{28}|\setcounter{scratchcounter}{28}\\
%\verb|\makeAlph{\value{scratchcounter}}{\makeAlpherrordefault}| yields: \makeAlph{\value{scratchcounter}}{\makeAlpherrordefault}\\
\verb|\makeAlph{\value{scratchcounter}}{Error-Tokens.}| yields: \makeAlph{\value{scratchcounter}}{Error-Tokens.}

\end{document}


I can offer a macro

\ExtractKthArg{⟨TeX-⟨number⟩-quantity with integer-value K⟩}%
{⟨tokens in case list of undelimited arguments doesn't have a k-th argument⟩}%
{⟨list of undelimited arguments⟩}%

which does the following:

In case there is no ⟨K⟩-th argument in the ⟨list of undelimited arguments⟩:
Does deliver ⟨tokens in case list of undelimited arguments doesn't have a k-th argument⟩.

In case there is a ⟨K⟩-th argument in the ⟨list of undelimited arguments⟩:
Does deliver that ⟨K⟩-th argument with one level of braces removed.

Examples:

\ExtractKthArg{0}{not available}{ABCDE} yields: not available

\ExtractKthArg{3}{not available}{ABCDE} yields: C

\ExtractKthArg{3}{not available}{AB{CD}E} yields: CD

\ExtractKthArg{4}{not available}{{001}{002}{003}{004}{005}} yields: 004

\ExtractKthArg{6}{not available}{{001}{002}{003}} yields: not available

You can easily define \makeAlph in terms of \ExtractKthArg as follows:

\newcommand\makeAlph[2]{%
\ExtractKthArg{\number\numexpr#1+1\relax}{#2}{abcdefghijklmnopqrstuvwxyz}%
}%


This way \makeAlph takes two arguments, the first argument being the TeX-⟨number⟩-quantity to convert to character, the second argument denoting tokens to be delivered in case of the first argument not being in range 0..25.

With the minimal working example below it is just relied on \makeAlph's 1st argument being a TeX-⟨number⟩-quantity. There is no checking if \makeAlph's 1st argument is a TeX-⟨number⟩-quantity: The 1st argument is a set of tokens, thus is something that might form an arbitrary (expansion-based) algorithm. Checking if the result of carrying out such an algorithm yields a TeX-⟨number⟩-quantity subsumes checking if such an algorithm terminates at all/terminates without error-message. This in turn reminds me of the halting-problem ...
!!!\makeAlph's 1st argument not being a TeX-⟨number⟩-quantity may result in all kinds of unpredictable behavior, leading to inscrutable error-messages!!!

Here comes the minimal working example:

\errorcontextlines=10000
\documentclass{article}

\makeatletter
%% Code for \ExtractKthArg
%%=============================================================================
%% Paraphernalia:
%%    \UD@firstoftwo, \UD@secondoftwo, \UD@PassFirstToSecond, \UD@Exchange,
%%    \UD@stopromannumeral, \UD@CheckWhetherNull
%%=============================================================================
\newcommand\UD@firstoftwo[2]{#1}%
\newcommand\UD@secondoftwo[2]{#2}%
\newcommand\UD@PassFirstToSecond[2]{#2{#1}}%
\newcommand\UD@Exchange[2]{#2#1}%
\@ifdefinable\UD@stopromannumeral{\chardef\UD@stopromannumeral=\^^00}%
%%-----------------------------------------------------------------------------
%% Check whether argument is empty:
%%.............................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is empty>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is not empty>}%
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
\newcommand\UD@CheckWhetherNull[1]{%
\romannumeral\expandafter\UD@secondoftwo\string{\expandafter
\UD@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
\UD@secondoftwo\string}\expandafter\UD@firstoftwo\expandafter{\expandafter
\UD@secondoftwo\string}\expandafter\UD@stopromannumeral\UD@secondoftwo}{%
\expandafter\UD@stopromannumeral\UD@firstoftwo}%
}%
%%=============================================================================
%% Extract K-th inner undelimited argument:
%%
%% \ExtractKthArg{<integer K>}%
%%               {<tokens in case list of undelimited arguments doesn't have a k-th argument>}%
%%               {<list of undelimited arguments>}%
%%
%% In case there is no K-th argument in <list of indelimited arguments> :
%%   Does deliver <tokens in case list of undelimited arguments doesn't have a k-th argument.
%% In case there is a K-th argument in <list of undelimited arguments> :
%%   Does deliver that K-th argument with one level of braces removed.
%%
%% Examples:
%%
%%   \ExtractKthArg{0}{not available}{ABCDE} yields: not available
%%
%%   \ExtractKthArg{3}{not available}{ABCDE} yields:  C
%%
%%   \ExtractKthArg{3}{not available}{AB{CD}E} yields:  CD
%%
%%   \ExtractKthArg{4}{not available}{{001}{002}{003}{004}{005}} yields: 004
%%
%%   \ExtractKthArg{6}{not available}{{001}{002}{003}} yields: not available
%%
%%=============================================================================
\newcommand\ExtractKthArg[2]{%
\romannumeral%
% #1: <integer number K>
% #2: <action if there is no K-th argument>
\expandafter\UD@ExtractKthArgCheck
\expandafter{\romannumeral\number\number#1 000}{#2}%
}%
\newcommand\UD@ExtractKthArgCheck[3]{%
\UD@CheckWhetherNull{#1}{\UD@stopromannumeral#2}{% empty
\expandafter\UD@ExtractKthArgLoop\expandafter{\UD@firstoftwo{}#1}{#2}{#3}%
}%
}%
\begingroup
\def\UD@ExtractFirstArgLoop#1{%
\endgroup
\@ifdefinable\UD@RemoveTillFrozenrelax{%
\long\def\UD@RemoveTillFrozenrelax##1##2#1{{##1}}%
}%
\newcommand\UD@ExtractKthArgLoop[3]{%
\expandafter\UD@CheckWhetherNull\expandafter{\UD@firstoftwo##3{}.}{\UD@stopromannumeral##2}{%
\UD@CheckWhetherNull{##1}{%
\UD@ExtractFirstArgLoop{##3#1}%
}{%
\expandafter\UD@PassFirstToSecond\expandafter{\UD@firstoftwo{}##3}%
{\expandafter\UD@ExtractKthArgLoop\expandafter{\UD@firstoftwo{}##1}{##2}}%
}%
}%
}%
}%
\expandafter\expandafter\expandafter\UD@ExtractFirstArgLoop
\expandafter\expandafter\expandafter{%
\expandafter\expandafter\ifnum0=0\fi}%
%% Usage of frozen-\relax as delimiter is for speeding things up by reducing the
%% amount of iterations needed. I chose frozen-\relax because David Carlisle
%% pointed out in   <https://tex.stackexchange.com/a/578877>
%% that frozen-\relax cannot be (re)defined in terms of \outer and cannot be
%% affected by \uppercase/\lowercase.
%%
%% \UD@ExtractFirstArg's argument may contain frozen-\relax:
%% The only effect is that internally more iterations are needed for
%% obtaining the result.
\newcommand\UD@ExtractFirstArgLoop[1]{%
\expandafter\UD@CheckWhetherNull\expandafter{\UD@firstoftwo{}#1}%
{\expandafter\UD@stopromannumeral\UD@firstoftwo#1{}}%
{\expandafter\UD@ExtractFirstArgLoop\expandafter{\UD@RemoveTillFrozenrelax#1}}%
}%
%% End of code for \ExtractKthArg.
\makeatother

\newcommand\makeAlph[2]{%
\ExtractKthArg{\number\numexpr#1+1\relax}{#2}{abcdefghijklmnopqrstuvwxyz}%
}%

\begin{document}

\noindent
\verb|\makeAlph{0}{\makeAlpherrordefault}| yields: \makeAlph{0}{\makeAlpherrordefault}\\
\verb|\makeAlph{1}{\makeAlpherrordefault}| yields: \makeAlph{1}{\makeAlpherrordefault}\\
\verb|\makeAlph{2}{\makeAlpherrordefault}| yields: \makeAlph{2}{\makeAlpherrordefault}\\
\verb|\makeAlph{3}{\makeAlpherrordefault}| yields: \makeAlph{3}{\makeAlpherrordefault}\\
\verb|\makeAlph{4}{\makeAlpherrordefault}| yields: \makeAlph{4}{\makeAlpherrordefault}\\
\verb|\makeAlph{5}{\makeAlpherrordefault}| yields: \makeAlph{5}{\makeAlpherrordefault}\\
\verb|\makeAlph{6}{\makeAlpherrordefault}| yields: \makeAlph{6}{\makeAlpherrordefault}\\
\verb|\makeAlph{7}{\makeAlpherrordefault}| yields: \makeAlph{7}{\makeAlpherrordefault}\\
\verb|\makeAlph{8}{\makeAlpherrordefault}| yields: \makeAlph{8}{\makeAlpherrordefault}\\
\verb|\makeAlph{9}{\makeAlpherrordefault}| yields: \makeAlph{9}{\makeAlpherrordefault}\\
\verb|\makeAlph{10}{\makeAlpherrordefault}| yields: \makeAlph{10}{\makeAlpherrordefault}\\
\verb|\makeAlph{11}{\makeAlpherrordefault}| yields: \makeAlph{11}{\makeAlpherrordefault}\\
\verb|\makeAlph{12}{\makeAlpherrordefault}| yields: \makeAlph{12}{\makeAlpherrordefault}\\
\verb|\makeAlph{13}{\makeAlpherrordefault}| yields: \makeAlph{13}{\makeAlpherrordefault}\\
\verb|\makeAlph{14}{\makeAlpherrordefault}| yields: \makeAlph{14}{\makeAlpherrordefault}\\
\verb|\makeAlph{15}{\makeAlpherrordefault}| yields: \makeAlph{15}{\makeAlpherrordefault}\\
\verb|\makeAlph{16}{\makeAlpherrordefault}| yields: \makeAlph{16}{\makeAlpherrordefault}\\
\verb|\makeAlph{17}{\makeAlpherrordefault}| yields: \makeAlph{17}{\makeAlpherrordefault}\\
\verb|\makeAlph{18}{\makeAlpherrordefault}| yields: \makeAlph{18}{\makeAlpherrordefault}\\
\verb|\makeAlph{19}{\makeAlpherrordefault}| yields: \makeAlph{19}{\makeAlpherrordefault}\\
\verb|\makeAlph{20}{\makeAlpherrordefault}| yields: \makeAlph{20}{\makeAlpherrordefault}\\
\verb|\makeAlph{21}{\makeAlpherrordefault}| yields: \makeAlph{21}{\makeAlpherrordefault}\\
\verb|\makeAlph{22}{\makeAlpherrordefault}| yields: \makeAlph{22}{\makeAlpherrordefault}\\
\verb|\makeAlph{23}{\makeAlpherrordefault}| yields: \makeAlph{23}{\makeAlpherrordefault}\\
\verb|\makeAlph{24}{\makeAlpherrordefault}| yields: \makeAlph{24}{\makeAlpherrordefault}\\
\verb|\makeAlph{25}{\makeAlpherrordefault}| yields: \makeAlph{25}{\makeAlpherrordefault}

\bigskip

\noindent
\verb|\newcounter{scratchcounter}|\newcounter{scratchcounter}\\
\verb|\setcounter{scratchcounter}{12}|\setcounter{scratchcounter}{12}\\
\verb|\makeAlph{\value{scratchcounter}}{\makeAlpherrordefault}| yields: \makeAlph{\value{scratchcounter}}{\makeAlpherrordefault}

\bigskip

\noindent
% \makeAlpherrordefault delivers an error-message. Instead we want the phrase "Error-Tokens".
% \verb|\makeAlph{-1}{\makeAlpherordefault}| yields: \makeAlph{-1}{\makeAlpherordefault}\\
\verb|\makeAlph{-1}{Error-Tokens.}| yields: \makeAlph{-1}{Error-Tokens.}\\
% \verb|\makeAlph{26}{\makeAlpherrordefault}| yields: \makeAlph{26}{\makeAlpherrordefault}\\
\verb|\makeAlph{26}{Error-Tokens.}| yields: \makeAlph{26}{Error-Tokens.}

\bigskip

\noindent
\verb|\setcounter{scratchcounter}{28}|\setcounter{scratchcounter}{28}\\
%\verb|\makeAlph{\value{scratchcounter}}{\makeAlpherrordefault}| yields: \makeAlph{\value{scratchcounter}}{\makeAlpherrordefault}\\
\verb|\makeAlph{\value{scratchcounter}}{Error-Tokens.}| yields: \makeAlph{\value{scratchcounter}}{Error-Tokens.}

\end{document}
`