5

I store some strings in a variable \def\nomVAR{A12Z4E} and I want to create some other command using the content of \nomVAR. LaTeX doesn't accept to declare variable with number in its name. So the idea will be to convert all the number in the string using \numberstringnum command (fmtcount package). The xstring can extract some specific string in a string but I have to precise the position of each one.

Do you think it is possible to write a function to convert each number to a string in a string and to rebuilt it?

Thus A12Z4E will become AonetwoZfourE.

MNWE

\documentclass{minimal}

\usepackage{xstring}
\usepackage{fmtcount}

\begin{document}

\def\nomVAR {A12Z4E}

\nomVAR

\numberstringnum{1}

\numberstringnum{\nomVAR} %not working

\end{document}

SOLUTION (thanks egreg)

\documentclass{minimal}

\usepackage{xstring}

\begin{document}

\def\nomVAR {A12Z4E}

\nomVAR

\numberstringnum{1}

\newcommand{\changestep}[2]{%
  \expandafter\StrSubstitute\expandafter{\x}{#1}{#2}[\x]%
}
\newcommand{\changeall}[1]{
 % suppress expansions made by xstring
\StrSubstitute{#1}{0}{zero}[\x]%
\x
\noexpandarg
\changestep{1}{one}
\changestep{2}{two}
\changestep{3}{three}
\changestep{4}{four}
\changestep{5}{five}
\changestep{6}{six}
\changestep{7}{seven}
\changestep{8}{eight}
\changestep{9}{nine}
\x
}

\changeall{\nomVAR}

\end{document}
1
  • With xstring it's easy to replace each 1 with one and so on. But I'm not seeing what's the aim of this.
    – egreg
    Nov 25, 2015 at 12:56

2 Answers 2

4

You can do it expandably, provided the string only has alphanumeric ASCII characters:

\documentclass{article}

\makeatletter
\newcommand{\convertdigits}[1]{\expandafter\convert@digits#1\convert@digits}
\def\convert@digits#1{%
  \ifx#1\convert@digits
    \expandafter\@gobble
  \else
    \expandafter\@firstofone
  \fi
  {\convert@@digits#1}%
}
\def\convert@@digits#1{%
  \ifnum9=9#1%
    \expandafter\@gobble
  \else
    \expandafter\@firstofone
  \fi
  {\convert@@digit#1}\convert@digits
}
\def\convert@@digit#1{%
  \ifcase#1%
    zero\or
    one\or
    two\or
    three\or
    four\or
    five\or
    six\or
    seven\or
    eight\or
    nine\fi
}
\makeatother

\begin{document}

\def\myvar{A12Z4E}

\convertdigits{A12Z4E}

\convertdigits{\myvar}

\edef\myvartext{\convertdigits{\myvar}}
\texttt{\meaning\myvartext}

\end{document}

enter image description here

A different expl3 implementation: the argument to \convertdigits is fully expanded before being examined and scanned item by item.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\NewExpandableDocumentCommand{\convertdigits}{m}
 {
  \guuk_convertdigits:e { #1 }
 }

\cs_new:Nn \guuk_convertdigits:n
 {
  \tl_map_function:nN { #1 } \guuk_digit:n
 }
\cs_generate_variant:Nn \guuk_convertdigits:n { e }

\cs_new:Nn \guuk_digit:n
 {
  \str_case:nnF { #1 }
   {
    {0}{zero}
    {1}{one}
    {2}{two}
    {3}{three}
    {4}{four}
    {5}{five}
    {6}{six}
    {7}{seven}
    {8}{eight}
    {9}{nine}
   }
   {#1}% not a digit
 }
\ExplSyntaxOff

\begin{document}

\def\myvar{A12Z4E}

\convertdigits{A12Z4E}

\convertdigits{\myvar}

\edef\myvartext{\convertdigits{\myvar}}
\texttt{\meaning\myvartext}

\end{document}
0

Here I set up a tokencycle to look (token by token) for letters (catcode 11) and numerical digits. Anything else is discarded. Digits are processed via \spelldigit, which executes a simple \ifcase.

\documentclass{article}
\usepackage{tokcycle}
\newcommand\numberstringnum[1]{%
  \resettokcycle
  \Characterdirective{\tctestifcatnx A##1{##1}{\spelldigit##1}}%
  \expandafter\tokcyclexpress\expandafter{#1}}
\newcommand\spelldigit[1]{%
  \ifcase\numexpr`#1-`0 zero\or one\or two\or three\or four\or five\or
  six\or seven\or eight\or nine\fi}
\begin{document}
\def\nomVAR {A12Z4E}

\nomVAR

\numberstringnum{\nomVAR} 

\numberstringnum{AB23z0BN56q}
\end{document}

enter image description here

If you need to be able to use the string to build a command, for example, this variant does not output the result, but instead stores it in \thestring, which can be subsequently used, as shown in this MWE.

\documentclass{article}
\usepackage{tokcycle}
\newcommand\numberstringnum[1]{%
  \Characterdirective{\tctestifcatnx A##1{\addcytoks{##1}}%
    {\addcytoks[x]{\spelldigit##1}}}%
  \Groupdirective{}%
  \Macrodirective{}%
  \Spacedirective{}%
  \expandafter\tokcyclexpress\expandafter{#1}%
  \edef\thestring{\the\cytoks}%
  \expandafter\def\csname\thestring\expandafter\endcsname\expandafter
    {#1}}
\newcommand\spelldigit[1]{%
  \ifcase\numexpr`#1-`0 zero\or one\or two\or three\or four\or five\or
  six\or seven\or eight\or nine\fi}
\begin{document}
\def\nomVAR {A12Z4E}

\numberstringnum{\nomVAR}
\textbackslash\thestring=\csname\thestring\endcsname

\numberstringnum{AB23Z0BN56Q}
\textbackslash\thestring=\csname\thestring\endcsname
\end{document}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.