6

I use org-mode mostly (by far) directly within Emacs (as opposed to as a mark-up to be ultimately viewed through, say, a web browser or a PDF viewer). Therefore, I'm interested in ways to "hide"1 as much of the org-mode mark-up as possible.

In particular,

is there a way to hide org-mode target specs, of the form <<target>>?

I'm primarily interested in solutions that can be applied selectively (e.g. only target specs that match a particular regular expression get hidden), but a solution that hides all targets of this form would be OK too.

More generally, I'd be interested in ways to hide arbitrary org-mode mark-up.


1 By "hide" I mean whatever the process is that accounts for the "invisibility" (in an Emacs org-mode buffer) of the leading [[#target][ and trailing ]] (for example) in the hyperlink spec [[#target][here]]. This form of hiding should be contrasted with what happens with the leading stars of a heading when org-hide-leading-stars is non-nil. In the latter case, the stars are still being displayed, albeit in a color that approximates the window's background color. They still take up space on the screen. This is not what I'm referring to by "hiding" in this post.

2 Answers 2

6

Paste the following into your init files. This gives you a new customization option org-hidden-links-additional-re. You can switch this option off or parameterize it with a regular expression. The strings matching this regular expression in an org-buffer are hidden when "descriptive links" are activated (menu item Org->Hyperlinks->Descriptive Links). The default is <<[<]?[[:alnum:]]>>[>]? which hides link targets. This variable is buffer local. You can set it in the file-local variables.

(defcustom org-hidden-links-additional-re "<<[<]?[[:alnum:]]+>>[>]?"
  "Regular expression that matches strings where the invisible-property is set to org-link."
  :type '(choice (const :tag "Off" nil) regexp)
  :group 'org-link)
(make-variable-buffer-local 'org-hidden-links-additional-re)

(defun org-activate-hidden-links-additional (limit)
  "Put invisible-property org-link on strings matching `org-hide-links-additional-re'."
  (if org-hidden-links-additional-re
      (re-search-forward org-hidden-links-additional-re limit t)
    (goto-char limit)
    nil))

(add-hook 'org-font-lock-set-keywords-hook (lambda ()
                         (add-to-list 'org-font-lock-extra-keywords
                              '(org-activate-hidden-links-additional
                                (0 '(face org-target invisible org-link))))))

The following version addresses the wishes from Kartik Shenoy's first comment, i.e.: Just hide two of the angles at each end of the link text:

(defcustom org-hidden-links-additional-re "\\(<<\\)[[:alnum:]]+\\(>>\\)"
  "Regular expression that matches strings where the invisible-property of the sub-matches 1 and 2 is set to org-link."
  :type '(choice (const :tag "Off" nil) regexp)
  :group 'org-link)
(make-variable-buffer-local 'org-hidden-links-additional-re)

(defun org-activate-hidden-links-additional (limit)
  "Put invisible-property org-link on strings matching `org-hide-links-additional-re'."
  (if org-hidden-links-additional-re
      (re-search-forward org-hidden-links-additional-re limit t)
    (goto-char limit)
    nil))

(defun org-hidden-links-hook-function ()
  "Add rule for `org-activate-hidden-links-additional' to `org-font-lock-extra-keywords'.
You can include this function in `org-font-lock-set-keywords-hook'."
  (add-to-list 'org-font-lock-extra-keywords
                              '(org-activate-hidden-links-additional
                                (1 '(face org-target invisible org-link))
                (2 '(face org-target invisible org-link)))))

(add-hook 'org-font-lock-set-keywords-hook #'org-hidden-links-hook-function)
3
  • Hi, is it possible to modify this to hide just the angle braces and show the text between them? If I use this, I have to type the same thing twice eg. <<fancy term here>>fancy term here since everything including the angle braces get hidden. Additionally, is it possible to hide just the outer two angle braces but show the third one if it exists? I'd like to distinguish regular targets from radio targets.
    – kshenoy
    Commented Mar 19, 2017 at 21:04
  • @KartikShenoy Try the second elisp section in my answer instead of the first one.
    – Tobias
    Commented Mar 21, 2017 at 11:41
  • @Tobias Thanks for your very useful code snippet. I have turned it into a library on github (I wanted to be able to toggle this hiding on and off), which references you, Tobias, and this answer. P.S If you have an preferences over citations, attributions or licenses please tell me.
    – Att Righ
    Commented Jun 28, 2018 at 12:13
0

A very small improvement on Tobias's answer...

The :alnum: in the regexp org-hidden-links-additional-re regexp doesn't work for anchors containing spaces or punctuation, so I did:

org-hidden-links-additional-re "\\(<<\\)[[:print:]]+?\\(>>\\)"

Your Answer

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

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