This approach uses a defined macro \startcount
that ends with \stopcount
to count within a multi-paragraph argument. EDITED to add \pausecount
and \continuecount
functionality within paragraphs, even mid-sentence. RE-EDITED to detect sentences that are questions (?) and exclamations (!).
RE-EDITED [jorge]: Superscripts are used for the parenthesis indicating the number of sentence and the number of words in the sentence, and also for the brackets indicating the number of sentences and the number of words in a paragraph.
Color code:
Blue = Numbers of sentence and number of sentences in a paragraph.
Green = Number of words in a sentence and in a paragraph.
The superscripts are required to avoid confusion with different style citing references, e.g. AMA STYLE = You et al [5] or Vancouver = You (5).
(EDITED again to replace "dangerous" non-environment \countem...\endcountem
syntax with \startcount...\stopcount
; also inserted \unskip\@
between end of paragraph and the paragraph ledger, so as to obtain normal spacing there)
NOTE, for aesthetics and clarity, I used brackets rather than parens to display the end-of-paragraph ledger, to differentiate it from the end-of-sentence ledger.
In general, it expects ordinary words in the argument, not macros, display math and such (though macros won't necessarily break it, if one is careful). For example, inline math can be parsed, but it will use the spaces of the input (which of course have no meaning in math mode) to count words.
Alternately, one can group the math (including display math) in braces {}
and the embraced group will be counted as a single word if surrounded by spaces, or a single character, if not surrounded by spaces.
Thirdly (now shown in the MWE), within the paragraph or a sentence, one may invoke \pausecount
followed by a later \continuecount
to skip over counting a block of text, without disrupting the counting ledger.
I do not reset the counter myparagraphs
so that if different invocations of \startcount
are employed, the paragraph counter will pick up where it left off. Thus, \stopcount
can be used to skip over the counting of problematic paragraphs and the counting resumed with \startcount
.
\documentclass{article}
\usepackage{color}
\definecolor{Green}{rgb}{0.1,0.5,0.4}
\newcounter{totalwords}
\newcounter{mywords}
\newcounter{mysentences}
\newcounter{myparagraphs}
\setcounter{myparagraphs}{0}
\long\def\startcount#1\stopcount{%
\par\startcountpars\ignorespaces#1\par\relax}
\long\def\startcountpars#1\par#2\relax{%
\stepcounter{myparagraphs}%
\setcounter{mysentences}{0}%
\setcounter{totalwords}{0}%
(P\themyparagraphs) %
\startcountsentences#1. \relax\unskip\@ \ledger[p]{mysentences}{totalwords}\par %SuperScript + color
\ifx\relax#2\relax\else
\startcountpars#2\relax\fi
}
\def\startcountsentences#1. #2\relax{%
\hasitquestions#1? \relax% THAT ?-CHECK IS BEFORE !-CHECK HAS RAMIFICATIONS
\if T\ItHas\startcountquestions#1\relax%
\expandafter\startcountsentences\remainder. #2\relax\else
\hasitexclamations#1! \relax%
\if T\ItHas\startcountexclamations#1\relax%
\expandafter\startcountsentences\remainder. #2\relax\else
\ifx\relax#2\relax\else
\stepcounter{mysentences}%
\setcounter{mywords}{0}%
\startcountwords#1 \relax\unskip.\ledger{mysentences}{mywords}%
\startcountsentences#2\relax\fi\fi\fi
}
\def\hasitquestions#1? #2\relax{%
\ifx\relax#2\relax\def\ItHas{F}\else\def\ItHas{T}\fi
}
\def\startcountquestions#1? #2\relax{%
\hasitexclamations#1! \relax% MUST CHECK FOR ! WITHIN ?-SENTENCES
\if T\ItHas\startcountexclamations#1? #2\relax\else
\stepcounter{mysentences}%
\setcounter{mywords}{0}%
\startcountwords#1 \relax\unskip?\ledger{mysentences}{mywords}% change color
\def\remainder{#2}%
\fi
}
\def\hasitexclamations#1! #2\relax{%
\ifx\relax#2\relax\def\ItHas{F}\else\def\ItHas{T}\fi
}
\def\startcountexclamations#1! #2\relax{%
\stepcounter{mysentences}%
\setcounter{mywords}{0}%
\startcountwords#1 \relax\unskip!\ledger{mysentences}{mywords}%
\def\remainder{#2}%
}
\def\startcountwords#1 #2\relax{%
\ifx\pausecount#1{} \pausecount#2\relax\else
\stepcounter{mywords}%
\stepcounter{totalwords}%
#1 %
\ifx\relax#2\relax\else
\startcountwords#2\relax\fi
\fi
}
\def\pausecount#1\continuecount#2\relax{#1\startcountwords#2\relax}
\newcommand\ledger[3][s]{%
\def\colA{blue}\def\colB{Green}%
\if p#1\def\open{[}\def\close{]}%
\ifnum\value{#2}>8\def\colA{red}\fi\ifnum\value{#3}>90\def\colB{red}\fi\else
\def\open{(}\def\close{)}%
\ifnum\value{#2}>8\def\colA{red}\fi\ifnum\value{#3}>35\def\colB{red}\fi\fi
\allowbreak\textsuperscript{%
\open\textcolor{\colA}{\arabic{#2}}--\textcolor{\colB}{\arabic{#3}}\close} }
\def\cmd#1{\textbackslash\texttt{#1}}
\begin{document}
\def\eg{\textit{e.g.}}
\startcount
Is this the first, \eg, sentence?
This is ABSOLUTELY the second sentence!
Is this the third sentence of the paragraph?
Here we test inline math: $x^2$.
We begin a pause after this.
\pausecount
\[% NOTE THAT ANY \label HERE WILL NOT BE ACCESSIBLE LATER
y = mx + b
\]
\continuecount
Here we continue counting.
Within a paragraph, we use \cmd{pausecount}
and \cmd{continuecount} to skip over stuff.
Now here \pausecount \textit{we are pausing the count mid-sentence}
\continuecount for just a few words.
Another sentence that is only moderately long.
Another sentence that is only moderately long.
Another sentence that is very very very very very very very very very
very very very very very very very very very very very very
very very very very very very very very very very long.
Another sentence that is only moderately long.
\stopcount
To pause the count between paragraphs (as is done here), just
\cmd{stopcount} and, when ready to restart, reinvoke \cmd{startcount}.
\startcount
Here we are testing to see if we picked up where we left off in the
paragraph count.
Is it so?
Voila, it is so.
\stopcount
\end{document}
?
and!
before the sentence ledger, but place periods.
after it. Was that intentional? Also, I will re-edit to eliminate extraneous spaces there.