view = _{ SOI ~ tag ~ EOI }
identifier = _{ ('a'..'z' | 'A'..'Z' | '0'..'9' | "_" | "-")+ }
tag_name = @{ identifier }
tag = { single_tag | pair_tag }
pair_tag = _{ open_tag ~ children ~ close_tag }
single_tag = _{ "<" ~ tag_name ~ attributes ~ "/" ~ ">" }
children = {(tag | embedded_outer | text)*}
open_tag = _{ "<" ~ tag_name ~ attributes ~ ">" }
close_tag = _{ "<" ~ "/" ~ (!">" ~ ANY)+ ~ ">" }
attributes = { attribute* }
attribute = _{ key ~ "=" ~ (string_literal | bool | embedded_outer) }
key = @{ identifier }
string_literal = _{ "\"" ~ string ~ "\"" }
string = @{ (!"\"" ~ ANY)* }
embedded_outer = _{ "{" ~ embedded ~ "}" }
embedded = { (bracketed | (!"}" ~ ANY))* }
bracketed = _{ "{" ~ bracketed_inner ~ "}" }
bracketed_inner = _{ (bracketed | (!"}" ~ ANY))* }
bool = { "true" | "false" }
text = @{ (!("<" | "{") ~ ANY)+ }
newline = _{ "\n" | "\r\n" }
WHITESPACE = _{ " " | newline }