Tengo el siguiente código, el cual fue proporcionado por el xstring
autor Christian Tellechea, muchas gracias. La idea es contar el número de caracteres dentro de una estructura que pertenecen a una lista predefinida.
\documentclass{article}
\usepackage{xstring}
\usepackage{blindtext}
\makeatletter
\def\countoccurs#1#2{%
\saveexpandmode\expandarg
%\exploregroups
\expandafter\def\expandafter\tmp@list\expandafter{\list,}%
\let\nboccur\z@
\loop
\unless\ifx\empty\tmp@list
\StrCut\tmp@list,\tmp@cs\tmp@list
%\StrCount{\noexpand#2}\tmp@cs[\tmp@cs]%
\StrCount{#2}\tmp@cs[\tmp@cs]%
\edef\nboccur{\number\numexpr\nboccur+\tmp@cs}%
\repeat
\restoreexpandmode
}
%\def\list{12,a,bc,9} % list can also be defined as this
\def\list{%
a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,Q,r,s,t,u,v,w,x,y,z,%
A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,S,X,Y,Z,%
1,2,3,4,5,6,7,8,9,0,%
}
\def\countenv#1{#1\countoccurs\list{#1}}
\makeatother
\begin{document}
\countenv{\begin{tabular}{ll} a & b \\ a & c \end{tabular}}\par
I counted: \nboccur.
\noindent\hrulefill
\countenv{\textbf{D}2345}\par
I counted: \nboccur.
\noindent\hrulefill
\countenv{\blindtext}\par
I counted: \nboccur.
\noindent\hrulefill
%\countoccurs\list{12987d bc abcabc999}
\countenv{12987d bc abcabc999}\par
I counted: \nboccur.
\noindent\hrulefill
\end{document}
Como puede ver en el resultado, el primer y el último recuento son correctos, pero los demás no. Intenté utilizar \exploregroups
y \noexpand#2
pero tuve suerte con todos los ejemplos presentados. Por ejemplo, \noexpand#2
corrige la segunda salida, pero influye negativamente en la primera y la tercera. ¿Existe alguna opción que funcione para todos?
Respuesta1
\blindtext
no se expande a algún texto, pero ejecuta muchos comandos (no expandibles) antes de llegar a un texto.
Puedes probar con kantlipsum
, en su lugar, que tiene la posibilidad de definir una macro expandiéndose a uno de sus párrafos.
\documentclass{article}
\usepackage{xstring}
\usepackage{kantlipsum}
\kantdef\mytext{1}
\makeatletter
\def\countoccurs#1#2{%
\saveexpandmode\expandarg
%\exploregroups
\expandafter\def\expandafter\tmp@list\expandafter{\list,}%
\let\nboccur\z@
\loop
\unless\ifx\empty\tmp@list
\StrCut\tmp@list,\tmp@cs\tmp@list
%\StrCount{\noexpand#2}\tmp@cs[\tmp@cs]%
\StrCount{#2}\tmp@cs[\tmp@cs]%
\edef\nboccur{\number\numexpr\nboccur+\tmp@cs}%
\repeat
\restoreexpandmode
}
%\def\list{12,a,bc,9} % list can also be defined as this
\def\list{%
a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,Q,r,s,t,u,v,w,x,y,z,%
A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,S,X,Y,Z,%
1,2,3,4,5,6,7,8,9,0,%
}
\def\countenv#1{#1\countoccurs\list{#1}}
\makeatother
\begin{document}
\countenv{\begin{tabular}{ll} a & b \\ a & c \end{tabular}}\par
I counted: \nboccur.
\noindent\hrulefill
\countenv{\textbf{D}2345}\par
I counted: \nboccur.
\noindent\hrulefill
\countenv{\mytext}\par
I counted: \nboccur.
\noindent\hrulefill
%\countoccurs\list{12987d bc abcabc999}
\countenv{12987d bc abcabc999}\par
I counted: \nboccur.
\noindent\hrulefill
\end{document}
Después delargotiempo (15 segundos en mi máquina, que es unmuy largotiempo de procesamiento), obtienes esto.