Extra fancy HTML documents with OrgMode and JavaScript

Table of Contents

1. License

(C) Copyright 2022 by David T. O'Toole.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

The Software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the Software or the use or other dealings in the Software.

※ The MIT license above applies only to the included images and JavaScript add-on code of Org-fleuron. Org-info-js, IBM Plex, the Parenscript utility library, and other contributed resources of this project are distributed under their respective licenses. Please see the org-fleuron code repository for full details.

2. About this document

This HTML document can be viewed in two different ways. You can either:

  • Flip between the different sections, like the pages of a book; or,
  • Scroll through one long continuous document, like a web page.

The book-style view is the default. To switch views, click the Toggle view link at the upper right corner of the page. To navigate between pages, use the Next and Previous links at the top, or the , Back, or buttons at the lower right.

To save your place, use the +M button in the button bar. The next time you open the page, you can press →M to jump to the bookmarks tab. (These buttons are temporarily hidden when the screen is too narrow to display them; if you are using a mobile device in portrait mode, you might need to rotate to landscape mode for the buttons to appear.)

Press the ❦ button (the fleuron) in the lower left corner, or the HOME link at the top right, to leave this document and return to the home page.

If your device has a keyboard, you can use several shortcut keys:

Next page
Previous page
Back to the previous page in history
Toggle between book view and flat view
Toggle sidebar
Jump to Bookmarks
Help on more keys

2.1. Colophon

This document was written using GNU Emacs with Orgmode. Various versions (HTML, EPUB, PDF, plain text) can be produced automatically from the original Orgmode markup file.

The hierarchical section navigation in HTML format is provided by org-info-js. It has been extended to include graphical navigation buttons, a dynamic sidebar, bookmarking, and more as part of Org-fleuron.

The typeface used for this document is IBM Plex, distributed under the terms of the Open Font License. The colors are selected from the Solarized palette.

The fancy capital letters are in the public domain and were created by the 19th century designer William Morris.

3. About Org-fleuron

Org-fleuron is a JavaScript extension for org-info-js with several added features for fancy HTML documents exported from OrgMode:

  • Extends org-info-js with navigation buttons and more.
  • Sidebar with search, plus Table of Contents, Bookmarks, and Documents tabs.
  • Bookmark within org files and across a collection of org files.
  • Full-text search of a collection of org files (experimental).
  • Free Software distributed under the MIT License. (Note: org-info-js is GPLv3 and the Parenscript library uses an MIT-like license.)
  • Stylesheet customized for desktop, tablet, and mobile.
  • Main colors chosen from the Solarized light palette.
  • The IBM Plex fonts are included statically in TrueType format with Serif, Sans-serif, and Mono variants in Regular, Bold, Italic, and Bold Italic styles under the Open Font License.
  • Near WYSIWYG with M-x set-frame-font in Emacs and solarized-light theme.
  • Twenty-six fancy public domain capital letters by William Morris (see the Documents tab for an example.)
  • More to come!

Note: Org-fleuron is currently under construction.

You can continue browsing the current document for a guide to the configuration itself. Press the N key on the keyboard or the button in the lower right corner to continue.

4. Known issues

