mini_template 0.1.1

Small template engine with smarty like syntax
Documentation
WHITESPACE = _{" "|"\n"}
modifier = {"|" ~ identifier ~ argument*}
argument = { ":" ~ value }
calculated = {!"\\" ~ "{" ~ calculated_value ~ "}"}
calculated_value = { value ~ modifier* }
identifier = @{!(key_words) ~ 'a'..'z' ~ ('A'..'Z'|'a'..'z'|'0'..'9'|"_")*}
text = {(!"{" ~ ("\\{" | ANY))+}

assign = !{"{" ~ identifier ~ "=" ~ calculated_value ~ "}"}

// Template
template = {SOI ~ template_content ~ EOI}
template_content = ${ (while_loop|assign|calculated|text|conditional)* }

// Values
string = { "\"" ~ inner_string ~ "\"" }
inner_string = {(!"\"" ~ ( "\\\""| ANY))*}
number = { ("+"|"-")? ~ ASCII_DIGIT+ ~ ("." ~ ASCII_DIGIT+)? }
boolean = {true_key_word|false_key_word}
value = { boolean|identifier|number|string }

// Blocks
conditional = !{ 
    "{" ~ if_key_word ~ condition ~ "}" ~
        template_content ~
    (
        "{" ~ else_key_word ~ "}" ~
            template_content
    )? ~
    "{" ~ endif_key_word ~ "}" ~ "\n"?
}

while_loop = !{ 
    "{" ~ while_key_word ~ condition ~ "}" ~
        template_content ~
    "{" ~ endwhile_key_word ~ "}" ~ "\n"?
}

// Condition
condition = {
    (
        ("(" ~ condition ~ ")") | 
        compare_condition | 
        calculated_value
    )~ 
    (
        (and_operator|or_operator) ~ 
        (compare_condition | calculated_value | condition)
    )*
}

compare_condition = { calculated_value ~ compare_operator ~ calculated_value }

compare_operator = { 
    eq_operator|
    ne_operator|
    lt_operator|
    le_operator|
    gt_operator|
    ge_operator
}
eq_operator = { "==" }
ne_operator = { "!=" }
lt_operator = { "<" }
le_operator = { "<=" }
gt_operator = { ">" }
ge_operator = { ">=" }

and_operator = {"&&"}
or_operator = {"||"}

// Keywords
if_key_word = _{"if"}
else_key_word = _{"else"}
endif_key_word = _{"endif"}
while_key_word = _{"while"}
endwhile_key_word = _{"endwhile"}
true_key_word = _{"true"}
false_key_word = _{"false"}
key_words = { if_key_word | else_key_word | endif_key_word | true_key_word | false_key_word | while_key_word | endwhile_key_word }