Syntax highlighting for code snippets in Keynote with Pygments
2020-07-23

The general idea is to create an Automator workflow which copies the selected text into the clipboard, then runs it through Pygments, puts it back into the clipboard and pastes over the original selection.

Pygments provides a CLI interface called pygmentize which can output highlighted code in RTF format. This is then parsed by Keynote on paste, resulting in highlighted text.

The steps are:

  • Install pygments with brew install pygments
  • In Automator, create a Quick Action
  • In this Quick Action:
    • Add the action “Copy to clipboard”
    • Below, add the action “Run AppleScript”
    • In the body of the script, put the following, adjusting for the required language and visual styling:
-- fontsize parameter needs to be double the required font size in Keynote
set command to "/usr/local/bin/pygmentize -l ruby -f rtf -O style=monokai,fontface=\"Roboto Mono\",fontsize=52"

do shell script "/bin/bash -c 'pbpaste | " & command & " | pbcopy'"

tell application "System Events" to tell (process 1 where frontmost is true)
    click menu item "Paste" of menu 1 of menu bar item "Edit" of menu bar 1
end tell
  • Save the Quick Action (named “Syntax highlight”, for example)
  • Allow it to show up in the Services list (and possibly add a shortcut) by enabling it in System Preferences ➞ Keyboard ➞ Shortcuts

  • Add a style called custom with your own colours:

    • create a file called custom.py in the pygments.styles subpackage directory (in my case /usr/local/Cellar/pygments/2.6.1/libexec/lib/python3.8/site-packages/pygments/styles)
    • define the colors, for example as below (note the class name has to match the file name, so in my case it’s CustomStyle):
from pygments.style import Style
from pygments.token import Keyword, Name, Comment, String, Error, \
     Number, Operator, Generic

class CustomStyle(Style):
    default_style = ""
    styles = {
        Comment:                'bg: italic #888',
        Keyword:                'bg: bold #005',
        Name:                   'bg: #f00',
        Name.Function:          'bg: #0f0',
        Name.Class:             'bg: bold #ff0000',
        String:                 'bg: #111'
    }

After these steps, you should be able to run the Quick Action with pygmentize picking up the custom colours.

To use the Quick Action, select a code snippet in Keynote, then either use the shortcut or go to App menu ➞ Services ➞ Syntax highlight.

Sources: