Update: Hammerspoon Snipping Tool

Part of my knowledge system is saving critical highlights from blogs and documentation and storing it for use in newsletters, documentation, texts, or my zettelkasten.

I was using Brave's "run Javascript from Apple Events" feature for the last version… but I decided to move to some UI scripting so that it works with every browser in OS X. Here's the code:

The desired format that I've programmed into Drafts's built-in share feature looks like this:


> Highlighted content inside of quotes


The hardest part of this was ensuring that > characters for a quote were in front of every line in the snippet... I found a concise iterator on stack overflow (because I'm still horrible at lua!)

function magiclines(s)
  if s:sub(-1)~="\n" then s=s.."\n" end
  return s:gmatch("(.-)\n")

I wrap the whole thing in a hs.hotkey.modal called Hyper, then I go ahead and grab the focused window, and its title.

hyper:bind({}, 's', nil, function()
  local win = hs.window.focusedWindow()
  local title = win:title()

Now for some crufty UI Scripting! I grab the highlight by sending ⌘+C to copy the selection to the clipboard. I go ahead and use magiclines to put > in front each line.

  hs.eventtap.keyStroke('command', 'c')
  local highlight = hs.pasteboard.readString()
  local quote = ""
  for line in magiclines(highlight) do
    quote = quote .. "> " .. line .. "\n"

More UI scripting lets me hit ⌘+L for the "location bar," letting me grab the URL for the current page and save it to variable.

  hs.eventtap.keyStroke('command', 'l')
  hs.eventtap.keyStroke('command', 'c')
  local url = hs.pasteboard.readString()

Now that I have all the pieces, I can use string.format to build the template. (It's a little hard to read because I don't want to introduce leading whitespace.)

  local template = string.format([[%s

[%s](%s)]], title, quote, title, url)

Now I just use URL schemes to send it to Drafts.app, and I'm done!

  hs.urlevent.openURL("drafts://x-callback-url/create?tag=links&text=" .. hs.http.encodeForQuery(template))
  hs.notify.show("Snipped!", "The snippet has been sent to Drafts", "")

With this code, I can highlight and snip any text in Firefox or Webkit browsers. I use these markdown-formatted quotes in either my newsletter automations or saved to my zettelkasten. You can see the whole thing in the total config on github.

  • 2022-06-08 11:31:29 -0500
    Rename articles

  • 2021-01-27 16:35:08 -0600
    it's -> its

  • 2021-01-27 16:21:55 -0600
    New post: Updated snipping