Skip to content
Switch branches/tags


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

Table of Contents


literate-lisp provides an easy way to use literal programming in Common Lisp language. It extends the Common Lisp reader syntax so a Common Lisp vendor can read org files as Common Lisp source files.

By using this package(literate-lisp), Emacs org mode and Emacs Lisp library polymode, literate programming can be very easy in one org file containing both documentation and source codes, and this org file can interact well with SLIME.

The implementation detail of literate-lisp is in file ./ (pdf version).

This library contains the following files:


The restriction to the org file

The org file should start with a comment character and a space character(“# “), to drive lisp reader into ORG syntax. Actually it can be a convenient way for us to specify some local variables, for example I often put them in the first line of an org file:

# -*- encoding:utf-8 Mode: POLY-ORG;  -*- ---

Which make Emacs open file with utf-8 encoding and poly-org-mode.

install polymode in Emacs

It’s better to edit the org file with polymode, which will make code block use its native file mode. The following Emacs Lisp scripts in .emacs will install it.

(use-package poly-org
    :ensure t)

how to insert code block quickly

Please have a look of the section How to insert code block in org file in library literate-elisp.

a new code block header argument load

Please have a look of the section new defined header argument load in ./

Reference named blocks as global parameters

If a block has a named for it, that is, with a #+NAME: before it like this:

#+NAME: js-demo-code
  document.getElementById("demo").innerHTML = "Hello JavaScript";

Then after loading, a global parameter js-demo-code will contain the string in above block.

It is more friendly than write this string in lisp directly, because org mode can provide syntax for it and poly mode can even enable us edit this code block in js-mode.

You can visit these named blocks by Emacs Lisp function org-babel-goto-named-src-block, or by hacking sly like this:

(defun sly-edit-definition-of-named-block (&optional name method)
  (when (string-prefix-p "#+END_" (string-trim (buffer-substring (line-beginning-position) (line-end-position))) t)
    (let ((case-fold-search t))
      (search-forward-regexp (format "#\\+NAME:\s+%s" name))
      (forward-line 2)
      (goto-char (line-beginning-position)))))
(eval-after-load "sly"
  '(advice-add 'sly-edit-definition :after #'sly-edit-definition-of-named-block))

You can hack slime the same way.

NOTE You have to install literate-lisp to active *readtable* in sly when using SBCL to make above patch work, because the SBCL backend in sly will read the source code inside file when find definitions.


How to debug org file in LispWorks IDE

You have to add the following codes in your .lispworks to enable the debug facility in Lispworks Editor.

(defun check-org-mode (buffer truename)
  (when (and truename (equal (pathname-type truename) "org"))
    (setf (editor:buffer-major-mode buffer) "Lisp")))
(editor:add-global-hook editor::read-file-hook 'check-org-mode)

Thanks for Martin Simmons in LispWorks to support the above configuration codes.

How to integrate with namded-readtables

You may find that named-readtables is friendly to define the syntax for literate-lisp in your codes like this:

(named-readtables:defreadtable syntax
  (:merge :standard)
  (:dispatch-macro-char #\# #\space #'literate-lisp::sharp-space)
  (:dispatch-macro-char #\# #\+ #'literate-lisp::sharp-plus))

How to write user initialization file with literate programming style

You can put all initialization codes in an org source file, all you need is to load literate-lisp firstly. For example, you can put the following codes in file ~$HOME/.sbclrc~ for SBCL.

(require :asdf)
(load "~/projects/common-lisp/literate-lisp/literate-lisp.asd")
(asdf:oos 'asdf:load-op :literate-lisp)
  (load "~/projects/common-lisp/config/"))

I find it useful for various Lisp vendors so all initialization codes for them can be in just one file.

how to include org codes with ASDF package-inferred-system extension

The ASDF package-inferred-system extension is wonderful, in which each file is its own system, and dependencies are deduced from the defpackage form or its variant, uiop:define-package. You can also use literate-lisp to make a package inferred system by writing an ASD definition like this:

(asdf:defsystem literate-libraries
  :serial t
  :defsystem-depends-on (:literate-lisp)
  :default-component-class :org
  :class :package-inferred-system)

Here :class :package-inferred-system enables the package-inferred-system extension, and :default-component-class :org means that ASDF will look for all org files to find out a system and load it.

For example, you can create an org file in the same directory of above ASD definition file named as and contains the following codes

# -*- encoding:utf-8 Mode: POLY-ORG;  -*- ---
* Create a package for this package inferred system
#+BEGIN_SRC lisp
(defpackage literate-libraries/utilities
  (:use :cl)
  (:import-from :flexi-streams :octet :make-flexi-stream)
  (:import-from :log4cl :log-config)
  (:documentation "a utility module."))
* implementation
... ...

After loading the above ASD definition file, you can load system literate-libraries/utilities in your REPL.

(load "/some/path/literate-libraries.asd")
(ql:quickload :literate-libraries/utilities)

Please upgrade to ASDF or later, it is not supported in earlier ASDF versions.

packages written by literate-lisp

  • s-graphviz an S-expression presentation of GraphViz DOT Language

A demo literate application

The ASD file

We use the original ASD definition file, and extend the ASDF syntax(The documentation of extended ASDF syntax can be found in

In a short word, we should load literate-lisp by ASDF keyword :defsystem-depends-on and declare the org source file with new ASDF keyword :org.

Now let’s define the ASDF system file ./literate-demo.asd for this demo package

(asdf:defsystem literate-demo
  :author "Xu Jingtao <>"
  :version "0.1"
  :licence "MIT"
  :serial t
  :description "an demo project of literate-lisp"
  :defsystem-depends-on ("literate-lisp")
  :depends-on (:iterate #+dev :clgplot)
  :components ((:module :demo :pathname "./"
                        :components ((:org "puzzle")
                                     (:org "readme"))))
  :properties ((version "0.1")))

Which will load ./ and this file directly as a lisp source file.

The whole content of ASDF definition file is in ./literate-demo.asd.

a demo package for this file

(defpackage :literate-demo
  (:use :cl)
  (:export ))
(in-package :literate-demo)

Test cases


The FiveAM library is used to test.

(eval-when (:compile-toplevel :load-toplevel :execute)
  (unless (find-package :fiveam)
    #+quicklisp (ql:quickload :fiveam)
    #-quicklisp (asdf:load-system :fiveam)))
(5am:def-suite literate-demo-suite :description "The test suite of literate-demo.")
(5am:in-suite literate-demo-suite)

test case for named block

Let’s define a named code block for some javascript code:


Then try to read it in our test case

(5am:test named-block
  (5am:is (stringp js-demo-code-1))
  (5am:is (not (null (position #\" js-demo-code-1 :test #'char=)))))

run all tests in this library

This function is the entry point to run all tests and return true if all test cases pass.

(defun run-test ()
  (5am:run! 'literate-demo-suite))