Local browsing:

  • Fleuron uses the JavaScript localStorage feature for persisting state across pages. This can work differently when you are pointing the browser to a local copy of the website. In particular, when browsing locally, Fleuron may fail to navigate to the correct page from a full-text search result, and/or fail to preserve the state of the sidebar when switching documents from the Bookmarks or Documents tabs. If you need to browse the files locally and still have these features work, you can deploy a webserver on your machine and point your browser to localhost.


  • The search feature in org-info-js is currently a bit glitchy, and it does not properly search into document sections that are exported as lists (i.e. headings deeper than org-export-headline-levels). As a workaround, you can set org-export-headline-levels to a higher value, and I'm working on an overall fix for the issue.
  • Search only visits a document section once even if there are multiple occurrences of the search terms in the section.
  • Search can sometimes fail to find a term on the current page.
  • Full-text search is experimental; sometimes result links point to the wrong section.


  • Minibuffer stays visible until page flip on mobile (i.e. "press any key" doesn't work).
  • There needs to be a left-handed layout option and other accessibility improvements.
  • Funny rendering of headlines when tags are used in org export.
  • Minibuffer text doesn't wrap.

5. Code repository

If you want to dive right into the code, please visit the org-fleuron repository on Gitlab. Or, continue on to the next page here by pressing N, or the Next link at the top of the page, or the right arrow button at the bottom right corner of the page.

6. Configuration guide

6.1. Stylesheet

Here is the raw stylesheet. (It does need some tidying up.) Keep on reading for more information.

6.2. JavaScript plugin

6.2.1. Using a patched org-info-js

You must use my version of org-info-src.js which has been slightly modified to add some hooks. I am submitting a patch to upstream, so this step might not be necessary in the future.

To use this version, save it to your publishing directory and add the following configurations to your Org file:

#+INFOJS_OPT: path:org-info-src.js home:./index.html
#+INFOJS_OPT: toc:t ltoc:t view:info mouse:underline buttons:t

6.2.2. Including the plugin in your page

Include the following in your Org file:

#+HTML: <script type="text/javascript" src="fleuron.js">

The plugin source is written in Parenscript, which compiles to JavaScript. You can also browse a syntax highlighted version of the source.

Note that fleuron.js must run after loading org-info-src.js. Org normally loads org-info-src.js in the HTML HEAD element, so it is sufficient to load fleuron.js in the document body. A good bet is to put the SCRIPT tag before the first org heading.

6.2.3. Arranging your document

You must have License/Copyright as page 1 and the "About this document" help as page 2, or the ? and (C) buttons won't go to the right places. Or, you can set the JavaScript variables FleuronLicensePageNumber and FleuronHelpPageNumber.

 #+begin_export html
 <script type="text/javascript">
 FleuronLicensePageNumber = 1;
 FleuronHelpPageNumber = 2;

Be sure to set these variables after fleuron.js is loaded.

※ You may wish to use org's #+INCLUDE directive so that License and Help sections are shared among documents in a project. You can also place the JavaScript include there; see the next sections.

6.2.4. Showing the page bottom

The following code inserted in your Org file above the first heading (and before any INCLUDEs) shows when the info-js user has reached the bottom of the current page.

#+HTML: <div class="centeralign">
#+HTML: </div>

This can be included in your Org #+INCLUDE directive instead.

6.2.5. Creating the Documents tab

You may optionally set the variable FleuronDocuments to obtain a fancy index of available pages in the sidebar's Documents tab. Each entry is an array consisting of the URL, title, subtitle, and author. You may put this in your #+INCLUDE file.

 #+begin_export html
 <script type="text/javascript">
 FleuronDocuments = [['critical.html', 'Notebook for "Critical Thinking"', '', "David T. O'Toole"],
                     ['apriori.html', 'Understanding the a priori', 'A century of conceptual pragmatism', "David T. O'Toole"], 
                     ['fleuron.html', 'Org-fleuron', 'extra fancy HTML documents with OrgMode', "David T. O'Toole"],
                     ['wm.html', 'Walking meditation in Buddhism', '', "David T. O'Toole"]];

6.2.6. Arranging your #+INCLUDE files

For examples of what to put in your #+INCLUDE files, see:

For an example of usage, check out the OrgMode source of the current page.

6.2.7. Configuring full-text search

Fleuron has a built-in full-text search that uses a preprocessed index. This is not scalable but should be fine for smaller sites.

You can make the index using the code in fleuron.el. After publishing your HTML files from Org, make sure to set these variables:

  • fleuron-directory — Name of directory where org files are stored
  • fleuron-files — List of Org files to index (without directory portion)
  • fleuron-output-file — Output *.js file for index

Then issue the command M-x fleuron-make-index RET to build the index.

Then, you must create a special org file like this:

After publishing, you can visit search.html from the browser.

To set up automatic index generation with org-publish, you can use fleuron-make-index as a :completion-function in your org-publish-project-alist.

If you wish to disable this feature entirely, set the JavaScript variable FleuronFullTextSearchIsEnabled to the value false.

6.3. Adjusting the margins for tablet and mobile

Here is an excerpt from the stylesheet. These pixel widths aren't exact but seem to work well.

@media (max-width: 641px) {

    body {
        padding-left: 0.2em;
        padding-right: 0.2em;
        margin-left: 1em;
        margin-right: 1em;

@media (min-width: 642px) and (max-width: 1150px) {

    body {
        padding-left: 0.2em;
        padding-right: 0.2em;
        margin-left: 3.5em;
        margin-right: 3.5em;

6.4. Favicon

Put this in your org HTML header:

<link rel="icon" type="image/x-png" href="fleuron.png">


6.5. Near WYSIWYG in Emacs

You can make your Emacs buffer look more like the finished page (i.e. What You See Is What You Get, a.k.a. WYSIWYG).

Install the TTF fonts according to your distribution's proper method, and then in your Emacs configuration:

(set-frame-font "IBM Plex Serif")

You may also wish to try the following:

  • Solarized-light color theme
  • Olivetti-mode for nice centering (this is especially useful on larger screens)
  • Org-modern-mode