Pretty Org babel blocks
I show how to use
prettify-symbols-mode to display Org Babel blocks as
something like this:
where “☰” expands to the header arguments of the block as shown in the picture.
I have been using Org and Babel to create “interactive” slides. A slide is a narrowed subtree. To not confuse listeners I want to hide the details of the rather verbose source block syntax.
I tried to hack something together with
even getting the compositing right I was still missing the
“uncomposition” behavior of
prettify-symbols-unprettify-at-point is non-nil (I like
prettify-symbols-alist only supports strings, not
regexps as it uses
regexp-opt behind the scene.
Thus, I decided to just hack something together with
prettify-symbols-mode. rasmus/org-prettify-src–update goes through
the buffer and add all occurrences of header arguments to
prettify-symbols-alist and also removes old chun. This is probably
not very efficient… Next, rasmus/org-prettify-src takes care of
calling the update function whenever the cursor was in a
before and now is not. Finally, rasmus/org-prettify-symbols is a hook
that can be added to Org.
If you don’t want to use the burger icon you can change it by changing rasmus/ob-header-symbol.
This is clearly a hack! Some obvious flaws are:
prettify-symbols-modedoesn’t support regexp you can’t fully match the proper Org syntax. E.g. this is not valid syntax, but would still be prettified.
- It might be nice to reveal the burger whenever the cursor is on the same line as the burger. I tried to get this working, but I couldn’t get it working property.
- It would be nice to turn it into a proper minor-mode to easily toggle fortification of header arguments…
(with-eval-after-load 'org (defvar-local rasmus/org-at-src-begin -1 "Variable that holds whether last position was a ") (defvar rasmus/ob-header-symbol ?☰ "Symbol used for babel headers") (defun rasmus/org-prettify-src--update () (let ((case-fold-search t) (re "^[ \t]*#\\+begin_src[ \t]+[^ \f\t\n\r\v]+[ \t]*") found) (save-excursion (goto-char (point-min)) (while (re-search-forward re nil t) (goto-char (match-end 0)) (let ((args (org-trim (buffer-substring-no-properties (point) (line-end-position))))) (when (org-string-nw-p args) (let ((new-cell (cons args rasmus/ob-header-symbol))) (cl-pushnew new-cell prettify-symbols-alist :test #'equal) (cl-pushnew new-cell found :test #'equal))))) (setq prettify-symbols-alist (cl-set-difference prettify-symbols-alist (cl-set-difference (cl-remove-if-not (lambda (elm) (eq (cdr elm) rasmus/ob-header-symbol)) prettify-symbols-alist) found :test #'equal))) ;; Clean up old font-lock-keywords. (font-lock-remove-keywords nil prettify-symbols--keywords) (setq prettify-symbols--keywords (prettify-symbols--make-keywords)) (font-lock-add-keywords nil prettify-symbols--keywords) (while (re-search-forward re nil t) (font-lock-flush (line-beginning-position) (line-end-position)))))) (defun rasmus/org-prettify-src () "Hide src options via `prettify-symbols-mode'. `prettify-symbols-mode' is used because it has uncollpasing. It's may not be efficient." (let* ((case-fold-search t) (at-src-block (save-excursion (beginning-of-line) (looking-at "^[ \t]*#\\+begin_src[ \t]+[^ \f\t\n\r\v]+[ \t]*")))) ;; Test if we moved out of a block. (when (or (and rasmus/org-at-src-begin (not at-src-block)) ;; File was just opened. (eq rasmus/org-at-src-begin -1)) (rasmus/org-prettify-src--update)) ;; Remove composition if at line; doesn't work properly. ;; (when at-src-block ;; (with-silent-modifications ;; (remove-text-properties (match-end 0) ;; (1+ (line-end-position)) ;; '(composition)))) (setq rasmus/org-at-src-begin at-src-block))) (defun rasmus/org-prettify-symbols () (mapc (apply-partially 'add-to-list 'prettify-symbols-alist) (cl-reduce 'append (mapcar (lambda (x) (list x (cons (upcase (car x)) (cdr x)))) `(("#+begin_src" . ?✎) ;; ➤ 🖝 ➟ ➤ ✎ ("#+end_src" . ?□) ;; ⏹ ("#+header:" . ,rasmus/ob-header-symbol) ("#+begin_quote" . ?») ("#+end_quote" . ?«))))) (turn-on-prettify-symbols-mode) (add-hook 'post-command-hook 'rasmus/org-prettify-src t t)) (add-hook 'org-mode-hook #'rasmus/org-prettify-symbols))