diff --git a/Makefile b/Makefile index 8f9aa6b..c4a7793 100755 --- a/Makefile +++ b/Makefile @@ -29,3 +29,4 @@ clean: rm -fv ebin/*.beam rm -fv ebin/$(APP) rm -fv erl_crash.dump $(PARSER).erl + rm -fv examples/rendered_output/* diff --git a/src/erlydtl/erlydtl_filters.erl b/src/erlydtl/erlydtl_filters.erl index dcfc02e..5e3feca 100755 --- a/src/erlydtl/erlydtl_filters.erl +++ b/src/erlydtl/erlydtl_filters.erl @@ -38,7 +38,7 @@ -export([add/2, capfirst/1, center/2, date/2, escapejs/1, first/1]). -export([fix_ampersands/1, force_escape/1, format_integer/1, format_number/1]). -export([join/2, last/1, length/1, length_is/2, linebreaksbr/1, ljust/2]). --export([lower/1, rjust/2, upper/1, urlencode/1]). +-export([lower/1, rjust/2, truncatewords/2, upper/1, urlencode/1]). -define(NO_ENCODE(C), ((C >= $a andalso C =< $z) orelse (C >= $A andalso C =< $Z) orelse @@ -194,6 +194,16 @@ rjust(Input, Number) when is_binary(Input) -> rjust(Input, Number) -> string:right(Input, Number). +%% @doc Truncates a string after a certain number of words. +truncatewords([Input], Max) when is_list(Input) or is_binary(Input) -> + truncatewords(Input, Max); +truncatewords(Input, Max) when is_binary(Input) -> + list_to_binary(truncatewords(binary_to_list(Input), Max)); +truncatewords(_Input, Max) when Max =< 0 -> + ""; +truncatewords(Input, Max) -> + truncatewords(Input, Max, []). + %% @doc Converts a string into all uppercase. upper([Input]) when is_list(Input) or is_binary(Input) -> upper(Input); @@ -316,6 +326,15 @@ lower(Input, Index) -> Input end. +truncatewords(Input, _WordsLeft, Acc) when length(Input) =:= 0 -> + lists:reverse(Acc); +truncatewords(_Input, WordsLeft, Acc) when WordsLeft =:= 0 -> + lists:reverse("..." ++ Acc); +truncatewords([C1, C2|Rest], WordsLeft, Acc) when C1 =/= $\ andalso C2 =:= $\ -> + truncatewords([C2|Rest], WordsLeft - 1, [C1|Acc]); +truncatewords([C1|Rest], WordsLeft, Acc) -> + truncatewords(Rest, WordsLeft, [C1|Acc]). + % Taken from quote_plus of mochiweb_util urlencode(Input, Index) when is_binary(Input) -> diff --git a/src/tests/erlydtl_unittests.erl b/src/tests/erlydtl_unittests.erl index b1656f2..c52f795 100644 --- a/src/tests/erlydtl_unittests.erl +++ b/src/tests/erlydtl_unittests.erl @@ -298,6 +298,15 @@ tests() -> {"|rjust:10", <<"{{ var1|rjust:10 }}">>, [{var1, "Bush"}], <<" Bush">>}, + {"|truncatewords:0", + <<"{{ var1|truncatewords:0 }}">>, [{var1, "Empty Me"}], + <<"">>}, + {"|truncatewords:2", + <<"{{ var1|truncatewords:2 }}">>, [{var1, "Truncate Me Please"}], + <<"Truncate Me...">>}, + {"|truncatewords:3", + <<"{{ var1|truncatewords:3 }}">>, [{var1, "Don't Truncate Me"}], + <<"Don't Truncate Me">>}, {"|upper", <<"{{ message|upper }}">>, [{message, "That man has a gun."}], <<"THAT MAN HAS A GUN.">>},