Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I'm trying to built a code that counts the number of \ in a string. My code can work with any other symbols (for example, if I need to count the number of 'a's, that works). I already tried to modify the catcode of the backslash symbol to 12, but with no success.

Any ideas?

My (incomplete) solution:

\newcounter{alternatives}
\renewcommand\thealternatives{\alph{alternatives}}
\makeatletter
\def\endtab{\vspace{-4 mm}}
\def\endtabi{\endtab}

\newcount\testcount
\def\gobblechar{\let\char= }
    \newcount\slashcount
\def\countunlessnil
{%
    \let\a=0
    \let\\=\a
    \ifx\char\a
%       \slashcount=
        \advance\slashcount by 1
    \fi
    \ifx\char\nil
        \let\next=\relax%
    \else%
        \let\next=\auxcountchar%
    \fi
    \let\\=\\
    \next
}%
\def\auxcountchar{%
  \afterassignment\countunlessnil\gobblechar%
}
\def\countchar#1{\edef\xx{#1} \expandafter\auxcountchar\xx\nil}
\def\analyze#1{%
  \countchar{#1}%
}
\newlength{\alternativessize}
\newlength{\abcde}
\settowidth{\abcde}{a)~b)~c)~d)~e)}
\WithSuffix\DeclareRobustCommand\tab+{\@tabbb}
\def\@tabbb#1 \endtab
{
    \tabiiii#1
    \endtab\\
        \analyze{dfgreggegewg\a}
    \the\testcount
%   \setcounter{alternatives}{0}
    \settowidth{\alternativessize}{#1}
    \setlength{\alternativessize}{\linewidth - \alternativessize}
    \setlength{\alternativessize}{\alternativessize - \abcde}
    \the\value{alternatives}\\[4 mm]
    \ifthenelse{\equal{\value{alternatives}}{5}}
    {
    \setlength{\alternativessize}{0.17\alternativessize}
    }
    {
        \setlength{\alternativessize}{0.27\alternativessize}
    }
    \setcounter{alternatives}{0}
%   \setlength{\alternativessize}{0.18\alternativessize}
    \begin{minipage}[t]{\linewidth}
            \tabiii#1
    \end{minipage}\vspace{-2 mm}\\
    \endtab\\
\setcounter{alternatives}{0}
}
\def\tabiii#1\\
{
    \def\tempa{#1}
    \ifx\tempa\endtabi
        \endtab

    \else
        \if\relax\detokenize{#1}\relax
        \else
            \stepcounter{alternatives}\thealternatives)~~\@ifnextchar {_}{}#1
            \hspace{\alternativessize}
        \fi
        \expandafter\tabiii
    \fi
}
\def\tabiiii#1\\
{
    \def\tempa{#1}
    \ifx\tempa\endtabi
        \endtab
    \else
        \if\relax\detokenize{#1}\relax
        \else
            \stepcounter{alternatives}\thealternatives)~~\@ifnextchar {_}{}#1
            \hspace{\alternativessize}
        \fi
        \expandafter\tabiii
    \fi
}
\makeatother

When tabiii is called, it detokenize the sequence: aaaaa\\ bbbbb\\ ccccc\\ ddddd\\

and so on, putting a marker a), b), c) in front of each line. I need to count the number of \, OR get the count of the \thealternative. Reason: I'm trying to make a code that cant put 4 or 5 alternatives in the same line, but I need to know the string size BEFORE TeX read it. This is why I'm calling tabiii and tabiiii: tabiiii reads the sentence to calculate the size of the spaces, and tabiii prints the content on the PDF file. Any ideas?

share|improve this question
    
It would be helpful if you would compose a fully compilable MWE that shows your existing solution and that it works. Also, don't forget that the \ indicates the beginning of a control sequence to LaTeX. –  Peter Grill May 24 '12 at 5:09
    
What number should a\\ \foo\\ c return? This seems an XY question, however: what's the real problem you want to solve? –  egreg May 24 '12 at 13:17
add comment

2 Answers

Here is a solution involving xstring (in order to count the occurrences) and catcode changes:

\documentclass{article}
\usepackage{xstring}
\begingroup
\catcode`\|0
|catcode`|\12
|makeatletter
|gdef|mymacro{|begingroup|catcode`|\12 |mymacro@i}
|gdef|mymacro@i#1{|endgroup|StrCount{#1}\}
|endgroup
\begin{document}
\mymacro{\ifnum`\\=0 \textbf{0}\else\textif{non zero}\fi}
\end{document}
share|improve this answer
add comment

Here are two ways to get the number of \\ tokens in an argument. In both cases the counter \l_cnobs_count_int will contain that number (three for the example).

First way (with token lists)

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\countbstl}{m}
 {
  \cnobs_main_one:n { #1 }
 }

\int_new:N \l_cnobs_count_int

\cs_new_protected:Npn \cnobs_main_one:n #1
 {
  \int_zero:N \l_cnobs_count_int
  \tl_map_inline:nn { #1 } 
   {
    \tl_if_eq:nnT { ##1 } { \\ } { \int_incr:N \l_cnobs_count_int }
   }
  \int_show:N \l_cnobs_count_int
 }
\ExplSyntaxOff

\countbstl{aaa\\ bbb \\ ccc \\}

\stop

Second way (with regular expressions)

\documentclass{article}
\usepackage{xparse,l3regex}
\ExplSyntaxOn
\NewDocumentCommand{\countbsregex}{m}
 {
  \cnobs_main_two:n { #1 }
 }

\int_new:N \l_cnobs_count_int

\cs_new_protected:Npn \cnobs_main_two:n #1
 {
  \int_zero:N \l_cnobs_count_int
  \regex_count:nnN { \c{ \\ } } { #1 } \l_cnobs_count_int
  \int_show:N \l_cnobs_count_int
 }

\ExplSyntaxOff

\countbsregex{aaa\\ bbb \\ ccc \\}

\stop

One might easily modify this to count the number of control sequences; by changing the \regex_count:nnN line into

  \regex_count:nnN { \c{ .* } } { #1 } \l_cnobs_count_int

an input such as

\countbsregex{\textbf{aaa}\\ bbb \\ ccc \\}

will store 4 in the counter. A further change

  \regex_count:nnN { \c{ .* } | \cA. } { #1 } \l_cnobs_count_int

will count also active characters, so

\countbsregex{\textbf{aaa}\\ bbb~bbb \\ ccc \\}

stores 5 in the counter.


It's hard to say how to use this in your very complicated (and unexplained) code.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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