A unified interface for Emacs' Org-mode block & link types (•̀ᴗ•́)و
Which is used to obtain 30 new custom blocks and 34 link types ¯\_(ツ)_/¯
Abstract
The aim is to write something once using Org-mode markup then generate the markup for multiple backends. That is, write once, generate many!
In particular, we are concerned with ‘custom’, or ‘special’, blocks which delimit how a particular region of text is supposed to be formatted according to the possible export backends. In some sense, special blocks are meta-blocks. Rather than writing text in, say, LaTeX environments using LaTeX commands or in HTML
div
's using HTML tags, we promote using Org-mode markup in special blocks —Org markup cannot be used explicitly within HTML or LaTeX environments.Special blocks, like
centre
andquote
, allow us to use Org-mode as the primary interface regardless of whether the final result is an HTML or PDF article; sometime we need to make our own special blocks to avoid a duplication of effort. However, this can be difficult and may require familiarity with relatively advanced ELisp concepts, such as macros and hooks; as such, users may not be willing to put in the time and instead use ad-hoc solutions.We present a new macro, defblock, which is similar in-spirit to Lisp's standard except that where the latter defines functions, ours defines new special blocks for Emacs' Org-mode —as well as, simultaneously, defining new Org link types. Besides the macro, the primary contribution of this effort is an interface for special blocks that admits arguments and is familar to Org users —namely, we ‘try to reuse’ the familiar
src
-block interface, including header-args, but for special blocks.It is hoped that the ease of creating custom special blocks will be a gateway for many Emacs users to start using Lisp.
**
A 5-page PDF covering ELisp fundamentals
** can be found here.
This article is featured in EmacsConf2020, with slides here: No pictures, instead we use this system to make the slides have a variety of styling information; i.e., we write Org and the result looks nice. “Look ma, no HTML required!”
Table of Contents
The full article may be read as a PDF or as HTML —or visit the repo. Installation instructions are .
Installation Instructions
Manually or using quelpa:
;; ⟨0⟩ Download the org-special-block-extras.el file manually or using quelpa
(quelpa '(org-special-block-extras :fetcher github :repo
"alhassy/org-special-block-extras"))
;; ⟨1⟩ Have this always active in Org buffers
(add-hook #'org-mode-hook #'org-special-block-extras-mode)
;; ⟨1′⟩ Or use: “M-x org-special-block-extras-mode” to turn it on/off
Or with use-package:
(use-package org-special-block-extras
:ensure t
:hook (org-mode . org-special-block-extras-mode)
;; All relevant Lisp functions are prefixed ‘o-’; e.g., `o-docs-insert'.
:custom
(o-docs-libraries
'("~/org-special-block-extras/documentation.org")
"The places where I keep my ‘#+documentation’")))
Then, provide support for a new type of special block, say re-using the src
blocks that, say, folds up all such blocks in HTML export, by declaring the
following.
(o-defblock src (lang nil) (title nil exports nil file nil)
"Fold-away all ‘src’ blocks as ‘<details>’ HTML export.
If a block has a ‘:title’, use that to title the ‘<details>’."
(format "<details> <summary> %s </summary> <pre> %s </pre></details>"
(or title (concat "Details; " lang))
raw-contents))
Minimal working example
The following example showcases the prominent features of this library.
#+begin_parallel
[[color:orange][Are you excited to learn some Lisp?]] [[blue:Yes!]]
Pop-quiz: How does doc:apply work?
#+end_parallel
#+begin_details Answer
link-here:solution
Syntactically, ~(apply f '(x0 ... xN)) = (f x0 ... xN)~.
[[remark:Musa][Ain't that cool?]]
#+begin_spoiler aqua
That is, [[color:magenta][we can ((apply)) a function to a list of arguments!]]
#+end_spoiler
#+end_details
#+html: <br>
#+begin_box
octoicon:report Note that kbd:C-x_C-e evaluates a Lisp form!
#+end_box
#+LATEX_HEADER: \usepackage{multicol}
#+LATEX_HEADER: \usepackage{tcolorbox}
#+latex: In the LaTeX output, we have a glossary.
show:GLOSSARY
badge:Thanks|for_reading
tweet:https://github.com/alhassy/org-special-block-extras
badge:|buy_me_a coffee|gray|https://www.buymeacoffee.com/alhassy|buy-me-a-coffee
Here is what it looks like as HTML (left) and LaTeX (right):
The above section, , presents a few puzzles to get you
comfortable with defblock
;-)