8
\$\begingroup\$

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}

Pdf file rendered

\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

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}

enter image description here

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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