October 11, 2018
Copying source code from a plain text editor and pasting it into Keynote, Pages, an Office document or some other rich text application often yields disappointing results. Where is the monospaced programming font? Where is the syntax highlighting? Why is the indentation all messed up?
This little Mac automation allows you to paste a copied code block as fully formatted, syntax highlighted code and works with many different languages. It leans on the Pygments project to do the heavy lifting. Many thanks to Brett Terpstra for pointing me in the right direction when I was getting started with this.
The required version of Python is already installed on macOS. You just need to:
pip install Pygments
Starting from version 3, it is possible to create this automation using BetterTouchTool.
I’m using ⌃⌥⌘ V as the shortcut trigger but you can use whatever you like. The shortcut has three actions:
Step 2 (Trigger predefined action) is the important one.
The terminal command is:
pbpaste | awk '{ gsub(/\t/, " "); print }' | /usr/local/bin/pygmentize -f rtf | pbcopy
To try this out, select a block of unformatted code you’ve pasted into your rich text application, trigger the automation with ⌃⌥⌘ V, and watch as the code is first copied to the clipboard, run through the pygmentize
command which converts it to nicely formatted RTF text, and then pasted back over your original selection.
Or, just copy some code from your editor, switch into your rich text application and (without selecting anything) invoke the trigger keystroke. The formatted code will be pasted in.
I use Quicksilver and this is how I usually Paste as Code. I’ve added a custom trigger that uses the Run Text as an AppleScript action to run this code:
delay 0.5 tell application "System Events" to keystroke "c" using command down do shell script "/bin/bash -c \"pbpaste | awk '{ gsub(/ /, \\\" \\\"); print }' | /usr/local/bin/pygmentize -f rtf | pbcopy\"" delay 0.5 tell application "System Events" to keystroke "v" using command down
This works just like the BetterTouchTool automation.
If you already have the plain text on your clipboard you can use TextExpander to paste the formatted version at the insertion point. Here is the snippet. Be sure to set the Content type of the snippet to AppleScript.
do shell script "/bin/bash -c \"pbpaste | awk '{ gsub(/\t/, \\\" \\\"); print }' | /usr/local/bin/pygmentize -f rtf | pbcopy\"" delay 0.5 tell application "System Events" to keystroke "v" using command down
My TextExpander abbreviation for this is ;code
You can put a whole (plain text) source file on your clipboard in a hurry, and you’re ready to Paste as Code.
cat my_source_file.js | pbcopy
If the snippet you copy is too short, semantically ambiguous, or in an unsupported language, pygmentize
will not be able to apply correct syntax highlighting. In that case you’ll get monospaced text without the colors. If you often find yourself pasting short snippets of, say, bash scripts that pygmetize has trouble detecting you can create a bash-specific shortcut using this command-line:
pbpaste | awk '{ gsub(/\t/, " "); print }' | /usr/local/bin/pygmentize -l bash -f rtf | pbcopy
In this case the -l bash
forces pygmentize to color the snippet as a bash shell script and skip auto-detection. Here is the list of supported lexers.
If you find Paste as Code useful and have any ideas for how to make it better please let me know.