albertobosia” post=73556cito dal texbook a pag 219
`\def\length#1{{\count0=0 \getlength#1\end \number\count0}}
\def\getlength#1{\ifx#1\end \let\next=\relax
\else\advance\count0 by1 \let\next=\getlength\fi \next}`quando poi scrivo \length{ciao mamma} mi compare 9.
vorrei che fosse contato anche lo spazio, senza fare \length{ciao\ mamma}
come posso fare?
Quella macro conta i token che non sono spazi, perché usa una macro con argomento e, nella ricerca di argomenti non delimitati, gli spazi sono ignorati. Soluzione “facile”:
`
\newcount\lencount
\def\length{\begingroup\catcode`\ =12 \lengthaux}
\def\lengthaux#1{\lencount=0 \getlength#1\getlength\number\lencount\endgroup}
\def\getlength#1{%
\ifx#1\getlength
\expandafter\gobble
\else
\advance\lencount by 1
\fi
\getlength}
\long\def\gobble#1{}
`
Non è tanto diverso da quello di prima; ho solo usato un contatore riservato (non cambierebbe nulla con [tt]\count0[/tt] invece di [tt]\lencount[/tt]) e una struttura condizionale che evita [tt]\let\next\relax[/tt] ma esegue lo stesso una tail recursion. La vera differenza è il cambiamento di codice di categoria dello spazio.
Questo impedisce di dare [tt]\length[/tt] come argomento di un altro comando. Non è che si possa fare moltissimo al riguardo. L’alternativa è di usare una routine più lenta con [tt]\futurelet[/tt].
Versione LaTeX3:
`
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\length}{m}{\length_compute:n {#1}}
\cs_new:Npn \length_compute:n #1
{
\tl_set_rescan:Nnn \l_tmpa_tl { \char_set_catcode_other:N \ } { #1 }
\int_to_arabic:n { \tl_length:N \l_tmpa_tl }
}
\ExplSyntaxOff
\length{ciao mamma}
`
In alternativa
`\cs_new:Npn \length_compute:n #1
{
\tl_set:Nn \l_tmpa_tl { #1 }
\tl_replace_all:Nnn \l_tmpa_tl { ~ } { \c_space_token }
\int_to_arabic:n { \tl_length:N \l_tmpa_tl }
}`
Ciao
Enrico