4

The following mwe has been discussed in this post, and this one. The mwe no longer works after a system update. Any guidance on troubleshooting is greatly appreciated.

W10, MikTeX 2.9, TeXWorks, installed Perl 5.30, installed grep, confirm that both are installed, added paths of external scripts to PATH through PC or TeXWorks, (both seem like they do the same thing)

The limited debug messages I see in the console are:

("C:\Users\Chris\AppData\Local\Programs\MiKTeX 2.9\tex/context/base/mkii\supp-p
df.mkii"
[Loading MPS to PDF converter (version 2006.09.02).]
)
\sectioncount=

Here is the mwe:

\documentclass{article}%
%\usepackage{titlesec} %**** uncomment to see error message


% Compile with  --enable-write18 or --shell-escape options   
\immediate\write18{texcount -char -merge -tex -sum \jobname.tex | grep -i section > \jobname Count.txt} % counts characters
%\immediate\write18{texcount -merge -tex -sum \jobname.tex | grep -i section > \jobname Count.txt} % counts words
\newcommand{\limitcount}{-1}

\usepackage{xstring}
\usepackage{ifthen}
\usepackage{xcolor}
\usepackage{nameref}

\newcommand{\processCount}{%
 \newread\counts
 \def\zpar{\par}
 \openin\counts=\jobname Count.txt
 \loop
 \read\counts to \sectioncount
 \ifx\sectioncount\zpar\else
 \showcount{\sectioncount}\\
 \fi
 \ifeof\counts
 \else
 \repeat
}

