erlydtl_unparser.erl 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. -module(erlydtl_unparser).
  2. -export([unparse/1]).
  3. unparse(DjangoParseTree) ->
  4. unparse(DjangoParseTree, []).
  5. unparse([], Acc) ->
  6. lists:flatten(lists:reverse(Acc));
  7. unparse([{'extends', Value}|Rest], Acc) ->
  8. unparse(Rest, [["{% extends ", unparse_value(Value), " %}"]|Acc]);
  9. unparse([{'autoescape', OnOrOff, Contents}|Rest], Acc) ->
  10. unparse(Rest, [["{% autoescape ", unparse_identifier(OnOrOff), " %}", unparse(Contents), "{% endautoescape %}"]|Acc]);
  11. unparse([{'block', Identifier, Contents}|Rest], Acc) ->
  12. unparse(Rest, [["{% block ", unparse_identifier(Identifier), " %}", unparse(Contents), "{% endblock %}"]|Acc]);
  13. unparse([{'blocktrans', Args, Contents, undefined}|Rest], Acc) ->
  14. unparse(Rest, [["{% blocktrans ", unparse_blocktrans_args(Args), "%}", unparse(Contents), "{% endblocktrans %}"]|Acc]);
  15. unparse([{'blocktrans', Args, Contents, PluralContents}|Rest], Acc) ->
  16. unparse(Rest, [["{% blocktrans ", unparse_args(Args), " %}",
  17. unparse(Contents),
  18. "{% plural %}",
  19. unparse(PluralContents),
  20. "{% endblocktrans %}"]|Acc]);
  21. unparse([{'call', Identifier}|Rest], Acc) ->
  22. unparse(Rest, [["{% call ", unparse_identifier(Identifier), " %}"]|Acc]);
  23. unparse([{'call', Identifier, With}|Rest], Acc) ->
  24. unparse(Rest, [["{% call ", unparse_identifier(Identifier), " with ", unparse_args(With), " %}"]|Acc]);
  25. unparse([{'comment', Contents}|Rest], Acc) ->
  26. unparse(Rest, [["{% comment %}", unparse(Contents), "{% endcomment %}"]|Acc]);
  27. unparse([{'comment_tag', _Pos, Text}|Rest], Acc) ->
  28. unparse(Rest, [["{#", Text, "#}"]|Acc]);
  29. unparse([{'cycle', Names}|Rest], Acc) ->
  30. unparse(Rest, [["{% cycle ", unparse(Names), " %}"]|Acc]);
  31. unparse([{'cycle_compat', Names}|Rest], Acc) ->
  32. unparse(Rest, [["{% cycle ", unparse_cycle_compat_names(Names), " %}"]|Acc]);
  33. unparse([{'date', 'now', Value}|Rest], Acc) ->
  34. unparse(Rest, [["{% now ", unparse_value(Value), " %}"]|Acc]);
  35. unparse([{'filter', FilterList, Contents}|Rest], Acc) ->
  36. unparse(Rest, [["{% filter ", unparse_filters(FilterList), " %}", unparse(Contents), "{% endfilter %}"]|Acc]);
  37. unparse([{'firstof', Vars}|Rest], Acc) ->
  38. unparse(Rest, [["{% firstof ", unparse(Vars), " %}"]|Acc]);
  39. unparse([{'for', {'in', IteratorList, Identifier}, Contents}|Rest], Acc) ->
  40. unparse(Rest, [["{% for ", unparse_identifier(Identifier), " in ", unparse(IteratorList), " %}",
  41. unparse(Contents),
  42. "{% endfor %}"]|Acc]);
  43. unparse([{'for', {'in', IteratorList, Identifier}, Contents, EmptyPartsContents}|Rest], Acc) ->
  44. unparse(Rest, [["{% for ", unparse_identifier(Identifier), " in ", unparse(IteratorList), " %}",
  45. unparse(Contents),
  46. "{% empty %}",
  47. unparse(EmptyPartsContents),
  48. "{% endfor %}"]|Acc]);
  49. unparse([{'if', Expression, Contents}|Rest], Acc) ->
  50. unparse(Rest, [["{% if ", unparse_expression(Expression), " %}",
  51. unparse(Contents),
  52. "{% endif %}"]|Acc]);
  53. unparse([{'ifchanged', Expression, IfContents}|Rest], Acc) ->
  54. unparse(Rest, [["{% ifchanged ", unparse_expression(Expression), " %}",
  55. unparse(IfContents),
  56. "{% endifchanged %}"]|Acc]);
  57. unparse([{'ifchangedelse', Expression, IfContents, ElseContents}|Rest], Acc) ->
  58. unparse(Rest, [["{% ifchanged ", unparse_expression(Expression), " %}",
  59. unparse(IfContents),
  60. "{% else %}",
  61. unparse(ElseContents),
  62. "{% endifchanged %}"]|Acc]);
  63. unparse([{'ifelse', Expression, IfContents, ElseContents}|Rest], Acc) ->
  64. unparse(Rest, [["{% if ", unparse_expression(Expression), " %}",
  65. unparse(IfContents),
  66. "{% else %}",
  67. unparse(ElseContents),
  68. "{% endif %}"]|Acc]);
  69. unparse([{'ifequal', [Arg1, Arg2], Contents}|Rest], Acc) ->
  70. unparse(Rest, [["{% ifequal ", unparse_value(Arg1), " ", unparse_value(Arg2), " %}",
  71. unparse(Contents),
  72. "{% endifequal %}"]|Acc]);
  73. unparse([{'ifequalelse', [Arg1, Arg2], IfContents, ElseContents}|Rest], Acc) ->
  74. unparse(Rest, [["{% ifequal ", unparse_value(Arg1), " ", unparse_value(Arg2), " %}",
  75. unparse(IfContents),
  76. "{% else %}",
  77. unparse(ElseContents),
  78. "{% endifequal %}"]|Acc]);
  79. unparse([{'ifnotequal', [Arg1, Arg2], Contents}|Rest], Acc) ->
  80. unparse(Rest, [["{% ifnotequal ", unparse_value(Arg1), " ", unparse_value(Arg2), " %}",
  81. unparse(Contents),
  82. "{% endifnotequal %}"]|Acc]);
  83. unparse([{'ifnotequalelse', [Arg1, Arg2], IfContents, ElseContents}|Rest], Acc) ->
  84. unparse(Rest, [["{% ifnotequal ", unparse_value(Arg1), " ", unparse_value(Arg2), " %}",
  85. unparse(IfContents),
  86. "{% else %}",
  87. unparse(ElseContents),
  88. "{% endifnotequal %}"]|Acc]);
  89. unparse([{'include', Value, []}|Rest], Acc) ->
  90. unparse(Rest, [["{% include ", unparse_value(Value), " %}"]|Acc]);
  91. unparse([{'include', Value, Args}|Rest], Acc) ->
  92. unparse(Rest, [["{% include ", unparse_value(Value), " with ", unparse_args(Args)]|Acc]);
  93. unparse([{'include_only', Value, []}|Rest], Acc) ->
  94. unparse(Rest, [["{% include ", unparse_value(Value), " only %}"]|Acc]);
  95. unparse([{'include_only', Value, Args}|Rest], Acc) ->
  96. unparse(Rest, [["{% include ", unparse_value(Value), " with ", unparse_args(Args), " only %}"]|Acc]);
  97. unparse([{'regroup', {Variable, Identifier1, Identifier2}, Contents}|Rest], Acc) ->
  98. unparse(Rest, [["{% regroup ", unparse_value(Variable), " by ", unparse_identifier(Identifier1), " as ", unparse_identifier(Identifier2), " %}",
  99. unparse(Contents),
  100. "{% endregroup %}"]|Acc]);
  101. unparse([{'spaceless', Contents}|Rest], Acc) ->
  102. unparse(Rest, [["{% spaceless %}", unparse(Contents), "{% endspaceless %}"]|Acc]);
  103. unparse([{'ssi', Arg}|Rest], Acc) ->
  104. unparse(Rest, [["{% ssi ", unparse_value(Arg), " %}"]|Acc]);
  105. unparse([{'ssi_parsed', Arg}|Rest], Acc) ->
  106. unparse(Rest, [["{% ssi ", unparse_value(Arg), " parsed %}"]|Acc]);
  107. unparse([{'string', _, String}|Rest], Acc) ->
  108. unparse(Rest, [[String]|Acc]);
  109. unparse([{'tag', Identifier, []}|Rest], Acc) ->
  110. unparse(Rest, [["{% ", unparse_identifier(Identifier), " %}"]|Acc]);
  111. unparse([{'tag', Identifier, Args}|Rest], Acc) ->
  112. unparse(Rest, [["{% ", unparse_identifier(Identifier), " ", unparse_args(Args), " %}"]|Acc]);
  113. unparse([{'templatetag', Identifier}|Rest], Acc) ->
  114. unparse(Rest, [["{% templatetag ", unparse_identifier(Identifier), " %}"]|Acc]);
  115. unparse([{'trans', Value}|Rest], Acc) ->
  116. unparse(Rest, [["{% trans ", unparse_value(Value), " %}"]|Acc]);
  117. unparse([{'widthratio', Numerator, Denominator, Scale}|Rest], Acc) ->
  118. unparse(Rest, [["{% widthratio ", unparse_value(Numerator), " ", unparse_value(Denominator), " ", unparse_value(Scale), " %}"]|Acc]);
  119. unparse([{'with', Args, Contents}|Rest], Acc) ->
  120. unparse(Rest, [["{% with ", unparse_args(Args), " %}",
  121. unparse(Contents),
  122. "{% endwidth %}"]|Acc]);
  123. unparse([ValueToken|Rest], Acc) ->
  124. unparse(Rest, [["{{ ", unparse_value(ValueToken), " }}"]|Acc]).
  125. unparse_identifier({identifier, _, Name}) ->
  126. atom_to_list(Name).
  127. unparse_filters(FilterList) ->
  128. unparse_filters(FilterList, []).
  129. unparse_filters([], Acc) ->
  130. lists:reverse(Acc);
  131. unparse_filters([Filter], Acc) ->
  132. unparse_filters([], [unparse_filter(Filter)|Acc]);
  133. unparse_filters([Filter|Rest], Acc) ->
  134. unparse_filters(Rest, lists:reverse([unparse_filter(Filter), "|"], Acc)).
  135. unparse_filter([Identifier]) ->
  136. unparse_identifier(Identifier);
  137. unparse_filter([Identifier, Arg]) ->
  138. [unparse_identifier(Identifier), ":", unparse_value(Arg)].
  139. unparse_expression({'expr', "in", Arg1, Arg2}) ->
  140. [unparse_value(Arg1), " in ", unparse_value(Arg2)];
  141. unparse_expression({'expr', "not", {'expr', "in", Arg1, Arg2}}) ->
  142. [unparse_value(Arg1), " not in ", unparse_value(Arg2)];
  143. unparse_expression({'expr', "not", Expr}) ->
  144. ["not ", unparse_expression(Expr)];
  145. unparse_expression({'expr', "eq", Arg1, Arg2}) ->
  146. [unparse_value(Arg1), " == ", unparse_value(Arg2)];
  147. unparse_expression({'expr', "ne", Arg1, Arg2}) ->
  148. [unparse_value(Arg1), " != ", unparse_value(Arg2)];
  149. unparse_expression({'expr', "ge", Arg1, Arg2}) ->
  150. [unparse_value(Arg1), " >= ", unparse_value(Arg2)];
  151. unparse_expression({'expr', "le", Arg1, Arg2}) ->
  152. [unparse_value(Arg1), " <= ", unparse_value(Arg2)];
  153. unparse_expression({'expr', "gt", Arg1, Arg2}) ->
  154. [unparse_value(Arg1), " > ", unparse_value(Arg2)];
  155. unparse_expression({'expr', "lt", Arg1, Arg2}) ->
  156. [unparse_value(Arg1), " < ", unparse_value(Arg2)];
  157. unparse_expression({'expr', "or", Arg1, Arg2}) ->
  158. [unparse_expression(Arg1), " or ", unparse_expression(Arg2)];
  159. unparse_expression({'expr', "and", Arg1, Arg2}) ->
  160. [unparse_expression(Arg1), " and ", unparse_expression(Arg2)];
  161. unparse_expression(Other) ->
  162. unparse_value(Other).
  163. unparse_value({'string_literal', _, Value}) ->
  164. Value;
  165. unparse_value({'number_literal', _, Value}) ->
  166. Value;
  167. unparse_value({'apply_filter', Variable, Filter}) ->
  168. [unparse_value(Variable), "|", unparse_filter(Filter)];
  169. unparse_value({'attribute', {Variable, Identifier}}) ->
  170. [unparse_value(Variable), ".", unparse_identifier(Identifier)];
  171. unparse_value({'variable', Identifier}) ->
  172. unparse_identifier(Identifier).
  173. unparse_args(Args) ->
  174. unparse_args(Args, []).
  175. unparse_args([], Acc) ->
  176. lists:reverse(Acc);
  177. unparse_args([{{identifier, _, Name}, Value}], Acc) ->
  178. unparse_args([], [[atom_to_list(Name), "=", unparse_value(Value)]|Acc]);
  179. unparse_args([{{identifier, _, Name}, Value}|Rest], Acc) ->
  180. unparse_args(Rest, lists:reverse([[atom_to_list(Name), "=", unparse_value(Value)], " "], Acc)).
  181. unparse_cycle_compat_names(Names) ->
  182. unparse_cycle_compat_names(Names, []).
  183. unparse_cycle_compat_names([], Acc) ->
  184. lists:reverse(Acc);
  185. unparse_cycle_compat_names([{identifier, _, Name}], Acc) ->
  186. unparse_cycle_compat_names([], [atom_to_list(Name)|Acc]);
  187. unparse_cycle_compat_names([{identifier, _, Name}|Rest], Acc) ->
  188. unparse_cycle_compat_names(Rest, lists:reverse([atom_to_list(Name), ", "], Acc)).
  189. unparse_blocktrans_args(Args) ->
  190. unparse_blocktrans_args(Args, []).
  191. unparse_blocktrans_args([{args, WithArgs}|Args], Acc) ->
  192. unparse_blocktrans_args(
  193. Args, [["with ", unparse_args(WithArgs)]|Acc]);
  194. unparse_blocktrans_args([{count, Count}|Args], Acc) ->
  195. unparse_blocktrans_args(
  196. Args, [["count ", unparse_args([Count])]|Acc]);
  197. unparse_blocktrans_args([{context, Context}|Args], Acc) ->
  198. unparse_blocktrans_args(
  199. Args, [["context ", unparse_value(Context)]|Acc]);
  200. unparse_blocktrans_args([], Acc) ->
  201. lists:reverse(Acc).