1

I like using texcount for counting words in my LaTeX documents, and I was wondering whether it could give me something a bit more precise than the default information.

In this assignment I'm writing, the words in a given caption (on a table or figure) don't count, except if there are more than 50 words in it. As it is, texcount only gives me the total number of words in captions and footnotes, so I was wondering if I could write some code to get more detailed output:

  • Is it possible to get a list of wordcounts in each caption? At the very least, that would allow me to see which I should add to my word count. Or, better yet,
  • Is it possible to make texcount only record the wordcount in captions with more than a threshold (like 50 words)?

In most situations the default behaviour is acceptable in my case, since if the total otherwords count is low enough I know that I'm good. Nonetheless I want to take this opportunity to understand a little better how texcount works.

1
  • Afaik, there are not ways to conditional counts but you can count specific parts of the document and make subcounts of captions. Examples: here, here and here.
    – Fran
    Apr 21, 2020 at 23:35

2 Answers 2

1

This is not a proper answer, but more than just a comment.

As already noted by Marijn in his answer, TeXcount adds words to the count one by one is it goes along: ie, it does not analyse text recursively, one block/group/argument at a time, and then add that to the one containing it. So it doesn't know how many words is in each block when adding it to the total, making it hard to do filtering by size. Marijn's solution is a hack, but probably the simplest solution is along those lines.

An alternative could be to save the word count at the start of the caption and check at the end of the caption to see if it should be kept or the count be reverted to the one at the start. I'll see if I can come up with something that might work...doesn't come off the head.

As for listing the word count per caption, I can't think of any nice solution, but again there is a hack that this time does not require changing the script. It involves defining \caption as a breakpoint at which new subcounts are started: intended for \section similar macros. The documentation happens to be incorrect on the usage, but this should sort of work when added somewhere at the top of the document:

%TC:breakmacro \caption Caption

The output caused by this won't be pretty as it will essentially use the caption as the title of the new subcount. However, caption words will now be counted as 'words outside text'. To avoid the issue of other 'words outside text' getting added to this, you might need to specify captions as a separate counter making this the full set of instructions:

%TC:breakmacro \caption Caption
%TC:newcounter caption Caption text
%TC:macro \caption [caption]
%TC:floatinclude \caption [caption]

Note that floatinclude is like macro, but specifies a macro handling rule inside a floating environment.

1
  • As you warned, the output is not as clear as I'd like, but it gives me the information I want and has the advantage that I don't have to learn Perl (yet!).
    – mantheflan
    Apr 23, 2020 at 15:39
1

The following is a proof-of-concept to count conditionally on the number of words in a macro argument, in this case \caption. It requires modifying the source of texcount, which is written in Perl.

There is a subroutine inc_count (around line 2800 in texcount 3.1.1) that counts words one by one. The line that actually increases the count is

${$count->{'counts'}}[$cnt]+=$value;

with the variable $cnt representing the type of count. Captions are type 3.

You can add some checks to this function to count caption words only if the total number in that caption reaches a predefined threshold. To do this you need to use a variable to keep track of the current total of words in a caption, and another variable to keep track of what the type of the previous word was. The possible situations that the check needs to account for are:

  • The type is not a caption. Then, reset the caption word count and count the word normally for its type.
    • Optionally, check if the previous word was in a caption, if yes, then that caption has now ended, and the number of words can be printed.
  • The type is a caption. Then, check if the previous word was also a caption.
    • If not, then a new caption has started. Set temporary count to one, do not store the count yet.
    • If the previous word was a caption, then check if the threshold has been reached.
      • If not, then increase the count, but don't store the count yet.
      • If the count is at the threshold, then store the current count.
      • If the count is over the threshold, then store an additional count of one.

MWE:

my $prev_type;
my $capt_count;
# Increment TeX count for a given count type
sub inc_count {
  my ($tex,$cnt,$value)=@_;
  my $count=$tex->{'subcount'};
  if (!defined $value) {$value=1;}
  if (!defined $prev_type) {$prev_type = -1;}
  if (!defined $capt_count) {$capt_count = 0;}
  my $CAPT_THRESHOLD = 3;
  if ($cnt != 3){ # not a caption, reset and count as normal
    if($prev_type == 3){ # previous word in caption, which has now ended
      print "Caption: $capt_count words\n";
    }
    $capt_count = 0; # reset
    $prev_type = $cnt;
    ${$count->{'counts'}}[$cnt]+=$value; # count as normal
  }else{ # in a caption
    if ($prev_type == 3) { # check if previous word was also in a caption
      $capt_count++;
      if ($capt_count == $CAPT_THRESHOLD) { # at threshold
        ${$count->{'counts'}}[$cnt]+=$capt_count; # count previously ignored words
      }
      if ($capt_count > $CAPT_THRESHOLD) { # over threshold
        ${$count->{'counts'}}[$cnt]+=$value; # count one for current word
      }
    } else { # previous was not a caption, so start of new caption
      $prev_type = 3;
      $capt_count = 1;
    }
  }
}

LaTeX document:

\documentclass{article}
\begin{document}
Some normal text
\begin{figure}
text in figure
\caption{short caption}
\end{figure}

\begin{figure}
text in figure
\caption{one two three four five}
\end{figure}
more text
\end{document}

texcount output (threshold = 3, so the first caption is not counted but the second caption is counted):

Caption: 2 words
Caption: 5 words
File: captioncount.tex
Encoding: ascii
Words in text: 5
Words in headers: 0
Words outside text (captions, etc.): 5
Number of headers: 0
Number of floats/tables/figures: 2
Number of math inlines: 0
Number of math displayed: 0

Note that the added Perl code is not very clean or conforming to best practise, and may produce incorrect results - it is a proof of concept only.

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.