\newcommand*{\showcount}[1]{%
 % e.g. 67+18+0 (1/0/0/0) S[ubs]ection: The first subsection
 \StrBehind{#1}{ection: }[\sectiontitleplusspace]
 \StrGobbleRight{\sectiontitleplusspace}{1}[\sectiontitle]
 \StrBefore{#1}{+}[\thiscount]
 \expandafter\ifcsname\sectiontitle limit\endcsname%
  \renewcommand{\limitcount}{\csname\sectiontitle limit\endcsname}%
 \else%
  \renewcommand{\limitcount}{-1}%
 \fi%
 \sectiontitle:
 {%
  \ifthenelse{\thiscount>\limitcount}{%
   \textcolor{red}{\thiscount/\limitcount}%
   \ifthenelse{\limitcount>-1}{%
    \ (over by \number\numexpr\thiscount-\limitcount\relax)%
   }{}%
  }{%
   \textcolor{green}{\thiscount/\limitcount}%
  }%
 }
}

\makeatletter
\newcommand*{\contentlimit}[1]{%
 \expandafter\newcommand\csname\@currentlabelname limit\endcsname{#1}
}
\makeatother


\begin{document}

\section*{Over the Limit}
\contentlimit{5}

This content is over the limt.

\section*{Under the Limit}
\contentlimit{100}

More content, this time under the limit.

%TC:ignore 

% display information on document
\section*{Document analysis}
\processCount

%TC:endignore 

\end{document}

Update:

I verified that texcount.pl was present. I verified that texcount.exe was present. I verified that the Texworks compiler options included references to the paths corresponding to the above.

Still getting sectioncount= as an error.

8
  • 1
    in texlive 2020 if I uncomment the titlesec line I get the error that \limit is defined, do you not see that error? – David Carlisle Jan 2 at 18:19
  • Yes, I get \limit already defined. – John Chris Jan 2 at 19:01
  • 2
    That isn't what you say about the log file in the question:-) – David Carlisle Jan 2 at 19:34
  • 1
    Are you sure that it worked before? I get \limit already defined error in texlive 2016,2017,2018,2019,2020 – David Carlisle Jan 2 at 19:40
  • 1
    @JohnChris An alternative?? tex.stackexchange.com/questions/44618/… – Steven B. Segletes Apr 8 at 10:29
4
+100

A possible alternative to texcount.

Based on my answer here, Dynamically count and return number of words in a section, this is a pure TeX solution to the problem. No write-18 required. I adapted the other solution in several ways. I tried to match the OP's syntax when possible. However, one still needs to manually set the start and stop points (\countem...\endcountem). I also now keep a global tabulation of the multiple countem environments that arise in the document.

The countem environment can span across paragraphs, sections, if needed, even tables, equations, etc. Of course, it will count the invoking syntax of that stuff (unless you |escape the code| between the designated escape-delimiters). The only proviso is that you can't apply it to stuff that changes the catcodes of its argument (notably verbatim), because the method involves scanning all the tokens in advance...thus, token catcodes are set before the user's macro/environment has a chance to change them.

EDIT: I have added the macro \disablecountem, so that when you are happy with the counted-document results, you merely need invoke this at the beginning of your document to restore a normal non-counting compilation (exception: if you employed the code-escape mechanism of tokcycle to temporarily bypass counting, you will also have to let the escape token to \empty. This is by default a | but can be changed in the code, even to a macro, with \settcEscapechar{}).

At the request of the OP's comment, I made a 2nd EDIT to allow, with the declaration \countspacestrue, to add the count of spaces and punctuation (that is to say, cat-10 and cat-12 tokens) into the letter count. Look for the 4 lines in the MWE labeled with the comment NEW!! to see how this change was implemented.

Even NEWER! I have added support for \obeyspaces in the counting of spaces. To the Macro directive in \countem, I added the line \ifactivetok\ifnum\numberˋ##1=32\relax\stepcounter{lettercount}\fi, since \obeyspaces works by making the space token active.

\documentclass{article}
\usepackage{tokcycle}[2021-03-10]
\usepackage{xcolor}
\newcounter{wordcount}
\newcounter{lettercount}
\newcounter{wordlimit}
\newif\ifinword
% USER PARAMETERS
\newif\ifrunningcount
\newif\ifsummarycount
\def\limitcolor{red}
\setcounter{wordlimit}{0}
%%
\makeatletter
% \tc@defx is like \def, but expands the replacement text once prior to assignment
\newcommand\addtomacro[2]{\tc@defx#1{#1#2}}
\newcommand\changecolor[1]{\tctestifx{.#1}{}{\addcytoks{\color{#1}{}}%
  \tc@defx\currentcolor{#1}}}
\makeatother
\newcommand\dumpword{%
  \addcytoks[1]{\accumword}%
  \ifinword\stepcounter{wordcount}
    \ifrunningcount\addcytoks[x]{$^{\thewordcount,\thelettercount}$}\fi
    \ifnum\thewordcount=\value{wordlimit}\relax\changecolor{\limitcolor}\fi
  \fi%
  \inwordfalse
  \def\accumword{}}
\newcommand\addletter[1]{%
  \tctestifcatnx A#1{\stepcounter{lettercount}\inwordtrue}{\dumpword}%
  \ifcountspaces\tctestifcatnx .#1{\stepcounter{lettercount}}{}\fi% NEW!!
  \addtomacro\accumword{#1}}
\newif\ifcountspaces% NEW!!
\xtokcycleenvironment\countem
  {\addletter{##1}}
  {\dumpword\groupedcytoks{\processtoks{##1}\dumpword\expandafter}\expandafter
    \changecolor\expandafter{\currentcolor}}
  {\dumpword\ifactivetok\ifnum\number`##1=32\relax
    \stepcounter{lettercount}\fi\fi\addcytoks{##1}}
  {\dumpword\ifcountspaces\stepcounter{lettercount}\fi\addcytoks{##1}}% NEW!!
  {\stripgroupingtrue\def\accumword{}\def\currentcolor{.}
    \setcounter{wordcount}{0}\setcounter{lettercount}{0}}
  {\dumpword\retainsum\ifsummarycount\tcafterenv{%
    \par(Wordcount=\thewordcount, Lettercount=\thelettercount)}\fi}

\newcommand\contentlimit[1]{\setcounter{wordlimit}{#1}}

\newcounter{globalwordcount}
\newcounter{globallettercount}
\newcommand\retainsum{%
  \addtocounter{globalwordcount}{\thewordcount}%
  \addtocounter{globallettercount}{\thelettercount}%
}

\newcommand\processCount{\ifnum\thegloballettercount>0%
  \par Global Wordcount=\theglobalwordcount\\
  Global Lettercount=\thegloballettercount
\fi}

\newcommand\disablecountem{\let\countem\empty\let\endcountem\empty}

\begin{document}
%\disablecountem% TO TURN OFF COUNTING, WITHOUT CHANGING DOCUMENT
\section*{Over the Limit}

\contentlimit{5}\countem
This content is over the limit.
\endcountem

\section*{Over the Limit with running count shown}

\contentlimit{5}\runningcounttrue\countem
This content is also somewhat over the limit.
\endcountem\runningcountfalse

\section*{Under the Limit with summary count shown}

\contentlimit{100}\summarycounttrue\countem
More content, this time under the limit.
\endcountem

\section*{Example of also counting spaces and punctuation}

\countspacestrue% NEW!!
\countem
Obeyspaces     is    off...\endcountem

{\obeyspaces\countem
Obeyspaces     is     on...\endcountem}

\section*{Document analysis}
\processCount

\end{document}

enter image description here

7
  • Brilliant. Thoughts on a switch to toggle between considering spaces to not considering spaces? – John Chris Apr 8 at 12:36
  • 1
    @JohnChris I presume you mean to count them as characters. I think that would be easy. Let me have a look. – Steven B. Segletes Apr 8 at 13:26
  • 1
    @JohnChris If one creates \newif\ifcountspaces and sets the fourth argument of the \countem definition to {\dumpword\ifcountspaces\stepcounter{lettercount}\fi\addcytoks{##1}}, then spaces are counted when \countspacestrue is declared. However, punctuation is still not counted, since the \addletter macro screens for catcode 11. However, if this line were added to the \addletter macro, \ifcountspaces\tctestifcatnx .#1{\stepcounter{lettercount}}{}\fi, then cat-12 punctuation would be letter-counted as well when \countspacestrue was set. – Steven B. Segletes Apr 8 at 13:46
  • 1
    @JohnChris I have added those changes to the MWE. – Steven B. Segletes Apr 8 at 14:01
  • 1
    @StevenB.Segletes One of best suggestion...heart full congrats.... – MadyYuvi Apr 8 at 17:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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