Markdown Style Guide

A markdown file is a plain text document with short, easily typed symbol patterns indicating how the content should be rendered into HTML.

In Octoboxy, markdown is our preferred language for document assets.

On top of basic markdown syntax we have layered a set of our own best practices. Our goal here is to imply a minimal structure to documents such that a content management system can deeply parse them and provide unique high-level features.

This particular document is written in our markdown. It serves as example as much as explanation.

This document can be read in its plain text form here.

Let’s dive in. First we discuss overall markdown file structure. Then we go deep into all the details of the rich styling syntax.



File Structure

Markdown files are unicode text and should be saved with UTF-8 encoding.

A markdown file usually has a file extension of .md

The file’s name without extension is transformed into what we call the file’s slug. The slug is a lowercase version, with symbols removed, and spaces turned into underscores. Our system uses the document’s slug as the document’s identity.

For example, a file named “Markdown Style” would be known in Octoboxy as “markdown_style_guide”.


The very top lines of the document can be a preamble written in YAML that calls out some additional metadata about the file’s contents.

For example, the very top lines in this file are:

icon: ruler-triangle
  Reference document for how the markdown language is used within Octoboxy.
allow_plaintext_rendering: true

This block of properties tells our system what icon best represents this page, augments the page with a summary description (used on our parent page), and authorizes Octoboxy to display the document in plain text when you ask.

Metadata Reference

Octoboxy currently recognizes all of the following metadata tags:

information used when other pages are referring to this document

  • color:
    • red, orange, yellow, green, blue, purple, black, or white
    • grey0 (equal to black) through grey8 (equal to white)
  • icon:
  • title0, title1, and byline:
    • these may also be extracted from headings, see below
  • description:
    • a single paragraph of text describing the document
  • excerpt:
    • a single paragraph of text copied from within the document
    • defaults to the first few lines of prose

how the document itself is rendered

  • align:
    • paragraph alignment: left, right, center, or justify
  • iconset:
    • weight of icons: light, regular, solid, or duotone
  • skintone:
    • shade of UX widgets: light or dark
  • wallpaper:
    • which wallpaper to use

these are supported but their use is generally discouraged

  • allow_plaintext_rendering:
    • if true then the system allows the document to be viewed in plaintext when ?rx=text is appended to the page’s url
  • pagestyle:
    • work in progress; currently either default or prose
  • orient:
    • a layout hint that we are not yet using: tall, wide, or square
  • slug:
    • the slug of the document can be overridden

For paragraph metadata, like description: and excerpt:, the paragraph text can be broken across multiple lines:

  This is my long description that
  has been split across multiple lines.


Normally a markdown file includes horizontal rules by placing --- on a line by itself. We call this a hard break or a section break.

  • for most documents we show the section break as a shaded horizontal rule.
  • in eBooks we turn it into a page break

We’ve also introduced a soft break, which is typed as either ... or . . . on a line by itself. In standard markdown this has no special meaning, but in our system it is rendered as a glyph, which is a tiny image usually scaled down from the website’s logo:

Subtle: the metadata preamble, discussed above, is fenced using these same break markers. (This is standard YAML syntax.) However, neither the preamble nor its markers are included when a document is converted into HTML.


