cdoc-parser 0.1.1

A markdown-based document parser with custom syntax
Documentation
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 }