Simon Braß

Home-Office Physicist
Atom Icon - atom by Erin Agnoli from the Noun Project

Org-mode: Publishing

<2020-11-03 Tue>

Org-mode comes with the possibility to export your Org-based "source" code - everything is plain text - into a markup language of your choice. In the case of this blog, it is HTML. In addtion, Org-mode allows us to comfortably publish the exports to a web server, and, it makes the process extremely easy to do so.

The base setup is as following: I need to specify a project in my Emacs configuration, i.e. .spacemacs, where I define which files are exported and where to. Emacs and org-mode then take care of everything else.

My sole tweak to the publication project is to generally suppress the table of contents, section numbers and add an auto-generated sitemap. Furthermore, I include my own pre- and postamble, which contain the site title and information, i.e. last-modified, name and email.

:recursive t
:with-toc nil
:auto-sitemap t
:html-head "<link rel=\"stylesheet\"
:html-doctype "html5"
:html-preamble t
:html-preamble-format (("en"
                        "<p class=\"title\">Simon Braß</p>
<p class=\"subtitle\">DESY Theory Group<br /><img src=\"DESY_logo_3C_web_tiny.jpg\" alt=\"DESY Logo\" style=\"padding: 2ch 0 0 0\"></p>
<ul id=\"navbar\">
<li><a href=\"index.html\">Home</a></li>
<li><a href=\"about.html\">About</a></li>
<li><a href=\"sitemap.html\">Sitemap</a></li>
:html-postamble t
:html-postamble-format (("en" "<p class=\"author\">%a (%e)</p><p class=\"date\">Last modified: %C</p><p class=\"creator\">%c</p><p class=\"validation\">%v</p>"))
:html-preamble t


I use several directory layers to organize my web-related org files. The top-level directory holds the primary static files, i.e. the About Me and front page. The latter is static, but I will update it quite often, hopefully.

I put my articles (or blog entries) in the article subdirectory, which I may use to further structure my articles with different directory levels, e.g. differentiating between computational- or physics-related articles.

Furthermore, I place my stylesheet and my images in separate directories. Therefore, I find the following structure:

   |- css
   |- img
   |- article
   |   |  `- draft (exclude directory from export)
   |   |- publish.org
   |   |- ...
   |   `- index.org (auto-generated)
   |- index.org
   |- about.org
   `- sitemap.org (auto-generated)

We start with a top-level directory, and a single sub-directory called article to store expanded texts. We use the top-level directory to store mostly static pages, i.e. about Me page, and the front page of my blog, which I use to point to new articles or smaller texts. The top-level directory and the org-file residing there, However, in order for the Org-mode publisher to find those files I need to tell it to search the sub-directories for it, i.e. :recursive t. I place all other files in the top-level directory.


Org-mode generates a sitemap file, which the exporter then transforms into the specific output with the publishing-function. Again, we can tweak the generation and appearance with the help of generic functions.

We can modify the appearance of the sitemap entries with :sitemap-format-entry, which defaults org-publish-sitemap-default-entry.

(defun org-publish-sitemap-default-entry (entry style project)
  "Default format for site map ENTRY, as a string.
ENTRY is a file name.  STYLE is the style of the sitemap.
PROJECT is the current project."
  (cond ((not (directory-name-p entry))
         (format "[[file:%s][%s]]"
                 (org-publish-find-title entry project)))
        ((eq style 'tree)
         ;; Return only last subdir.
         (file-name-nondirectory (directory-file-name entry)))
        (t entry)))

We can modify the appearance of the sitemap document itself with :sitemap-function, which defaults to org-publish-sitemap-default.

(defun org-publish-sitemap-default (title list)
"Default site map, as a string.
TITLE is the the title of the site map.  LIST is an internal
representation for the files to include, as returned by
`org-list-to-lisp'.  PROJECT is the current project."
(concat "#+TITLE: " title "\n\n"
(org-list-to-org list)))

Last, but not least, we can adjust the sitemap title :sitemap-title.

In principle, we write a function a org-publish-sitemap-desy, which takes the title and a list, and add the #+AUTHOR and #+EMAIL tags (to the concat function call).


Pre- and postamble


It's just a tiny bit of CSS (from my side) and HTML, however, org-mode brings some styling.

I recommend the article 58 bytes of css to look great nearly everywhere (https://jrl.ninja/etc/1/), which I extended by my own (minimal) font settings.

font-family: "Proxima Nova", Monospace;
font-size: 16px;

The navigation bar is just an inlined, unordered list found on w3schools.

ul#navbar li {
    display: inline;

And a minor tweak for inlined source code:

code {
    font-family: Georgia, Serif;
    background-color: rgb(190, 190, 190, 0.2)

Simon Braß ([email protected])

Created: 2020-10-23 Fri 00:00 and last modified: 2021-03-08 Mon 11:59

Emacs 27.2 (Org mode 9.4.4)