Markdown headings and sub-headings are made by starting a line of text with hash marks (#). The top level heading gets one hash mark, second level headings two hash marks, third get three, etc.

Our system uses the three highest-level headings, with no peers, in the first section of the document, as the document’s title0:, title1:, and byline: metadata properties respectively.

For example, consider a markdown document like this:

# This becomes title0

## This becomes title1

### This is rendered as a heading but NOT used as the byline...

### ...because multiple headings in this section are at the same level.

Various plain text here.


## This does not interfere with title1...

...because it comes after the section break.

Our system also renders HTML ids onto every heading, so that deep-linking into the document is possible. Each heading is identified with the slug equivalent of the heading’s text.

To continue our example, the second section of our document would be rendered into HTML as:

<h2 id="this_does_not_interfere_with_title1"></h2>

Style-wise, we render the first three heading levels as various sizes of centered text, and heading levels four or deeper as aligned with the left* edge.

* - we’re not good at i18n yet.



Styling Syntax

Markdown is an amazing invention of readable-everywhere-forever, but suffers in that it’s only semi-standardized. One large gap is that while the official markdown language specifies how a plain-text document should be rendered into HTML, it says nothing about how that HTML should be styled for display.

For example, most markdown renderers use single *-mark around text to mean italics and double **-marks around text to mean bold, but the popular communication app Slack is exactly backwards.

In addition, many system implementers have defined their own extensions onto the language; and in this regard Octoboxy is proudly no different.

Here we describe markdown syntax as rendered and styled by our system. We will do our best to call-out how this differs from other markdown styles you may encounter.

Note that, in general, a backslash (\) may escape any styling feature.

Inline Formatting

Inline text formatting is typed by bookending groups of words with simple symbols.

Our convention is this:

  • one * means italics
  • two ** means bold
  • three *** means bold-italics
  • one _ means underline
    • but middle_of_word underlining (such as filenames) should be unaffected
  • two ~~ means strikethrough
  • two == means highlight
  • one backtick ` means fixed-width typeface

Superscript and subscript can be typed as a single symbol followed by one or more words in parenthesis:

  • superscriptyou would use a ^
  • subscriptyou do with a ~

There is no part of markdown less standardized than inline formatting. We mentioned before that the Slack communication app reverses bold and italics. Many editors allow * and _ to be used fully interchangeably, but those editors also usually do not support underline. Some editors use parenthesis around superscript text, while others use a pair of carets, and most do not support subscript.

On the finest detail, some editors disallow bold or italics from starting inside quote marks but finishing outside. We took care to make sure this is supported in our system, because a pedantic author might insist that closing smart quotes render into the same font-style as the characters they abut, “like this.”

There is no way to standardize all this without upsetting someone. Please accept our apology for any problems caused by our style interpretations.

Typographic Characters

We convert many ascii character patterns into prettier unicode or HTML equivalents:

  • quotes: ‘single’, “double”, even «double-angle»
  • dashes: en–dash and em—dash
  • ellipsis: …
  • symbols: ™, ©, ®, ±, ≠
  • arrows: →, ←, ↔
  • fractions: ¼, ½, ¾, ⅓, ⅔, ⅕, ⅖, ⅗, ⅘, ⅙, ⅚, ⅛, ⅜, ⅝, ⅞
  • counts: 1st, 2nd, 3rd, 4th … 9th


Icons are useful replacements for highly recognizable words. Our system assigns an icon to every document. In addition, we allow you to insert icons inline into your text using double parenthesis syntax: ((icon-name)) You may also specify a color if desired – see the list of colors under Metadata Reference.

For example, a purple dragon would be: ((dragon purple)):

FontAwesome is our authority for icons.

All icons on a page get rendered in the same fontawesome style. You can use the page document’s iconset: metadata property to choose which style.

Hyperlinks may be generated in two ways:

  • implicitly by typing a full URL like
  • explicitly using [title](url) syntax

When typing an explicit link, the URL can be one of:

  • an absolute URL like
  • a relative URL* like /relative/path
  • the slug of another page**

* - be careful of relative paths that look like, and get interpreted as, slugs of pages.

** - Octoboxy extension

It’s highly recommended that you specify page links by slug rather than relative path: it’s less brittle, and we can do more, such as use the target page’s image or icon as part of the link.

Specifically, we have two slightly different syntaxes to link to page by slug:

  • standard-ish markdown
  • Octoboxy style flags
    • [[image gallery size0]](markdown_style_guide)
    • asks the system to make link with an image inside a “gallery” frame

Because no image is associated with this page, the system makes a square-shaped button out of the page's icon.

Our style flags are described under template syntax.


A markdown image is denoted using ![alt text](url) syntax, which differs from a page link only by the leading ! symbol.

Similar to links, we allow and encourage making image references via slug. Referencing images via absolute URL is also possible, but discouraged for mild ethical reasons.

With images, standard-ish markdown syntax renders the image in a small size with your custom alt text. Using Octoboxy double-square-brackets syntax again lets you specify specific custom style flags.

Template Syntax

Our markdown syntax for links and images is designed to be simple, but ultimately is not as expressive as what you may need. However, what we’re doing with markdown link and image syntax is transforming them into tags in Django template syntax. If the markdown abbreviations are insufficient for your needs, you may freely use the template syntax directly.

For example, the following two lines, both calling for an image, are equivalent:

  • ![[ gallery size0 zoom ]]( slug )

  • {% image images.slug 'gallery size0 zoom' %}

Similarly, linking to a page via [...](slug) becomes {% page pages.slug ... %} in template syntax.

Note that the template tag is NOT limited to resolving images or pages only by slug, but may render any asset that happens to be in the template context, such as face.logo:

  • {% image face.logo 'gallery size0 zoom' %}

The various flags accepted by these template tags are, unfortunately, under-documented at this time.

In brief:

For images you specify the frame style, the size, and “zoom” if you want a click-to-zoom-in behavior. Sizes range from size0 to size4, plus other options for special use cases. Frame style should be one of: gallery, padded, url (which emits the raw URL instead of a link), or some other rare options.

For page links you specify one of title, button, or image. If title or button you may specify noicon to omit the page’s icon. If image you may add any of the image style flags, described just above.

Image styling is slated for change in the next version of the system and this section will be filled with more detail once that work is done.

Block Formatting

Any block of text in a markdown file without other special indicators around it becomes a standard paragraph in HTML.

Line Breaks

A line break inside a paragraph,
per markdown spec,
is any line ending in two spaces,
such as these.

But some text editors auto-strip
terminal whitespace,
making that fragile.
So we also allow lines ending in backslash (\)
to receive a line break.

Combining these techniques  does not work  as it yields non-breaking spaces instead.

Blank Lines

You can backslash-escape a space (\<space>) to make it a non-breaking space, that is, HTML entity &nbsp;

This provides an easy way to add blank lines to a document, by simply escaping a space as a paragraph by itself:


Again, some text editors auto-strip trailing whitespace, so we also allow a period on a line by itself* to also mean blank line:


* - which does work with extra whitespace after it

Centering, Etc.

Octoboxy includes an extension to let you specify if a paragraph should be centered or aligned to an edge. Our syntax is short ASCII arrows on both ends of a paragraph, as follows:

<- justified ->

<- left-aligned <-

-> centered <-

-> right-aligned ->





Block Quotes

Block quotes are specified by prefixing one or more lines with an angle bracket (>):

  • When rendering for the web we put a semi-transparent pane behind your block of text.

    • When rendering for eBooks our style is: still being designed
  • Most language features can be embedded in a block quote. That is, you can use lists inside block quotes, block quotes inside block quotes, etc.

Special Case

Special Case: When you use headers inside a blockquote, we turn your 2nd-level headers (##) into a solid bar across the width of the pane.

Code Blocks

Code blocks are similar to block quotes in that they are rendered into a pane. They differ in that the text is rendered in a fixed-width typeface and assumed to be pre-formated – that is, linebreaks and extra whitespace are preserved.

You fence a code block with triple back ticks ``` around a block of text:

  This is a code block.

Many markdown editors allow an alternate style where text is merely indented with (usually 4) spaces to become a code block, something we have opted not to support. Also, some editors disable line wrap inside a code block. Our style choice is to line-wrap, as naïve users are often prone to not notice truncated text.


Simple tables are supported:

|   Cat   | Markings |
| Tiger   |  stripes |
| Cheetah |   spots  |

Renders (into a blockquote) as:

Cat Markings
Tiger stripes
Cheetah spots


Markdown allows all the flavors of HTML lists: bullet, number, and definition.

Bullet Lists

Bullet (unordered) lists may be typed with either * or - as a list bullet.

Sub-lists should be indented exactly two spaces. We would love to be more tolerant and allow at least two spaces instead of exactly two spaces, but this is hard-coded into the list-processing extension that we use and no good workaround has been found. Someday we’ll make our own list-processor, I’m sure.

For example:

- item a
  * sub-item
    - sub-sub-item
- item b
  * sub-item 1
  * sub-item 2\
    with extra text on the next line

Renders (into a blockquote) as:

  • item a
    • sub-item
      • sub-sub-item
  • item b
    • sub-item 1
    • sub-item 2
      with extra text on the next line

There are two rendering styles for lists, which differ by how much whitespace they leave around each item. You specify you want the expanded whitespace version by leaving blank lines in your list.

  • item a

    • sub-item
      • sub-sub-item
  • item b

    • sub-item 1
    • sub-item 2
      with extra text on the next line

There is a unicode bullet character () that can be easily typed on many platforms. For example, on a mac: ⌥8

• The bullet character may be used to make text that looks like a list without triggering an actual bulleted list block.

Number Lists

Number lists work intuitively, using a number, a period, and your text:

1. First list item
2. Second list item

A line of normal paragraph text.

3. Third list item\*
  - interleaved with a bullet list

Renders (into a blockquote) as:

  1. First list item
  2. Second list item

A line of normal paragraph text.

  1. Third list item*
    • interleaved with a bullet list

* - Many markdown editors label the third list item with “1” again, even though our text specifies “3.” Apparently that style choice originates with the creator of markdown?
Regardless, it’s the wrong decision, and this is right.
Because we say so.

Definition Lists

Definition lists do not allow nesting, so the syntax is simpler by comparison:

Term 1
: definition 1

Term 2
: definition 2a
: definition 2b

Renders (into a blockquote) as:

Term 1
definition 1
Term 2
definition 2a
definition 2b



Future Work: Card Files RightDown


“Card Files” as described here are now a real thing. Please see RightDown for info on the open-source library we’ve built. It’s a drop-in Markdown replacement that gives python programmers rich structured data as described here.

Warning: card files are in-progress work and subject to change.

As our system evolves, we imagine markdown files being used to define a graph of interrelated knowledge topics, which we call Cards. Towards this end, we suggest further constraining the first section of a markdown document to include very little prose.

A card file (carddown?) would be structured as follows:

orient: tall

# title0

## title1

### byline

field1: value1

: value2a
: value2b

- References
    - [named link](to_another_document)
    - yet_another_document_link_but_with_no_special_name



## section heading

actual prose or other content

Here a few things are different about the first section.

• First, the YAML preamble includes a new metadata tag called orient which specifies the visual orientation of the summary card about this document.

• Next, we’ve included two structured fields. The field1 line and field2 definition list represent data that should be parsed into separate attributes of the card and not treated like standard prose. These fields differ from the YAML preamble in that the structured fields are rendered into the page (YAML preamble is not), just with a higher level of visual design.

• Thirdly, there is a references block. This is an unordered list that consists of only slug-style links to other documents.

• Finally, the description metadata is extracted. Here we define description as all remaining text of the first section in the document, after titles, fields, and references have all been extracted.

Again, the card file specification is very much a work-in-progress and may change drastically before the card feature is generally available in our system.

Back to Octoboxy