Jul
26
OS X Service – Word Count (and More)
Filed Under Computers & Tech, Software Development, My Projects on July 26, 2013 at 1:28 am
Inspired by a recent episode of The Mac Cast I decided to see if I could come up with a simple way of getting a word count of a PDF on OS X using only tools that come standard with the OS.
Because of OS X’s Unix underpinnings, all Macs have access to the Unix wc
command which calculates word counts on given input. OS X also has a handy built in Terminal command to access the contents of the clipboard (pbpaste
). This leads to an obvious simple manual solution:
- Open the PDF in Preview
- Select All Text
- Copy to clipboard
- Run the Terminal command:
pbpaste | wc -w
This is a bit cumbersome though, so I went on to create a simple OS X Service to calculate the word count of any selectable text in any app (the fact that this is even possible, let alone easy, is why I love OS X).
For those of you just looking for a copy of the Service, you can download it here:
To install the service simply extract the automator file from the ZIP archive and copy it into either the Library/Services
folder in your home directory, or the system-wide service folder /Library/Services
.
Once the Service is installed you can use it in almost any OS X app (specifically in any app written using the standard Cocoa libraries) by selecting some text, right-clicking on it, and selecting the Word Count service:
When done the results will look something like this:
Those of you who want to see how easy this Service was to write, read on and I’ll walk you through it.
The Automator app that comes free with OS X makes it easy to create system-wide services. Lets start by launching that app, and selecting Service from the list of possible action types to create.
Using the drop-downs at the top of the workflow, set the input to Service receives selected Text in any application.
Next add a Copy to Clipboard action into the workflow, and then add a Run Shell Script action below that, within the Run Shell Script action set the shell to /bin/bash
.
Then paste the following code into the body of the Run Shell Script action:
word_count=`/usr/bin/pbpaste | /usr/bin/wc -w` /usr/bin/osascript -e "tell app \"System Events\" to display alert \"Word Count: $word_count\""
The first line calculates the word count of the contents of the clipboard and saves it to a variable, and the second line uses Apple Script to display the calculated word count in a dialog box.
All you have to do now is save the action and give it a name, then it’s ready to use!
We can do a little better though – why only show the word count, why not list the character count and line count as well? OK, lets do that, alter the contents of the Run Shell Script to the following and save:
char_count=`/usr/bin/pbpaste | /usr/bin/wc -m` word_count=`/usr/bin/pbpaste | /usr/bin/wc -w` line_count=`/usr/bin/pbpaste | /usr/bin/wc -l` /usr/bin/osascript -e "tell app \"System Events\" to display alert \"Character Count: $char_count\nWord Count: $word_count\nLine Count: $line_count\""
When you’re done your Automator workflow should look like this:
If you are using bash, there’s a shorter version of the script that calls pbpaste and wc only once and uses less resources. How about using the following:
count=($(pbpaste | wc))
osascript -e “tell app \”System Events\” to display alert \”Character Count: ${count[2]}\nWord Count: ${count[1]}\nLine Count: ${count[0]}\””
By using an array, you call the commands once and save overhead.
Also, in the Maccast where I heard about this post, I forgot what you called osascript but the “osa” stands for Open Systems Architecture.
Finally, I have no problems with not using full path names. The commands used are standard commands in the standard locations that are set by the default PATH variable.
Good luck!
Fabuloso! I was suddenly needing the word count of an abstract I was writing in Evernote. I thought, oh no, drag into Word, wait, word count… that’ll work. But then wondered about a Service – so I pressed right click – Nothing.
SO I thought Web search, there might be some else who had the same thought and wrote it already! It might even be quicker than the Word solution!
Well, maybe it wasn’t faster than starting Word in the end, but it was pretty close, and solved a long term problem more elegantly.
Many thanks this was perfect. barns
Great tip! You don’t need to copy to the clipboard. I prefer not to replace the current clipboard contents in case I need them. Remove the copy to clipboard action and set the “Pass input” option of the “Run Shell Script” action to “to stdin”. Then use this simple script:
count=($(wc))
osascript -e “display notification \”${count[0]} Lines, ${count[2]} Characters\” with title \”Word Count\” subtitle \”${count[1]} Words\””
Note I also use “display notification” so that a (Yosemite/Mavericks) notification appears in the upper right of the screen, then fades away. This way you don’t have to click it away. I put the word count in the subtitle so it’s bold and appears first.
That is kick-ass. I’m absolutely amazed that whenever I need something, someone has already done it.
The Line Count actually turns up a Page Count, but that’s okay. It’s the Word Count I really needed. You might want to rename it though to accurately reflect what it actually counts.
Thanks again!
Mark — I get an error in Automator when I try to use your simplified script. “0:1: syntax error: A unknown token can’t go here. (-2740)”
I’m wondering if something has been screwed up in the copying and pasting into your post? Or from your post to my Automator?
I’m running on MacOS 10.12 Sierra.
Mark – I eventually figured out the problem. It was the form of the quotes – this CMS must convert quotes to stylised quotes, when they need to be standard straight quotes for them to be understood by BASH. So replacing the quotes in your post by retyping them did the trick.
Now, if only I could get the service to actually show in Preview! Although it is set to be available to any app offering text, it doesn’t appear in the Preview menu. (Appears fine in other apps like Notes which makes me wonder if Preview does not consider a text selection in a PDF as “text”.)
Works well – with the exception of the line count. Doesn’t count lines for sure and also not pages as suggested above?
How could you count lines?
Hi Maximilian,
Could you expand on what you mean when you say it doesn’t count lines? What is your definition of a line? The underlying `wc` command line tool considers a line to end at an explicit line-break character, do you have a different definition?
There is no way to count pages with the `wc` command line tool, it has no concept of pages.
B.
Indeed, the end of a line needs to be defined for a line count… and what looks like one line on a screen might be the result of wrapping the text into the available space, hence difficult to count as lines. How is Word counting it then as if I wrap the text tight it counts more lines…
Still if I count your above reply (including “Maximilian” and the signature “B.”) I get 3 lines whereas it should be 4?
Best regards, Max