Two Ways To Capture Links Into Org Files
The Good Way
I discovered this method somehow on the internet. I read it somewhere, but I can't find the source anymore, because, dah! I didn't have good integration between my web content and my org-mode notes yet before I found that solution, did I? The gist of it is to wrap emacsclient into a native mac app, so you can leverage URL scheme for apps, an excellent built-in feature of macOS.
But you don't want to create a real mac app, right? Good news, there's an app called Platypus, which allows you to create native Mac app from command line scripts. Being a native app, you can register your own URL scheme protocol (org-protocol
of cause) that you can invoke system-wide. But it stopped working after I upgraded to Big Sur, as it would, of course. Then I found this on GitHub and later the same information on org-roam documentation, tried it quickly, still no luck for me. I am pretty sure it's my own fault during the process (7 steps or so?), but I am too old to patiently following other people's steps, so instead, I create my own way.
A Better Way
Cut to the chase, instead of hacking the system (Yes, I consider creating a fake app to trick the system into recognizing a URL scheme a hack). I decided to stick to the tool that's built for automation: Automator. Here's how.
Create a Quick Action
Make it look like this.
You can follow the screenshot up there. I will break it down now, so you know exactly what to do, and customise accordingly.
Quick Action Config
The workflow receives Automatic (Nothing)
, because you can look at the dropdown list, there isn't an ideal option based on our needs (you will know how I mean it in a second). Also, choose your default browser app there, for me it's Safari.
Run JavaScript
AppleScript
if you prefer it, but I never familiar myself enough to use it fluently. Here is the code.
function run(input, parameters) {
const safari = Application('Safari');
const tab = safari.windows[0].currentTab; const url = encodeURIComponent(tab.url());
const name = encodeURIComponent(tab.name());
return [url, name];
}
To summarise the code: find the front-most tab from Safari (or another browser of your choosing), return the url
and the name
(i.e. the <title/>
). We need both the URL and the name information from the tab, that's why the options in the "workflow receives" can't help me.
Run Shell Script
/usr/local/bin/emacsclient --no-wait "org-protocol://roam-ref?template=r&ref=$1&title=$2" -a 'open -a /Applications/Emacs.app'
This is my way of capturing the link, i.e. using org-roam and roam-ref sub-protocol. Of course, you can change it to whatever way you'd like it to be. $1
would be the url
, and $2
is the name
, from the previous step.
Launch Emacs
So that Emacs is called to the front and focused.
Test it out
Now is a good time to test and debug it.
Save it
Then you can find it in the services menu for Safari.
Assign a shortcut to it in system preferences.
Why is it Better?
- The
Better Way
is an all-in-one solution. You keep all the implementation details within this Quick Action. It's totally self-contained. For comparison, with theGood Way
, you need to maintain the following things: - A native mac App, which is an Application bundle, which is hard to version control. Also subject to break after macOS update.
- Complicated URL for invoking the app, it's not fun scattering something like this everywhere.
javascript:location.href%20='org-protocol://roam-ref?template=r&ref='%20+%20encodeURIComponent(location.href)%20+%20'&title='%20+%20encodeURIComponent(document.title)'
- Being an all-in-one solution, with the
Better Way
, you can pack it up and share it, version control it, make it downloadable.
- With the
Better Way
, you can easily assign keyboard shortcuts to Quick Actions; In contrast, browser bookmark is a mouse-clicking action.
- With the
Good Way
, You are kind of limited to browsers since it's easy to create a special bookmark that invokes the org-protocol URL scheme. If you want to capture other things, you need a totally different solution, like Alfred actions or, guess what, Automator.
- With the
Good Way
, After the org-protocol is invoked, Emacs is not brought to the front, at least for me. Maybe there are ways to improve that, but I just don't bother. - With the
Better Way
, You don't need to create a fake app, it feels cleaner, doesn't it? Apps are, well Apps, not scripts. Maybe I have OCD.
Talk to me if you have any questions or different opinions, I am open to any suggestions. Let's make each other's life easier; even though that we are strangers. That's how awesome us nerds are.