Skip to content

Commit

Permalink
Improve floatformat.
Browse files Browse the repository at this point in the history
Fixes #41, #53.
  • Loading branch information
kaos committed Nov 29, 2013
1 parent 8ee31b8 commit b57284a
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 26 deletions.
38 changes: 21 additions & 17 deletions src/erlydtl_filters.erl
Expand Up @@ -66,6 +66,7 @@
filesizeformat/1,
first/1,
fix_ampersands/1,
floatformat/1,
floatformat/2,
force_escape/1,
format_integer/1,
Expand Down Expand Up @@ -328,33 +329,30 @@ fix_ampersands(Input) when is_list(Input) ->

%% @doc When used without an argument, rounds a floating-point number to one decimal place
%% -- but only if there's a decimal part to be displayed
floatformat(Number, Place) when is_binary(Number) ->
floatformat(binary_to_list(Number), Place);
floatformat(Number) ->
floatformat(Number, []).

floatformat(Number, Place) ->
floatformat_io(Number, cast_to_integer(Place)).
floatformat_io(cast_to_float(Number), cast_to_integer(Place)).

floatformat_io(Number, []) ->
floatformat_io(Number, -1);
floatformat_io(Number, 0) ->
hd(io_lib:format("~B", [erlang:round(Number)]));
floatformat_io(Number, Precision) when Precision > 0 ->
Format = lists:flatten(io_lib:format("~~.~Bf",[Precision])),
[Result] = io_lib:format(Format,[Number]),
Result;
hd(io_lib:format("~.*f",[Precision, Number]));
floatformat_io(Number, Precision) when Precision < 0 ->
Round = erlang:round(Number),
RoundPrecision = round(Number, -Precision),
case RoundPrecision == Round of
true ->
%Format = lists:flatten(io_lib:format("~~~BB",[-Precision])),
[Result] = io_lib:format("~B",[Round]);
false ->
Format = lists:flatten(io_lib:format("~~.~Bf",[-Precision])),
[Result] = io_lib:format(Format,[RoundPrecision])
end,
Result.
if RoundPrecision == Round ->
floatformat_io(Round, 0);
true ->
floatformat_io(RoundPrecision, -Precision)
end.

round(Number, Precision) ->
P = math:pow(10, Precision),
round(Number * P) / P.
erlang:round(Number * P) / P.

%% @doc Applies HTML escaping to a string.
force_escape(Input) when is_list(Input) ->
Expand Down Expand Up @@ -720,7 +718,13 @@ cast_to_float(Input) when is_float(Input) ->
Input;
cast_to_float(Input) when is_integer(Input) ->
Input + 0.0;
cast_to_float(Input) ->
cast_to_float(Input) when is_binary(Input) ->
try binary_to_float(Input)

This comment has been minimized.

Copy link
@connorsml

connorsml Nov 29, 2013

That will only work from R16 upwards. Is that intended?

This comment has been minimized.

Copy link
@kaos

kaos Nov 29, 2013

Author Member

No, god d**n it, that they can't include version added info in the Erlang docs!..

Thanks for pointing that out Michael.

This comment has been minimized.

Copy link
@kaos

kaos Nov 29, 2013

Author Member

Fixed in 0c67090.

catch
error:_Reason ->
binary_to_integer(Input) + 0.0
end;
cast_to_float(Input) when is_list(Input) ->
try list_to_float(Input)
catch
error:_Reason ->
Expand Down
57 changes: 48 additions & 9 deletions tests/src/erlydtl_unittests.erl
Expand Up @@ -468,15 +468,54 @@ tests() ->
{"|floatformat:\"-1\"",
<<"{{ var1|floatformat:\"-1\" }}">>, [{var1, 34.23234}],
<<"34.2">>},
%% ?assertEqual( "", erlydtl_filters:floatformat(,)),
%% ?assertEqual( "34", erlydtl_filters:floatformat(34.00000,-1)),
%% ?assertEqual( "34.3", erlydtl_filters:floatformat(34.26000,-1)),
%% ?assertEqual( "34.232", erlydtl_filters:floatformat(34.23234,3)),
%% ?assertEqual( "34.000", erlydtl_filters:floatformat(34.00000,3)),
%% ?assertEqual( "34.260", erlydtl_filters:floatformat(34.26000,3)),
%% ?assertEqual( "34.232", erlydtl_filters:floatformat(34.23234,-3)),
%% ?assertEqual( "34", erlydtl_filters:floatformat(34.00000,-3)),
%% ?assertEqual( "34.260", erlydtl_filters:floatformat(34.26000,-3)).
{"int |floatformat",
<<"{{ var1|floatformat:\"-1\" }}">>, [{var1, 123}],
<<"123">>},
{"string |floatformat",
<<"{{ var1|floatformat:\"-1\" }}">>, [{var1, "123.321"}],
<<"123.3">>},
{"binary |floatformat",
<<"{{ var1|floatformat:\"-1\" }}">>, [{var1, <<"123.321">>}],
<<"123.3">>},

%% from: https://docs.djangoproject.com/en/1.6/ref/templates/builtins/#floatformat
{"1.a) |floatformat",
<<"{{ var1|floatformat }}">>, [{var1, 34.23234}],
<<"34.2">>},
{"1.b) |floatformat",
<<"{{ var1|floatformat }}">>, [{var1, 34.00000}],
<<"34">>},
{"1.c) |floatformat",
<<"{{ var1|floatformat }}">>, [{var1, 34.26000}],
<<"34.3">>},
{"2.a) |floatformat:\"3\"",
<<"{{ var1|floatformat:\"3\" }}">>, [{var1, 34.23234}],
<<"34.232">>},
{"2.b) |floatformat:\"3\"",
<<"{{ var1|floatformat:\"3\" }}">>, [{var1, 34.00000}],
<<"34.000">>},
{"2.c) |floatformat:\"3\"",
<<"{{ var1|floatformat:\"3\" }}">>, [{var1, 34.26000}],
<<"34.260">>},
{"3.a) |floatformat:\"0\"",
<<"{{ var1|floatformat:\"0\" }}">>, [{var1, 34.23234}],
<<"34">>},
{"3.b) |floatformat:\"0\"",
<<"{{ var1|floatformat:\"0\" }}">>, [{var1, 34.00000}],
<<"34">>},
{"3.c) |floatformat:\"0\"",
<<"{{ var1|floatformat:\"0\" }}">>, [{var1, 39.56000}],
<<"40">>},
{"4.a) |floatformat:\"-3\"",
<<"{{ var1|floatformat:\"-3\" }}">>, [{var1, 34.23234}],
<<"34.232">>},
{"4.b) |floatformat:\"-3\"",
<<"{{ var1|floatformat:\"-3\" }}">>, [{var1, 34.00000}],
<<"34">>},
{"4.c) |floatformat:\"-3\"",
<<"{{ var1|floatformat:\"-3\" }}">>, [{var1, 34.26000}],
<<"34.260">>},

{"|force_escape",
<<"{{ var1|force_escape }}">>, [{var1, "Ben & Jerry's <=> \"The World's Best Ice Cream\""}],
<<"Ben &amp; Jerry&#039;s &lt;=&gt; &quot;The World&#039;s Best Ice Cream&quot;">>},
Expand Down

0 comments on commit b57284a

Please sign in to comment.