9

Environment that counts words inside does like the title says, but prints the words that it counts, too. Is there a way to count the words without printing them?

\countCommand{Four and twenty blackbirds} % should print: 4

3 Answers 3

4

If you mean counting the spaces in the argument, at all brace levels, with l3regex you can do it:

\documentclass{article}
\usepackage{xparse,l3regex}

\ExplSyntaxOn
\NewDocumentCommand{\countwords}{+m} % allow \par (or blank lines in the argument)
 {
  \regex_count:nnN { \s } { #1 } \l_corneli_words_int
  \int_to_arabic:n { \l_corneli_words_int + 1 }
 }
\int_new:N \l_corneli_words_int
\ExplSyntaxOff

\begin{document}
\countwords{Four and twenty blackbirds}

\countwords{Four \emph{and twenty} blackbirds}
\end{document}

This prints

4
4

3
  • This seems the most robust so far for dealing with included LaTeX markup (environments, citations, hyperref). It doesn't like paragraph breaks, but that seems like a minor point. Mar 3, 2014 at 13:16
  • @JoeCorneli Without a complete specification it's difficult to do more. For allowing \par, just type {+m} instead of {m} in the definition of \countwords.
    – egreg
    Mar 3, 2014 at 13:18
  • Cool! OK, I think this answer wins the checkmark. Mar 3, 2014 at 13:23
6

Here's a simple solution using xstring

% arara: pdflatex
\documentclass{article}

\usepackage{xstring}

\newcommand{\wordcount}[1]{\StrCount{#1}{\space}[\tmp]%
\number\numexpr\tmp+1\relax}
\begin{document}

\wordcount{Four and twenty blackbirds}
\end{document}

It works by counting the spaces, and then adding 1; it works fine even when there are multiple spaces between words, so you can use

\wordcount{Four    and     twenty     blackbirds}

and still get 4. However if you try anything like

\wordcount{ Four and twenty blackbirds}
\wordcount{Four and twenty blackbirds }
\wordcount{ Four and twenty blackbirds }

then you won't get the expected result. You can fix this using, for example, something like the following:

\newcount\cmh
\newcommand{\wordcount}[1]{%
\StrCount{#1}{\space}[\tmp]%
\cmh=\tmp%
\IfBeginWith{#1}{\space}{\advance\cmh by -1\relax}{}%
\IfEndWith{#1}{\space}{\advance\cmh by -1\relax}{}%
\number\numexpr\cmh+1\relax
}
3
  • ah, \space - that's helpful! Very useful piece of information that :-) Mar 3, 2014 at 3:23
  • @JoeCorneli glad it helped ;) it works fine with multiple spaces between words, too!
    – cmhughes
    Mar 3, 2014 at 3:26
  • ... and newlines too! Impressed! Mar 3, 2014 at 3:30
3
\documentclass{article}
\usepackage{readarray}
\begin{document}
\getargsC{Four and twenty blackbirds}
Words = \narg\par
The words are \argi, \argii, \argiii, and \argiv.
\end{document} 

Thus, based on this MWE, \def\wordcount#1{\getargsC{#1}\narg} would suffice to answer the OP's question. Note that \getargsC is functionally equivalent but far superior in speed to the \getargs macro of the stringstrings package.

2
  • This one has the benefit of being more robust vis a vis hyperref, although neither this answer nor the other one are working with things like quoting environments. Indeed, \wordcount{\emph{Four and twenty blackbirds}} gives 1 as the answer. Mar 3, 2014 at 4:21
  • @JoeCorneli Indeed, \emph{...} is treated as a single word, precisely because that is the way LaTeX treats groups (think about how we define arguments); however, \itshape four and twenty blackbirds would pickup the proper number of words. Mar 3, 2014 at 4:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .