Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

A unified interface for Emacs' Org-mode block & link types (•̀ᴗ•́)و

Which is used to obtain 30 new custom blocks and 34 link types ¯\_(ツ)_/¯


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 and quote, 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

  1. Installation Instructions
  2. Minimal working example
  3. Bye!

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

;; ⟨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'.
     "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))

Minimal working example

The following example showcases the prominent features of this library.

[[color:orange][Are you excited to learn some Lisp?]] [[blue:Yes!]]

Pop-quiz: How does doc:apply work?

#+begin_details Answer
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!]]


#+html: <br>
octoicon:report Note that kbd:C-x_C-e evaluates a Lisp form!

#+LATEX_HEADER: \usepackage{multicol}
#+LATEX_HEADER: \usepackage{tcolorbox}
#+latex: In the LaTeX output, we have a glossary.


badge:|buy_me_a coffee|gray||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 ;-)