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? Jan 2, 2021 at 18:19
  • Yes, I get \limit already defined.
    – John Chris
    Jan 2, 2021 at 19:01
  • 2
    That isn't what you say about the log file in the question:-) Jan 2, 2021 at 19:34
  • 1
    Are you sure that it worked before? I get \limit already defined error in texlive 2016,2017,2018,2019,2020 Jan 2, 2021 at 19:40
  • 1
    @JohnChris An alternative?? tex.stackexchange.com/questions/44618/… Apr 8, 2021 at 10:29

1 Answer 1

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, 2021 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. Apr 8, 2021 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. Apr 8, 2021 at 13:46
  • 1
    @JohnChris I have added those changes to the MWE. Apr 8, 2021 at 14:01
  • 1
    @StevenB.Segletes One of best suggestion...heart full congrats....
    – MadyYuvi
    Apr 8, 2021 at 17:06

You must log in to answer this question.

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