Icon of a thin page Icon of a thick page

Differential Word Counts

David A. Harding

I've been trying to write a constant number of words each weekday for this blog. If I started and finished a single entry every day, this would be easy: I would run wc -w on the current file whenever I wanted to know how many words I'd written so far and do some math in my head to figure out how many words still need to be written. But some blogs I write want to be longer than the number of words I choose to write and some blogs want to be shorter, and very few blogs want to be just right, as Goldilocks might say. So I've done what I always do, I've written a script to overcome the shortcomings of reality.

My idea is simple: run wc, a command that does word counts, on a file before I open the file, save the results, then run wc on the file at any later time, and find the difference between the two results.

wcstate record somefile
echo foo > somefile
wcstate status somefile
1 1 3 somefile (changes since 2007-04-16 07:25:09.00 -0400)

A final command wcstate supports is wcstate stop, which cleans up a temporary file created to store the state of the file when wcstate record is run.


Nvi Integration
To make running wcstate quicker and easier, I've written a small shell script called blog that does all the work of calling wcstate before and after I run my editor, nvi (a vi clone), on the file that contains my unpublished blogs:

#!/bin/bash -u

BLOGFILE="$HOME/doc/mine/blogs/newblogs"
wcstate rec "$BLOGFILE" && \
        nvi "$BLOGFILE" && \
        wcstate stop "$BLOGFILE"

Running wcstate status on the current file from nvi is easy: :!wcstate status %. The colon means, run the following command in ex mode, the exclamation point means, execute the following command in the shell, and the percentage sign is replaced with the name of the current file. The output of the command is displayed by nvi in a special screen:

!wcstate status doc/mine/blogs/newblogs
6 77 578 doc/mine/blogs/newblogs (changes since 2007-04-18 07:34:46.00 -0400)

Being lazy, I alias that command to something simpler: =wcs, and so all I have to do is type that in command line mode to see a summary like the one above. This is a single line addition to my ~/.exrc:

map =wcs :!wcstate status %


Notes
I wrote the script for bash, but I now regret that. I could've written a much simpler script, with less error checking (and possibility for errors), if I just re-implemented the functionality of wc in perl and wrote my script around that function. Note, wcstate will make a copy of your file, and so you should be wary of using it for things that shouldn't be copied. Also, it won't automatically clean up the state directory; you need to use wcstate stop to remove the redundant file when your done.

The paragraph above is a verbose way of saying, you get no guarantees if you use wcstate.