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
10
  • Do you have to test individual numbers in 123, or can you just test 123 as a whole?
    – Werner
    Commented Dec 28, 2016 at 19:12
  • Easy: if you say \let\next=1, then \ifnum0<0\next returns false, because \next is not expandable.
    – egreg
    Commented Dec 28, 2016 at 19:13
  • @Werner: I have to test individual characters as some of them may not be numeric.
    – Vincent
    Commented Dec 28, 2016 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
    – Vincent
    Commented Dec 28, 2016 at 19:19
  • @egreg: I thought that #1 was \ch@r which expands well...
    – Vincent
    Commented Dec 28, 2016 at 19:23

1 Answer 1

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}
6
  • Looks good! I didn't know the \@tfor command.
    – Vincent
    Commented Dec 29, 2016 at 8:18
  • Now, what if I want to use something like that? : \def\myString{a123b}\test\myString
    – Vincent
    Commented Dec 29, 2016 at 8:20
  • @zigma12 \expandafter\test\expandafter{\mystring} Commented Dec 29, 2016 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?
    – Vincent
    Commented Dec 29, 2016 at 13:05
  • @zigma12 no the second \expandafter expands \mystring, the first \expandafter expands the second \expandafter. Commented Dec 29, 2016 at 16:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .