An extended markdown parser written in pure rust
You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Go to file
trivernis 14862990f2
Add build-and-release task and rust-toolchain file
Signed-off-by: trivernis <>
3 years ago
.github/workflows Add build-and-release task and rust-toolchain file 3 years ago
images Add snekdown logo to README 3 years ago
src Fix warnings and update Readme 3 years ago
.gitignore Add automated parsing tests 4 years ago
Cargo.lock Update dependencies 3 years ago
Cargo.toml Update dependencies 3 years ago
LICENSE Create LICENSE 4 years ago Fix warnings and update Readme 3 years ago
rust-toolchain Add build-and-release task and rust-toolchain file 3 years ago

Snekdown - More than just Markdown

This projects goal is to implement a fast markdown parser with an extended syntax fitted for my needs.


You need a working rust installation, for example by using rustup.

cargo install snekdown

With pdf rendering

cargo install snekdown --features pdf


    snekdown [FLAGS] [OPTIONS] <input> <output> [SUBCOMMAND]

    -h, --help        Prints help information
        --no-cache    Don't use the cache
    -V, --version     Prints version information

    -f, --format <format>    the output format [default: html]

    <input>     Path to the input file
    <output>    Path for the output file

    help      Prints this message or the help of the given subcommand(s)
    render    Default. Parse and render the document
    watch     Watch the document and its imports and render on change



Simple Syntax

Extended syntax with a description

Extended syntax with metadata to specify the size

Extended syntax with metadata and no description

When generating the html file the images are base64 embedded. To turn off this behaviour set the config parameter embed-external to false.


Simple (default) Syntax
> This is a quote

> This is a 
> Multiline Quote

Quote with metadata (e.g. Author)
[author=Trivernis year=2020 display='{{author}} - {{year}}']> This is a quote with metadata


Imports can be used to import a different document to be attached to the main document. Imports are parsed via multithreading.




The parser differentiates four different types of imported files.

  • document - The default import which is just another snekdown document
  • stylesheet - CSS Stylesheets that are inclued when rendering
  • bibliography - A file including bibliography
  • config/manifest - A config file that contains metadata

If no type is provided the parser guesses the type of file from the extension.


Tables MUST start with a pipe character |

Standalone header:
| header | header | header

Header with rows
| header | header | header
| row    | row    | row


Placeholders can be used to insert special elements in a specific place. Placeholders are always case insensitive.

Insert the table of contents

Insert the current date

Insert the current time


Additional metadata can be provided for some elements.

String value
[key = value]

String value
[key = "String value"]

Integer value
[key = 123]

Float value
[key = 1.23]


[key = false]

[key = [[placeholder]]]

Metadata can also be defined in a separate toml file with simple key-value pairs. Example:

# bibliography.bib.toml
author = "Snek"
published = "2020"
test-key = ["test value", "test value 2"]

# those files won't get imported
ignored-imports = ["style.css"]        

# stylesheets that should be included
included-stylesheets = ["style2.css"] 

# other metadata files that should be included
included-configs = []

# bibliography that should be included
included-bibliography = ["mybib.toml"]

# glossary that sould be included      
included-glossary = ["myglossary.toml"]     

# if external sources (images, stylesheets, MathJax)
# should be embedded into the document (default: true)
embed-external = true

# If SmartArrows should be used (default: true)
smart-arrows = true

# Includes a MathJax script tag in the document to render MathML in chromium.
# (default: true)
include-math-jax = true

The [Section] keys are not relevant as the structure gets flattened before the values are read.


Hide a section (including subsections) in the TOC
#[toc-hidden] Section

Set the size of an image
!(url)[width = 42% height=auto]

Set the source of a quote
[author=Me date=[[date]] display="{{author}} - {{date}}"]> It's me

Set options for placeholders

Centered Text

|| These two lines
|| are centered


§[#0C0]Colored text§[] §[red] red §[]


Bibliography entries can be defined and referenced anywhere in the document.


[SD_BOOK]:[type=book, author=Snek, title = "Snekdown Book" date="20.08.2020", publisher=Snek]


There is a book about snekdown[^book] and a github repo[^github].

Entries can also be defined in a separate toml file with the following data layout:

# snekdown.toml
key = "value"

type = "book"
author = "Snek"
title = "Snekdown Book"
date = "20.08.2020"
publisher = "Snek"

type = "website"
url = ""

The valid types for entries and required fields can be found on in the bibliographix README.

Bibliography entries are not rendered. To render a list of used bibliography insert the bib placeholder at the place you want it to be rendered.


Glossary entries are to be defined in a glossary.toml file or any other toml file that is imported as type glossary. The definition of glossary entries has to follow the following structure

long = "Long Form"
description = "The description of the entry"

# Example
long = "Hypertext Markup Language"
description = "The markup language of the web"

Those glossary entries can be referenced in the snekdown file as follows:

~HTML is widely used for websites.
The format ~HTML is not considered a programming language by some definitions.


The first occurence of the glossary entry (~HTML) always uses the long form. The second will always be the short form. The long form can be enforced by using two (~~HTML) tildes.


Snekdown allows the embedding of AsciiMath: The AsciiMath parser is provided in the asciimath-rs crate

inline math $$ a^2 + b^2 = c^2 $$

Block Math
A = [[1, 2],[3,4]]

The expression get's converted into MathML which is then converted by MathJax when loaded in the browser.

Smart Arrows

Snekdown automatically renders the sequences -->, ==>, <--, <==, <-->, <==> as their respective unicode arrows (similar to markdown-it-smartarrows). This behavior can be turned off by setting the config parameter smart-arrows to false (the config needs to be imported before the arrows are used for that to work).


The end goal is to have a markup language with features similar to LaTeX.

  • Checkboxes
  • Emojis (:emoji:)
  • Colors
  • Watching and rendering on change
  • Metadata files
  • Bibliography
  • Math
  • Glossary
  • Chromium based pdf rendering
  • Custom Stylesheets
  • Smart arrows
  • Custom Elements via templates (50%)
  • Cross References
  • Figures
  • EPUB Rendering
  • Text sizes
  • Title pages