WHITESPACE = _{ (" " | "\t" | "\r") }
ANY_SPACE = _{ WHITESPACE | NEWLINE }
SHORTCODE_SIGIL = _{ "#" }
command_disallow = _{ !(SHORTCODE_SIGIL ~ ident) }
BASE_CHARS = _{ ASCII_ALPHANUMERIC | SYMBOL | NEWLINE | "-" | "/" | " " | "*" | "_" | "." | "," | "`" | ":" | ";" | "%" | "^" | "$" | "\\" | "(" | ")" | "\t" | "=" | "<" | ">" | "?" | "'" }
string = { (!"\\{" ~ !"\\}" ~ !"$" ~ BASE_CHARS)+ }
md_val = { (command | code_def | math_block | verbatim_def | string)* }
string_v = _{ ("\"" | "“") ~ string ~ ("\"" | "”") }
markdown_string = _{ "{" ~ md_val ~ "}" }
basic_val = { ASCII_ALPHANUMERIC ~ (ASCII_ALPHANUMERIC | WHITESPACE | "#" | " " | "-" | "/" | "*" | "_" | "." | ":" | ";" | "%" | "^" | "$" | "\\" | "<" | ">" | "{" | "}" | "?" | "'")* }
ident = { ASCII_ALPHANUMERIC ~ (ASCII_ALPHANUMERIC | "_" | "-" | ":")* }
key = { (ASCII_ALPHANUMERIC | "_" | "-")+ }
flag = { (ASCII_ALPHANUMERIC | "_" | "-")+ }
flag_def = _{ ":" ~ flag }
value = _{ basic_val | string_v | markdown_string | flag_def }
param = { (key ~ "=" ~ value) | value }
parameters = { "(" ~ ANY_SPACE* ~ param ~ ("," ~ ANY_SPACE* ~ param)* ~ ANY_SPACE* ~ ")" }
body = ${ "#" | (!"}" ~ !"\\{" ~ command_disallow ~ !"`" ~ !"$" ~ ANY)+ }
body_inner = _{ (code_def | math_block | command | verbatim_def | body)* }
body_def_tagged = _{ "{" ~ body_inner ~ "}" ~ (POP ~ SHORTCODE_SIGIL) }
body_def_untagged = _{ "{" ~ body_inner ~ "}" ~ DROP }
body_def = { body_def_tagged | body_def_untagged }
label_def = _{ "|" ~ label }
label = ${ ident }
command_name = ${ SHORTCODE_SIGIL ~ PUSH(ident) }
command = { command_name ~ !")" ~ label_def? ~ parameters? ~ (body_def | DROP) ~ !"(" ~ !")" }
math_block = { math_lvl ~ math_body ~ POP ~ label_def? }
math_body = { math }
math_lvl = { PUSH("$"+) }
math_chars = { (!PEEK ~ !"{" ~ !"}" ~ ("\\{" | "\\}" | ANY))+ }
math_block_curly = { "{" ~ math ~ "}" }
// math_block_bracket = { "[" ~ math ~ "]" }
// math_block_paren = { "(" ~ math ~ ")" }
math = _{ (math_chars | math_block_curly)* }
verbatim_def = _{ "\\{" ~ verbatim ~ "\\}" }
code_param = { (key ~ "=" ~ basic_val) | basic_val }
code_def = { code_lvl ~ code_params? ~ code ~ POP ~ label_def? }
code_params = !{ code_param ~ ("," ~ code_param)* ~ NEWLINE }
code_lvl = { PUSH("`"+) }
code = { (!PEEK ~ ANY)+ }
verbatim = { (!"\\}" ~ ANY)+ }
src = ${ ("#"+ ~ WHITESPACE) | "#" | (command_disallow ~ !"$" ~ !"`" ~ !"\\{" ~ !"\\}" ~ ANY)+ }
element = _{ math_block | code_def | verbatim_def | command | src }
meta = { (!(NEWLINE ~ "---") ~ ANY)* }
meta_def = _{ ("---" ~ NEWLINE) ~ meta ~ (NEWLINE ~ "---") }
doc = ${ meta_def? ~ element* }
top = _{ doc ~ EOI }