erlydtl_runtime.erl 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. -module(erlydtl_runtime).
  2. -compile(export_all).
  3. find_value(_, undefined) ->
  4. undefined;
  5. find_value(Key, Fun) when is_function(Fun, 1) ->
  6. Fun(Key);
  7. find_value(Key, L) when is_list(L) ->
  8. case proplists:get_value(Key, L) of
  9. undefined ->
  10. case proplists:get_value(atom_to_list(Key), L) of
  11. undefined ->
  12. proplists:get_value(list_to_binary(atom_to_list(Key)), L);
  13. Val -> Val
  14. end;
  15. Val -> Val
  16. end;
  17. find_value(Key, {GBSize, GBData}) when is_integer(GBSize) ->
  18. case gb_trees:lookup(Key, {GBSize, GBData}) of
  19. {value, Val} ->
  20. Val;
  21. _ ->
  22. undefined
  23. end;
  24. find_value(Key, Tuple) when is_tuple(Tuple) ->
  25. Module = element(1, Tuple),
  26. case Module of
  27. dict ->
  28. case dict:find(Key, Tuple) of
  29. {ok, Val} ->
  30. Val;
  31. _ ->
  32. undefined
  33. end;
  34. Module ->
  35. case lists:member({Key, 1}, Module:module_info(exports)) of
  36. true ->
  37. Tuple:Key();
  38. _ ->
  39. undefined
  40. end
  41. end.
  42. fetch_value(Key, Data) ->
  43. case find_value(Key, Data) of
  44. undefined ->
  45. throw({undefined_variable, Key});
  46. Val ->
  47. Val
  48. end.
  49. translate(_, none, Default) ->
  50. Default;
  51. translate(String, TranslationFun, Default) when is_binary(String) ->
  52. translate(binary_to_list(String), TranslationFun, Default);
  53. translate(String, TranslationFun, Default) when is_function(TranslationFun) ->
  54. case TranslationFun(String) of
  55. undefined -> Default;
  56. "" -> Default;
  57. Str -> Str
  58. end.
  59. are_equal(Arg1, Arg2) when Arg1 =:= Arg2 ->
  60. true;
  61. are_equal(Arg1, Arg2) when is_binary(Arg1) ->
  62. are_equal(binary_to_list(Arg1), Arg2);
  63. are_equal(Arg1, Arg2) when is_binary(Arg2) ->
  64. are_equal(Arg1, binary_to_list(Arg2));
  65. are_equal(Arg1, Arg2) when is_integer(Arg1) ->
  66. are_equal(integer_to_list(Arg1), Arg2);
  67. are_equal(Arg1, Arg2) when is_integer(Arg2) ->
  68. are_equal(Arg1, integer_to_list(Arg2));
  69. are_equal(Arg1, Arg2) when is_atom(Arg1), is_list(Arg2) ->
  70. are_equal(atom_to_list(Arg1), Arg2);
  71. are_equal(Arg1, Arg2) when is_list(Arg1), is_atom(Arg2) ->
  72. are_equal(Arg1, atom_to_list(Arg2));
  73. are_equal(_, _) ->
  74. false.
  75. is_false("") ->
  76. true;
  77. is_false(false) ->
  78. true;
  79. is_false(undefined) ->
  80. true;
  81. is_false("0") ->
  82. true;
  83. is_false(<<"0">>) ->
  84. true;
  85. is_false(<<>>) ->
  86. true;
  87. is_false(_) ->
  88. false.
  89. is_true(V) ->
  90. not is_false(V).
  91. 'in'(Sublist, [Sublist|_]) ->
  92. true;
  93. 'in'(Sublist, List) when is_atom(List) ->
  94. 'in'(Sublist, atom_to_list(List));
  95. 'in'(Sublist, List) when is_binary(Sublist) ->
  96. 'in'(binary_to_list(Sublist), List);
  97. 'in'(Sublist, List) when is_binary(List) ->
  98. 'in'(Sublist, binary_to_list(List));
  99. 'in'(Sublist, [C|Rest]) when is_list(Sublist) andalso is_binary(C) ->
  100. 'in'(Sublist, [binary_to_list(C)|Rest]);
  101. 'in'(Sublist, [C|Rest]) when is_list(Sublist) andalso is_list(C) ->
  102. 'in'(Sublist, Rest);
  103. 'in'(Sublist, List) when is_list(Sublist) andalso is_list(List) ->
  104. string:str(List, Sublist) > 0;
  105. 'in'(Element, List) when is_list(List) ->
  106. lists:member(Element, List);
  107. 'in'(_, _) ->
  108. false.
  109. 'not'(Value) ->
  110. not is_true(Value).
  111. 'or'(Value1, Value2) ->
  112. is_true(Value1) or is_true(Value2).
  113. 'and'(Value1, Value2) ->
  114. is_true(Value1) and is_true(Value2).
  115. 'eq'(Value1, Value2) ->
  116. are_equal(Value1, Value2).
  117. 'ne'(Value1, Value2) ->
  118. not are_equal(Value1, Value2).
  119. 'le'(Value1, Value2) ->
  120. not 'gt'(Value1, Value2).
  121. 'ge'(Value1, Value2) ->
  122. not 'lt'(Value1, Value2).
  123. 'gt'(Value1, Value2) when is_list(Value1) ->
  124. 'gt'(list_to_integer(Value1), Value2);
  125. 'gt'(Value1, Value2) when is_list(Value2) ->
  126. 'gt'(Value1, list_to_integer(Value2));
  127. 'gt'(Value1, Value2) when Value1 > Value2 ->
  128. true;
  129. 'gt'(_, _) ->
  130. false.
  131. 'lt'(Value1, Value2) when is_list(Value1) ->
  132. 'lt'(list_to_integer(Value1), Value2);
  133. 'lt'(Value1, Value2) when is_list(Value2) ->
  134. 'lt'(Value1, list_to_integer(Value2));
  135. 'lt'(Value1, Value2) when Value1 < Value2 ->
  136. true;
  137. 'lt'(_, _) ->
  138. false.
  139. stringify_final(In) ->
  140. stringify_final(In, []).
  141. stringify_final([], Out) ->
  142. lists:reverse(Out);
  143. stringify_final([El | Rest], Out) when is_atom(El) ->
  144. stringify_final(Rest, [atom_to_list(El) | Out]);
  145. stringify_final([El | Rest], Out) when is_list(El) ->
  146. stringify_final(Rest, [stringify_final(El) | Out]);
  147. stringify_final([El | Rest], Out) when is_tuple(El) ->
  148. stringify_final(Rest, [io_lib:print(El) | Out]);
  149. stringify_final([El | Rest], Out) ->
  150. stringify_final(Rest, [El | Out]).
  151. init_counter_stats(List) ->
  152. init_counter_stats(List, undefined).
  153. init_counter_stats(List, Parent) ->
  154. [{counter, 1},
  155. {counter0, 0},
  156. {revcounter, length(List)},
  157. {revcounter0, length(List) - 1},
  158. {first, true},
  159. {last, length(List) =:= 1},
  160. {parentloop, Parent}].
  161. increment_counter_stats([{counter, Counter}, {counter0, Counter0}, {revcounter, RevCounter},
  162. {revcounter0, RevCounter0}, {first, _}, {last, _}, {parentloop, Parent}]) ->
  163. [{counter, Counter + 1},
  164. {counter0, Counter0 + 1},
  165. {revcounter, RevCounter - 1},
  166. {revcounter0, RevCounter0 - 1},
  167. {first, false}, {last, RevCounter0 =:= 1},
  168. {parentloop, Parent}].
  169. cycle(NamesTuple, Counters) when is_tuple(NamesTuple) ->
  170. element(fetch_value(counter0, Counters) rem size(NamesTuple) + 1, NamesTuple).
  171. widthratio(Numerator, Denominator, Scale) ->
  172. round(Numerator / Denominator * Scale).
  173. spaceless(Contents) ->
  174. Contents1 = lists:flatten(Contents),
  175. Contents2 = re:replace(Contents1, "^\s+<", "<", [{return,list}]),
  176. Contents3 = re:replace(Contents2, ">\s+$", ">", [{return,list}]),
  177. Contents4 = re:replace(Contents3, ">\s+<", "><", [global, {return,list}]),
  178. Contents4.
  179. read_file(Module, Function, DocRoot, FileName) ->
  180. AbsName = case filename:absname(FileName) of
  181. FileName -> FileName;
  182. _ -> filename:join([DocRoot, FileName])
  183. end,
  184. {ok, Binary} = Module:Function(AbsName),
  185. binary_to_list(Binary).