|
@@ -1,129 +1,153 @@
|
|
|
-module(erlydtl_unparser).
|
|
|
--export([unparse/1]).
|
|
|
+-export([unparse/1, unparse/2]).
|
|
|
+
|
|
|
+unparse(DjangoParseTree, undefined) ->
|
|
|
+ unparse(DjangoParseTree);
|
|
|
+unparse(DjangoParseTree, true) ->
|
|
|
+ Text = unparse(DjangoParseTree),
|
|
|
+ Trimmed = re:replace(Text, <<"(^\\s+)|(\\s+$)|\n">>, <<"">>, [global, multiline]),
|
|
|
+ Joined = join_iolist(Trimmed, " "),
|
|
|
+ binary_to_list(iolist_to_binary(Joined)).
|
|
|
+
|
|
|
+join_iolist(IOList, Sep) ->
|
|
|
+ join_iolist(IOList, Sep, []).
|
|
|
+
|
|
|
+join_iolist([[]|IOList], Sep, Acc) ->
|
|
|
+ join_iolist(IOList, Sep, Acc);
|
|
|
+join_iolist([Data|IOList], Sep, Acc) ->
|
|
|
+ join_iolist(IOList, Sep, [Sep, Data|Acc]);
|
|
|
+join_iolist([], _, [_|Acc]) ->
|
|
|
+ lists:reverse(Acc);
|
|
|
+join_iolist(IOList, _, Acc) ->
|
|
|
+ lists:reverse([IOList|Acc]).
|
|
|
+
|
|
|
|
|
|
unparse(DjangoParseTree) ->
|
|
|
- unparse(DjangoParseTree, []).
|
|
|
+ do_unparse(DjangoParseTree).
|
|
|
+
|
|
|
+do_unparse(DjangoParseTree) ->
|
|
|
+ do_unparse(DjangoParseTree, []).
|
|
|
|
|
|
-unparse([], Acc) ->
|
|
|
+do_unparse([], Acc) ->
|
|
|
lists:flatten(lists:reverse(Acc));
|
|
|
-unparse([{'extends', Value}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% extends ", unparse_value(Value), " %}"]|Acc]);
|
|
|
-unparse([{'autoescape', OnOrOff, Contents}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% autoescape ", unparse_identifier(OnOrOff), " %}", unparse(Contents), "{% endautoescape %}"]|Acc]);
|
|
|
-unparse([{'block', Identifier, Contents}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% block ", unparse_identifier(Identifier), " %}", unparse(Contents), "{% endblock %}"]|Acc]);
|
|
|
-unparse([{'blocktrans', Args, Contents, undefined}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% blocktrans ", unparse_blocktrans_args(Args), " %}", unparse(Contents), "{% endblocktrans %}"]|Acc]);
|
|
|
-unparse([{'blocktrans', Args, Contents, PluralContents}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% blocktrans ", unparse_blocktrans_args(Args), " %}",
|
|
|
- unparse(Contents),
|
|
|
+do_unparse([{'extends', Value}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% extends ", unparse_value(Value), " %}"]|Acc]);
|
|
|
+do_unparse([{'autoescape', OnOrOff, Contents}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% autoescape ", unparse_identifier(OnOrOff), " %}", do_unparse(Contents), "{% endautoescape %}"]|Acc]);
|
|
|
+do_unparse([{'block', Identifier, Contents}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% block ", unparse_identifier(Identifier), " %}", do_unparse(Contents), "{% endblock %}"]|Acc]);
|
|
|
+do_unparse([{'blocktrans', Args, Contents, undefined}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% blocktrans ", unparse_blocktrans_args(Args), " %}", do_unparse(Contents), "{% endblocktrans %}"]|Acc]);
|
|
|
+do_unparse([{'blocktrans', Args, Contents, PluralContents}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% blocktrans ", unparse_blocktrans_args(Args), " %}",
|
|
|
+ do_unparse(Contents),
|
|
|
"{% plural %}",
|
|
|
- unparse(PluralContents),
|
|
|
+ do_unparse(PluralContents),
|
|
|
"{% endblocktrans %}"]|Acc]);
|
|
|
-unparse([{'call', Identifier}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% call ", unparse_identifier(Identifier), " %}"]|Acc]);
|
|
|
-unparse([{'call', Identifier, With}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% call ", unparse_identifier(Identifier), " with ", unparse_args(With), " %}"]|Acc]);
|
|
|
-unparse([{'comment', Contents}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% comment %}", unparse(Contents), "{% endcomment %}"]|Acc]);
|
|
|
-unparse([{'comment_tag', _Pos, Text}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{#", Text, "#}"]|Acc]);
|
|
|
-unparse([{'cycle', Names}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% cycle ", unparse(Names), " %}"]|Acc]);
|
|
|
-unparse([{'cycle_compat', Names}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% cycle ", unparse_cycle_compat_names(Names), " %}"]|Acc]);
|
|
|
-unparse([{'date', 'now', Value}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% now ", unparse_value(Value), " %}"]|Acc]);
|
|
|
-unparse([{'filter', FilterList, Contents}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% filter ", unparse_filters(FilterList), " %}", unparse(Contents), "{% endfilter %}"]|Acc]);
|
|
|
-unparse([{'firstof', Vars}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% firstof ", unparse(Vars), " %}"]|Acc]);
|
|
|
-unparse([{'for', {'in', IteratorList, Identifier}, Contents}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% for ", unparse_identifier(Identifier), " in ", unparse(IteratorList), " %}",
|
|
|
- unparse(Contents),
|
|
|
+do_unparse([{'call', Identifier}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% call ", unparse_identifier(Identifier), " %}"]|Acc]);
|
|
|
+do_unparse([{'call', Identifier, With}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% call ", unparse_identifier(Identifier), " with ", unparse_args(With), " %}"]|Acc]);
|
|
|
+do_unparse([{'comment', Contents}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% comment %}", do_unparse(Contents), "{% endcomment %}"]|Acc]);
|
|
|
+do_unparse([{'comment_tag', _Pos, Text}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{#", Text, "#}"]|Acc]);
|
|
|
+do_unparse([{'cycle', Names}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% cycle ", do_unparse(Names), " %}"]|Acc]);
|
|
|
+do_unparse([{'cycle_compat', Names}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% cycle ", unparse_cycle_compat_names(Names), " %}"]|Acc]);
|
|
|
+do_unparse([{'date', 'now', Value}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% now ", unparse_value(Value), " %}"]|Acc]);
|
|
|
+do_unparse([{'filter', FilterList, Contents}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% filter ", unparse_filters(FilterList), " %}", do_unparse(Contents), "{% endfilter %}"]|Acc]);
|
|
|
+do_unparse([{'firstof', Vars}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% firstof ", do_unparse(Vars), " %}"]|Acc]);
|
|
|
+do_unparse([{'for', {'in', IteratorList, Identifier}, Contents}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% for ", unparse_identifier(Identifier), " in ", do_unparse(IteratorList), " %}",
|
|
|
+ do_unparse(Contents),
|
|
|
"{% endfor %}"]|Acc]);
|
|
|
-unparse([{'for', {'in', IteratorList, Identifier}, Contents, EmptyPartsContents}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% for ", unparse_identifier(Identifier), " in ", unparse(IteratorList), " %}",
|
|
|
- unparse(Contents),
|
|
|
+do_unparse([{'for', {'in', IteratorList, Identifier}, Contents, EmptyPartsContents}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% for ", unparse_identifier(Identifier), " in ", do_unparse(IteratorList), " %}",
|
|
|
+ do_unparse(Contents),
|
|
|
"{% empty %}",
|
|
|
- unparse(EmptyPartsContents),
|
|
|
+ do_unparse(EmptyPartsContents),
|
|
|
"{% endfor %}"]|Acc]);
|
|
|
-unparse([{'if', Expression, Contents}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% if ", unparse_expression(Expression), " %}",
|
|
|
- unparse(Contents),
|
|
|
+do_unparse([{'if', Expression, Contents}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% if ", unparse_expression(Expression), " %}",
|
|
|
+ do_unparse(Contents),
|
|
|
"{% endif %}"]|Acc]);
|
|
|
-unparse([{'ifchanged', Expression, IfContents}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% ifchanged ", unparse_expression(Expression), " %}",
|
|
|
- unparse(IfContents),
|
|
|
+do_unparse([{'ifchanged', Expression, IfContents}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% ifchanged ", unparse_expression(Expression), " %}",
|
|
|
+ do_unparse(IfContents),
|
|
|
"{% endifchanged %}"]|Acc]);
|
|
|
-unparse([{'ifchangedelse', Expression, IfContents, ElseContents}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% ifchanged ", unparse_expression(Expression), " %}",
|
|
|
- unparse(IfContents),
|
|
|
+do_unparse([{'ifchangedelse', Expression, IfContents, ElseContents}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% ifchanged ", unparse_expression(Expression), " %}",
|
|
|
+ do_unparse(IfContents),
|
|
|
"{% else %}",
|
|
|
- unparse(ElseContents),
|
|
|
+ do_unparse(ElseContents),
|
|
|
"{% endifchanged %}"]|Acc]);
|
|
|
-unparse([{'ifelse', Expression, IfContents, ElseContents}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% if ", unparse_expression(Expression), " %}",
|
|
|
- unparse(IfContents),
|
|
|
+do_unparse([{'ifelse', Expression, IfContents, ElseContents}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% if ", unparse_expression(Expression), " %}",
|
|
|
+ do_unparse(IfContents),
|
|
|
"{% else %}",
|
|
|
- unparse(ElseContents),
|
|
|
+ do_unparse(ElseContents),
|
|
|
"{% endif %}"]|Acc]);
|
|
|
-unparse([{'ifequal', [Arg1, Arg2], Contents}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% ifequal ", unparse_value(Arg1), " ", unparse_value(Arg2), " %}",
|
|
|
- unparse(Contents),
|
|
|
+do_unparse([{'ifequal', [Arg1, Arg2], Contents}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% ifequal ", unparse_value(Arg1), " ", unparse_value(Arg2), " %}",
|
|
|
+ do_unparse(Contents),
|
|
|
"{% endifequal %}"]|Acc]);
|
|
|
-unparse([{'ifequalelse', [Arg1, Arg2], IfContents, ElseContents}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% ifequal ", unparse_value(Arg1), " ", unparse_value(Arg2), " %}",
|
|
|
- unparse(IfContents),
|
|
|
+do_unparse([{'ifequalelse', [Arg1, Arg2], IfContents, ElseContents}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% ifequal ", unparse_value(Arg1), " ", unparse_value(Arg2), " %}",
|
|
|
+ do_unparse(IfContents),
|
|
|
"{% else %}",
|
|
|
- unparse(ElseContents),
|
|
|
+ do_unparse(ElseContents),
|
|
|
"{% endifequal %}"]|Acc]);
|
|
|
-unparse([{'ifnotequal', [Arg1, Arg2], Contents}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% ifnotequal ", unparse_value(Arg1), " ", unparse_value(Arg2), " %}",
|
|
|
- unparse(Contents),
|
|
|
+do_unparse([{'ifnotequal', [Arg1, Arg2], Contents}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% ifnotequal ", unparse_value(Arg1), " ", unparse_value(Arg2), " %}",
|
|
|
+ do_unparse(Contents),
|
|
|
"{% endifnotequal %}"]|Acc]);
|
|
|
-unparse([{'ifnotequalelse', [Arg1, Arg2], IfContents, ElseContents}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% ifnotequal ", unparse_value(Arg1), " ", unparse_value(Arg2), " %}",
|
|
|
- unparse(IfContents),
|
|
|
+do_unparse([{'ifnotequalelse', [Arg1, Arg2], IfContents, ElseContents}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% ifnotequal ", unparse_value(Arg1), " ", unparse_value(Arg2), " %}",
|
|
|
+ do_unparse(IfContents),
|
|
|
"{% else %}",
|
|
|
- unparse(ElseContents),
|
|
|
+ do_unparse(ElseContents),
|
|
|
"{% endifnotequal %}"]|Acc]);
|
|
|
-unparse([{'include', Value, []}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% include ", unparse_value(Value), " %}"]|Acc]);
|
|
|
-unparse([{'include', Value, Args}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% include ", unparse_value(Value), " with ", unparse_args(Args)]|Acc]);
|
|
|
-unparse([{'include_only', Value, []}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% include ", unparse_value(Value), " only %}"]|Acc]);
|
|
|
-unparse([{'include_only', Value, Args}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% include ", unparse_value(Value), " with ", unparse_args(Args), " only %}"]|Acc]);
|
|
|
-unparse([{'regroup', {Variable, Identifier1, Identifier2}, Contents}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% regroup ", unparse_value(Variable), " by ", unparse_identifier(Identifier1), " as ", unparse_identifier(Identifier2), " %}",
|
|
|
- unparse(Contents),
|
|
|
+do_unparse([{'include', Value, []}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% include ", unparse_value(Value), " %}"]|Acc]);
|
|
|
+do_unparse([{'include', Value, Args}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% include ", unparse_value(Value), " with ", unparse_args(Args)]|Acc]);
|
|
|
+do_unparse([{'include_only', Value, []}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% include ", unparse_value(Value), " only %}"]|Acc]);
|
|
|
+do_unparse([{'include_only', Value, Args}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% include ", unparse_value(Value), " with ", unparse_args(Args), " only %}"]|Acc]);
|
|
|
+do_unparse([{'regroup', {Variable, Identifier1, Identifier2}, Contents}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% regroup ", unparse_value(Variable), " by ", unparse_identifier(Identifier1), " as ", unparse_identifier(Identifier2), " %}",
|
|
|
+ do_unparse(Contents),
|
|
|
"{% endregroup %}"]|Acc]);
|
|
|
-unparse([{'spaceless', Contents}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% spaceless %}", unparse(Contents), "{% endspaceless %}"]|Acc]);
|
|
|
-unparse([{'ssi', Arg}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% ssi ", unparse_value(Arg), " %}"]|Acc]);
|
|
|
-unparse([{'ssi_parsed', Arg}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% ssi ", unparse_value(Arg), " parsed %}"]|Acc]);
|
|
|
-unparse([{'string', _, String}|Rest], Acc) ->
|
|
|
- unparse(Rest, [[String]|Acc]);
|
|
|
-unparse([{'tag', Identifier, []}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% ", unparse_identifier(Identifier), " %}"]|Acc]);
|
|
|
-unparse([{'tag', Identifier, Args}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% ", unparse_identifier(Identifier), " ", unparse_args(Args), " %}"]|Acc]);
|
|
|
-unparse([{'templatetag', Identifier}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% templatetag ", unparse_identifier(Identifier), " %}"]|Acc]);
|
|
|
-unparse([{'trans', Value}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% trans ", unparse_value(Value), " %}"]|Acc]);
|
|
|
-unparse([{'widthratio', Numerator, Denominator, Scale}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% widthratio ", unparse_value(Numerator), " ", unparse_value(Denominator), " ", unparse_value(Scale), " %}"]|Acc]);
|
|
|
-unparse([{'with', Args, Contents}|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{% with ", unparse_args(Args), " %}",
|
|
|
- unparse(Contents),
|
|
|
+do_unparse([{'spaceless', Contents}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% spaceless %}", do_unparse(Contents), "{% endspaceless %}"]|Acc]);
|
|
|
+do_unparse([{'ssi', Arg}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% ssi ", unparse_value(Arg), " %}"]|Acc]);
|
|
|
+do_unparse([{'ssi_parsed', Arg}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% ssi ", unparse_value(Arg), " parsed %}"]|Acc]);
|
|
|
+do_unparse([{'string', _, String}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [[String]|Acc]);
|
|
|
+do_unparse([{'tag', Identifier, []}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% ", unparse_identifier(Identifier), " %}"]|Acc]);
|
|
|
+do_unparse([{'tag', Identifier, Args}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% ", unparse_identifier(Identifier), " ", unparse_args(Args), " %}"]|Acc]);
|
|
|
+do_unparse([{'templatetag', Identifier}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% templatetag ", unparse_identifier(Identifier), " %}"]|Acc]);
|
|
|
+do_unparse([{'trans', Value}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% trans ", unparse_value(Value), " %}"]|Acc]);
|
|
|
+do_unparse([{'widthratio', Numerator, Denominator, Scale}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% widthratio ", unparse_value(Numerator), " ", unparse_value(Denominator), " ", unparse_value(Scale), " %}"]|Acc]);
|
|
|
+do_unparse([{'with', Args, Contents}|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{% with ", unparse_args(Args), " %}",
|
|
|
+ do_unparse(Contents),
|
|
|
"{% endwidth %}"]|Acc]);
|
|
|
-unparse([ValueToken|Rest], Acc) ->
|
|
|
- unparse(Rest, [["{{ ", unparse_value(ValueToken), " }}"]|Acc]).
|
|
|
+do_unparse([ValueToken|Rest], Acc) ->
|
|
|
+ do_unparse(Rest, [["{{ ", unparse_value(ValueToken), " }}"]|Acc]).
|
|
|
|
|
|
|
|
|
unparse_identifier({identifier, _, Name}) ->
|