23

At times, I need to use the same link at multiple places in a long document.

For those cases it would be useful to have link IDs like in markdown. From markdown syntax ref,

You can optionally use a space to separate the sets of brackets:

This is [an example] [id] reference-style link. 

Then, anywhere in the document, you define your link label like this, on a line by itself:

[id]: http://example.com/ "Optional Title Here"

I believed that the Link Abbreviation in org-mode would work the same way (without tags) but it doesn't.

The purpose of link IDs is to have a central place for editing the links. A good location would be at the end of the document. Full links are defined in the ID but only the ID is used elsewhere in the document where we need to place the hyperlinks. When exporting, the IDs are replaced with the actual hyperlinks.

Benefits of this approach are,

  • When the links change, we need to just modify the ID definitions. On exporting, the hyperlinks in the document will be updated to that.
  • Faster hyperlink insertion when writing the document as one doesn't have to get and paste the full links every time. You type the IDs in the document and define them in a block at the end of the document.
3

1 Answer 1

21

This page has a nice description on how to extend org-mode links. It doesn’t address your specific concern, but it explains the basic principle.
Let’s say we want your links to be defined like this, anywhere in the buffer,

#+LINK-ID: wiki http://www.emacswiki.org

and invoked like this

[[lid:wiki][You should check out the wiki]]

First, you need to tell org how to follow and how to export your link.

(org-add-link-type "lid" 'endless/open-id-link 'endless/export-id-link)

(defun endless/open-id-link (path)
  "Follow an ID link to PATH."
  (browse-url (endless/find-id-link path)))

(defun endless/export-id-link (path desc format)
  "Create the export version of an ID link specified by PATH and DESC.
FORMATs understood are 'latex and 'html."
  (setq path (endless/find-id-link path))
  (cond
   ((eq format 'html) (format "<a href=\"%s\">%s</a>" path desc))
   ((eq format 'latex) (format "\\href{%s}{%s}" path desc))
   (t desc)))

Then, you just need to decide how you want to handle this link.

(defun endless/find-id-link (id &optional noerror)
  "Find \"#+LINK-ID: ID\" in current buffer and return the link.
Unless NOERROR is non-nil, throw an error if link not found."
  (save-excursion
    (goto-char (point-min))
    (let ((case-fold-search t))
      (when (search-forward-regexp 
             (format "^#\\+LINK-ID: \\b%s\\b +\\(.*\\) *$" id)
             nil noerror)
        (match-string-no-properties 1)))))
2
  • I'm not sure what the title you mentioned in the would be used for. If you let me know I can add it in.
    – Malabarba
    Oct 2, 2014 at 8:58
  • 1
    I notice that for the existing export function examples: docview, bbdb, along the org-add-link-type function call, they also do (add-hook 'org-store-link-functions 'org-LINKTYPE-store-link). Oct 2, 2014 at 12:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.