| whitespace = _{ " "|"\t"|"\n"|"\r" } |
| keywords = @{ "as" | "else" } |
| |
| escape = @{ ("\\" ~ "{{" ~ "{{"?) | ("\\" ~ "\\"+ ~ &"{{") } |
| raw_text = ${ ( escape | (!"{{" ~ any) )+ } |
| raw_block_text = ${ ( escape | (!"{{{{" ~ any) )* } |
| |
| literal = { string_literal | |
| array_literal | |
| object_literal | |
| number_literal | |
| null_literal | |
| boolean_literal } |
| |
| null_literal = { "null" } |
| boolean_literal = { "true"|"false" } |
| number_literal = @{ "-"? ~ '0'..'9'+ ~ "."? ~ '0'..'9'* |
| ~ ("E" ~ "-"? ~ '0'..'9'+)? } |
| string_literal = @{ "\"" ~ (!"\"" ~ ("\\\"" | any))* ~ "\"" } |
| array_literal = { "[" ~ literal? ~ ("," ~ literal)* ~ "]" } |
| object_literal = { "{" ~ (string_literal ~ ":" ~ literal)? |
| ~ ("," ~ string_literal ~ ":" ~ literal)* ~ "}" } |
| |
| symbol_char = _{'a'..'z'|'A'..'Z'|'0'..'9'|"@"|"-"|"_"|'\u{80}'..'\u{7ff}'|'\u{800}'..'\u{ffff}'|'\u{10000}'..'\u{10ffff}'} |
| path_char = _{ "/" } |
| |
| identifier = @{ symbol_char+ } |
| reference = @{ "@"? ~ path_inline } |
| name = _{ subexpression | reference } |
| |
| param = { !(keywords ~ !symbol_char) ~ (literal | reference | subexpression) } |
| hash = { identifier ~ "=" ~ param } |
| block_param = { "as" ~ "|" ~ identifier ~ identifier? ~ "|"} |
| exp_line = _{ identifier ~ (hash|param)* ~ block_param?} |
| partial_exp_line = _{ name ~ (hash|param)* } |
| |
| subexpression = { "(" ~ name ~ (hash|param)* ~ ")" } |
| |
| pre_whitespace_omitter = { "~" } |
| pro_whitespace_omitter = { "~" } |
| |
| expression = { !invert_tag ~ "{{" ~ pre_whitespace_omitter? ~ name ~ |
| pro_whitespace_omitter? ~ "}}" } |
| |
| html_expression = { "{{{" ~ pre_whitespace_omitter? ~ name ~ |
| pro_whitespace_omitter? ~ "}}}" } |
| |
| helper_expression = { !invert_tag ~ "{{" ~ pre_whitespace_omitter? ~ exp_line ~ |
| pro_whitespace_omitter? ~ "}}" } |
| |
| directive_expression = { "{{" ~ pre_whitespace_omitter? ~ "*" ~ exp_line ~ |
| pro_whitespace_omitter? ~ "}}" } |
| partial_expression = { "{{" ~ pre_whitespace_omitter? ~ ">" ~ partial_exp_line |
| ~ pro_whitespace_omitter? ~ "}}" } |
| invert_tag_item = { "else"|"^" } |
| invert_tag = { !escape ~ "{{" ~ pre_whitespace_omitter? ~ invert_tag_item |
| ~ pro_whitespace_omitter? ~ "}}"} |
| helper_block_start = { "{{" ~ pre_whitespace_omitter? ~ "#" ~ exp_line ~ |
| pro_whitespace_omitter? ~ "}}" } |
| helper_block_end = { "{{" ~ pre_whitespace_omitter? ~ "/" ~ name ~ |
| pro_whitespace_omitter? ~ "}}" } |
| helper_block = _{ helper_block_start ~ template ~ |
| (invert_tag ~ template)? ~ helper_block_end } |
| |
| directive_block_start = { "{{" ~ pre_whitespace_omitter? ~ "#" ~ "*" |
| ~ exp_line ~ pro_whitespace_omitter? ~ "}}" } |
| directive_block_end = { "{{" ~ pre_whitespace_omitter? ~ "/" ~ name ~ |
| pro_whitespace_omitter? ~ "}}" } |
| directive_block = _{ directive_block_start ~ template ~ |
| directive_block_end } |
| |
| partial_block_start = { "{{" ~ pre_whitespace_omitter? ~ "#" ~ ">" |
| ~ partial_exp_line ~ pro_whitespace_omitter? ~ "}}" } |
| partial_block_end = { "{{" ~ pre_whitespace_omitter? ~ "/" ~ name ~ |
| pro_whitespace_omitter? ~ "}}" } |
| partial_block = _{ partial_block_start ~ template ~ partial_block_end } |
| |
| raw_block_start = { "{{{{" ~ pre_whitespace_omitter? ~ exp_line ~ |
| pro_whitespace_omitter? ~ "}}}}" } |
| raw_block_end = { "{{{{" ~ pre_whitespace_omitter? ~ "/" ~ name ~ |
| pro_whitespace_omitter? ~ "}}}}" } |
| raw_block = _{ raw_block_start ~ raw_block_text ~ raw_block_end } |
| |
| hbs_comment = { "{{!--" ~ (!"--}}" ~ any)* ~ "--}}" } |
| hbs_comment_compact = { "{{!" ~ (!"}}" ~ any)* ~ "}}" } |
| |
| template = { ( |
| raw_text | |
| expression | |
| html_expression | |
| helper_expression | |
| helper_block | |
| raw_block | |
| hbs_comment | |
| hbs_comment_compact | |
| directive_expression | |
| directive_block | |
| partial_expression | |
| partial_block )* } |
| |
| parameter = _{ param ~ eoi } |
| handlebars = _{ template ~ eoi } |
| |
| // json path visitor |
| // Disallowed chars: Whitespace ! " # % & ' ( ) * + , . / ; < = > @ [ \ ] ^ ` { | } ~ |
| |
| path_id = { symbol_char+ } |
| |
| path_raw_id = { (!"]" ~ any)* } |
| path_sep = _{ "/" | "." } |
| path_up = { ".." } |
| path_key = _{ "[" ~ path_raw_id ~ "]" } |
| path_item = _{ path_up|path_id|path_current|path_key } |
| path_current = { "this" | "." } |
| |
| path_inline = _{ path_item ~ (path_sep ~ path_item)* } |
| path = _{ path_inline ~ eoi } |