Text FormattingWord counting environment

Information and discussion about LaTeX's general text formatting features (e.g. bold, italic, enumerations, ...)
Post Reply
rspringuel
Posts: 19
Joined: Wed Apr 28, 2010 7:16 pm

Word counting environment

Post by rspringuel »

I have a personalized class file in which I've defined the following environment:

Code: Select all

\newcounter{words}
\newenvironment{counted}{%
  \noindent\hrulefill\par
  \marginpar{\footnotesize\textit{Begin counting words}}
  \setcounter{words}{0}
  \SearchList!{wordcount}{\stepcounter{words}}
    {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?}
  \UndoBoundary{'}
  \SearchOrder{p;}}{%
  \StopSearching\marginpar{\footnotesize\textit{\thewords\ words}}
  \noindent\hrulefill}
The environment counts the number of words within it, places horizontal rules as delimiters around the contained text, and places marginal notes indicating what's going on (the first note) and the results (the second note).

I'd like to reverse the order of the marginal notes so that the word count appears at the beginning of the environment rather than at the end. However, simply reversing the order of the margin notes (as in the snippet below) does not have the desired effect. The count is 0 at the time the first margin note is printed.

Code: Select all

\newcounter{words}
\newenvironment{counted}{%
  \noindent\hrulefill\par
  \marginpar{\footnotesize\textit{\thewords\ words}}
  \setcounter{words}{0}
  \SearchList!{wordcount}{\stepcounter{words}}
    {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?}
  \UndoBoundary{'}
  \SearchOrder{p;}}{%
  \StopSearching
  \marginpar{\footnotesize\textit{End counting words}}
  \noindent\hrulefill}
I realize that I probably have to store the value of the words counter at the end of the environment in the aux file and then pull that number out on the next compilation in order to get this to work right (I've used this approach before in other single use cases), but am not sure how to do that here because the environment needs to support multiple uses in the same document (something the original did, but only because the word count was used immediately and then reset when the environment was used again).

Below is a full MWE which separates out the environment definition from my personalized class file and provides a test case. The last line in the body of the text shows what the word count should be.

Code: Select all

% !TEX program = XeLaTeX
\documentclass{article}

\usepackage{xesearch}

\newcounter{words}
\newenvironment{counted}{%
  \noindent\hrulefill\par
  \marginpar{\footnotesize\textit{\thewords\ words}}
  \setcounter{words}{0}
  \SearchList!{wordcount}{\stepcounter{words}}
    {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?}
  \UndoBoundary{'}
  \SearchOrder{p;}}{%
  \StopSearching
  \marginpar{\raggedright\footnotesize\textit{End counting words}}
  \par\noindent\hrulefill}

\begin{document}
\begin{counted}
In order to better understand this sentence we will expand the predicate by replacing each term with its definition.  “Reverence” is an intentional action directed towards an object (using “object” in the broadest sense of the word so that it includes everything which can be thought of) for the purpose of honoring that object and/or acknowledging the subordination of the subject to the object (the actual mix being determined on a case-by-case basis).  The modification by “natural” in the sentence indicates that this action is not one which is learned, but rather arises from the essence of the subject performing the action.  The possessive “mind's” further modifies this action to indicate that it is one involving the active mental faculties.  Further it restricts the possible domain of subjects to those which possess said active mental faculties.  Putting all this together, the predicate can be expanded as “the intentional actions of a being with active mental faculties which direct said faculties towards an object for the purpose of honoring or subordinating the subject to said object and which arise from the essence of the being possessing said faculties.”
\end{counted}

The above response contains \thewords\ words.
\end{document}

Recommended reading 2024:

LaTeXguide.org • LaTeX-Cookbook.net • TikZ.org

NEW: TikZ book now 40% off at Amazon.com for a short time.

And: Currently, Packt sells ebooks for $4.99 each if you buy 5 of their over 1000 ebooks. If you choose only a single one, $9.99. How about combining 3 LaTeX books with Python, gnuplot, mathplotlib, Matlab, ChatGPT or other AI books? Epub and PDF. Bundle (3 books, add more for higher discount): https://packt.link/MDH5p

rais
Posts: 419
Joined: Sun Nov 16, 2014 8:51 pm

Word counting environment

Post by rais »

rspringuel wrote:I realize that I probably have to store the value of the words counter at the end of the environment in the aux file and then pull that number out on the next compilation in order to get this to work right (I've used this approach before in other single use cases), but am not sure how to do that here because the environment needs to support multiple uses in the same document (something the original did, but only because the word count was used immediately and then reset when the environment was used again).
I think the easiest way for this would be to introduce yet another counter (`counted' below) that is incremented with each call of your counted environment and used for creating a unique macro via the .aux file.

Code: Select all

    % !TEX program = XeLaTeX
    \documentclass{article}

    \usepackage{xesearch}

    \newcounter{counted}% for creating unique counted* macros
    \newcounter{words}[counted]% let words counter be reset by counted 
\makeatletter
    \newenvironment{counted}{%
      \noindent\hrulefill\par
      \stepcounter{counted}%
      \@ifundefined{counted\thecounted}{%
        \marginpar{\footnotesize\itshape?? words}%
      }{%
        \marginpar{\footnotesize\itshape\@nameuse{counted\thecounted} words}%
      }%
%      \marginpar{\footnotesize\textit{\thewords\ words}}%
%      \setcounter{words}{0}%
      \SearchList!{wordcount}{\stepcounter{words}}
        {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?}
      \UndoBoundary{'}
      \SearchOrder{p;}}{%
      \StopSearching
      \immediate\write\@auxout{\string\global\string\@namedef{counted\thecounted}{\thewords}}%
      \marginpar{\raggedright\footnotesize\textit{End counting words}}
      \par\noindent\hrulefill}
\makeatother
    \begin{document}
    \begin{counted}
    In order to better understand this sentence we will expand the predicate by replacing each term with its definition.  “Reverence” is an intentional action directed towards an object (using “object” in the broadest sense of the word so that it includes everything which can be thought of) for the purpose of honoring that object and/or acknowledging the subordination of the subject to the object (the actual mix being determined on a case-by-case basis).  The modification by “natural” in the sentence indicates that this action is not one which is learned, but rather arises from the essence of the subject performing the action.  The possessive “mind's” further modifies this action to indicate that it is one involving the active mental faculties.  Further it restricts the possible domain of subjects to those which possess said active mental faculties.  Putting all this together, the predicate can be expanded as “the intentional actions of a being with active mental faculties which direct said faculties towards an object for the purpose of honoring or subordinating the subject to said object and which arise from the essence of the being possessing said faculties.”
    \end{counted}

    The above response contains \thewords\ words.
\begin{counted}
a second test for counting words.
\end{counted}
    \end{document}
After the first XeLaTeX run, you'll just see ?? instead of the word count (because the macro's to be used aren't defined yet).
However, at that time the definitions should be made available through the .aux file and will be read from the second XeLaTeX run onwards.

KR
Rainer
rspringuel
Posts: 19
Joined: Wed Apr 28, 2010 7:16 pm

Re: Word counting environment

Post by rspringuel »

That works great. Thanks much.

I'm sure I'll now find other uses for this method of defining several unique variables too.
Post Reply