In Email and News and Information Pipelines I sketched out a data-flow of information from the internet in to my brain and my exobrain, the Zettelkasten. I am zooming in here on a specific edge of that graph on this page, a direct conduit between Firefox Desktop and my Archive. When I am actively reading a web page, when I need to jot a quick piece of information down, or remember a GitHub project, or capture a YouTube video to add to my queue later in the night, I want to get the information in to Emacs as quickly as possible. For anything that needs longer work or more thinking or will be done at a later date, I put it in to my Read It Later bag.
This page is a CCE module based on two sources[fn:1:https://cestlaz.github.io/post/using-emacs-70-org-protocol/][fn:2:https://org-roam.readthedocs.io/en/develop/roam_protocol/] from the WWW (Probably one of Sacha's Emacs weeklies) and the org-roam documentation.
org-roam provides native functionality for this in the org-roam-protocol library. I create a second capture template that just uses plain old org-protocol on its own to quickly capture YouTube videos or other things I wish to watch.
This desktop file creates an org-protocol:// URL handler and forwards the URL to emacsclient. the roam-ref org-protocol handler will create a document in the wiki, with the title and ROAM_REF property keyword filled in. The javascript at the end is saved as bookmark in my Firefox toolbar and can be bound to keyboard with a thing like ShortcutKey2URL (WebExtensions) or the bookmarklets can be placed in the Bookmarks toolbar or to use the Awesomebar as a CLI.
{ pkgs, ... }:
{
home.packages = [
(pkgs.makeDesktopItem {
name = "org-protocol";
desktopName = "Emacs org-protocol handler";
exec = "emacsclient -c %u";
terminal = false;
categories = ["System"];
mimeTypes = ["x-scheme-handler/org-protocol"];
})
];
programs.firefox.profiles.default.settings = {
"network.protocol-handler.expose.org-protocol" = true;
"network.protocol-handler.warn-external.org-protocol" = false;
"security.external_protocol_requires_permission" = false; # sickos.jpg
};
}DONE figure out why Firefox on Nix always asks if it's okay to open external on each domain despite warn-external set
Capture Templates
org-roam reference capture
Wiring it all together, the org-roam reference capture:
(with-eval-after-load 'org-roam
(require 'org-roam-protocol)
(add-to-list 'org-roam-capture-ref-templates
`("r" "reference" entry
,(s-join
"\n"
'("* %? :Archive:"
"#+begin_quote"
"${body}"
"#+END_QUOTE"
))
:unnarrowed t
:target
(file
"journals/%<%Y-%m-%d>.org"
))))javascript:location.href = 'org-protocol://roam-ref?template=r&ref='+ encodeURIComponent(location.href) + '&title=' + encodeURIComponent(document.title) + '&body=' + encodeURIComponent(window.getSelection()); void(0);Thread capture
And one for quickly capturing Twitter Threads and posts in to my Archive
(with-eval-after-load 'org-roam
(require 'org-roam-protocol)
(add-to-list 'org-roam-capture-ref-templates
`("t" "thread" plain
,(s-join
"\n"
'("[[id:d17a9ccf-0bfe-426e-85b3-d15771d3ee03][Archive]] [[id:threads][Thread]] about $?"
"#+BEGIN_QUOTE"
"${body}"
"#+END_QUOTE"))
:unnarrowed t
:if-new
(file+head
"%<%Y%m%d%H%M%S>-${slug}.org"
,(s-join
"\n"
'(":PROPERTIES:"
":roam_refs: ${ref}"
":END:"
"#+title: ${title}"
"#+filetags: :Archive:Thread:"))))))This one extracts the quoted tweet out of the title:
javascript:location.href = 'org-protocol://roam-ref?template=t&ref='+ encodeURIComponent(location.href) + '&title=' + encodeURIComponent(document.title.match(/"(.*)"/)[0].substring(0,64)) + '&body=' + encodeURIComponent(window.getSelection().toString() || document.title.match(/"(.*)"/)); void(0);org-roam capture to clock
(with-eval-after-load 'org-capture
(add-to-list 'org-capture-templates
`("R" "Capture to Clock" entry
(clock)
,(s-join "\n"
'("* %a %? :Archive:"
":PROPERTIES:"
":ROAM_REFS: %l"
":END:"
"%U"))
:unnarrowed
:jump-to-captured)))javascript:location.href='org-protocol://capture?template=R&url='+encodeURIComponent(location.href)+'&title='+ encodeURIComponent(document.title)+'&body='+ encodeURIComponent(window.getSelection()); void(0);Videos queue capture
And one for capturing videos in to a watch queue.
(with-eval-after-load 'org-roam
(require 'org-roam-protocol)
(add-to-list 'org-roam-capture-ref-templates
`("O" "org-protocol video" plain
,(s-join
"\n"
'("* NEXT [[${ref}][${title}]]"
":PROPERTIES:"
":roam_refs: ${ref}"
":END:"
""
"${body}"))
:if-new
(file+head
"~/org/Video.org"
,(s-join
"\n"
'("#+title: Video Queue"
"#+ARCHIVE: video_archive.org::"
"#+filetags: Archive"))))))javascript:location.href = 'org-protocol://roam-ref?template=O&ref='+ encodeURIComponent(location.href) + '&title=' + encodeURIComponent(document.title) + '&body=' + encodeURIComponent(window.getSelection()); void(0);NEXT Interesting Github Projects collects projects I'm likely to want to use or peruse some day
need to just make this use regular org-protocol capture templates..... or figure out how to use org-roam-capture-ref-templates better...
(with-eval-after-load 'org-roam
(require 'org-roam-protocol)
(add-to-list 'org-roam-capture-ref-templates
`("P" "org-protocol project bookmark" entry
,(s-join
"\n"
'("* [[${ref}][${title}]]"
":PROPERTIES:"
":roam_refs: ${ref}"
":END:"
""
"${body} %?"))
:if-new
(file+head
"~/org/interesting_github_projects.org"
,(s-join
"\n"
'("#+title: Interesting GitHub Projects"
"#+filetags: Archive Topic"))))))javascript:location.href='org-protocol://capture?template=P&url='+encodeURIComponent(location.href)+'&title='+ encodeURIComponent(document.title)+'&body='+ encodeURIComponent(window.getSelection()); void(0);People capture
And one for quickly capturing Facebook friends' list in to People pages
(with-eval-after-load 'org-roam
(require 'org-roam-protocol)
(add-to-list 'org-roam-capture-ref-templates
`("p" "person" plain
,(s-join
"\n"
'("[[file:People.org][People]]"
"#+BIRTHDAY: %^{Birthday}t%?"
"#+BEGIN_QUOTE"
"${body}"
"#+END_QUOTE"))
:unnarrowed t
:if-new
(file+head
"%<%Y%m%d%H%M%S>-${slug}.org"
,(s-join
"\n"
'(":PROPERTIES:"
":roam_refs: ${ref}"
":END:"
"#+title: ${title}"
"#+filetags: Person"))))))javascript:location.href = 'org-protocol://roam-ref?template=p&ref='+ encodeURIComponent(location.href) + '&title=' + encodeURIComponent(document.title) + '&body=' + encodeURIComponent(window.getSelection()); void(0);Provide the ELisp feature at the end
This is a stub...
(provide 'cce/org-protocol)