How To Roll Your Own Text Services

ted Written by Ted on August 17th, 2012 in Engineering

I’m one of the Engineers at Realmac, and it’s our job to help take the great ideas and designs from the rest of the team and build them. If a designer deals in pixels, an engineer deals in text - a lot of text! Fortunately OS X has some great features to easily automate text editing tasks which could otherwise be very tedious. Some might even call it fun.

What are Services?

Services

Select some of the text in this blog post and give it a right click. At the bottom of the context menu which comes up you’ll see a much neglected list of Services, or if you have lots of Services then you will see a ‘Services’ sub-menu. Have a peek in there and you’ll see a few things you can do with the text. The list you will see varies based on three things:

  • which application you’re currently in.
  • what you right clicked on (file, directory, photo, etc.).
  • what applications and services you have installed.

Have an explore around your system - check out the Services menu on a few files, and text in a few different applications. If you have Courier or “Twitter for Mac”, for instance, you might see something in a few of those contexts.

There’s an article on Macworld talking about the improvements made to Services in Snow Leopard as well as how to enable / disable them. Services, specifically text Services, are what we’re going to play with for the rest of this blog post.

The Automator

For a lot of people the only reference to the Automator they will have heard about is its beautifully redrawn retina icon for OS X 10.7.4. This is a real shame as it’s an incredibly powerful tool.

automator(/assets/images/blog/502d0727934d4automator.png)

Automator works by dragging “Actions” into an order. Each Action takes an input and then uses that in some way to create an output when can then go into another Action. Chaining several of these can create some very useful and interesting results.

That’s enough talking about it though; let’s actually make something. We’ll start by recreating one of the built in services: ‘Start Speaking’. To try out the built in version:

  1. Select some text
  2. Right click to get the context menu up
  3. Click on Speech->Start Speaking

If your sound isn’t muted, you should have heard your Mac read out your selection. Now we’ll get on with recreating this ourselves:

  1. Open Automator, you should find it in the Applications folder or via Spotlight.
  2. Automator should ask what type of document you’d like, if not go to File->New
  3. Select ‘Service’ and hit ‘Choose’.
  4. You will now have a blank Service showing you the actions on the left. The Service takes text from any application and then feeds it into the (currently empty) workflow.
  5. Type ‘speak’ into the ‘Name’ search box in the top left.
  6. You’ll notice there’s a brief description of this action at the bottom. Drag the item over to the blank space on the right.
  7. Choose a voice and hit ‘Save’.
  8. I gave it the name ‘Simon Says’, but call it what you like.

simon says

Now select some text like you did before, but instead of going to Speech->Start Speaking, look in the ‘Services’ sub-menu and click on the Service you just saved. You just created your first Service - well done!

The Terminal

When the Matrix came out I used to take advantage of my poor friends’ lack of computing knowledge. Whilst fixing minor problems they had on their computers, I’d open up the Terminal or DOS prompt, set the text colour to green on black and then run a simple command to list every file and folder on their system. Whilst all this text was streaming quickly by, I’d randomly bash all the keys on the keyboard and tell them I was working on the problem.

terminal

The Terminal can be quite intimidating at first, but once you get the hang of it, it gives you access to a wealth of tools which have been developed.

For those who’ve not heard of it before, it’s a way of interacting with your Mac via text commands. It prompts you to type something with a little rectangle (this is called the prompt), you type something and once you’re done, hit the ‘enter’ key. The Mac then interprets what you just typed and either does something or points out any errors in what you wrote. The system doing this is called Bash and it’s called an ‘interpreted language’ or a scripting language. Yes, it is actually programming in a loose sense.

Learning the basics of Bash is a bit beyond the scope of this post, but don’t worry. All you need to know is that we’re going to be dipping our toe in and making use of a few bits and pieces. There’s a nice introduction to the basics over here and then after that there’s the full reference manual.

The ‘Sort Text’ Service

