In Situ Syntax Highlighting in macOS Applications Like Keynote

surprisetalk1 pts0 comments

In situ Syntax Highlighting in macOS Applications Like Keynote – Eric’s Archived Thoughts

Earlier this month, I returned to CSS Day for the first time since<br>2018 to deliver my first in-person talk since 2022.  “Forging Our Own<br>Paths” should be available at some point; in the meantime, for the six or<br>seven people in my audience who might need to do something similar, I’d<br>like to share a small macOS workflow I developed to make syntax-highlighting<br>code blocks in situ in Keynote a lot simpler.  The<br>end result is to have an entry (or entries) in the Services submenu of<br>the contextual (right-click) menu for highlighted text.  All this is adapted from an old blog<br>post I found copied in a few places, and which needed some updates to<br>make things work in 2026.

This is what it looks like for me.  It could look much the same for you!

First, install highlight.  I used brew install highlight, and the rest of this piece assumes you’ve done it that way.  If you install it another way, such that it ends up in a different location than Homebrew would give it, you’ll need to modify a variable value later on, which I’ll point out when we get there.

Next, you need to install the following (also available as a gist) as a shell script called keynote-highlight:

#!  /bin/bash<br>set -e<br>while getopts 'h:o:i:s:t:' OPTION; do<br>case "$OPTION" in<br>h)<br>highlighthome="$OPTARG"<br>;;<br>o)<br>outputrtf="$OPTARG"<br>;;<br>i)<br>inputrtf="$OPTARG"<br>;;<br>s)<br>syntax="$OPTARG"<br>;;<br>t)<br>theme="$OPTARG"<br>;;<br>?)<br>echo "script usage incorrect?" >&2<br>exit 1<br>;;<br>esac<br>done<br>shift "$(($OPTIND -1))"

#=============================

inputrtf="$(pbpaste -pboard -prefer public.rtf)"

regex="fcharset0 ([a-zA-Z0-9 ]+);"<br>if [[ "$inputrtf" =~ $regex ]]<br>then<br>fontface=${BASH_REMATCH[1]}<br>else<br>fontface="Courier"<br>fi

regex="fs([0-9]{1,5})"<br>if [[ "$inputrtf" =~ $regex ]]<br>then<br>fontsize=${BASH_REMATCH[1]}<br>fontsize2=$((fontsize/2))<br>else<br>fontsize2="12"<br>fi

if [ -z "$theme" ]; then<br>theme="candy"<br>fi

if [ -z "$highlighthome" ]; then<br>highlighthome="/opt/homebrew/bin/highlight"<br>fi

highlighted=$("$highlighthome" --out-format="rtf" --syntax="$syntax" --style="$theme" --font="$fontface" --font-size="$fontsize2" --no-trailing-nl --stdout)<br>echo "$highlighted"

Put the script wherever you store your shell scripts, and make sure<br>it’s both executable and can be invoked from the command line.  I<br>believe, without any real basis for doing so, that if you<br>already have syntax-highlight<br>installed, which is (among other things) a wrapper around<br>highlight, you could use it by modifying the<br>highlighthome variable assignment to point to it rather<br>than highlight, as well as modifying a variable in an<br>upcoming bit of code.  But, as I say, I’m just guessing about that.

Once the shell script is installed and ready to execute, launch<br>Automator and create a new Quick Action.  Call it “Syntax Highlight CSS”<br>or something similar.  If you want to set up highlighting for other kinds<br>of code, like HTML or any of the nearly 250<br>languages (!!!) highlight supports, each language has<br>to be given its own Quick Action.  Thus, if you want them all next to<br>each other in the Services menu, pick an appropriate naming scheme.  For<br>this one, we’re doing CSS, but later you’ll see how you can quickly set<br>up this same thing for other formats.

At the top of the right-hand panel in the new Quick Action workflow,<br>check the “Workflow receives current” dropdown to make sure it’s set to<br>either “Automatic (rich text)” or “rich text”, the latter if you plan to<br>never, ever use this in any non-RTF setting.  I go with the Automatic<br>option.  If you want to restrict the action to a particular application,<br>like Keynote, change the dropdown that says “any application” to pick a<br>specific application.  I leave mine to be available in any application,<br>just in case I’m ever syntax highlighting code in TextEdit or something.  I also set the color to “Red”, because clearly that makes it go<br>faster.

With all those things set, the first thing to add to the workflow is<br>a “Copy to Clipboard” action.  That’s it for this step, just add that and<br>leave it alone.

Now, add a “Run AppleScript” action.  Paste the following (also available<br>as a gist) into the textbox that contains the boilerplate skeleton<br>(replace the skeleton):

on run {input, parameters}<br>set highlightHome to "/opt/homebrew/bin/highlight"<br>set syntaxType to "css"<br>set themeName to "navy"<br>set command to "PATH_TO_SCRIPT/keynote-highlight -h " & highlightHome & " -s " & syntaxType & " -t " & themeName<br>do shell script "/bin/bash -c 'pbpaste | " & command & " | pbcopy'"<br>delay 0.1<br>tell application "System Events" to keystroke "v" using command down<br>end run

Change the PATH_TO_SCRIPT in there to wherever you put<br>the shell script, save the workflow, and it should be ready to go!

What the Automator workflow should look like.

…unless your copy of highlight lives somewhere else or<br>you’re trying out using syntax-highlight in its place, or<br>you have a different theme you’d like to use.  In either case, change the<br>value...

highlight syntax like highlighthome keynote workflow

Related Articles