Random ramblings about Mac, Python, TeX, programming, and more   |     |        |     |  



Open Emacs from a link in an HTML file on Mac OS X

December 14, 2015  |  web, os-x, programming

Since I do most of my writing in LaTeX, I have all my references (publications I cite when I write papers) in a series of bib-files (for BibTeX). To easier browse and search these references I have created a small Python script that generates a HTML document with all these references. Each reference also includes a link to the bib-file this reference was found in. In the link, I include the key of the reference as a fragment identifier. To specify that I want this link to be open in Emacs, I identify the URL protocol as emacs. The following is an example of such a URL:

emacs:///path/to/file/refs.bib#smith1999a

This link should open Emacs at the start of the reference with the key smith1999a in the file /path/to/file/mybib.bib. The next step is to create an application doing the necessary work and register the URL protocol emacs to activate this application. The easiest approach on a Mac is the write a short AppleScript Application. I have followed the instructions found in these two articles: Launch Scripts from Webpage Links and OS X URL handler to open links to local files. First, I created the following AppleScript application:

on open location emacsURL

  -- Find file path and BibTeX key positions in URL
  set p to the offset of "///" in emacsURL
  set i to the offset of "#" in emacsURL
	
  -- File path
  set fn to text (p + 2) thru (i - 1) of emacsURL
	
  -- BibTeX key
  set bk to text (i + 1) thru -1 of emacsURL
	
  -- Line number of BibTeX key, e.g. 
  -- grep -n {smith199a, refs.bib | awk -F:'{ print $1 }'
  set ln to (do shell script "grep -n {" & bk
    & ", " & fn & " | awk -F: '{ print $1 }'")
	
  -- Open file in Emacs on correct line using 
  -- "+line:ln "
  if application "Emacs" is not running then
    tell application "Emacs" to activate
    delay 2 -- To ensure Emacs is ready
    do shell script "/usr/local/bin/emacsclient -n +"
      & ln & " " & fn
  else
    do shell script "/usr/local/bin/emacsclient -c -n +"
      & ln & " " & fn
  end if
	
end open location

From the Script Editor, I saved the above AppleScript code as an Application. Then I had to edit the property list file of the application. In Finder, click on the application with the Control key held down and choose Show Package Contents. Go to the Contents folder and edit the Info.plist file (using Emacs or other suitable programs like Vim, Coda or Xcode). I changed the CFBundleIdentifier and added the following lines to register this application to handle the emacs URLs:

<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleURLName</key>
    <string>Emacs Helper</string>
    <key>CFBundleURLSchemes</key>
    <array>
      <string>emacs</string>
    </array>
  </dict>
</array>

The application has to execute once the register (activate) the URL handling.

Last updated: June 22, 2024