We’re now going to create our first useful text Service. In Bash there’s a command called sort. Sort takes in text as its input and then sorts all the lines alphabetically. By default it will group all the uppercase and all the lowercase separately, but if you give it the command line switch ‘-f’ it will ignore the case.

  1. Open up Automator and create a new Service.
  2. This time search for ‘shell’.
  3. Drag ‘Run Shell Script’ over to the right hand pane.
  4. This time we’ll tick ‘Output replaces selected text’ as we want the processed text to replace our selection.
  5. In the main window, add the text ‘sort -f’.
  6. Now save the service and give it a name, I went for ‘Sort’.

It should look something like this:

Sort_service

To test the service, select a list of text in an editable area (such as TextEdit or an email) and then apply the service. The selection should get replaced with a sorted list of the same text.

As a further improvement, you could add a ‘-u’ flag to the sort command to remove duplicate entries. Handy if you’re keeping track of things and might have added something twice by accident.

Regular Expressions

Picture, if you will, Keyboard Cat’s elder brother. Like his younger brother he likes keyboards a lot, but this cat is a programmer. He’s incredibly hungry after all that typing and eats the first thing available to him: his keyboard. In a combination of eating too quickly, indigestion and a hair ball, the elder Keyboard Cat regurgitates all the keys.

The seemingly random arrangement of letters, punctuation and numbers produced by this look very much like a regular expression.

/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-])\/?$/

This is where the similarities end though because regular expressions are very useful.

Have you ever wondered how your iPhone is able to detect phone numbers in an email, or your Mac underline addresses and links? These and many other seemingly magical things are done using regular expressions. Regular expressions define patterns - certain combinations of letters, numbers and symbols and the related order in which they are expected to appear. Best of all, regular expressions can be defined to do replacements in certain utilities. This is the tool we are going to use for next few services.

Big Numbers

Sometimes I’m pasting an outputted number into an email and I can’t parse it in my head, it’s just too many digits. I find myself manually putting in the thousands, millions, billions commas. Would it be great if we had a service to do this for us?

There’s a regular expression for that, combined with sed (the stream editor - an amazingly powerful tool). The tool takes in streams of text, changes it based on rules you give and then spits it out the other end:

sed -e :a -e 's/(.*[0-9])([0-9]{3})/\1,\2/;ta'

We’re getting quite a few services cluttering up our menu now, so this time we’re going to restrict the service to only apply to text selected in Mail. I only tend to do this in emails to people, so I shouldn’t need it anywhere else. To do this, click the ‘any application’ drop down and select ‘Mail’. You could of course browse and select any other application you like here.

big_numbers

To try it out, create a new email in Mail, type a big number with no commas, and then apply the Service as usual.

Markdown lists

I tend to write most of my documentation in Markdown, in fact this blog post is written using it. Sometimes I write a list and then need to go back and insert all the leading hyphens so that it’s interpreted as a bulleted list. Here’s a Service for that:

sed -e 's/.*/-&/'

markdown(/assets/images/blog/502d079a36b33markdown_list.png)

What if you don’t want to overwrite the selected text?

Let’s go back to the sort example. Sometimes you might select some text on a page that you can’t edit, you want to sort it and then paste it somewhere else. We’ll modify that example accordingly:

  1. Create the service as before
  2. Un-tick ‘Output replaces selected text’
  3. Append | pbcopy to the end of the sort command

Step 3 is the important bit, this says ‘take the output of the sort command and send it to the pbcopy command’. The command ‘pbcopy’ takes any text you give it and then copies it to your clipboard.

Sort_replace

Conclusion

Hopefully this has given you a little glimpse into the world of Services and has maybe inspired you to learn a little more about the command line and regular expressions. You should now have a starting point to invent your own custom Services.

If anyone has come up with a useful Service after reading this, or has an idea for one and they’re not quite sure where to start, I’d be really interested to read about it in the comments.