markdoll spec
this content of this page is an automatic transclusion from the specification on codeberg
this rest of this page is rendered using this site's custom variants of tags click here to see what this page looks like with markdoll's original standard library
the site's CSS applies always, so this will look different than a plain html render
this is markdoll
markdoll is an extensible markup language written in rust, made: by dolls, for dolls
how is it different from other markup languages?
like HTML, markdoll is a tree shaped system. for example, headers always precede sections, which have a defined ending point, an explicit hierarchy, rather than an implicit one
specification
whitespace
in markdoll, tab characters are significant, they help define sections and lists, and provide a boundary for block-content tags
markdoll specifically does not assign importance to spaces, but does prohibit them in certain cases
newlines are also very signficant:
- unless the last character of the line is a backslash (
\), splitting text by a newline instead inserts a space - separating text/tags by an empty line splits it into two paragraphs
- separating list elements by an empty line splits it into two lists
do note that all .doll files must be LF, CR characters will cause a fatal parsing error
tags
markdoll has a concept of "tags", which have a keyword and may choose to have arguments and content
tags can be written multiple ways:
| kind | syntax | result |
|---|---|---|
| no-arg & no-content | #txt · 1 lines | invokes sometag, does not provide an argument or any content |
| arg & no-content | #txt · 1 lines | invokes sometag, providing the argument text, but no content |
| no-arg & content | #txt · 4 lines
| invokes sometag, does not provide an argument, but provides content* |
| arg & content | #txt · 4 lines
| invokes sometag, providing an argument and content* |
[block-tags ^1 ^2]:
block tags allow far more flexibility in the content of tags, being able to put anything inside of them, without markdoll interpreting it whatsoever, leaving that to that tag (including escape sequences!)
however, this requires that the content is indented one level further than the tag, to let the parser know what is and is not part of the content
escape sequences
most parts of markdoll support escape sequences with the backslash character (
\)for example:
[em:\]]results in: ][em:\\]results in: \
inline tags do not need to escape balanced square brackets, however
[em:]]is unbalanced and will end early[em:[]]is balanced and will not end early
block tags completely ignore escaping/balancing, their content is fed as-is into the tag, after the indentation of the tag + 1 has been stripped. they dont have to care about escaping/balancing because the only way to terminate them is to lower the indentation again, which isnt something that could be escaped
lists
unordered and ordered lists are also easy:
| kind | syntax | result |
|---|---|---|
| unordered | #txt · 5 lines
|
|
| ordered | #txt · 5 lines
|
|
sections
a section is preceded by a heading, and its content is indented 1 level higher
| syntax | result |
|---|---|
#txt · 5 lines
| helloworldcontent goes here |
when emitting to HTML, it is not recommended to have more than one top-level section, as multiple h1 elements causes accessibility issues
frontmatter
markdoll differentiates between parsing as a document and everything else:
- each tag parses its content as embedded markdoll source via
parse_embedded, so frontmatter would not be parsed in these situations - but when parsing a main document via
parse_document, frontmatter is permitted.
frontmatter works almost identically to the way it does in many other markup languages, with an optional section at the very beginning of a file that is fenced with
---:#txt · 5 lines
---whatever---normal content goes here
extensibility
markdoll and its standard library emits HTML by default, but it doesn't have to!
markdoll does not load any tags automatically, all of them must be manually inserted. the standard library all supports HTML by default, and can be extended with other targets
standard extensions
the standard library is in the
markdoll::ext modulecommon
in module
markdoll::ext::common| tag | description | syntax | result |
|---|---|---|---|
// | the comment tag is very simple, its content is not parsed and is excluded from the output | #txt · 1 lines |
formatting
in module
markdoll::ext::formatting| tag | description | syntax | result |
|---|---|---|---|
em | apply one or more forms of emphasis to the content flags:
| #txt · 1 lines | italics |
#txt · 1 lines | italics (explicit) | ||
#txt · 1 lines | bold | ||
#txt · 1 lines | underline | ||
#txt · 1 lines | |||
#txt · 1 lines | highlight | ||
#txt · 1 lines | quote | ||
#txt · 1 lines | everything | ||
quote | block quotes an optional cite argument may be provided | #txt · 3 lines
| block quotes can contain markdoll |
#txt · 3 lines
| citation goes hereblock quotes can contain markdoll |
code
in module
markdoll::ext::code| tag | description | syntax | result |
|---|---|---|---|
code | inline code blocks | #txt · 1 lines | whatever code goes here, it is not [parsed] |
codeblock | multi-line code blocks | #txt · 3 lines
| #txt · 1 lines |
links
in module
markdoll::ext::links| tag | description | syntax | result |
|---|---|---|---|
link | link to content | #txt · 1 lines | markdoll |
img | insert images | #txt · 3 lines
| ![]() |
anchor | invisible anchors to be used with the ref tag (ideal for section heads) | #txt · 1 lines | |
def | in-page anchors to be used with the ref tag | #txt · 1 lines | [def-tag]: some definition |
ref | link to an anchor defined by the def tag | #txt · 1 lines | this is a reference** |
table
in module
markdoll::ext::table| tag | description | syntax | result | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
table | tables tables have two syntaxes (that can be mix-matched, even within eachother):
| #txt · 13 lines
|
| |||||||||
#txt · 19 lines
|
| |||||||||||
tr | create table rows inside tables pass the head flag to insert it into the head section | #txt · 5 lines
|
| |||||||||
#txt · 8 lines
|
| |||||||||||
tc | create table cells inside table rows pass the head flag to make it a head cellset the rows/cols props to make cells that span multiple rows/columns | #txt · 5 lines
|
| |||||||||
#txt · 5 lines
|
| |||||||||||
#txt · 9 lines
|
| |||||||||||
#txt · 9 lines
|
| |||||||||||
danger zone
by enabling the crate feature
danger, the ext::danger module becomes available for use, and is automatically loaded into the default binarythis contains potentially dangerous tags, proceed with caution
| tag | description | syntax |
|---|---|---|
invoke | invoke an external command, passing arguments as cli args, content as stdin, dumping stdout into the output stream | #txt · 1 lines test.sh sees the flip argument and returns a version of stdin with all the letters flipped around |
| created: | |
|---|---|
| updated: | |
| built: |
