3

Here is a problem that has been puzzling me for a few days. Basically, I try to parse strings and test their symbols one by one to define whether they are or not numbers (in order to achieve some more complicated treatment, beyond this topic).

The macros \@neByOne, \aux@neByOne, \c@untunlessnil and \gobblechar split the string. For each symbol, the macro \testSymbol is called and is meant to tell if it is a number.

The problem: when called directly, \testSymbol returns the expected result. But when called by \c@untunlessnil, the test fails. In fact, the parameter #1 is not seen as a number by \ifnum. Below are my files and the results I get.

Thank you for your help.

Content of myExtension.sty

\def\testSymbol#1{%
     \ifnum0<0#1\relax%
        <<#1>> is a number\\
    \else%
        <<#1>> is a NOT number\\
    \fi%
}


\def\gobblechar{\let\ch@r= }
\def\c@untunlessnil{%
    \ifx\ch@r\nil%
        \let\next=\relax%
    \else%
        \testSymbol\ch@r%
        \let\next=\aux@neByOne%
    \fi\next
}
\def\aux@neByOne{\afterassignment\c@untunlessnil\gobblechar}
\def\@neByOne#1{\edef\xx{#1}\expandafter\aux@neByOne\xx\nil}


\def\test#1{BEGIN\\\@neByOne{#1}END\\}

Content of myMainFile.tex :

\documentclass[a4paper,10pt]{article}
\usepackage[utf8x]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{myExtension}

\begin{document}
\test{123}
\testSymbol{1}
\testSymbol{2}
\testSymbol{3}

The output I get:

BEGIN
«1» is a NOT number
«2» is a NOT number
«3» is a NOT number
END
«1» is a number
«2» is a number
«3» is a number
  • Do you have to test individual numbers in 123, or can you just test 123 as a whole? – Werner Dec 28 '16 at 19:12
  • Easy: if you say \let\next=1, then \ifnum0<0\next returns false, because \next is not expandable. – egreg Dec 28 '16 at 19:13
  • @Werner: I have to test individual characters as some of them may not be numeric. – zigma12 Dec 28 '16 at 19:16
  • @egreg: I am sorry but I do not understand what you mean. I have to admit that the "splitting" macros are not from me thus I do not get exactly how they work. Thank you – zigma12 Dec 28 '16 at 19:19
  • @egreg: I thought that #1 was \ch@r which expands well... – zigma12 Dec 28 '16 at 19:23
3

You can use a test such as the following

enter image description here

\documentclass[a4paper,10pt]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}

\makeatletter
\def\test#1{\@tfor\tmp:=#1\do{%
<<\tmp>>
\ifcat1\expandafter\noexpand\tmp
  \ifnum\expandafter`\tmp>47
    \ifnum\expandafter`\tmp<58
      IS
    \else
      IS NOT
    \fi
  \else
    IS NOT
  \fi
\else
IS NOT
\fi
a number\par
}}

\begin{document}
\test{123}
\test{1}
\test{2}
\test{3}
\test{4abc5}
\end{document}
  • Looks good! I didn't know the \@tfor command. – zigma12 Dec 29 '16 at 8:18
  • Now, what if I want to use something like that? : \def\myString{a123b}\test\myString – zigma12 Dec 29 '16 at 8:20
  • @zigma12 \expandafter\test\expandafter{\mystring} – David Carlisle Dec 29 '16 at 12:30
  • Many thanks. I tried to put some \expandafter but not the right way. Please, tell me if I get it right: the 2nd \expandafter applies to the opening (and so closing) brace? – zigma12 Dec 29 '16 at 13:05
  • @zigma12 no the second \expandafter expands \mystring, the first \expandafter expands the second \expandafter. – David Carlisle Dec 29 '16 at 16:38

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.