murkdown 0.1.1

An experimental semantic markup language and static site generator for composing and decomposing hypertext documents
Documentation
// Roots
RootA            =  { SOI ~ RootHeader? ~ RootBlock*  ~ EOI }
RootB            =  { SOI ~ RootHeader? ~ RootBlockB* ~ EOI } // variant b supports four-space root block

// Blocks
Control         = _{ &(BLOCK_START ~ (ShortBlock_ | LongBlocks_)) ~ Block }
ControlB        = _{                                                Block }
Content         = _{ ("\\" ~ &STOP | !STOP) ~ (Ellipsis | Line) ~ NEWLINE | (EllipsisEOI | LineEOI) }

Block           =  {
                     (BLOCK_START_B     ~ !(NEWLINE | EOI) ~ (ShortBlock_ | LongBlocksB_)) |
                     (PUSH(BLOCK_START) ~ !(NEWLINE | EOI) ~ (ShortBlock_ | LongBlocks_) ~ DROP)
                   }

LongBlocks_     = _{ (BlockHeader ~ (NEWLINE | EOI) ~ CONTROL_INDENT?)? ~ LongBlock? ~ (CONTROL_INDENT ~ LongBlock )* }
LongBlocksB_    = _{ (BlockHeader ~ (NEWLINE | EOI) ~ "   "          )? ~ LongBlockB ~ ("   "          ~ LongBlockB)* }
ShortBlock_     = _{  BlockHeader                                       ~ ShortBlock }

RootBlock       =  { (        SectHeader | Control  |         Content) ~ (CONTROL_INDENT ~ Control  | CONTENT_INDENT ~ Content)* }
RootBlockB      =  { (        SectHeader | ControlB |         Content) ~ (CONTROL_INDENT ~ ControlB | CONTENT_INDENT ~ Content)* }
LongBlock       =  { (SPACE ~ SectHeader | Control  | SPACE ~ Content) ~ (CONTROL_INDENT ~ Control  | CONTENT_INDENT ~ Content)* }
LongBlockB      =  { (SPACE ~ SectHeader |            SPACE ~ Content) ~ (                            "   " ~ SPACE  ~ Content)* }
ShortBlock      =  { (                                SPACE ~ Content) }

Line            =  { ANY_LETTER* }
LineEOI         =  { ANY_LETTER+ ~ &EOI }
Ellipsis        =  { "..." }
EllipsisEOI     =  { "..." ~ &EOI }

BlockHeader     = _{ SPACE ~ BlockHeader_ }
RootHeader      = _{ BlockHeader_ ~ (NEWLINE | &EOI) }
SectHeader      = _{ SectHeader_ ~ NEWLINE }
BlockHeader_    = _{ "[!" ~ BLOCK_HEADER ~ "]" ~ ("("  ~ BLOCK_PROPS ~ ")")? }
SectHeader_     = _{ "[~" ~ SECT_HEADER  ~ "]" ~ ("("  ~ BLOCK_PROPS ~ ")")? }

BLOCK_START     =  { "|" | ">" | "*" | "+" | "-" | "#" }
BLOCK_START_B   =  { "   " }
BLOCK_HEADER    =  { (!"]"          ~ ANY_LETTER)* }
SECT_HEADER     =  { (!"]"          ~ ANY_LETTER)* }
BLOCK_PROPS     =  { ("\\)"  | !")" ~ ANY_LETTER)* }
BLOCK_INDENT    = _{ PEEK[..-1] ~ &BLOCK_START ~ PEEK }  // prefix for block control
CONTROL_INDENT  = _{ BLOCK_INDENT          | NO_INDENT } // prefix for block control or root control
CONTENT_INDENT  = _{ BLOCK_INDENT ~ SPACE? | NO_INDENT } // prefix for block content or root content
NO_INDENT       = _{ &PEEK_ALL ~ "" }
STOP            = _{ SectHeader }

ANY_LETTER      = _{ LETTER | NUMBER | MARK | PUNCTUATION | SYMBOL | SEPARATOR }
SPACE           = _{ " " | "\t" }

// Block props
BlockProps      = _{ Attribute* }
Attribute       =  { WHITE_SPACE* ~ Key ~ WHITE_SPACE* ~ "=" ~ WHITE_SPACE* ~ Value_ ~ WHITE_SPACE* }
Value_          = _{ PUSH("\"") ~ Value ~ POP }
Key             =  { ("\\="  | !("=" | WHITE_SPACE) ~ ANY_LETTER)* }
Value           =  { ("\\\"" | !"\"" ~ ANY_LETTER)* }

// Misc
Pointer         = _{ "dummy" }
Paragraph       = _{ "dummy" }
Section         = _{ "dummy" }