• reports errors when encountering syntax errors (so does not continue like regular Markdown);

  • supports attributes with {attr} syntax, multiple attributes delimited with ; (semi-colon). These attributes can be:

    • CSS classes with: .class

    • CSS properties with: key: value

    • HTML tag attributes with: key=value

    • HTML ids with: #id

  • span with [content], div with [[ \n content \n ]] \n. If a [[ has an additional enter after, paragraphs will be inserted in the content;

  • mark: ==content== becomes content, and abbr: =content= becomes content;

  • superscript with x^^[2] (x2), and subscript with CO~~[2] (CO2);

  • icons with :faX-hexagon: (with X: s becomes , r becomes , l becomes , d becomes );

  • as-is copy to output with [[[[as-is-content]]]];

  • bold/italic/marks/abbr in the middle of a word with foo\ *bar* (foobar) or some\ **thing**\ else (somethingelse). This helps to generate proper error messages.

  • no tables as of yet;

  • regular Markdown constructs like `code` for code, $`\frac{1}{n}`$ for math/LaTeX 1n (or ```math \n \frac{1}{n} \n ``` for display mode), **text** for bold, *text* for italic.

Processing additions

The markdowny library has some additional processing abilities, that can come in useful.

Figures and listings can be handled. Figures are wrapped in a blockquote (so the >>> toggle or the > prefix). If the first line starts with a description line, that blockquote is converted to a figure. The description line has as format listing #some_key: description. The reference key is some_key, the first word is the figure type (so figure, listing, etc). The caption can be either a new paragraph, or exists after the span seperated wih a :. Some examples are in 1, 2, and 3. Auto number links with [?](#reference_key).

Some contents.

listing 1 figure example.
> listing #markdowntexttemplate: example caption.
> some contents
listing 2 figure example.
listing #markdowntexttemplate2: some description.

==[](markdowntexttemplate2)== example caption (note the contents of the mark is not rendered as link inside this blockquote, but as regular text).

some contents
listing 3 another figure example.

Code listings and math formulas are rendered directly with highlight.js and KaTeX, so these libraries do not need to be included in the resulting HTML page. This will improve the viewing experience, as pages load faster. There is also a special latex2svg code listing. This converts LaTeX snippets (such as figures) to SVGs, which are included in the output. Preamble commands can be added before an optional --- line in the code listing.


The md2h utility also supports Bit Powder text templates. Variables can be declared at top of an input file with key: json-value pairs. The templates supports:

  • values with \{{value}};

  • iterators and conditional with \{{#value}}contents\{{/}}. Contents is displayed (if this default form is used) if value is an object, array of objects, or true. An iteration variable can be specified with \{{#name -> variable}}content\{{/}}, which can be used to iterate over (arrays of) any type. Iterators can have optional default values (in object) with \{{#name <- object}}content\{{/}} (these object defaults are evaluated once during parsing of the file and can reference global variables);

  • template definition with \{{=name}}content\{{/}}. Templates can have optional default values (in object) with \{{=name <- object}}content\{{/}};

  • template instantation with \{{>name}} or \{{name <- value}};

  • Error handling is different from normal Mustache: missing fields is always considered an error. Errors can be suppressed with the expr ??? alternative try syntax (on error in expr, alternative will be executed). Shorthand for expr ??? null is expr ??? (which can be used in loops with \{{#someField???}}, which ignores errors if the field is not found).

Binary Object expressions can be used instead of values as above (think of expressions, functional calls, selectors, etc). This utility supports also Lua in the templates. Prefix anywhere a value is accepted with lua: to run Lua code (with current value in this).

There are a couple of special functions added to the Binary Object expressions:

  • string compile(string template, [any context])
    Compiles a string to a dynamic Mustache template that can be evaluated, and evaluates the defaults using the optional context context (otherwise empty context is used).

  • string eval(string compiled_template, any context)
    Evaluates a dynamic Mustache template using the context context.

  • void set(string key, any value)

  • any get(string key)
    Sets/retrieves a global value (useful for figure numbers etc).

  • string filehash(string path)

  • string filewithhash(string path)
    Calculates the xxhash32 for the contents of the file specified by path (relative to the --base flag). Useful to support caching with a long TTL: setting the hash as query makes the URL unique for the content (if the content changes). The function call filewithhash(path) prints path?hash.

{{=cardfeature <- {fillHeight: true, dark: false, photoHideBreakpoint: "md"}}}
[[{.card\{{#!dark}}; .light{{/}}}
  {{eval(body, this)}}

{{cardfeature <- {
  dark: true,
  icon: "calendar-star",
  title: "Upcoming",
  body: compile(|
    On **Tuesday 1 December** from **16:00 - 17:30**, *X* will present her recently published book 'XYZ'.
  buttonLeft: {icon: "sign-in", name: "join", href: "http://"},
  buttonRight: {icon: "calendar", name: "calendar feed", href: "http://"}
listing 4 example combining markdown with text templates.