I am writing a book and trying to add a service to provide syntax highlighting to text selected in Pages with Automator. I have a service accepts selected text and runs it through a shell command (pygmentize) which converts it to syntax highlighted RTF.

The problem is that when the text is returned, Automator treats it as plain text and I get gibberish back. I've tried changing the accepts back and forth between rich and plain and it doesn't make any difference. I've tried piping the output through textutil to no avail.

My only work around for now is to have the shell command copy to the clipboard with pbcopy and then use an Automator to grab the contents of the clipboard. I'd rather find a way to do this without having to wipe the clipboard, any suggestions for getting Automator to treat my shell commands output as rich text?

Is there anyway to make this work with AppleScript?

2 Answers 2


I usually use scripts like this instead of Automator services:

    set old to the clipboard as record
end try
tell application "System Events" to keystroke "c" using command down
do shell script "export LC_CTYPE=UTF-8; pbpaste | /usr/local/bin/pygmentize -g -f rtf | pbcopy"
tell application "System Events" to keystroke "v" using command down
delay 0.05
    set the clipboard to old
end try
  • If the clipboard is empty, trying to get it results in an error.
  • pbpaste and pbcopy use ASCII if the locale variables are unset. I couldn't get pygmentize -f rtf to work with non-ASCII characters though.
  • Without the delay set the clipboard to old would sometimes be run before the text would get pasted.

Possible Race Condition

I'm learning a lot from @Lauri Ranta's answer, but I think that the answer can still be improved.

I believe that her script has what's called a "race-condition". A race-condition can be a problem because it is a "race" to see which process will finish first. There is the pbcopy process which could take different amounts of time, depending upon how much text is being copied, and then there's the delay process in AppleScript which pauses for the same amount of time, but it might not be enough time. Maybe a race-condition is why the delay was needed to prevent an error from occurring, I'm not sure, but it could be a problem.

For race conditions, you don't want to pause too long and slow everything down and you don't want to pause to little and cause a possible data loss such as the old clipboard being restored when pbcopy is still copying.

I believe that it would be good to call the Unix command called "wait" as part of the shell script to wait for the pbcopy to finish and then do away with the call to "delay" in the AppleScript portion. That just feels better to me.

  • The problem is that the keystroke command just simulates pressing a key combination: it doesn't wait for the actions triggered by the key combination to finish. When I have tried removing the delay, set the clipboard to old was run before the text actually got pasted.
    – Lri
    Commented Jun 23, 2013 at 1:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .