Auction Manual

Auction is an exporter and web UI for org mode.

This manual is written for Auction version 1.0.0. The version of the manual itself is 1.0.0. Both this manual and Auction are public domain.

Auction is an exporter and web UI for org mode. It takes a single org file as input, and generates a single HTML file as output. The generated files (such as this one) contain all styling and scripting information necessary to provide an interactive user interface.

Features

πŸ“¦ Static & Self Contained
Just like other org to HTML exporters, documents generated with Auction are static - they require no server side code to be run, and have no dependencies on external resources.
πŸ“š Sectioned Presentation
Unlike other org to HTML exporters, Auction presents documents in sections instead of rendering everything at once to make documents approachable and easy to read.
πŸ—ΊοΈ Intuitive Document Navigation
Various features such as the sidebar, search, breadcrumbs, and links at the bottoms of sections make documents easy to navigate on all screen sizes.
πŸ” Responsive Search
Searching is handled by client-side JavaScript, making it responsive (almost infinitely so compared to the modern paradigm of offloading such functionality to third party search-as-a-service platforms).
πŸ’Ύ Downloadable Output
As a consequence of being static and self-contained any document generated with Auction can be downloaded simply via Control+S, and the local copies retain all features of their online counterparts.
πŸ“Ά Progressive Enhancement
Documents generated with Auction render correctly with JavaScript disabled, and even without CSS, e.g. in text-based web browsers such as eww.
πŸ› οΈ Minimal Dependencies
Auction is written in HTML, CSS, JavaScript, AWK, POSIX shell and Emacs Lisp. The use of vanilla web technologies means Auction can be configured directly by editing the CSS and JS files associated with it - there are no build steps.

Drawbacks

βš™οΈ Requires a Backend for SEO
The single page paradigm of Auction combined with sectioned presentation means that by default it uses internal links to represent different sections, which is not good for SEO. The good news is that there's a fix for this, but it does require the use of a backend with basic capabilities such as routing and templating.
πŸ“€ Custom Exporter
Auction uses a custom org to HTML exporter, and as a consequence its capabilities differ from other exporters such as the default ox.el for org mode and pandoc. See exporter for details.
πŸ‘€ Minification Left to the User
Auction does not produce minified documents - make sure to minify its results before uploading them online to reduce their size. See minification for details.
🚧 New and Largely Untested
Auction is new and has not yet been extensively tested. I'll be relying on you to report bugs!

Getting Started

Dependencies

You need to have the following software installed to be able to use Auction:

GNU Awk
The GNU implementation of Awk is explicitly required - you can check which implementation you have by running awk --version
Emacs
Any version from the last decade should be fine
A POSIX-Compatible Shell
Any version

Installation

  1. Download

  2. Extract the archive

    tar xzf auction.tar.gz
  3. The org version of this manual is included with the installation to serve as a reference.

    Navigate to the directory and export it:

    cd auction; ./auction.sh manual.org

    This will generate a manual.html file in the same directory.

This is how documents are exported with Auction: you execute auction.sh with the path to the org file you want to export, and it'll generate an HTML file in the working directory.

The rest of this manual discusses everything there is to know about Auction in detail. But before you proceed you may want to take a moment here and take a look at the manual.org file you just exported to get a feel of things.

Exporter

Auction uses a custom exporter written in AWK (which I originally wrote for a static site generator named Mossgreen) to translate org documents to HTML. As a consequence its capabilities differ from other exporters such as the default org export engine (ox.el) or pandoc.

In short Auction supports all the basics of org: headings, lists, links, bold, italic, underlined, strikethrough text, inline code, #+begin / #+end blocks, and a few export directives such as #+TITLE, #+DATE and #+META. Notably it does not support features like tables, comments and macros. I feel that this is a reasonable set of features to support, but if you think there's anything that's sorely missing feel free to reach out to me.

Text

The following text effects are supported:

  • bold text with *

  • italic text with /

  • underlined text with _

  • strikethrough text with +

  • inline code with ~

These use the semantic HTML elements strong/em/ins/del. For inline code a span with the class inline-code is used. Delimiters can be escaped with backslashes, e.g. \* to avoid bold text. The text highlighting algorithm is not completely identical to org: for example in org escaped delimiters can be significant on the right-side of the text they're highlighting. But for the most part things should work the same.

Characters that are syntactically significant in HTML such as <less than< >greater than> symbols, &ampersands& </etcetera> are properly escaped. You can use backticks to avoid this and export text literally, e.g. `<span style="color: red;">I'm red</span>` is exported as I'm red.

Headings

Headings can be nested to arbitrary level. Since HTML only provides 6 heading levels, heading levels exceeding this depth are translated to ordered lists. When rendered as a section, heading levels are "promoted" as appropriate. (e.g. the name of this section, Exporter, is rendered with an h1 element, despite it being a second-level heading in the org file using two asterisks.)

Heading Property Blocks

In org-mode, headings can have property blocks as follows:

**** Heading Property Blocks
:PROPERTIES:
:ID: violet-heading
:STYLE: color: violet;
:END:

The key-value pairs found in such blocks are exported as HTML attributes, which is why this heading appears violet: it has a STYLE property with the value color: violet;. It also has an ID property, which allows for the creation of internal links in HTML. We'll be linking to the current heading shortly.

Links

