Cleopatra Elisp Package

Table of Contents

1 cleopatra.el

1.1 Init

(defvar cleopatra:*emacs-dir* (concat (getenv "ROOT") "/.cleopatra/emacs.d/"))

(setq user-emacs-directory cleopatra:*emacs-dir*)
(setq package-user-dir (concat cleopatra:*emacs-dir* "packages"))

(setq package-archives
      '(("gnu"   . "https://elpa.gnu.org/packages/")
        ("melpa" . "https://melpa.org/packages/")))


(or (file-exists-p package-user-dir)

(cleopatra:ensure-package-installed 'use-package)

(require 'use-package)
(use-package org :ensure t)
(use-package htmlize :ensure t)

1.2 cleopatra:configure

We provide a “sensible” (that is, to our opinion) default configuration for Org mode and Babel.

(defun cleopatra:configure ()
  (setq backup-inhibited t)
  (setq org-src-fontify-natively t)
  (setq org-export-with-sub-superscripts nil)
  (setq org-confirm-babel-evaluate nil)
  (setq org-publish-timestamp-directory
        (concat cleopatra:*emacs-dir* "cache/"))
  (setq org-confirm-babel-evaluate nil)
  (setq org-src-preserve-indentation t)
  (add-to-list 'org-babel-default-header-args
               '(:mkdirp . "yes"))
  (add-to-list 'org-babel-default-header-args
               '(:noweb-sep . "\n\n")))

1.3 cleopatra:tangle-publish

cleopatra “tangling semantics” slightly differs from Babel’s default one. The key difference is that, contrary to Babel, cleopatra does not force the structure of your literate sources to match the structure of your tangled sources.

For instance, let IN be is the directory wherein lives your literate sources, OUT be the directory wherein your tangled sources shall be placed, and IN/a/b.org be a file which contains a source block intended to be tangled in c/d.txt.

  • Babel will assume you want d.txt to be placed in OUT/a/c/, that is to reflect the fact that b.org lives in a
  • cleopatra won’t, and d.txt will be placed in OUT/c/

cleopatra:tangle-publish is a function to be used with org-publish. To implement the desire behavior, it does not use the third argument (which is updated by Babel to take into account the structure of the literate programming source), but we rather use the first argument which contains the component configuration, and this configuration needs to contains a field :publishing-directory.

(defun cleopatra:tangle-publish (conf filename _pub-dir)
  (let ((pub-dir (plist-get conf :publishing-directory)))
    (if pub-dir
          (find-file-read-only filename)
          (cd (getenv "ROOT"))
          (unless (file-exists-p pub-dir)
            (make-directory pub-dir))
          (cd pub-dir)
      (error "cleopatra: missing :publishing-directory option"))))

2 Emacs Aliases

To generation processes, we provide cleopatra-emacs, to be called from within a cleopatra execution context. cleopatra-emacs is intended to be used using the --script command-line argument to execute Emacs lisp script with the proper configuration (in particular, with cleopatra.el loaded). But it can also be used as-is to use the exact same Emacs that is being used for exporting and tangling (this may be useful for debugging).

set -e
emacs -Q --load="${ROOT}/.cleopatra/emacs.d/cleopatra.el" $@
set -e
emacs -Q --batch \
         --load="${ROOT}/.cleopatra/emacs.d/cleopatra.el" \

Author: Thomas Letan

Created: 2020-04-05 Sun 13:56