xstring で文字数を数える

xstring で文字数を数える

以下のコードは、xstringChristian Tellechea 氏から提供されたものです。ありがとうございます。このアイデアは、定義済みリストに属する構造体内の文字数をカウントするというものです。

\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}

出力を見るとわかるように、最初と最後のカウントは正しいのですが、他のカウントは正しくありません。 と を使用しようとしましたが、\exploregroups提示\noexpand#2されたすべての例でうまくいきませんでした。たとえば、 は\noexpand#22 番目の出力を修正しますが、最初と 3 番目の出力に悪影響を及ぼします。すべてに機能する の方法はありますか?

答え1

\blindtext何らかのテキストに展開されるのではなく、テキストに到達する前に多くの (展開できない) コマンドが実行されます。

代わりに、を試すことができますkantlipsum。これにより、段落の 1 つに展開するマクロを定義できる可能性があります。

\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}

その後長さ(私のマシンでは15秒ですが、とても長い処理時間) の場合は、次のようになります。

ここに画像の説明を入力してください

関連情報