Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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
share|improve this question

3 Answers 3

up vote 3 down vote accepted

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

share|improve this answer
    
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. –  Joe Corneli Mar 3 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 at 13:18
    
Cool! OK, I think this answer wins the checkmark. –  Joe Corneli Mar 3 at 13:23

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
}
share|improve this answer
    
ah, \space - that's helpful! Very useful piece of information that :-) –  Joe Corneli Mar 3 at 3:23
    
@JoeCorneli glad it helped ;) it works fine with multiple spaces between words, too! –  cmhughes Mar 3 at 3:26
    
... and newlines too! Impressed! –  Joe Corneli Mar 3 at 3:30
\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.

share|improve this answer
    
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. –  Joe Corneli Mar 3 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. –  Steven B. Segletes Mar 3 at 4:25

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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