ID links in the format [[id:violet-heading][example]] are translated to internal links such as example. Any other link such as [[https://monospace.games/][example 2]] is exported without change to its link: example 2.

One very small feature; if a link is a mailto: link and the mail address associated with it is the same as the link text, the link element is given the mail class. Here's one example of such a link: test@example.com. The reason for this is that such links are not possible to detect with CSS alone, and you may want to style them differently, e.g. avoiding line breaks in them.

Blocks

Code blocks (those that begin and end with #+begin_src, #+end_src) are syntax highlighted. Here's the script that does the highlighting:

#! /usr/local/bin/emacs --script

;; Load htmlize
(require 'package)
(package-initialize)
(require 'htmlize)

(let ((target (pop command-line-args-left)))
  (find-file target)
  (kill-whole-line)          ; Delete the first line, which is used to set mode
  (font-lock-fontify-buffer) ; Force fontification, required in batch mode
  (with-current-buffer (htmlize-buffer)
    (princ (buffer-string))))

Any other block is exported literally. This makes it possible to embed markup, styling and scripts directly in your document, as an example here's an SVG:

I'm an SVG embeddedin an org documentthat has beenexported to HTML!

Lists

Unordered lists can be constructed with - and +. Ordered lists can be constructed with 1., 1), A., A). Similar to headings, lists can be nested to arbitrary level. Paragraphs will break out of lists according to their indentation level as appropriate. Definition lists are also supported with the - term :: definition syntax, e.g.:

term
definition
other term
other definition

Export Settings

#+TITLE is exported as the top-level heading of the document. The use of a title is required: it's treated as the root of the section tree for the document.

The #+DATE setting is exported as a time element. It's optional and can occur more than once in the file. Its value should be a timestamp containing both date and time, e.g. <1969-07-20 Sun 20:17>

#+META is for any other information - contents of #+META directives are appended at the end of the document in an HTML comment block.

Sections

Intead of rendering the whole document at once, Auction renders documents in sections. Sections are generated from org headings and also appear on the sidebar.

By default each org heading generates a section. Headings can be prevented from generating sections in the following two ways:

  1. If a heading has the class terminal-section, none of its child headings create sections.

  2. If a heading has the class non-section, it does not create a section.

    (For this class to have effect, the heading must appear before any headings that generate a section in its parent.)

Classes are assigned using PROPERTIES blocks just like any other HTML attribute, as explained in the previous section. Here's an example:

*** Example Heading
:PROPERTIES:
:CLASS: terminal-section
:END:

ID Auto-Generation

Since sections represent portions of the document that render as standalone units, they must be capable of being linked to, thus each section must have an ID. If the heading associated with a section does not have an existing ID, one is auto-generated from the section name according to the following algorithm:

  1. Get the text up to the first opening parenthesis

  2. Replace spaces with dashes and remove non-alphanumerical characters

  3. Turn to lowercase

As an example this generates the id "whats-auction" from "What's Auction"

Note that this method does not check whether the generated ID's are unique or not, as it's not possible to infer which heading you may have meant if the ID has been used in a link. You should pay attention to the names of the headings in your document, and assign ID's explicitly if any two share the same name.

The data-bottom-navbar attribute determines the links that appear at the bottom of sections. It can be set to the following values:

none
No links.
next
Links to the next section.
sequential
This section, and all sections that descend from it, link to next section.
children-direct
Links to sections which are direct children.

Note that this is not a class but a custom attribute, hence the data- prefix. Here's an example of how it's used:

**** Example Heading
:PROPERTIES:
:CLASS: terminal-section
:DATA-BOTTOM-NAVBAR: children-direct
:END:

If multiple data-bottom-navbar values apply to a section, the priority order is as follows:

none > children-direct > next == sequential

Other Classes

Miscellaneous Behavior
navpanel-open
The section starts toggled open on the sidebar, so that its child sections appear visible.
landing-section
The section to be displayed when the user opens the document for the first time (if the link they've used does not indicate any explicit sections to be rendered). Subsequent visits of the same link will take the user to the top level instead.
Collapsible Headings

Headings that do not generate sections can be given the following classes to make their contents collapsible:

collapsible-body
Makes the body of the heading collapsible by clicking on the heading.
collapsible-body-cascade
Applies collapsible-body to the heading, and all of its child headings.
collapsible-content
Clicking on the heading collapses only the heading's own content, not those of its child headings. Applies to the child headings as well.

Here are some example collapsible headings:

I'm collapsible-body

Clicking on me reveals my contents and child headings.

  1. Child heading of collapsible-body

    I am not interactive.

I'm collapsible-body-cascade

Clicking on me reveals my contents and child headings.

  1. Child heading of collapsible-body-cascade

    I'm interactive just like my parent.

I'm collapsible-content

Clicking on me toggles my own content on/off, while my child headings remain visible.

  1. Child heading of collapsible-content

    My heading remains visible regardless of my parent's state, and my content is independently toggled on/off.

Minification

Auction does not produce minified documents. The HTML, CSS and JS files associated with it are intended to be human-readable, and they're included in the output as-is.

A minifier can do adjustments such as getting rid of comments, excess whitespace, and replacing variable names with shorter ones to significantly reduce the size of web documents without altering their behavior. You're highly recommended to use one before publishing the documents you generate with Auction online.

An example minifier is the npm package minify. You can use it as follows:

  1. Install npm

  2. Install minify

    npm install -g minify
  3. Call minify on your output

    minify manual.html > manual-min.html

In the draft version of this document minification results in a ~30% reduction in file size.

Configuration

If you wish to configure Auction you'll have to edit its source files. But that's not as scary as it may sound, and here I'll describe how to do a few configurations that you're most likely to be interested in.

The source files reside in the internal directory, which has the following contents:

internal
├── base.html
├── style.css
├── script.js
├── export.awk
└── syntax-highlight.el

The style.css file determines the style and appearance of your documents. export.awk and syntax-highlight.el deal with turning org to HTML, script.js deals with interactivity, and base.html is the output template.

The main thing you'll wish to configure will likely be the color palette. This information resides in the following two rulesets in style.css:

body[data-theme="light"] {
  /* Light palette */
  --color-text-main: #1e1e1e;
  --color-text-deemphasized: #6f6f6f;
  --color-text-highlighted: #d00058;
  --color-text-error: #ff2951;
  --color-link-unvisited: #00adff;
  --color-link-visited: #0069c2;
  --color-bg-main: #fff;
  --color-bg-surface-one: #e0e0e0;
  --color-bg-surface-two: #525157;
  --color-bg-surface-three: #d2d1d7;
  --color-accent-one: #1c86ee;
  --color-accent-two: #e5f3fe;
}

body {
  /* Dark palette - default  */
  --color-text-main: #e3e3e3;
  --color-text-deemphasized: #9e9e9e;
  --color-text-highlighted: #e6cd69;
  --color-text-error: #ff2951;
  --color-link-unvisited: #00adff;
  --color-link-visited: #6dcfff;
  --color-bg-main: #1b1b1b;
  --color-bg-surface-one: #313131;
  --color-bg-surface-two: #3b3a40;
  --color-bg-surface-three: #525157;
  --color-accent-one: #1c86ee;
  --color-accent-two: #182631;
}

The first set lists the colors associated with the light theme, and the second the dark theme. To alter the palette of your document just replace the RGB color values listed here and re-export.

You may also be interested in altering the icons used in your document. These are stored in the style.css file as follows:

  background: url("data:image/svg+xml;base64,<base64-encoded-svg-source>");

Find the icon you wish to edit, e.g. header .theme-toggle[data-state="dark"] is the icon of the theme toggle button when dark theme is active, and decode the SVG as follows:

echo "<base64-encoded-svg-source>" | base64 -d

This will produce the SVG source for the icon, e.g.

<svg xmlns='http://www.w3.org/2000/svg' viewBox="0 0 100 100">
  <defs>
    <path id="ray" d="M 50 15 v -10"
          stroke="#ffd700" stroke-width="5" stroke-linecap="round" />
  </defs>
  <circle cx="50" cy="50" r="27.5" fill="#ffd700" />
  <use href="#ray" transform="rotate(0 50 50)" />
  <use href="#ray" transform="rotate(45 50 50)" />
  <use href="#ray" transform="rotate(90 50 50)" />
  <use href="#ray" transform="rotate(135 50 50)" />
  <use href="#ray" transform="rotate(180 50 50)" />
  <use href="#ray" transform="rotate(225 50 50)" />
  <use href="#ray" transform="rotate(270 50 50)" />
  <use href="#ray" transform="rotate(315 50 50)" />
</svg>

Which is rendered as:

Edit this image (I have a blog post on this that you might want to read), and when done base64 encode your image and replace the original string.

echo $(base64 -w 0 your-image.svg)

SEO Fix

Auction represent sections with internal links by default, e.g. manual.html#seo-fix for this section. But internal links are not indexed as distinct pages by search engines. To fix this we want to link to our sections in the form manual/seo-fix instead.

Auction has a backend-agnostic "hosted" mode for this purpose. To use it, build your document with the url option, e.g.

./auction.sh url="https://www.example.com/manual" manual.org

Then open the generated HTML file, and edit it so that the INITIAL_RENDER variable in the script block just below the title is initialized to the string section when the user visits the URL manual/section. In django this can be accomplished by editing just two lines as follows:

  1. Add the URL pattern:

    urlpatterns = [
        path("manual/<slug:slug>", TemplateView.as_view(template_name="manual.html")),
    ]
    
  2. Move the manual.html to an appropriate template location, and edit INITIAL_RENDER so that it's initialized to the slug captured from the URL:

    <script>
      HOSTURL = "https://www.example.com/manual"
      INITIAL_RENDER = "{{ slug }}"
    </script>
    

In hosted mode Auction does not send a fresh request each time you navigate to a section, instead it detects such links and treats them as if they're internal.

Auction will also detect if a hosted document is not being read from the URL it has been exported with (e.g. a hosted document that has been downloaded by the user) and fall back to the default behavior in such cases.

Endnotes

You can contact me by sending an email to monodev@monospace.games. Feel free to do so for any bug reports and feature requests.

Auction is something that I've developed for personal use, namely for the manual of Monospace Engine. By the time I was fairly satisfied with it I realized it merited being released for general use.

Both this manual and Auction itself are public domain. You don't need to do it, but I'd appreciate it if you included an attribution in the documents you publish so that it can be useful to more people.