# A LaTeX environment that counts words

I am new to TeX and here is my attempt to (ab)use mfirstuc to define an environment that counts the words. I am looking for suggestions on how to improve the implementation.

\documentclass{article}
\usepackage{mfirstuc}
\newcounter{wordcount}
%Make sure we don't accidentally overwrite things with \def and \let
\newcommand\cwaux\relax
\newcommand\oldgmfu\relax
\newcommand\temppar\relax
%
\newtoks\temppar
\def\cwaux#1\par{\capitalisewords{#1}\par}
\newcommand*\myglsmakefirstuc[1]{\stepcounter{wordcount}#1}
\newenvironment{countwords}{%
\setcounter{wordcount}{0}\let\oldgmfu\glsmakefirstuc\let\glsmakefirstuc\myglsmakefirstuc\temppar\everypar\everypar{\cwaux}%
}{%
\everypar\temppar\let\glsmakefirstuc\oldgmfu Word count:\arabic{wordcount}%
}
\begin{document}
\capitalisewords{Outside the environment, \texttt{\textbackslash capitalisewords} works normally.}

\begin{countwords}
One paragraph.

Another paragraph which is longer.

\end{countwords}

\begin{countwords}
The third paragraph.

I am glad to see this works.

\end{countwords}

\capitalisewords{Outside the environment, \texttt{\textbackslash capitalisewords} works normally.}

\end{document}


You can do it in a more robust way, using expl3.

\documentclass{article}
\usepackage{xparse}
\usepackage{mfirstuc}

\ExplSyntaxOn
\NewDocumentEnvironment{countwords}{+b}
{
% typeset the contents and add \par at the end
#1 \par

% save the contents of the environment in a token list variable
\tl_set:Nn \l_tmpa_tl { #1 }
% blank lines generate a \par, change it into a space
\tl_replace_all:Nnn \l_tmpa_tl { \par } { ~ }
% split the token list at spaces
\seq_set_split:NnV \l_tmpa_seq { ~ } \l_tmpa_tl
% remove blank items
\seq_remove_all:Nn \l_tmpa_seq { }
% print the word count
Word~count:~\int_to_arabic:n { \seq_count:N \l_tmpa_seq }
}{}
\ExplSyntaxOff

\begin{document}

\capitalisewords{Outside the environment, \texttt{\textbackslash capitalisewords} works normally.}

\begin{countwords}
One paragraph.

Another paragraph which is longer.

\end{countwords}

\begin{countwords}
The third paragraph.

I am glad to see this works.
\end{countwords}

\capitalisewords{Outside the environment, \texttt{\textbackslash capitalisewords} works normally.}

\end{document}