Part 2: Counting Words
This post is part of a series.
- Part 1: Using Org to Develop E-lisp Snippets
- (You are here) Part 2: Counting Words
I often use an separate (Org) file to develop written content, especially when I am filling out an application that has essay questions. The answers often have a word-count or character-count limit. Let’s use Emacs and Org to count words!
Exploring Existing Functionality
First, I use builtin documentation (and tab completion) to compile some useful functions. Actually, I flailed a lot and bugged my friend who knows a bunch about Emacs and Org.
count-words function is obviously a good place to start.
The documentation indicates that functions works on either a region or buffer and that it acts differently if called from lisp (rather than interactively).
I don’t know anything about regions, but the Emacs Lisp documentation for “The Region” mentions two more useful functions:
Looking through all the Org functions, two stick out:
These functions create a region on a specified chunk of Org content.
Finally, I’ll need to go to the Org location to mark the region.
There are a few functions that look good for that:
org-goto (though that seems to be very interactive) and
Also, I come across
I already know how to name a source block.
For the other go-tos, making an Org ID is easy enough:
org-id-new looks promising, I eventually learn that it doesn’t do what I want).
Marking and Counting
I need to create an Org section for each answer that I want to word count.
I can either use a header/node/subtree or a source block (of text).
In the first case, I’ll add a unique ID to the header (by invoking the
org-id-get-create) so I can use the
In the source block case, I can simply give it a name.
The snippet for counting words in a subtree looks something like:
Unfortunately, the first snippet doesn’t work. Instead, it shows the error “Wrong type argument: markerp nil”.
Let’s try the source block way:
Huzzah! This one works. Strangely, the result appears below the question block, not where I would expect it (below the code snippet).
My friend (who actually reads books) shows me an awesome Emacs lisp function6:
save-excursion: Save point, and current buffer; execute BODY; restore those things.
Turns out, this function is all over a bunch of e-lisp code. Let’s try it! First, the subtree version of counting words:
Low and behold! It suddenly works.
Plus, the results appear below the current code block.
save-excursion also fixes the source block method, making the results block appear near it.
One remaining issue with the subtree method is that it counts the Org properties drawer in the word count.
Count All the Things!
Finally, our word counting snippet should work on a bunch of subtrees or blocks. Let’s pass some input to the snippets. Also, we should pretty print the results. Finally, I’ve included the code to count the characters as well. The source block method ends up looking like:
The same can be done for the subtree method, but with IDs as the input.