I was reading, and watching, Mike Zamansky's blog post series about org-capture and how he manages his bookmarks. His blog and video series are a big recommendation from me, he is teaching me tons every time I watch his videos. His inspirational videos were what made me dig down on how I could do what he's doing but… my way…
I stumbled across this blog post that describes the process of using
org-cliplink to insert the title of the post into an org-mode link. Basically, what I wanted to do is provide a link and get an org-mode link. Sounds simple enough. Let's dig in.
Org Capture Templates
I will assume that you went through Mike's part 1 and part 2 posts to understand what
org-capture-templates are and how they work. I essentially learned it from him and I do not think I can do a better job than a teacher.
Now that we understand where we need to start from, let's explain the situation. We need to find a way to call
org-capture and provide it with a template. This template will need to take a url and add an org-mode url in our bookmarks. It will look something like the following.
(setq org-capture-templates '(("b" "Bookmark (Clipboard)" entry (file+headline "~/path/to/bookmarks.org" "Bookmarks") "** %(some-function-here-to-call)\n:PROPERTIES:\n:TIMESTAMP: %t\n:END:%?\n" :empty-lines 1 :prepend t)))
I formatted it a bit so it would have some properties. I simply used the
%t to put the timestamp of when I took the bookmark. I used the
%? to drop me at the end for editing. Then
some-function-here-to-call a function to call to generate our bookmark section with a title.
The blog post I eluded to earlier solved it by using org-cliplink. While
org-cliplink is great for getting titles and manipulating them, I don't really need that functionality. I can do it manually. Sometimes, though, I would like to copy a page… Maybe if there is a project that could attempt to do someth… Got it… org-web-tools.
Configuring org-capture with org-web-tools
You would assume that you would be able to just pop
(org-web-tools-insert-link-for-url) in the previous block and you're all done. But uhhh….
Wrong number of arguments: (1 . 1), 0
No dice. What would seem to be the problem ?
We look at the definition and we find this.
(defun org-web-tools-insert-link-for-url (url) "Insert Org link to URL using title of HTML page at URL. If URL is not given, look for first URL in `kill-ring'." (interactive (list (org-web-tools--get-first-url))) (insert (org-web-tools--org-link-for-url url)))
I don't know why, exactly, it doesn't work by calling it straight away because I do not know emacs-lisp at all. If you do, let me know. I suspect it has something to do with
(interactive) and the list provided to it as arguments.
Anyway, I can see it is using
org-web-tools--org-link-for-url, which the documentation suggests does the same thing as
org-web-tools-insert-link-for-url, but is not exposed with
(interactive). Okay, we have bits and pieces of the puzzle. Let's put it together.
First, we create the function.
(defun org-web-tools-insert-link-for-clipboard-url () "Extend =org-web-tools-inster-link-for-url= to take URL from clipboard or kill-ring" (interactive) (org-web-tools--org-link-for-url (org-web-tools--get-first-url)))
Then, we set our
org-capture-templates variable to the list of our only item.
(setq org-capture-templates '(("b" "Bookmark (Clipboard)" entry (file+headline "~/path/to/bookmarks.org" "Bookmarks") "** %(org-web-tools-insert-link-for-clipboard-url)\n:PROPERTIES:\n:TIMESTAMP: %t\n:END:%?\n" :empty-lines 1 :prepend t)))
Now if we copy a link into the clipboard and then call
org-capture with the option
b, we get prompted to edit the following before adding it to our bookmarks.
** [[https://cestlaz.github.io/stories/emacs/][Using Emacs Series - C'est la Z]] :PROPERTIES: :TIMESTAMP: <2020-09-17 do> :END:
Works like a charm.
What if we need to modify the url in some way before providing it. I have that use case. All I needed to do is create a function that takes input from the user and provide it to
org-web-tools--org-link-for-url. How hard can that be ?! uhoh! I said the curse phrase didn't I ?
(defun org-web-tools-insert-link-for-given-url () "Extend =org-web-tools-inster-link-for-url= to take a user given URL" (interactive) (let ((url (read-string "Link: "))) (org-web-tools--org-link-for-url url)))
We can, then, hook the whole thing up to our
org-capture-templates and we get.
(setq org-capture-templates '(("b" "Bookmark (Clipboard)" entry (file+headline "~/path/to/bookmarks.org" "Bookmarks") "** %(org-web-tools-insert-link-for-clipboard-url)\n:PROPERTIES:\n:TIMESTAMP: %t\n:END:%?\n" :empty-lines 1 :prepend t) ("B" "Bookmark (Paste)" entry (file+headline "~/path/to/bookmarks.org" "Bookmarks") "** %(org-web-tools-insert-link-for-given-url)\n:PROPERTIES:\n:TIMESTAMP: %t\n:END:%?\n" :empty-lines 1 :prepend t)))
if we use the
B, this time, it will prompt us for input.
I thought this was going to be harder to pull off but, alas, it was simple, even for someone who doesn't know emacs-lisp, to figure out. I hope I'd get more familiar with emacs-lisp with time and be able to do more. Until next time, I recommend you hook
org-capture into your workflow. Make sure it fits your work style, otherwise you will not use it, and make your path a more productive one.