--- /dev/null
+start\r
+ =\r
+ expression\r
+ $\r
+ ;\r
+\r
+expression\r
+ =\r
+ { !matching_expression CHAR }* &matching_expression\r
+ ;\r
+\r
+matching_expression\r
+ =\r
+ raw_block_expression | block_expression | variable_expression | comment_expression\r
+ ;\r
+\r
+raw_block_expression\r
+ =\r
+ "{% raw %}"\r
+ { !raw_block_end CHAR }*\r
+ raw_block_end\r
+ ;\r
+\r
+raw_block_end\r
+ =\r
+ "{% endraw %}"\r
+ ;\r
+\r
+block_expression\r
+ =\r
+ block_start {SP}* expression {SP}* block_end\r
+ #| block_start\r
+ ;\r
+\r
+block_start\r
+ =\r
+ block_open !("end") IDENTIFIER {block_parameter}* block_close\r
+ ;\r
+\r
+block_end\r
+ =\r
+ block_open "end" IDENTIFIER block_close\r
+ ;\r
+\r
+block_open\r
+ =\r
+ @:"{%" {SP}*\r
+ ;\r
+block_close\r
+ =\r
+ {SP}* @:"%}"\r
+ ;\r
+\r
+block_parameter\r
+ =\r
+ {SP}+ @:(IDENTIFIER "=" block_parameter_value)\r
+ | {SP}+ @:block_parameter_value\r
+ ;\r
+block_parameter_value\r
+ =\r
+ {ALPHA}+\r
+ ;\r
+\r
+variable_expression\r
+ =\r
+ variable_open IDENTIFIER { !variable_close variable_filter }* variable_close\r
+ ;\r
+variable_open\r
+ =\r
+ @:"{{" {SP}*\r
+ ;\r
+variable_close\r
+ =\r
+ {SP}* @:"}}"\r
+ ;\r
+\r
+variable_filter\r
+ =\r
+ {SP}* "|" {SP}* @:filter\r
+ ;\r
+filter = @+:IDENTIFIER [@+:filter_parameters];\r
+filter_parameters = "(" [@+:filter_parameter {"," {SP}* @+:filter_parameter}*] ")";\r
+filter_parameter = {CHAR}* ;\r
+\r
+comment_expression = comment_open comment comment_close ;\r
+comment_open = "{#" ;\r
+comment_close = "#}" ;\r
+comment = {!comment_close CHAR}* ;\r
+\r
+content = {CHAR}* ;\r
+\r
+IDENTIFIER\r
+ =\r
+ /[a-zA-Z]+/\r
+ ;\r
+\r
+ALPHA\r
+ =\r
+ /[a-zA-Z]/\r
+ ;\r
+\r
+DIGIT\r
+ =\r
+ /[0-9]/\r
+ ;\r
+\r
+SP\r
+ =\r
+ /\s/\r
+ ;\r
+\r
+CHAR\r
+ =\r
+ ?'.' | ?'\s'\r
+ ;
\ No newline at end of file
--- /dev/null
+from tatsu.util import asjson\r
+import json\r
+import tatsu\r
+\r
+\r
+with open('tatsu_grammar.txt', 'r') as tatsu_grammar:\r
+ with open('test_template.jinja', 'r') as test_template:\r
+ ast = tatsu.parse(tatsu_grammar.read(), test_template.read(), whitespace='')\r
+\r
+ print(json.dumps(asjson(ast), indent=4))
\ No newline at end of file
--- /dev/null
+{%block single key=val param=value %}\r
+test {{var}}\r
+{%endblock%}\r
+{# comment contents\r
+across lines #}\r
+{% raw %}\r
+{% block %}fake content{{ fake vars }}\r
+{% endraw %}
\ No newline at end of file