Просмотр исходного кода

Fix indentation according to erlang-mode.

My apologies for anyone having outstanding changes, getting a lot of
conflicts due to this. But it is a pain to keep the code tidy with
disagreeing indentation policies.
Andreas Stenius 11 лет назад
Родитель
Сommit
c484084b59

+ 1 - 1
src/erlydtl.app.src

@@ -1,7 +1,7 @@
 %% -*- mode: erlang -*-
 {application, erlydtl,
  [{description, "ErlyDTL compiles the Django Template Language to Erlang bytecode"},
-  {vsn, "0.7.0"},
+  {vsn, git},
   {modules, [
             ]},
   {applications, [kernel, stdlib, compiler, syntax_tools]},

+ 2 - 2
src/erlydtl.erl

@@ -3,9 +3,9 @@
 %%% @author    Roberto Saccon <rsaccon@gmail.com> [http://rsaccon.com]
 %%% @author    Evan Miller <emmiller@gmail.com>
 %%% @copyright 2008 Roberto Saccon, Evan Miller
-%%% @doc  
+%%% @doc
 %%% Public interface for ErlyDTL
-%%% @end  
+%%% @end
 %%%
 %%% The MIT License
 %%%

+ 557 - 557
src/erlydtl_compiler.erl

@@ -4,9 +4,9 @@
 %%% @author    Evan Miller <emmiller@gmail.com>
 %%% @author    Andreas Stenius <kaos@astekk.se>
 %%% @copyright 2008 Roberto Saccon, Evan Miller
-%%% @doc  
+%%% @doc
 %%% ErlyDTL template compiler
-%%% @end  
+%%% @end
 %%%
 %%% The MIT License
 %%%
@@ -44,8 +44,8 @@
 
 %% exported for use by extension modules
 -export([
-         merge_info/2, 
-         format/3, 
+         merge_info/2,
+         format/3,
          value_ast/5,
          resolve_scoped_variable_ast/2,
          interpret_args/3,
@@ -80,7 +80,7 @@ compile(Binary, Module, Options0) when is_binary(Binary) ->
 compile(File, Module, Options0) ->
     Options = maybe_add_env_default_opts(Options0),
     Context = init_dtl_context(File, Module, Options),
-    case parse(File, Context) of  
+    case parse(File, Context) of
         ok ->
             ok;
         {ok, DjangoParseTree, CheckSum} ->
@@ -105,25 +105,25 @@ compile_dir(Dir, Module, Options0) ->
     %% files ending in "~").
     Files = filelib:fold_files(Dir, ".+[^~]$", true, fun(F1,Acc1) -> [F1 | Acc1] end, []),
     {ParserResults, ParserErrors} = lists:foldl(fun
-						    (File, {ResultAcc, ErrorAcc}) ->
-						       case filename:basename(File) of
-							   "."++_ ->
-							       {ResultAcc, ErrorAcc};
-							   _ ->
-							       FilePath = filename:absname(File),
-							       case filelib:is_dir(FilePath) of
-								   true ->
-								       {ResultAcc, ErrorAcc};
-								   false ->
-								       case parse(FilePath, Context) of
-									   ok -> {ResultAcc, ErrorAcc};
-									   {ok, DjangoParseTree, CheckSum} -> 
-									       {[{File, DjangoParseTree, CheckSum}|ResultAcc], ErrorAcc};
-									   Err -> {ResultAcc, [Err|ErrorAcc]}
-								       end
-							       end
-						       end
-					       end, {[], []}, Files),
+                                                    (File, {ResultAcc, ErrorAcc}) ->
+                                                       case filename:basename(File) of
+                                                           "."++_ ->
+                                                               {ResultAcc, ErrorAcc};
+                                                           _ ->
+                                                               FilePath = filename:absname(File),
+                                                               case filelib:is_dir(FilePath) of
+                                                                   true ->
+                                                                       {ResultAcc, ErrorAcc};
+                                                                   false ->
+                                                                       case parse(FilePath, Context) of
+                                                                           ok -> {ResultAcc, ErrorAcc};
+                                                                           {ok, DjangoParseTree, CheckSum} ->
+                                                                               {[{File, DjangoParseTree, CheckSum}|ResultAcc], ErrorAcc};
+                                                                           Err -> {ResultAcc, [Err|ErrorAcc]}
+                                                                       end
+                                                               end
+                                                       end
+                                               end, {[], []}, Files),
     case ParserErrors of
         [] ->
             case compile_multiple_to_binary(Dir, ParserResults, Context) of
@@ -179,37 +179,37 @@ write_binary(Module1, Bin, Options, Warnings) ->
             BeamFile = filename:join([OutDir, atom_to_list(Module1) ++ ".beam"]),
 
             print(Verbose, "Template module: ~w -> ~s~s\n",
-		  [Module1, BeamFile,
-		   case Warnings of
-		       [] -> "";
-		       _  -> io_lib:format("\n  Warnings: ~p", [Warnings])
-		   end]),
+                  [Module1, BeamFile,
+                   case Warnings of
+                       [] -> "";
+                       _  -> io_lib:format("\n  Warnings: ~p", [Warnings])
+                   end]),
 
             case file:write_file(BeamFile, Bin) of
                 ok ->
                     ok;
                 {error, Reason} ->
                     {error, lists:flatten(
-			      io_lib:format("Beam generation of '~s' failed: ~p",
-					    [BeamFile, file:format_error(Reason)]))}
+                              io_lib:format("Beam generation of '~s' failed: ~p",
+                                            [BeamFile, file:format_error(Reason)]))}
             end
     end.
 
 compile_multiple_to_binary(Dir, ParserResults, Context) ->
-    MatchAst = options_match_ast(Context), 
+    MatchAst = options_match_ast(Context),
     {Functions, {AstInfo, _}} = lists:mapfoldl(fun({File, DjangoParseTree, CheckSum}, {AstInfo, TreeWalker}) ->
-						       FilePath = full_path(File, Context#dtl_context.doc_root),
-						       {{BodyAst, BodyInfo}, TreeWalker1} = with_dependency({FilePath, CheckSum}, body_ast(DjangoParseTree, Context, TreeWalker)),
-						       FunctionName = filename:rootname(filename:basename(File)),
-						       Function1 = erl_syntax:function(erl_syntax:atom(FunctionName),
-										       [erl_syntax:clause([erl_syntax:variable("_Variables")], none,
-													  [erl_syntax:application(none, erl_syntax:atom(FunctionName), 
-																  [erl_syntax:variable("_Variables"), erl_syntax:list([])])])]),
-						       Function2 = erl_syntax:function(erl_syntax:atom(FunctionName), 
-										       [erl_syntax:clause([erl_syntax:variable("_Variables"), erl_syntax:variable("RenderOptions")], none,
-													  MatchAst ++ [BodyAst])]),
-						       {{FunctionName, Function1, Function2}, {merge_info(AstInfo, BodyInfo), TreeWalker1}}
-					       end, {#ast_info{}, init_treewalker(Context)}, ParserResults),
+                                                       FilePath = full_path(File, Context#dtl_context.doc_root),
+                                                       {{BodyAst, BodyInfo}, TreeWalker1} = with_dependency({FilePath, CheckSum}, body_ast(DjangoParseTree, Context, TreeWalker)),
+                                                       FunctionName = filename:rootname(filename:basename(File)),
+                                                       Function1 = erl_syntax:function(erl_syntax:atom(FunctionName),
+                                                                                       [erl_syntax:clause([erl_syntax:variable("_Variables")], none,
+                                                                                                          [erl_syntax:application(none, erl_syntax:atom(FunctionName),
+                                                                                                                                  [erl_syntax:variable("_Variables"), erl_syntax:list([])])])]),
+                                                       Function2 = erl_syntax:function(erl_syntax:atom(FunctionName),
+                                                                                       [erl_syntax:clause([erl_syntax:variable("_Variables"), erl_syntax:variable("RenderOptions")], none,
+                                                                                                          MatchAst ++ [BodyAst])]),
+                                                       {{FunctionName, Function1, Function2}, {merge_info(AstInfo, BodyInfo), TreeWalker1}}
+                                               end, {#ast_info{}, init_treewalker(Context)}, ParserResults),
     Forms = custom_forms(Dir, Context#dtl_context.module, Functions, AstInfo),
     compile_forms_and_reload(Dir, Forms, Context).
 
@@ -218,21 +218,21 @@ compile_to_binary(File, DjangoParseTree, Context, CheckSum) ->
         {{BodyAst, BodyInfo}, BodyTreeWalker} ->
             try custom_tags_ast(BodyInfo#ast_info.custom_tags, Context, BodyTreeWalker) of
                 {{CustomTagsAst, CustomTagsInfo}, _} ->
-                    Forms = forms(File, Context#dtl_context.module, {BodyAst, BodyInfo}, 
-				  {CustomTagsAst, CustomTagsInfo}, CheckSum, Context, BodyTreeWalker), 
+                    Forms = forms(File, Context#dtl_context.module, {BodyAst, BodyInfo},
+                                  {CustomTagsAst, CustomTagsInfo}, CheckSum, Context, BodyTreeWalker),
                     compile_forms_and_reload(File, Forms, Context)
-            catch 
+            catch
                 throw:Error -> Error
             end
-    catch 
+    catch
         throw:Error -> Error
     end.
 
 compile_forms_and_reload(File, Forms, Context) ->
     case proplists:get_value(debug_compiler, Context#dtl_context.compiler_options) of
-	true ->
-	    io:format("template source:~n~s~n",
-                      [try 
+        true ->
+            io:format("template source:~n~s~n",
+                      [try
                            erl_prettypr:format(erl_syntax:form_list(Forms))
                        catch
                            error:Err ->
@@ -240,10 +240,10 @@ compile_forms_and_reload(File, Forms, Context) ->
                                              [Err, Context, Forms])
                        end
                       ]);
-	_ -> nop
+        _ -> nop
     end,
     case compile:forms(Forms, Context#dtl_context.compiler_options) of
-        {ok, Module1, Bin} -> 
+        {ok, Module1, Bin} ->
             load_code(Module1, Bin, []);
         {ok, Module1, Bin, Warnings} ->
             load_code(Module1, Bin, Warnings);
@@ -264,25 +264,25 @@ init_context(IsCompilingDir, ParseTrail, DefDir, Module, Options) ->
     Ctx = #dtl_context{},
     Context = #dtl_context{
                  all_options = Options,
-		  parse_trail = ParseTrail,
-		  module = Module,
-		  doc_root = proplists:get_value(doc_root, Options, DefDir),
-		  filter_modules = proplists:get_value(custom_filters_modules, Options, Ctx#dtl_context.filter_modules) ++ [erlydtl_filters],
-		  custom_tags_dir = proplists:get_value(custom_tags_dir, Options, filename:join([erlydtl_deps:get_base_dir(), "priv", "custom_tags"])),
-		  custom_tags_modules = proplists:get_value(custom_tags_modules, Options, Ctx#dtl_context.custom_tags_modules),
-		  blocktrans_fun = proplists:get_value(blocktrans_fun, Options, Ctx#dtl_context.blocktrans_fun),
-		  blocktrans_locales = proplists:get_value(blocktrans_locales, Options, Ctx#dtl_context.blocktrans_locales),
-		  vars = proplists:get_value(vars, Options, Ctx#dtl_context.vars), 
-		  reader = proplists:get_value(reader, Options, Ctx#dtl_context.reader),
-		  compiler_options = proplists:get_value(compiler_options, Options, Ctx#dtl_context.compiler_options),
-		  binary_strings = proplists:get_value(binary_strings, Options, Ctx#dtl_context.binary_strings),
-		  force_recompile = proplists:get_value(force_recompile, Options, Ctx#dtl_context.force_recompile),
-		  locale = proplists:get_value(locale, Options, Ctx#dtl_context.locale),
-		  verbose = proplists:get_value(verbose, Options, Ctx#dtl_context.verbose),
-		  is_compiling_dir = IsCompilingDir,
-		  extension_module = proplists:get_value(extension_module, Options, Ctx#dtl_context.extension_module),
-		  scanner_module = proplists:get_value(scanner_module, Options, Ctx#dtl_context.scanner_module)
-		},
+                 parse_trail = ParseTrail,
+                 module = Module,
+                 doc_root = proplists:get_value(doc_root, Options, DefDir),
+                 filter_modules = proplists:get_value(custom_filters_modules, Options, Ctx#dtl_context.filter_modules) ++ [erlydtl_filters],
+                 custom_tags_dir = proplists:get_value(custom_tags_dir, Options, filename:join([erlydtl_deps:get_base_dir(), "priv", "custom_tags"])),
+                 custom_tags_modules = proplists:get_value(custom_tags_modules, Options, Ctx#dtl_context.custom_tags_modules),
+                 blocktrans_fun = proplists:get_value(blocktrans_fun, Options, Ctx#dtl_context.blocktrans_fun),
+                 blocktrans_locales = proplists:get_value(blocktrans_locales, Options, Ctx#dtl_context.blocktrans_locales),
+                 vars = proplists:get_value(vars, Options, Ctx#dtl_context.vars),
+                 reader = proplists:get_value(reader, Options, Ctx#dtl_context.reader),
+                 compiler_options = proplists:get_value(compiler_options, Options, Ctx#dtl_context.compiler_options),
+                 binary_strings = proplists:get_value(binary_strings, Options, Ctx#dtl_context.binary_strings),
+                 force_recompile = proplists:get_value(force_recompile, Options, Ctx#dtl_context.force_recompile),
+                 locale = proplists:get_value(locale, Options, Ctx#dtl_context.locale),
+                 verbose = proplists:get_value(verbose, Options, Ctx#dtl_context.verbose),
+                 is_compiling_dir = IsCompilingDir,
+                 extension_module = proplists:get_value(extension_module, Options, Ctx#dtl_context.extension_module),
+                 scanner_module = proplists:get_value(scanner_module, Options, Ctx#dtl_context.scanner_module)
+                },
     case call_extension(Context, init_context, [Context]) of
         {ok, C} when is_record(C, dtl_context) -> C;
         undefined -> Context
@@ -311,25 +311,25 @@ is_up_to_date(CheckSum, Context) ->
     Module = Context#dtl_context.module,
     {M, F} = Context#dtl_context.reader,
     case catch Module:source() of
-        {_, CheckSum} -> 
+        {_, CheckSum} ->
             case catch Module:dependencies() of
                 L when is_list(L) ->
                     RecompileList = lists:foldl(fun
-						    ({XFile, XCheckSum}, Acc) ->
-						       case catch M:F(XFile) of
-							   {ok, Data} ->
-							       case binary_to_list(erlang:md5(Data)) of
-								   XCheckSum ->
-								       Acc;
-								   _ ->
-								       [recompile | Acc]
-							       end;
-							   _ ->
-							       [recompile | Acc]
-						       end                                        
-					       end, [], L),
+                                                    ({XFile, XCheckSum}, Acc) ->
+                                                       case catch M:F(XFile) of
+                                                           {ok, Data} ->
+                                                               case binary_to_list(erlang:md5(Data)) of
+                                                                   XCheckSum ->
+                                                                       Acc;
+                                                                   _ ->
+                                                                       [recompile | Acc]
+                                                               end;
+                                                           _ ->
+                                                               [recompile | Acc]
+                                                       end
+                                               end, [], L),
                     case RecompileList of
-                        [] -> true; 
+                        [] -> true;
                         _ -> false
                     end;
                 _ ->
@@ -345,7 +345,7 @@ parse(Data) ->
 parse(Data, #dtl_context{ scanner_module=Scanner }=Context)
   when is_binary(Data) ->
     check_scan(apply(Scanner, scan, [binary_to_list(Data)]), Context);
-parse(File, Context) ->  
+parse(File, Context) ->
     {M, F} = Context#dtl_context.reader,
     case catch M:F(File) of
         {ok, Data} ->
@@ -377,27 +377,27 @@ parse(CheckSum, Data, Context) ->
 
 call_extension(#dtl_context{ extension_module=undefined }, _Fun, _Args) ->
     undefined;
-call_extension(#dtl_context{ extension_module=Mod }, Fun, Args) 
+call_extension(#dtl_context{ extension_module=Mod }, Fun, Args)
   when is_atom(Mod), is_atom(Fun), is_list(Args) ->
     M = case code:is_loaded(Mod) of
-	    false ->
-		case code:load_file(Mod) of
-		    {module, Mod} ->
-			Mod;
-		    _ ->
-			undefined
-		end;
-	    _ -> Mod
-	end,
+            false ->
+                case code:load_file(Mod) of
+                    {module, Mod} ->
+                        Mod;
+                    _ ->
+                        undefined
+                end;
+            _ -> Mod
+        end,
     if M /= undefined ->
-	    case erlang:function_exported(M, Fun, length(Args)) of
-		true ->
-		    apply(M, Fun, Args);
-		false ->
-		    undefined
-	    end;
+            case erlang:function_exported(M, Fun, length(Args)) of
+                true ->
+                    apply(M, Fun, Args);
+                false ->
+                    undefined
+            end;
        true ->
-	    undefined
+            undefined
     end.
 
 check_scan({ok, Tokens}, Context) ->
@@ -490,7 +490,7 @@ custom_tags_clauses_ast1([], _ExcludeTags, ClauseAcc, InfoAcc, Context, TreeWalk
         case call_extension(Context, custom_tag_ast, [Context, TreeWalker]) of
             undefined ->
                 {{erl_syntax:clause(
-                    [erl_syntax:variable("_TagName"), erl_syntax:underscore(), erl_syntax:underscore()], 
+                    [erl_syntax:variable("_TagName"), erl_syntax:underscore(), erl_syntax:underscore()],
                     none,
                     [erl_syntax:list([])]),
                   InfoAcc},
@@ -513,14 +513,14 @@ custom_tags_clauses_ast1([Tag|CustomTags], ExcludeTags, ClauseAcc, InfoAcc, Cont
                     case parse(CustomTagFile, Context) of
                         {ok, DjangoParseTree, CheckSum} ->
                             {{BodyAst, BodyAstInfo}, TreeWalker1} = with_dependency(
-								      {CustomTagFile, CheckSum}, body_ast(DjangoParseTree, Context, TreeWalker)),
-                            MatchAst = options_match_ast(Context, TreeWalker), 
+                                                                      {CustomTagFile, CheckSum}, body_ast(DjangoParseTree, Context, TreeWalker)),
+                            MatchAst = options_match_ast(Context, TreeWalker),
                             Clause = erl_syntax:clause(
-				       [erl_syntax:atom(Tag), erl_syntax:variable("_Variables"), erl_syntax:variable("RenderOptions")],
-				       none, MatchAst ++ [BodyAst]),
+                                       [erl_syntax:atom(Tag), erl_syntax:variable("_Variables"), erl_syntax:variable("RenderOptions")],
+                                       none, MatchAst ++ [BodyAst]),
                             custom_tags_clauses_ast1(CustomTags, [Tag|ExcludeTags],
-						     [Clause|ClauseAcc], merge_info(BodyAstInfo, InfoAcc), 
-						     Context, TreeWalker1);
+                                                     [Clause|ClauseAcc], merge_info(BodyAstInfo, InfoAcc),
+                                                     Context, TreeWalker1);
                         Error ->
                             throw(Error)
                     end;
@@ -535,90 +535,90 @@ custom_tags_clauses_ast1([Tag|CustomTags], ExcludeTags, ClauseAcc, InfoAcc, Cont
                                        [erl_syntax:atom(Tag), erl_syntax:variable("_Variables"), erl_syntax:variable("RenderOptions")],
                                        none, options_match_ast(Context, TW) ++ [Ast]),
                             custom_tags_clauses_ast1(
-                             CustomTags, [Tag | ExcludeTags],
-                             [Clause|ClauseAcc], merge_info(Info, InfoAcc),
-                             Context, TW)
+                              CustomTags, [Tag | ExcludeTags],
+                              [Clause|ClauseAcc], merge_info(Info, InfoAcc),
+                              Context, TW)
                     end
             end
     end.
 
 dependencies_function(Dependencies) ->
     erl_syntax:function(
-      erl_syntax:atom(dependencies), [erl_syntax:clause([], none, 
-							[erl_syntax:list(lists:map(fun 
-										       ({XFile, XCheckSum}) -> 
-											  erl_syntax:tuple([erl_syntax:string(XFile), erl_syntax:string(XCheckSum)])
-										  end, Dependencies))])]).
+      erl_syntax:atom(dependencies), [erl_syntax:clause([], none,
+                                                        [erl_syntax:list(lists:map(fun
+                                                                                       ({XFile, XCheckSum}) ->
+                                                                                          erl_syntax:tuple([erl_syntax:string(XFile), erl_syntax:string(XCheckSum)])
+                                                                                  end, Dependencies))])]).
 
 translatable_strings_function(TranslatableStrings) ->
     erl_syntax:function(
       erl_syntax:atom(translatable_strings), [erl_syntax:clause([], none,
-								[erl_syntax:list(lists:map(fun(String) -> 
-												   erl_syntax:string(String) 
-											   end,
-											   TranslatableStrings))])]).
+                                                                [erl_syntax:list(lists:map(fun(String) ->
+                                                                                                   erl_syntax:string(String)
+                                                                                           end,
+                                                                                           TranslatableStrings))])]).
 
 translated_blocks_function(TranslatedBlocks) ->
     erl_syntax:function(
       erl_syntax:atom(translated_blocks), [erl_syntax:clause([], none,
-							     [erl_syntax:list(lists:map(fun(String) -> 
-												erl_syntax:string(String) 
-											end,
-											TranslatedBlocks))])]).
+                                                             [erl_syntax:list(lists:map(fun(String) ->
+                                                                                                erl_syntax:string(String)
+                                                                                        end,
+                                                                                        TranslatedBlocks))])]).
 
 variables_function(Variables) ->
     erl_syntax:function(
       erl_syntax:atom(variables), [erl_syntax:clause([], none,
-						     [erl_syntax:list([erl_syntax:atom(S) || S <- lists:usort(Variables)])])]). 
+                                                     [erl_syntax:list([erl_syntax:atom(S) || S <- lists:usort(Variables)])])]).
 
 custom_forms(Dir, Module, Functions, AstInfo) ->
     ModuleAst = erl_syntax:attribute(erl_syntax:atom(module), [erl_syntax:atom(Module)]),
     ExportAst = erl_syntax:attribute(erl_syntax:atom(export),
-				     [erl_syntax:list([
-						       erl_syntax:arity_qualifier(erl_syntax:atom(source_dir), erl_syntax:integer(0)),
-						       erl_syntax:arity_qualifier(erl_syntax:atom(dependencies), erl_syntax:integer(0)),
-						       erl_syntax:arity_qualifier(erl_syntax:atom(translatable_strings), erl_syntax:integer(0))
-						       | 
-						       lists:foldl(fun({FunctionName, _, _}, Acc) ->
-									   [erl_syntax:arity_qualifier(erl_syntax:atom(FunctionName), erl_syntax:integer(1)),
-									    erl_syntax:arity_qualifier(erl_syntax:atom(FunctionName), erl_syntax:integer(2))|Acc]
-								   end, [], Functions)]
-						     )]),
+                                     [erl_syntax:list([
+                                                       erl_syntax:arity_qualifier(erl_syntax:atom(source_dir), erl_syntax:integer(0)),
+                                                       erl_syntax:arity_qualifier(erl_syntax:atom(dependencies), erl_syntax:integer(0)),
+                                                       erl_syntax:arity_qualifier(erl_syntax:atom(translatable_strings), erl_syntax:integer(0))
+                                                       |
+                                                       lists:foldl(fun({FunctionName, _, _}, Acc) ->
+                                                                           [erl_syntax:arity_qualifier(erl_syntax:atom(FunctionName), erl_syntax:integer(1)),
+                                                                            erl_syntax:arity_qualifier(erl_syntax:atom(FunctionName), erl_syntax:integer(2))|Acc]
+                                                                   end, [], Functions)]
+                                                     )]),
     SourceFunctionAst = erl_syntax:function(
-			  erl_syntax:atom(source_dir), [erl_syntax:clause([], none, [erl_syntax:string(Dir)])]),
-    DependenciesFunctionAst = dependencies_function(AstInfo#ast_info.dependencies), 
+                          erl_syntax:atom(source_dir), [erl_syntax:clause([], none, [erl_syntax:string(Dir)])]),
+    DependenciesFunctionAst = dependencies_function(AstInfo#ast_info.dependencies),
     TranslatableStringsFunctionAst = translatable_strings_function(AstInfo#ast_info.translatable_strings),
     FunctionAsts = lists:foldl(fun({_, Function1, Function2}, Acc) -> [Function1, Function2 | Acc] end, [], Functions),
 
     [erl_syntax:revert(X) || X <- [ModuleAst, ExportAst, SourceFunctionAst, DependenciesFunctionAst, TranslatableStringsFunctionAst
-				   | FunctionAsts] ++ AstInfo#ast_info.pre_render_asts].
+                                   | FunctionAsts] ++ AstInfo#ast_info.pre_render_asts].
 
 forms(File, Module, {BodyAst, BodyInfo}, {CustomTagsFunctionAst, CustomTagsInfo}, CheckSum, Context, TreeWalker) ->
     MergedInfo = merge_info(BodyInfo, CustomTagsInfo),
     Render0FunctionAst = erl_syntax:function(erl_syntax:atom(render),
-					     [erl_syntax:clause([], none, [erl_syntax:application(none, 
-												  erl_syntax:atom(render), [erl_syntax:list([])])])]),
+                                             [erl_syntax:clause([], none, [erl_syntax:application(none,
+                                                                                                  erl_syntax:atom(render), [erl_syntax:list([])])])]),
     Render1FunctionAst = erl_syntax:function(erl_syntax:atom(render),
-					     [erl_syntax:clause([erl_syntax:variable("_Variables")], none,
-								[erl_syntax:application(none,
-											erl_syntax:atom(render),
-											[erl_syntax:variable("_Variables"), erl_syntax:list([])])])]),
-    Function2 = erl_syntax:application(none, erl_syntax:atom(render_internal), 
-				       [erl_syntax:variable("_Variables"), erl_syntax:variable("RenderOptions")]),
+                                             [erl_syntax:clause([erl_syntax:variable("_Variables")], none,
+                                                                [erl_syntax:application(none,
+                                                                                        erl_syntax:atom(render),
+                                                                                        [erl_syntax:variable("_Variables"), erl_syntax:list([])])])]),
+    Function2 = erl_syntax:application(none, erl_syntax:atom(render_internal),
+                                       [erl_syntax:variable("_Variables"), erl_syntax:variable("RenderOptions")]),
     ClauseOk = erl_syntax:clause([erl_syntax:variable("Val")], none,
-				 [erl_syntax:tuple([erl_syntax:atom(ok), erl_syntax:variable("Val")])]),     
+                                 [erl_syntax:tuple([erl_syntax:atom(ok), erl_syntax:variable("Val")])]),
     ClauseCatch = erl_syntax:clause([erl_syntax:variable("Err")], none,
-				    [erl_syntax:tuple([erl_syntax:atom(error), erl_syntax:variable("Err")])]),            
+                                    [erl_syntax:tuple([erl_syntax:atom(error), erl_syntax:variable("Err")])]),
     Render2FunctionAst = erl_syntax:function(erl_syntax:atom(render),
-					     [erl_syntax:clause([erl_syntax:variable("_Variables"),
-								 erl_syntax:variable("RenderOptions")], none, 
-								[erl_syntax:try_expr([Function2], [ClauseOk], [ClauseCatch])])]),  
+                                             [erl_syntax:clause([erl_syntax:variable("_Variables"),
+                                                                 erl_syntax:variable("RenderOptions")], none,
+                                                                [erl_syntax:try_expr([Function2], [ClauseOk], [ClauseCatch])])]),
 
     SourceFunctionTuple = erl_syntax:tuple(
-			    [erl_syntax:string(File), erl_syntax:string(CheckSum)]),
+                            [erl_syntax:string(File), erl_syntax:string(CheckSum)]),
     SourceFunctionAst = erl_syntax:function(
-			  erl_syntax:atom(source),
-			  [erl_syntax:clause([], none, [SourceFunctionTuple])]),
+                          erl_syntax:atom(source),
+                          [erl_syntax:clause([], none, [SourceFunctionTuple])]),
 
     DependenciesFunctionAst = dependencies_function(MergedInfo#ast_info.dependencies),
 
@@ -628,66 +628,66 @@ forms(File, Module, {BodyAst, BodyInfo}, {CustomTagsFunctionAst, CustomTagsInfo}
 
     VariablesAst = variables_function(MergedInfo#ast_info.var_names),
 
-    MatchAst = options_match_ast(Context, TreeWalker), 
+    MatchAst = options_match_ast(Context, TreeWalker),
 
     BodyAstTmp = MatchAst ++ [
-			      erl_syntax:application(
-				erl_syntax:atom(erlydtl_runtime),
-				erl_syntax:atom(stringify_final),
-				[BodyAst, erl_syntax:atom(Context#dtl_context.binary_strings)])
-			     ],
+                              erl_syntax:application(
+                                erl_syntax:atom(erlydtl_runtime),
+                                erl_syntax:atom(stringify_final),
+                                [BodyAst, erl_syntax:atom(Context#dtl_context.binary_strings)])
+                             ],
 
     RenderInternalFunctionAst = erl_syntax:function(
-				  erl_syntax:atom(render_internal), 
-				  [erl_syntax:clause([
-						      erl_syntax:variable("_Variables"),
-						      erl_syntax:variable("RenderOptions")],
-						     none, BodyAstTmp)]
-				 ),   
+                                  erl_syntax:atom(render_internal),
+                                  [erl_syntax:clause([
+                                                      erl_syntax:variable("_Variables"),
+                                                      erl_syntax:variable("RenderOptions")],
+                                                     none, BodyAstTmp)]
+                                 ),
 
     ModuleAst  = erl_syntax:attribute(erl_syntax:atom(module), [erl_syntax:atom(Module)]),
 
     ExportAst = erl_syntax:attribute(erl_syntax:atom(export),
-				     [erl_syntax:list([erl_syntax:arity_qualifier(erl_syntax:atom(render), erl_syntax:integer(0)),
-						       erl_syntax:arity_qualifier(erl_syntax:atom(render), erl_syntax:integer(1)),
-						       erl_syntax:arity_qualifier(erl_syntax:atom(render), erl_syntax:integer(2)),
-						       erl_syntax:arity_qualifier(erl_syntax:atom(source), erl_syntax:integer(0)),
-						       erl_syntax:arity_qualifier(erl_syntax:atom(dependencies), erl_syntax:integer(0)),
-						       erl_syntax:arity_qualifier(erl_syntax:atom(translatable_strings), erl_syntax:integer(0)),
-						       erl_syntax:arity_qualifier(erl_syntax:atom(translated_blocks), erl_syntax:integer(0)),
-						       erl_syntax:arity_qualifier(erl_syntax:atom(variables), erl_syntax:integer(0))
-						      ])]),
+                                     [erl_syntax:list([erl_syntax:arity_qualifier(erl_syntax:atom(render), erl_syntax:integer(0)),
+                                                       erl_syntax:arity_qualifier(erl_syntax:atom(render), erl_syntax:integer(1)),
+                                                       erl_syntax:arity_qualifier(erl_syntax:atom(render), erl_syntax:integer(2)),
+                                                       erl_syntax:arity_qualifier(erl_syntax:atom(source), erl_syntax:integer(0)),
+                                                       erl_syntax:arity_qualifier(erl_syntax:atom(dependencies), erl_syntax:integer(0)),
+                                                       erl_syntax:arity_qualifier(erl_syntax:atom(translatable_strings), erl_syntax:integer(0)),
+                                                       erl_syntax:arity_qualifier(erl_syntax:atom(translated_blocks), erl_syntax:integer(0)),
+                                                       erl_syntax:arity_qualifier(erl_syntax:atom(variables), erl_syntax:integer(0))
+                                                      ])]),
 
     erl_syntax:revert_forms(
       erl_syntax:form_list(
         [ModuleAst, ExportAst, Render0FunctionAst, Render1FunctionAst, Render2FunctionAst,
          SourceFunctionAst, DependenciesFunctionAst, TranslatableStringsAst,
-         TranslatedBlocksAst, VariablesAst, RenderInternalFunctionAst, 
+         TranslatedBlocksAst, VariablesAst, RenderInternalFunctionAst,
          CustomTagsFunctionAst
          |BodyInfo#ast_info.pre_render_asts])).
 
 options_match_ast(Context) -> options_match_ast(Context, undefined).
-options_match_ast(Context, TreeWalker) -> 
+options_match_ast(Context, TreeWalker) ->
     [
      erl_syntax:match_expr(
        erl_syntax:variable("_TranslationFun"),
        erl_syntax:application(
-	 erl_syntax:atom(proplists),
-	 erl_syntax:atom(get_value),
-	 [erl_syntax:atom(translation_fun), erl_syntax:variable("RenderOptions"), erl_syntax:atom(none)])),
+         erl_syntax:atom(proplists),
+         erl_syntax:atom(get_value),
+         [erl_syntax:atom(translation_fun), erl_syntax:variable("RenderOptions"), erl_syntax:atom(none)])),
      erl_syntax:match_expr(
        erl_syntax:variable("_CurrentLocale"),
        erl_syntax:application(
-	 erl_syntax:atom(proplists),
-	 erl_syntax:atom(get_value),
-	 [erl_syntax:atom(locale), erl_syntax:variable("RenderOptions"), erl_syntax:atom(none)]))
+         erl_syntax:atom(proplists),
+         erl_syntax:atom(get_value),
+         [erl_syntax:atom(locale), erl_syntax:variable("RenderOptions"), erl_syntax:atom(none)]))
      | case call_extension(Context, setup_render_ast, [Context, TreeWalker]) of
            undefined -> [];
            Ast when is_list(Ast) -> Ast
        end
     ].
 
-						% child templates should only consist of blocks at the top level
+                                                % child templates should only consist of blocks at the top level
 body_ast([{'extends', {string_literal, _Pos, String}} | ThisParseTree], Context, TreeWalker) ->
     File = full_path(unescape_string_literal(String), Context#dtl_context.doc_root),
     case lists:member(File, Context#dtl_context.parse_trail) of
@@ -697,160 +697,160 @@ body_ast([{'extends', {string_literal, _Pos, String}} | ThisParseTree], Context,
             case parse(File, Context) of
                 {ok, ParentParseTree, CheckSum} ->
                     BlockDict = lists:foldl(
-				  fun
-				      ({block, {identifier, _, Name}, Contents}, Dict) ->
-						   dict:store(Name, Contents, Dict);
-				      (_, Dict) ->
-						   Dict
-					   end, dict:new(), ThisParseTree),
+                                  fun
+                                      ({block, {identifier, _, Name}, Contents}, Dict) ->
+                                                   dict:store(Name, Contents, Dict);
+                                      (_, Dict) ->
+                                                   Dict
+                                           end, dict:new(), ThisParseTree),
                     with_dependency({File, CheckSum}, body_ast(ParentParseTree, Context#dtl_context{
-										  block_dict = dict:merge(fun(_Key, _ParentVal, ChildVal) -> ChildVal end,
-													  BlockDict, Context#dtl_context.block_dict),
-										  parse_trail = [File | Context#dtl_context.parse_trail]}, TreeWalker));
+                                                                                  block_dict = dict:merge(fun(_Key, _ParentVal, ChildVal) -> ChildVal end,
+                                                                                                          BlockDict, Context#dtl_context.block_dict),
+                                                                                  parse_trail = [File | Context#dtl_context.parse_trail]}, TreeWalker));
                 Err ->
                     throw(Err)
-            end        
+            end
     end;
 
 
 body_ast(DjangoParseTree, Context, TreeWalker) ->
     {AstInfoList, TreeWalker2} = lists:mapfoldl(
-				   fun
-				       ({'autoescape', {identifier, _, OnOrOff}, Contents}, TreeWalkerAcc) ->
-						       body_ast(Contents, Context#dtl_context{auto_escape = OnOrOff}, 
-								TreeWalkerAcc);
-				       ({'block', {identifier, _, Name}, Contents}, TreeWalkerAcc) ->
-						       Block = case dict:find(Name, Context#dtl_context.block_dict) of
-								   {ok, ChildBlock} -> ChildBlock;
-								   _ -> Contents
-							       end,
-						       body_ast(Block, Context, TreeWalkerAcc);
-				       ({'blocktrans', Args, Contents}, TreeWalkerAcc) ->
-						       blocktrans_ast(Args, Contents, Context, TreeWalkerAcc);
-				       ({'call', {identifier, _, Name}}, TreeWalkerAcc) ->
-						       call_ast(Name, TreeWalkerAcc);
-				       ({'call', {identifier, _, Name}, With}, TreeWalkerAcc) ->
-						       call_with_ast(Name, With, Context, TreeWalkerAcc);
-				       ({'comment', _Contents}, TreeWalkerAcc) ->
-						       empty_ast(TreeWalkerAcc);
-				       ({'cycle', Names}, TreeWalkerAcc) ->
-						       cycle_ast(Names, Context, TreeWalkerAcc);
-				       ({'cycle_compat', Names}, TreeWalkerAcc) ->
-						       cycle_compat_ast(Names, Context, TreeWalkerAcc);
-				       ({'date', 'now', {string_literal, _Pos, FormatString}}, TreeWalkerAcc) ->
-						       now_ast(FormatString, Context, TreeWalkerAcc);
-				       ({'filter', FilterList, Contents}, TreeWalkerAcc) ->
-						       filter_tag_ast(FilterList, Contents, Context, TreeWalkerAcc);
-				       ({'firstof', Vars}, TreeWalkerAcc) ->
-						       firstof_ast(Vars, Context, TreeWalkerAcc);
-				       ({'for', {'in', IteratorList, Variable, Reversed}, Contents}, TreeWalkerAcc) ->
-						       {EmptyAstInfo, TreeWalker1} = empty_ast(TreeWalkerAcc),
-						       for_loop_ast(IteratorList, Variable, Reversed, Contents, EmptyAstInfo, Context, TreeWalker1);
-				       ({'for', {'in', IteratorList, Variable, Reversed}, Contents, EmptyPartContents}, TreeWalkerAcc) ->
-						       {EmptyAstInfo, TreeWalker1} = body_ast(EmptyPartContents, Context, TreeWalkerAcc),
-						       for_loop_ast(IteratorList, Variable, Reversed, Contents, EmptyAstInfo, Context, TreeWalker1);
-				       ({'if', Expression, Contents, Elif}, TreeWalkerAcc) ->
-						       {IfAstInfo, TreeWalker1} = body_ast(Contents, Context, TreeWalkerAcc),
-						       {ElifAstInfo, TreeWalker2} = body_ast(Elif, Context, TreeWalker1),
-						       ifelse_ast(Expression, IfAstInfo, ElifAstInfo, Context, TreeWalker2);
-				       ({'if', Expression, Contents}, TreeWalkerAcc) ->
-						       {IfAstInfo, TreeWalker1} = body_ast(Contents, Context, TreeWalkerAcc),
-						       {ElseAstInfo, TreeWalker2} = empty_ast(TreeWalker1),
-						       ifelse_ast(Expression, IfAstInfo, ElseAstInfo, Context, TreeWalker2);
-				       ({'ifchanged', '$undefined', Contents}, TreeWalkerAcc) ->
-						       {IfAstInfo, TreeWalker1} = body_ast(Contents, Context, TreeWalkerAcc),
-						       {ElseAstInfo, TreeWalker2} = empty_ast(TreeWalker1),
-						       ifchanged_contents_ast(Contents, IfAstInfo, ElseAstInfo, Context, TreeWalker2);
-				       ({'ifchanged', Values, Contents}, TreeWalkerAcc) ->
-						       {IfAstInfo, TreeWalker1} = body_ast(Contents, Context, TreeWalkerAcc),
-						       {ElseAstInfo, TreeWalker2} = empty_ast(TreeWalker1),
-						       ifchanged_values_ast(Values, IfAstInfo, ElseAstInfo, Context, TreeWalker2);
-				       ({'ifchangedelse', '$undefined', IfContents, ElseContents}, TreeWalkerAcc) ->
-						       {IfAstInfo, TreeWalker1} = body_ast(IfContents, Context, TreeWalkerAcc),
-						       {ElseAstInfo, TreeWalker2} = body_ast(ElseContents, Context, TreeWalker1),
-						       ifchanged_contents_ast(IfContents, IfAstInfo, ElseAstInfo, Context, TreeWalker2);
-				       ({'ifchangedelse', Values, IfContents, ElseContents}, TreeWalkerAcc) ->
-						       {IfAstInfo, TreeWalker1} = body_ast(IfContents, Context, TreeWalkerAcc),
-						       {ElseAstInfo, TreeWalker2} = body_ast(ElseContents, Context, TreeWalker1),
-						       ifchanged_values_ast(Values, IfAstInfo, ElseAstInfo, Context, TreeWalker2);
-				       ({'ifelse', Expression, IfContents, ElseContents}, TreeWalkerAcc) ->
-						       {IfAstInfo, TreeWalker1} = body_ast(IfContents, Context, TreeWalkerAcc),
-						       {ElseAstInfo, TreeWalker2} = body_ast(ElseContents, Context, TreeWalker1),
-						       ifelse_ast(Expression, IfAstInfo, ElseAstInfo, Context, TreeWalker2);
-				       ({'ifequal', [Arg1, Arg2], Contents}, TreeWalkerAcc) ->
-						       {IfAstInfo, TreeWalker1} = body_ast(Contents, Context, TreeWalkerAcc),
-						       {ElseAstInfo, TreeWalker2} = empty_ast(TreeWalker1),
-						       ifelse_ast({'expr', "eq", Arg1, Arg2}, IfAstInfo, ElseAstInfo, Context, TreeWalker2);
-				       ({'ifequalelse', [Arg1, Arg2], IfContents, ElseContents}, TreeWalkerAcc) ->
-						       {IfAstInfo, TreeWalker1} = body_ast(IfContents, Context, TreeWalkerAcc), 
-						       {ElseAstInfo, TreeWalker2} = body_ast(ElseContents, Context,TreeWalker1),
-						       ifelse_ast({'expr', "eq", Arg1, Arg2}, IfAstInfo, ElseAstInfo, Context, TreeWalker2);                
-				       ({'ifnotequal', [Arg1, Arg2], Contents}, TreeWalkerAcc) ->
-						       {IfAstInfo, TreeWalker1} = body_ast(Contents, Context, TreeWalkerAcc),
-						       {ElseAstInfo, TreeWalker2} = empty_ast(TreeWalker1),
-						       ifelse_ast({'expr', "ne", Arg1, Arg2}, IfAstInfo, ElseAstInfo, Context, TreeWalker2);
-				       ({'ifnotequalelse', [Arg1, Arg2], IfContents, ElseContents}, TreeWalkerAcc) ->
-						       {IfAstInfo, TreeWalker1} = body_ast(IfContents, Context, TreeWalkerAcc),
-						       {ElseAstInfo, TreeWalker2} = body_ast(ElseContents, Context, TreeWalker1),
-						       ifelse_ast({'expr', "ne", Arg1, Arg2}, IfAstInfo, ElseAstInfo, Context, TreeWalker2);                    
-				       ({'include', {string_literal, _, File}, Args}, TreeWalkerAcc) ->
-						       include_ast(unescape_string_literal(File), Args, Context#dtl_context.local_scopes, Context, TreeWalkerAcc);
-				       ({'include_only', {string_literal, _, File}, Args}, TreeWalkerAcc) ->
-						       include_ast(unescape_string_literal(File), Args, [], Context, TreeWalkerAcc);
-				       ({'regroup', {ListVariable, Grouper, {identifier, _, NewVariable}}, Contents}, TreeWalkerAcc) ->
-						       regroup_ast(ListVariable, Grouper, NewVariable, Contents, Context, TreeWalkerAcc);
-				       ({'spaceless', Contents}, TreeWalkerAcc) ->
-						       spaceless_ast(Contents, Context, TreeWalkerAcc);
-				       ({'ssi', Arg}, TreeWalkerAcc) ->
-						       ssi_ast(Arg, Context, TreeWalkerAcc);
-				       ({'ssi_parsed', {string_literal, _, FileName}}, TreeWalkerAcc) ->
-						       include_ast(unescape_string_literal(FileName), [], Context#dtl_context.local_scopes, Context, TreeWalkerAcc);
-				       ({'string', _Pos, String}, TreeWalkerAcc) -> 
-						       string_ast(String, Context, TreeWalkerAcc);
-				       ({'tag', {identifier, _, Name}, Args}, TreeWalkerAcc) ->
-						       tag_ast(Name, Args, Context, TreeWalkerAcc);            
-				       ({'templatetag', {_, _, TagName}}, TreeWalkerAcc) ->
-						       templatetag_ast(TagName, Context, TreeWalkerAcc);
-				       ({'trans', Value}, TreeWalkerAcc) ->
-						       translated_ast(Value, Context, TreeWalkerAcc);
-				       ({'widthratio', Numerator, Denominator, Scale}, TreeWalkerAcc) ->
-						       widthratio_ast(Numerator, Denominator, Scale, Context, TreeWalkerAcc);
-				       ({'with', Args, Contents}, TreeWalkerAcc) ->
-						       with_ast(Args, Contents, Context, TreeWalkerAcc);
+                                   fun
+                                       ({'autoescape', {identifier, _, OnOrOff}, Contents}, TreeWalkerAcc) ->
+                                                       body_ast(Contents, Context#dtl_context{auto_escape = OnOrOff},
+                                                                TreeWalkerAcc);
+                                       ({'block', {identifier, _, Name}, Contents}, TreeWalkerAcc) ->
+                                                       Block = case dict:find(Name, Context#dtl_context.block_dict) of
+                                                                   {ok, ChildBlock} -> ChildBlock;
+                                                                   _ -> Contents
+                                                               end,
+                                                       body_ast(Block, Context, TreeWalkerAcc);
+                                       ({'blocktrans', Args, Contents}, TreeWalkerAcc) ->
+                                                       blocktrans_ast(Args, Contents, Context, TreeWalkerAcc);
+                                       ({'call', {identifier, _, Name}}, TreeWalkerAcc) ->
+                                                       call_ast(Name, TreeWalkerAcc);
+                                       ({'call', {identifier, _, Name}, With}, TreeWalkerAcc) ->
+                                                       call_with_ast(Name, With, Context, TreeWalkerAcc);
+                                       ({'comment', _Contents}, TreeWalkerAcc) ->
+                                                       empty_ast(TreeWalkerAcc);
+                                       ({'cycle', Names}, TreeWalkerAcc) ->
+                                                       cycle_ast(Names, Context, TreeWalkerAcc);
+                                       ({'cycle_compat', Names}, TreeWalkerAcc) ->
+                                                       cycle_compat_ast(Names, Context, TreeWalkerAcc);
+                                       ({'date', 'now', {string_literal, _Pos, FormatString}}, TreeWalkerAcc) ->
+                                                       now_ast(FormatString, Context, TreeWalkerAcc);
+                                       ({'filter', FilterList, Contents}, TreeWalkerAcc) ->
+                                                       filter_tag_ast(FilterList, Contents, Context, TreeWalkerAcc);
+                                       ({'firstof', Vars}, TreeWalkerAcc) ->
+                                                       firstof_ast(Vars, Context, TreeWalkerAcc);
+                                       ({'for', {'in', IteratorList, Variable, Reversed}, Contents}, TreeWalkerAcc) ->
+                                                       {EmptyAstInfo, TreeWalker1} = empty_ast(TreeWalkerAcc),
+                                                       for_loop_ast(IteratorList, Variable, Reversed, Contents, EmptyAstInfo, Context, TreeWalker1);
+                                       ({'for', {'in', IteratorList, Variable, Reversed}, Contents, EmptyPartContents}, TreeWalkerAcc) ->
+                                                       {EmptyAstInfo, TreeWalker1} = body_ast(EmptyPartContents, Context, TreeWalkerAcc),
+                                                       for_loop_ast(IteratorList, Variable, Reversed, Contents, EmptyAstInfo, Context, TreeWalker1);
+                                       ({'if', Expression, Contents, Elif}, TreeWalkerAcc) ->
+                                                       {IfAstInfo, TreeWalker1} = body_ast(Contents, Context, TreeWalkerAcc),
+                                                       {ElifAstInfo, TreeWalker2} = body_ast(Elif, Context, TreeWalker1),
+                                                       ifelse_ast(Expression, IfAstInfo, ElifAstInfo, Context, TreeWalker2);
+                                       ({'if', Expression, Contents}, TreeWalkerAcc) ->
+                                                       {IfAstInfo, TreeWalker1} = body_ast(Contents, Context, TreeWalkerAcc),
+                                                       {ElseAstInfo, TreeWalker2} = empty_ast(TreeWalker1),
+                                                       ifelse_ast(Expression, IfAstInfo, ElseAstInfo, Context, TreeWalker2);
+                                       ({'ifchanged', '$undefined', Contents}, TreeWalkerAcc) ->
+                                                       {IfAstInfo, TreeWalker1} = body_ast(Contents, Context, TreeWalkerAcc),
+                                                       {ElseAstInfo, TreeWalker2} = empty_ast(TreeWalker1),
+                                                       ifchanged_contents_ast(Contents, IfAstInfo, ElseAstInfo, Context, TreeWalker2);
+                                       ({'ifchanged', Values, Contents}, TreeWalkerAcc) ->
+                                                       {IfAstInfo, TreeWalker1} = body_ast(Contents, Context, TreeWalkerAcc),
+                                                       {ElseAstInfo, TreeWalker2} = empty_ast(TreeWalker1),
+                                                       ifchanged_values_ast(Values, IfAstInfo, ElseAstInfo, Context, TreeWalker2);
+                                       ({'ifchangedelse', '$undefined', IfContents, ElseContents}, TreeWalkerAcc) ->
+                                                       {IfAstInfo, TreeWalker1} = body_ast(IfContents, Context, TreeWalkerAcc),
+                                                       {ElseAstInfo, TreeWalker2} = body_ast(ElseContents, Context, TreeWalker1),
+                                                       ifchanged_contents_ast(IfContents, IfAstInfo, ElseAstInfo, Context, TreeWalker2);
+                                       ({'ifchangedelse', Values, IfContents, ElseContents}, TreeWalkerAcc) ->
+                                                       {IfAstInfo, TreeWalker1} = body_ast(IfContents, Context, TreeWalkerAcc),
+                                                       {ElseAstInfo, TreeWalker2} = body_ast(ElseContents, Context, TreeWalker1),
+                                                       ifchanged_values_ast(Values, IfAstInfo, ElseAstInfo, Context, TreeWalker2);
+                                       ({'ifelse', Expression, IfContents, ElseContents}, TreeWalkerAcc) ->
+                                                       {IfAstInfo, TreeWalker1} = body_ast(IfContents, Context, TreeWalkerAcc),
+                                                       {ElseAstInfo, TreeWalker2} = body_ast(ElseContents, Context, TreeWalker1),
+                                                       ifelse_ast(Expression, IfAstInfo, ElseAstInfo, Context, TreeWalker2);
+                                       ({'ifequal', [Arg1, Arg2], Contents}, TreeWalkerAcc) ->
+                                                       {IfAstInfo, TreeWalker1} = body_ast(Contents, Context, TreeWalkerAcc),
+                                                       {ElseAstInfo, TreeWalker2} = empty_ast(TreeWalker1),
+                                                       ifelse_ast({'expr', "eq", Arg1, Arg2}, IfAstInfo, ElseAstInfo, Context, TreeWalker2);
+                                       ({'ifequalelse', [Arg1, Arg2], IfContents, ElseContents}, TreeWalkerAcc) ->
+                                                       {IfAstInfo, TreeWalker1} = body_ast(IfContents, Context, TreeWalkerAcc),
+                                                       {ElseAstInfo, TreeWalker2} = body_ast(ElseContents, Context,TreeWalker1),
+                                                       ifelse_ast({'expr', "eq", Arg1, Arg2}, IfAstInfo, ElseAstInfo, Context, TreeWalker2);
+                                       ({'ifnotequal', [Arg1, Arg2], Contents}, TreeWalkerAcc) ->
+                                                       {IfAstInfo, TreeWalker1} = body_ast(Contents, Context, TreeWalkerAcc),
+                                                       {ElseAstInfo, TreeWalker2} = empty_ast(TreeWalker1),
+                                                       ifelse_ast({'expr', "ne", Arg1, Arg2}, IfAstInfo, ElseAstInfo, Context, TreeWalker2);
+                                       ({'ifnotequalelse', [Arg1, Arg2], IfContents, ElseContents}, TreeWalkerAcc) ->
+                                                       {IfAstInfo, TreeWalker1} = body_ast(IfContents, Context, TreeWalkerAcc),
+                                                       {ElseAstInfo, TreeWalker2} = body_ast(ElseContents, Context, TreeWalker1),
+                                                       ifelse_ast({'expr', "ne", Arg1, Arg2}, IfAstInfo, ElseAstInfo, Context, TreeWalker2);
+                                       ({'include', {string_literal, _, File}, Args}, TreeWalkerAcc) ->
+                                                       include_ast(unescape_string_literal(File), Args, Context#dtl_context.local_scopes, Context, TreeWalkerAcc);
+                                       ({'include_only', {string_literal, _, File}, Args}, TreeWalkerAcc) ->
+                                                       include_ast(unescape_string_literal(File), Args, [], Context, TreeWalkerAcc);
+                                       ({'regroup', {ListVariable, Grouper, {identifier, _, NewVariable}}, Contents}, TreeWalkerAcc) ->
+                                                       regroup_ast(ListVariable, Grouper, NewVariable, Contents, Context, TreeWalkerAcc);
+                                       ({'spaceless', Contents}, TreeWalkerAcc) ->
+                                                       spaceless_ast(Contents, Context, TreeWalkerAcc);
+                                       ({'ssi', Arg}, TreeWalkerAcc) ->
+                                                       ssi_ast(Arg, Context, TreeWalkerAcc);
+                                       ({'ssi_parsed', {string_literal, _, FileName}}, TreeWalkerAcc) ->
+                                                       include_ast(unescape_string_literal(FileName), [], Context#dtl_context.local_scopes, Context, TreeWalkerAcc);
+                                       ({'string', _Pos, String}, TreeWalkerAcc) ->
+                                                       string_ast(String, Context, TreeWalkerAcc);
+                                       ({'tag', {identifier, _, Name}, Args}, TreeWalkerAcc) ->
+                                                       tag_ast(Name, Args, Context, TreeWalkerAcc);
+                                       ({'templatetag', {_, _, TagName}}, TreeWalkerAcc) ->
+                                                       templatetag_ast(TagName, Context, TreeWalkerAcc);
+                                       ({'trans', Value}, TreeWalkerAcc) ->
+                                                       translated_ast(Value, Context, TreeWalkerAcc);
+                                       ({'widthratio', Numerator, Denominator, Scale}, TreeWalkerAcc) ->
+                                                       widthratio_ast(Numerator, Denominator, Scale, Context, TreeWalkerAcc);
+                                       ({'with', Args, Contents}, TreeWalkerAcc) ->
+                                                       with_ast(Args, Contents, Context, TreeWalkerAcc);
                                        ({'extension', Tag}, TreeWalkerAcc) ->
-                                           extension_ast(Tag, Context, TreeWalkerAcc);
-                       ({'extends', _}, _TreeWalkerAcc) ->
-                           throw({error, "The extends tag must be at the very top of the template"});
-				       (ValueToken, TreeWalkerAcc) -> 
-						       {{ValueAst,ValueInfo},ValueTreeWalker} = value_ast(ValueToken, true, true, Context, TreeWalkerAcc),
-						       {{format(ValueAst, Context, ValueTreeWalker),ValueInfo},ValueTreeWalker}
-					       end, TreeWalker, DjangoParseTree),   
+                                                       extension_ast(Tag, Context, TreeWalkerAcc);
+                                       ({'extends', _}, _TreeWalkerAcc) ->
+                                                       throw({error, "The extends tag must be at the very top of the template"});
+                                       (ValueToken, TreeWalkerAcc) ->
+                                                       {{ValueAst,ValueInfo},ValueTreeWalker} = value_ast(ValueToken, true, true, Context, TreeWalkerAcc),
+                                                       {{format(ValueAst, Context, ValueTreeWalker),ValueInfo},ValueTreeWalker}
+                                               end, TreeWalker, DjangoParseTree),
     {AstList, {Info, TreeWalker3}} = lists:mapfoldl(
-				       fun({Ast, Info}, {InfoAcc, TreeWalkerAcc}) -> 
-					       PresetVars = lists:foldl(fun
-									    (X, Acc) ->
-									       case proplists:lookup(X, Context#dtl_context.vars) of
-										   none ->
-										       Acc;
-										   Val ->
-										       [erl_syntax:abstract(Val) | Acc]
-									       end
-								       end, [], Info#ast_info.var_names),
-					       case PresetVars of
-						   [] ->
-						       {Ast, {merge_info(Info, InfoAcc), TreeWalkerAcc}};
-						   _ ->
-						       Counter = TreeWalkerAcc#treewalker.counter,
-						       Name = lists:concat([pre_render, Counter]),
-						       Ast1 = erl_syntax:application(none, erl_syntax:atom(Name),
-										     [erl_syntax:list(PresetVars)]),
-						       PreRenderAst = erl_syntax:function(erl_syntax:atom(Name),
-											  [erl_syntax:clause([erl_syntax:variable("_Variables")], none, [Ast])]),
-						       PreRenderAsts = Info#ast_info.pre_render_asts,
-						       Info1 = Info#ast_info{pre_render_asts = [PreRenderAst | PreRenderAsts]},     
-						       {Ast1, {merge_info(Info1, InfoAcc), TreeWalkerAcc#treewalker{counter = Counter + 1}}}
-					       end
-				       end, {#ast_info{}, TreeWalker2}, AstInfoList),
+                                       fun({Ast, Info}, {InfoAcc, TreeWalkerAcc}) ->
+                                               PresetVars = lists:foldl(fun
+                                                                            (X, Acc) ->
+                                                                               case proplists:lookup(X, Context#dtl_context.vars) of
+                                                                                   none ->
+                                                                                       Acc;
+                                                                                   Val ->
+                                                                                       [erl_syntax:abstract(Val) | Acc]
+                                                                               end
+                                                                       end, [], Info#ast_info.var_names),
+                                               case PresetVars of
+                                                   [] ->
+                                                       {Ast, {merge_info(Info, InfoAcc), TreeWalkerAcc}};
+                                                   _ ->
+                                                       Counter = TreeWalkerAcc#treewalker.counter,
+                                                       Name = lists:concat([pre_render, Counter]),
+                                                       Ast1 = erl_syntax:application(none, erl_syntax:atom(Name),
+                                                                                     [erl_syntax:list(PresetVars)]),
+                                                       PreRenderAst = erl_syntax:function(erl_syntax:atom(Name),
+                                                                                          [erl_syntax:clause([erl_syntax:variable("_Variables")], none, [Ast])]),
+                                                       PreRenderAsts = Info#ast_info.pre_render_asts,
+                                                       Info1 = Info#ast_info{pre_render_asts = [PreRenderAst | PreRenderAsts]},
+                                                       {Ast1, {merge_info(Info1, InfoAcc), TreeWalkerAcc#treewalker{counter = Counter + 1}}}
+                                               end
+                                       end, {#ast_info{}, TreeWalker2}, AstInfoList),
     {{erl_syntax:list(AstList), Info}, TreeWalker3}.
 
 
@@ -858,15 +858,15 @@ value_ast(ValueToken, AsString, EmptyIfUndefined, Context, TreeWalker) ->
     case ValueToken of
         {'expr', Operator, Value} ->
             {{ValueAst,InfoValue}, TreeWalker1} = value_ast(Value, false, EmptyIfUndefined, Context, TreeWalker),
-            Ast = erl_syntax:application(erl_syntax:atom(erlydtl_runtime), 
-                                         erl_syntax:atom(Operator), 
+            Ast = erl_syntax:application(erl_syntax:atom(erlydtl_runtime),
+                                         erl_syntax:atom(Operator),
                                          [ValueAst]),
             {{Ast, InfoValue}, TreeWalker1};
         {'expr', Operator, Value1, Value2} ->
             {{Value1Ast,InfoValue1}, TreeWalker1} = value_ast(Value1, false, EmptyIfUndefined, Context, TreeWalker),
             {{Value2Ast,InfoValue2}, TreeWalker2} = value_ast(Value2, false, EmptyIfUndefined, Context, TreeWalker1),
-            Ast = erl_syntax:application(erl_syntax:atom(erlydtl_runtime), 
-                                         erl_syntax:atom(Operator), 
+            Ast = erl_syntax:application(erl_syntax:atom(erlydtl_runtime),
+                                         erl_syntax:atom(Operator),
                                          [Value1Ast, Value2Ast]),
             {{Ast, merge_info(InfoValue1,InfoValue2)}, TreeWalker2};
         {'string_literal', _Pos, String} ->
@@ -896,30 +896,30 @@ extension_ast(Tag, Context, TreeWalker) ->
 
 merge_info(Info1, Info2) ->
     #ast_info{
-	    dependencies = 
-		lists:merge(
-		  lists:sort(Info1#ast_info.dependencies), 
-		  lists:sort(Info2#ast_info.dependencies)),
-	    var_names = 
-		lists:merge(
-		  lists:sort(Info1#ast_info.var_names), 
-		  lists:sort(Info2#ast_info.var_names)),
-	    translatable_strings =
-		lists:merge(
-		  lists:sort(Info1#ast_info.translatable_strings),
-		  lists:sort(Info2#ast_info.translatable_strings)),
-	    translated_blocks =
-		lists:merge(
-		  lists:sort(Info1#ast_info.translated_blocks),
-		  lists:sort(Info2#ast_info.translated_blocks)),
-	    custom_tags = 
-		lists:merge(
-		  lists:sort(Info1#ast_info.custom_tags),
-		  lists:sort(Info2#ast_info.custom_tags)),
-	    pre_render_asts = 
-		lists:merge(
-		  Info1#ast_info.pre_render_asts,
-		  Info2#ast_info.pre_render_asts)}.
+       dependencies =
+           lists:merge(
+             lists:sort(Info1#ast_info.dependencies),
+             lists:sort(Info2#ast_info.dependencies)),
+       var_names =
+           lists:merge(
+             lists:sort(Info1#ast_info.var_names),
+             lists:sort(Info2#ast_info.var_names)),
+       translatable_strings =
+           lists:merge(
+             lists:sort(Info1#ast_info.translatable_strings),
+             lists:sort(Info2#ast_info.translatable_strings)),
+       translated_blocks =
+           lists:merge(
+             lists:sort(Info1#ast_info.translated_blocks),
+             lists:sort(Info2#ast_info.translated_blocks)),
+       custom_tags =
+           lists:merge(
+             lists:sort(Info1#ast_info.custom_tags),
+             lists:sort(Info2#ast_info.custom_tags)),
+       pre_render_asts =
+           lists:merge(
+             Info1#ast_info.pre_render_asts,
+             Info2#ast_info.pre_render_asts)}.
 
 
 with_dependencies([], Args) ->
@@ -936,10 +936,10 @@ empty_ast(TreeWalker) ->
 
 blocktrans_ast(ArgList, Contents, Context, TreeWalker) ->
     {NewScope, {ArgInfo, TreeWalker1}} = lists:mapfoldl(fun
-							    ({{identifier, _, LocalVarName}, Value}, {AstInfo1, TreeWalker1}) ->
-							       {{Ast, Info}, TreeWalker2} = value_ast(Value, false, false, Context, TreeWalker1),
-							       {{LocalVarName, Ast}, {merge_info(AstInfo1, Info), TreeWalker2}}
-						       end, {#ast_info{}, TreeWalker}, ArgList),
+                                                            ({{identifier, _, LocalVarName}, Value}, {AstInfo1, TreeWalker1}) ->
+                                                               {{Ast, Info}, TreeWalker2} = value_ast(Value, false, false, Context, TreeWalker1),
+                                                               {{LocalVarName, Ast}, {merge_info(AstInfo1, Info), TreeWalker2}}
+                                                       end, {#ast_info{}, TreeWalker}, ArgList),
     NewContext = Context#dtl_context{ local_scopes = [NewScope|Context#dtl_context.local_scopes] },
     SourceText = lists:flatten(erlydtl_unparser:unparse(Contents)),
     {{DefaultAst, AstInfo}, TreeWalker2} = body_ast(Contents, NewContext, TreeWalker1),
@@ -949,18 +949,18 @@ blocktrans_ast(ArgList, Contents, Context, TreeWalker) ->
             {{DefaultAst, MergedInfo}, TreeWalker2};
         BlockTransFun when is_function(BlockTransFun) ->
             {FinalAstInfo, FinalTreeWalker, Clauses} = lists:foldr(fun(Locale, {AstInfoAcc, ThisTreeWalker, ClauseAcc}) ->
-									   case BlockTransFun(SourceText, Locale) of
-									       default ->
-										   {AstInfoAcc, ThisTreeWalker, ClauseAcc};
-									       Body ->
-										   {ok, DjangoParseTree} = parse(Body, Context),
-										   {{ThisAst, ThisAstInfo}, TreeWalker3} = body_ast(DjangoParseTree, NewContext, ThisTreeWalker),
-										   {merge_info(ThisAstInfo, AstInfoAcc), TreeWalker3, 
-										    [erl_syntax:clause([erl_syntax:string(Locale)], none, [ThisAst])|ClauseAcc]}
-									   end
-								   end, {MergedInfo, TreeWalker2, []}, Context#dtl_context.blocktrans_locales),
+                                                                           case BlockTransFun(SourceText, Locale) of
+                                                                               default ->
+                                                                                   {AstInfoAcc, ThisTreeWalker, ClauseAcc};
+                                                                               Body ->
+                                                                                   {ok, DjangoParseTree} = parse(Body, Context),
+                                                                                   {{ThisAst, ThisAstInfo}, TreeWalker3} = body_ast(DjangoParseTree, NewContext, ThisTreeWalker),
+                                                                                   {merge_info(ThisAstInfo, AstInfoAcc), TreeWalker3,
+                                                                                    [erl_syntax:clause([erl_syntax:string(Locale)], none, [ThisAst])|ClauseAcc]}
+                                                                           end
+                                                                   end, {MergedInfo, TreeWalker2, []}, Context#dtl_context.blocktrans_locales),
             Ast = erl_syntax:case_expr(erl_syntax:variable("_CurrentLocale"),
-				       Clauses ++ [erl_syntax:clause([erl_syntax:underscore()], none, [DefaultAst])]),
+                                       Clauses ++ [erl_syntax:clause([erl_syntax:underscore()], none, [DefaultAst])]),
             {{Ast, FinalAstInfo#ast_info{ translated_blocks = [SourceText] }}, FinalTreeWalker}
     end.
 
@@ -972,7 +972,7 @@ translated_ast({string_literal, _, String}, Context, TreeWalker) ->
                                 none -> UnescapedStr;
                                 Locale -> erlydtl_i18n:translate(UnescapedStr,Locale)
                             end,
-            translated_ast2(erl_syntax:string(UnescapedStr), erl_syntax:string(DefaultString), 
+            translated_ast2(erl_syntax:string(UnescapedStr), erl_syntax:string(DefaultString),
                             #ast_info{translatable_strings = [UnescapedStr]}, TreeWalker);
         Translated ->
             Translated
@@ -983,12 +983,12 @@ translated_ast(ValueToken, Context, TreeWalker) ->
 
 translated_ast2(UnescapedStrAst, DefaultStringAst, AstInfo, TreeWalker) ->
     StringLookupAst = erl_syntax:application(
-			erl_syntax:atom(erlydtl_runtime),
-			erl_syntax:atom(translate),
-			[UnescapedStrAst, erl_syntax:variable("_TranslationFun"), DefaultStringAst]),
+                        erl_syntax:atom(erlydtl_runtime),
+                        erl_syntax:atom(translate),
+                        [UnescapedStrAst, erl_syntax:variable("_TranslationFun"), DefaultStringAst]),
     {{StringLookupAst, AstInfo}, TreeWalker}.
 
-						% Completely unnecessary in ErlyDTL (use {{ "{%" }} etc), but implemented for compatibility.
+                                                % Completely unnecessary in ErlyDTL (use {{ "{%" }} etc), but implemented for compatibility.
 templatetag_ast("openblock", Context, TreeWalker) ->
     string_ast("{%", Context, TreeWalker);
 templatetag_ast("closeblock", Context, TreeWalker) ->
@@ -1012,9 +1012,9 @@ widthratio_ast(Numerator, Denominator, Scale, Context, TreeWalker) ->
     {{DenAst, DenInfo}, TreeWalker2} = value_ast(Denominator, false, true, Context, TreeWalker1),
     {{ScaleAst, ScaleInfo}, TreeWalker3} = value_ast(Scale, false, true, Context, TreeWalker2),
     {{format_number_ast(erl_syntax:application(
-			  erl_syntax:atom(erlydtl_runtime),
-			  erl_syntax:atom(widthratio),
-			  [NumAst, DenAst, ScaleAst])), merge_info(ScaleInfo, merge_info(NumInfo, DenInfo))},
+                          erl_syntax:atom(erlydtl_runtime),
+                          erl_syntax:atom(widthratio),
+                          [NumAst, DenAst, ScaleAst])), merge_info(ScaleInfo, merge_info(NumInfo, DenInfo))},
      TreeWalker3}.
 
 binary_string(String) ->
@@ -1033,57 +1033,57 @@ include_ast(File, ArgList, Scopes, Context, TreeWalker) ->
     case parse(FilePath, Context) of
         {ok, InclusionParseTree, CheckSum} ->
             {NewScope, {ArgInfo, TreeWalker1}} = lists:mapfoldl(fun
-								    ({{identifier, _, LocalVarName}, Value}, {AstInfo1, TreeWalker1}) ->
-								       {{Ast, Info}, TreeWalker2} = value_ast(Value, false, false, Context, TreeWalker1),
-								       {{LocalVarName, Ast}, {merge_info(AstInfo1, Info), TreeWalker2}}
-							       end, {#ast_info{}, TreeWalker}, ArgList),
+                                                                    ({{identifier, _, LocalVarName}, Value}, {AstInfo1, TreeWalker1}) ->
+                                                                       {{Ast, Info}, TreeWalker2} = value_ast(Value, false, false, Context, TreeWalker1),
+                                                                       {{LocalVarName, Ast}, {merge_info(AstInfo1, Info), TreeWalker2}}
+                                                               end, {#ast_info{}, TreeWalker}, ArgList),
 
-            {{BodyAst, BodyInfo}, TreeWalker2} = with_dependency({FilePath, CheckSum}, 
-								 body_ast(InclusionParseTree, Context#dtl_context{
-												parse_trail = [FilePath | Context#dtl_context.parse_trail],
-												local_scopes = [NewScope|Scopes]
-											       }, TreeWalker1)),
+            {{BodyAst, BodyInfo}, TreeWalker2} = with_dependency({FilePath, CheckSum},
+                                                                 body_ast(InclusionParseTree, Context#dtl_context{
+                                                                                                parse_trail = [FilePath | Context#dtl_context.parse_trail],
+                                                                                                local_scopes = [NewScope|Scopes]
+                                                                                               }, TreeWalker1)),
 
             {{BodyAst, merge_info(BodyInfo, ArgInfo)}, TreeWalker2};
         Err ->
             throw(Err)
     end.
 
-						% include at run-time
+                                                % include at run-time
 ssi_ast(FileName, Context, TreeWalker) ->
     {{Ast, Info}, TreeWalker1} = value_ast(FileName, true, true, Context, TreeWalker),
     {Mod, Fun} = Context#dtl_context.reader,
     {{erl_syntax:application(
-	erl_syntax:atom(erlydtl_runtime),
-	erl_syntax:atom(read_file),
-	[erl_syntax:atom(Mod), erl_syntax:atom(Fun), erl_syntax:string(Context#dtl_context.doc_root), Ast]), Info}, TreeWalker1}.
+        erl_syntax:atom(erlydtl_runtime),
+        erl_syntax:atom(read_file),
+        [erl_syntax:atom(Mod), erl_syntax:atom(Fun), erl_syntax:string(Context#dtl_context.doc_root), Ast]), Info}, TreeWalker1}.
 
 filter_tag_ast(FilterList, Contents, Context, TreeWalker) ->
     {{InnerAst, Info}, TreeWalker1} = body_ast(Contents, Context#dtl_context{auto_escape = did}, TreeWalker),
     {{FilteredAst, FilteredInfo}, TreeWalker2} = lists:foldl(fun
-								 ([{identifier, _, 'escape'}], {{AstAcc, InfoAcc}, TreeWalkerAcc}) ->
-								    {{AstAcc, InfoAcc}, TreeWalkerAcc#treewalker{safe = true}};
-								 ([{identifier, _, 'safe'}], {{AstAcc, InfoAcc}, TreeWalkerAcc}) ->
-								    {{AstAcc, InfoAcc}, TreeWalkerAcc#treewalker{safe = true}};
-								 ([{identifier, _, 'safeseq'}], {{AstAcc, InfoAcc}, TreeWalkerAcc}) ->
-								    {{AstAcc, InfoAcc}, TreeWalkerAcc#treewalker{safe = true}};
-								 (Filter, {{AstAcc, InfoAcc}, TreeWalkerAcc}) ->
-								    {{Ast, AstInfo}, TW} = filter_ast1(Filter, AstAcc, Context, TreeWalkerAcc),
-								    {{Ast, merge_info(InfoAcc, AstInfo)}, TW}
-							    end, {{erl_syntax:application(
-								     erl_syntax:atom(erlang),
-								     erl_syntax:atom(iolist_to_binary),
-								     [InnerAst]), Info}, TreeWalker1}, FilterList),
+                                                                 ([{identifier, _, 'escape'}], {{AstAcc, InfoAcc}, TreeWalkerAcc}) ->
+                                                                    {{AstAcc, InfoAcc}, TreeWalkerAcc#treewalker{safe = true}};
+                                                                 ([{identifier, _, 'safe'}], {{AstAcc, InfoAcc}, TreeWalkerAcc}) ->
+                                                                    {{AstAcc, InfoAcc}, TreeWalkerAcc#treewalker{safe = true}};
+                                                                 ([{identifier, _, 'safeseq'}], {{AstAcc, InfoAcc}, TreeWalkerAcc}) ->
+                                                                    {{AstAcc, InfoAcc}, TreeWalkerAcc#treewalker{safe = true}};
+                                                                 (Filter, {{AstAcc, InfoAcc}, TreeWalkerAcc}) ->
+                                                                    {{Ast, AstInfo}, TW} = filter_ast1(Filter, AstAcc, Context, TreeWalkerAcc),
+                                                                    {{Ast, merge_info(InfoAcc, AstInfo)}, TW}
+                                                            end, {{erl_syntax:application(
+                                                                     erl_syntax:atom(erlang),
+                                                                     erl_syntax:atom(iolist_to_binary),
+                                                                     [InnerAst]), Info}, TreeWalker1}, FilterList),
 
     EscapedAst = case search_for_escape_filter(lists:reverse(FilterList), Context) of
-		     on ->
-			 erl_syntax:application(
-			   erl_syntax:atom(erlydtl_filters), 
-			   erl_syntax:atom(force_escape), 
-			   [FilteredAst]);
-		     _ ->
-			 FilteredAst
-		 end,
+                     on ->
+                         erl_syntax:application(
+                           erl_syntax:atom(erlydtl_filters),
+                           erl_syntax:atom(force_escape),
+                           [FilteredAst]);
+                     _ ->
+                         FilteredAst
+                 end,
     {{EscapedAst, FilteredInfo}, TreeWalker2}.
 
 search_for_escape_filter(FilterList, #dtl_context{auto_escape = on}) ->
@@ -1107,21 +1107,21 @@ search_for_safe_filter([]) ->
     on.
 
 filter_ast(Variable, Filter, Context, TreeWalker) ->
-						% the escape filter is special; it is always applied last, so we have to go digging for it
+                                                % the escape filter is special; it is always applied last, so we have to go digging for it
 
-						% AutoEscape = 'did' means we (will have) decided whether to escape the current variable,
-						% so don't do any more escaping
-    {{UnescapedAst, Info}, TreeWalker2} = filter_ast_noescape(Variable, Filter, 
-							      Context#dtl_context{auto_escape = did}, TreeWalker),
+                                                % AutoEscape = 'did' means we (will have) decided whether to escape the current variable,
+                                                % so don't do any more escaping
+    {{UnescapedAst, Info}, TreeWalker2} = filter_ast_noescape(Variable, Filter,
+                                                              Context#dtl_context{auto_escape = did}, TreeWalker),
     EscapedAst = case search_for_escape_filter(Variable, Filter, Context) of
-		     on ->
-			 erl_syntax:application(
-			   erl_syntax:atom(erlydtl_filters), 
-			   erl_syntax:atom(force_escape), 
-			   [UnescapedAst]);
-		     _ -> 
-			 UnescapedAst
-		 end,
+                     on ->
+                         erl_syntax:application(
+                           erl_syntax:atom(erlydtl_filters),
+                           erl_syntax:atom(force_escape),
+                           [UnescapedAst]);
+                     _ ->
+                         UnescapedAst
+                 end,
     {{EscapedAst, Info}, TreeWalker2}.
 
 filter_ast_noescape(Variable, [{identifier, _, 'escape'}], Context, TreeWalker) ->
@@ -1213,10 +1213,10 @@ resolve_variable_ast(VarTuple, Context, TreeWalker, FinderFunction) ->
 
 resolve_variable_ast1({attribute, {{identifier, {Row, Col}, AttrName}, Variable}}, Context, TreeWalker, FinderFunction) ->
     {{VarAst, VarInfo}, TreeWalker1} = resolve_variable_ast(Variable, Context, TreeWalker, FinderFunction),
-    FileNameAst = case Context#dtl_context.parse_trail of 
-		      [] -> erl_syntax:atom(undefined); 
-		      [H|_] -> erl_syntax:string(H)
-		  end,
+    FileNameAst = case Context#dtl_context.parse_trail of
+                      [] -> erl_syntax:atom(undefined);
+                      [H|_] -> erl_syntax:string(H)
+                  end,
     {Runtime, Finder} = FinderFunction,
     {{erl_syntax:application(
         erl_syntax:atom(Runtime),
@@ -1247,18 +1247,18 @@ resolve_variable_ast1({variable, {identifier, {Row, Col}, VarName}}, Context, Tr
 
 resolve_scoped_variable_ast(VarName, Context) ->
     lists:foldl(fun(Scope, Value) ->
-			case Value of
-			    undefined -> proplists:get_value(VarName, Scope);
-			    _ -> Value
-			end
-		end, undefined, Context#dtl_context.local_scopes).
+                        case Value of
+                            undefined -> proplists:get_value(VarName, Scope);
+                            _ -> Value
+                        end
+                end, undefined, Context#dtl_context.local_scopes).
 
 format(Ast, Context, TreeWalker) ->
     auto_escape(format_number_ast(Ast), Context, TreeWalker).
 
 format_number_ast(Ast) ->
     erl_syntax:application(erl_syntax:atom(erlydtl_filters), erl_syntax:atom(format_number),
-			   [Ast]).
+                           [Ast]).
 
 
 auto_escape(Value, _, #treewalker{safe = true}) ->
@@ -1270,58 +1270,58 @@ auto_escape(Value, _, _) ->
 
 firstof_ast(Vars, Context, TreeWalker) ->
     body_ast([lists:foldr(fun
-			      ({L, _, _}=Var, []) when L=:=string_literal;L=:=number_literal ->
-				 Var;
-			      ({L, _, _}, _) when L=:=string_literal;L=:=number_literal ->
-				 erlang:error(errbadliteral);
-			      (Var, []) ->
-				 {'ifelse', Var, [Var], []};
-			      (Var, Acc) ->
-				 {'ifelse', Var, [Var], [Acc]} end,
-			  [], Vars)], Context, TreeWalker).
+                              ({L, _, _}=Var, []) when L=:=string_literal;L=:=number_literal ->
+                                 Var;
+                              ({L, _, _}, _) when L=:=string_literal;L=:=number_literal ->
+                                 erlang:error(errbadliteral);
+                              (Var, []) ->
+                                 {'ifelse', Var, [Var], []};
+                              (Var, Acc) ->
+                                 {'ifelse', Var, [Var], [Acc]} end,
+                          [], Vars)], Context, TreeWalker).
 
 ifelse_ast(Expression, {IfContentsAst, IfContentsInfo}, {ElseContentsAst, ElseContentsInfo}, Context, TreeWalker) ->
     Info = merge_info(IfContentsInfo, ElseContentsInfo),
-    {{Ast, ExpressionInfo}, TreeWalker1} = value_ast(Expression, false, false, Context, TreeWalker), 
+    {{Ast, ExpressionInfo}, TreeWalker1} = value_ast(Expression, false, false, Context, TreeWalker),
     {{erl_syntax:case_expr(erl_syntax:application(erl_syntax:atom(erlydtl_runtime), erl_syntax:atom(is_true), [Ast]),
-			   [erl_syntax:clause([erl_syntax:atom(true)], none, 
-					      [IfContentsAst]),
-			    erl_syntax:clause([erl_syntax:underscore()], none,
-					      [ElseContentsAst])
-			   ]), merge_info(ExpressionInfo, Info)}, TreeWalker1}.
+                           [erl_syntax:clause([erl_syntax:atom(true)], none,
+                                              [IfContentsAst]),
+                            erl_syntax:clause([erl_syntax:underscore()], none,
+                                              [ElseContentsAst])
+                           ]), merge_info(ExpressionInfo, Info)}, TreeWalker1}.
 
 with_ast(ArgList, Contents, Context, TreeWalker) ->
     {ArgAstList, {ArgInfo, TreeWalker1}} = lists:mapfoldl(fun
-							      ({{identifier, _, _LocalVarName}, Value}, {AstInfo1, TreeWalker1}) ->
-								 {{Ast, Info}, TreeWalker2} = value_ast(Value, false, false, Context, TreeWalker1),
-								 {Ast, {merge_info(AstInfo1, Info), TreeWalker2}}
-							 end, {#ast_info{}, TreeWalker}, ArgList),
+                                                              ({{identifier, _, _LocalVarName}, Value}, {AstInfo1, TreeWalker1}) ->
+                                                                 {{Ast, Info}, TreeWalker2} = value_ast(Value, false, false, Context, TreeWalker1),
+                                                                 {Ast, {merge_info(AstInfo1, Info), TreeWalker2}}
+                                                         end, {#ast_info{}, TreeWalker}, ArgList),
 
     NewScope = lists:map(fun({{identifier, _, LocalVarName}, _Value}) ->
-				 {LocalVarName, erl_syntax:variable(lists:concat(["Var_", LocalVarName]))}
-			 end, ArgList),
+                                 {LocalVarName, erl_syntax:variable(lists:concat(["Var_", LocalVarName]))}
+                         end, ArgList),
 
     {{InnerAst, InnerInfo}, TreeWalker2} = body_ast(Contents,
-						    Context#dtl_context{local_scopes = [NewScope|Context#dtl_context.local_scopes]}, TreeWalker1),
+                                                    Context#dtl_context{local_scopes = [NewScope|Context#dtl_context.local_scopes]}, TreeWalker1),
 
     {{erl_syntax:application(
-	erl_syntax:fun_expr([
-			     erl_syntax:clause(lists:map(fun({_, Var}) -> Var end, NewScope), none,
-					       [InnerAst])]), ArgAstList), merge_info(ArgInfo, InnerInfo)}, TreeWalker2}.
+        erl_syntax:fun_expr([
+                             erl_syntax:clause(lists:map(fun({_, Var}) -> Var end, NewScope), none,
+                                               [InnerAst])]), ArgAstList), merge_info(ArgInfo, InnerInfo)}, TreeWalker2}.
 
 regroup_ast(ListVariable, GrouperVariable, LocalVarName, Contents, Context, TreeWalker) ->
     {{ListAst, ListInfo}, TreeWalker1} = value_ast(ListVariable, false, true, Context, TreeWalker),
     NewScope = [{LocalVarName, erl_syntax:variable(lists:concat(["Var_", LocalVarName]))}],
 
-    {{InnerAst, InnerInfo}, TreeWalker2} = body_ast(Contents, 
-						    Context#dtl_context{ local_scopes = [NewScope|Context#dtl_context.local_scopes] }, TreeWalker1),
+    {{InnerAst, InnerInfo}, TreeWalker2} = body_ast(Contents,
+                                                    Context#dtl_context{ local_scopes = [NewScope|Context#dtl_context.local_scopes] }, TreeWalker1),
 
     Ast = {erl_syntax:application(
-	     erl_syntax:fun_expr([
-				  erl_syntax:clause([erl_syntax:variable(lists:concat(["Var_", LocalVarName]))], none,
-						    [InnerAst])]), 
-	     [erl_syntax:application(erl_syntax:atom(erlydtl_runtime), erl_syntax:atom(regroup),
-				     [ListAst, regroup_filter(GrouperVariable,[])])]), merge_info(ListInfo, InnerInfo)},
+             erl_syntax:fun_expr([
+                                  erl_syntax:clause([erl_syntax:variable(lists:concat(["Var_", LocalVarName]))], none,
+                                                    [InnerAst])]),
+             [erl_syntax:application(erl_syntax:atom(erlydtl_runtime), erl_syntax:atom(regroup),
+                                     [ListAst, regroup_filter(GrouperVariable,[])])]), merge_info(ListInfo, InnerInfo)},
     {Ast,TreeWalker2}.
 
 regroup_filter({attribute,{{identifier,_,Ident},Next}},Acc) ->
@@ -1331,47 +1331,47 @@ regroup_filter({variable,{identifier,_,Var}},Acc) ->
 
 
 for_loop_ast(IteratorList, LoopValue, IsReversed, Contents, {EmptyContentsAst, EmptyContentsInfo}, Context, TreeWalker) ->
-    Vars = lists:map(fun({identifier, _, Iterator}) -> 
-			     erl_syntax:variable(lists:concat(["Var_", Iterator])) 
-		     end, IteratorList),
+    Vars = lists:map(fun({identifier, _, Iterator}) ->
+                             erl_syntax:variable(lists:concat(["Var_", Iterator]))
+                     end, IteratorList),
     {{InnerAst, Info}, TreeWalker1} = body_ast(Contents,
-					       Context#dtl_context{local_scopes = [
-										   [{'forloop', erl_syntax:variable("Counters")} | lists:map(
-																     fun({identifier, _, Iterator}) ->
-																	     {Iterator, erl_syntax:variable(lists:concat(["Var_", Iterator]))} 
-																     end, IteratorList)] | Context#dtl_context.local_scopes]}, TreeWalker),
-    CounterAst = erl_syntax:application(erl_syntax:atom(erlydtl_runtime), 
-					erl_syntax:atom(increment_counter_stats), [erl_syntax:variable("Counters")]),
+                                               Context#dtl_context{local_scopes = [
+                                                                                   [{'forloop', erl_syntax:variable("Counters")} | lists:map(
+                                                                                                                                     fun({identifier, _, Iterator}) ->
+                                                                                                                                             {Iterator, erl_syntax:variable(lists:concat(["Var_", Iterator]))}
+                                                                                                                                     end, IteratorList)] | Context#dtl_context.local_scopes]}, TreeWalker),
+    CounterAst = erl_syntax:application(erl_syntax:atom(erlydtl_runtime),
+                                        erl_syntax:atom(increment_counter_stats), [erl_syntax:variable("Counters")]),
 
     {{LoopValueAst, LoopValueInfo}, TreeWalker2} = value_ast(LoopValue, false, true, Context, TreeWalker1),
 
     LoopValueAst0 = erl_syntax:application(erl_syntax:atom(erlydtl_runtime), erl_syntax:atom(to_list), [LoopValueAst, erl_syntax:atom(IsReversed)]),
 
     CounterVars0 = case resolve_scoped_variable_ast('forloop', Context) of
-		       undefined ->
-			   erl_syntax:application(erl_syntax:atom(erlydtl_runtime), erl_syntax:atom(init_counter_stats), [LoopValueAst0]);
-		       Value ->
-			   erl_syntax:application(erl_syntax:atom(erlydtl_runtime), erl_syntax:atom(init_counter_stats), [LoopValueAst0, Value])
-		   end,
+                       undefined ->
+                           erl_syntax:application(erl_syntax:atom(erlydtl_runtime), erl_syntax:atom(init_counter_stats), [LoopValueAst0]);
+                       Value ->
+                           erl_syntax:application(erl_syntax:atom(erlydtl_runtime), erl_syntax:atom(init_counter_stats), [LoopValueAst0, Value])
+                   end,
     {{erl_syntax:case_expr(
-	erl_syntax:application(
-	  erl_syntax:atom('erlydtl_runtime'), erl_syntax:atom('forloop'),
-	  [erl_syntax:fun_expr([
-                                erl_syntax:clause([erl_syntax:tuple(Vars), erl_syntax:variable("Counters")], none, 
-						  [erl_syntax:tuple([InnerAst, CounterAst])]),
+        erl_syntax:application(
+          erl_syntax:atom('erlydtl_runtime'), erl_syntax:atom('forloop'),
+          [erl_syntax:fun_expr([
+                                erl_syntax:clause([erl_syntax:tuple(Vars), erl_syntax:variable("Counters")], none,
+                                                  [erl_syntax:tuple([InnerAst, CounterAst])]),
                                 erl_syntax:clause(case Vars of [H] -> [H, erl_syntax:variable("Counters")];
-						      _ -> [erl_syntax:list(Vars), erl_syntax:variable("Counters")] end, none, 
-						  [erl_syntax:tuple([InnerAst, CounterAst])])
-			       ]),
-	   CounterVars0, LoopValueAst0]),
-	[erl_syntax:clause(
-	   [erl_syntax:tuple([erl_syntax:underscore(), 
-			      erl_syntax:list([erl_syntax:tuple([erl_syntax:atom(counter), erl_syntax:integer(1)])], 
-					      erl_syntax:underscore())])],
-	   none, [EmptyContentsAst]),
-	 erl_syntax:clause(
-	   [erl_syntax:tuple([erl_syntax:variable("L"), erl_syntax:underscore()])],
-	   none, [erl_syntax:variable("L")])]
+                                                      _ -> [erl_syntax:list(Vars), erl_syntax:variable("Counters")] end, none,
+                                                  [erl_syntax:tuple([InnerAst, CounterAst])])
+                               ]),
+           CounterVars0, LoopValueAst0]),
+        [erl_syntax:clause(
+           [erl_syntax:tuple([erl_syntax:underscore(),
+                              erl_syntax:list([erl_syntax:tuple([erl_syntax:atom(counter), erl_syntax:integer(1)])],
+                                              erl_syntax:underscore())])],
+           none, [EmptyContentsAst]),
+         erl_syntax:clause(
+           [erl_syntax:tuple([erl_syntax:variable("L"), erl_syntax:underscore()])],
+           none, [erl_syntax:variable("L")])]
        ),
       merge_info(merge_info(Info, EmptyContentsInfo), LoopValueInfo)
      }, TreeWalker2}.
@@ -1383,36 +1383,36 @@ ifchanged_values_ast(Values, {IfContentsAst, IfContentsInfo}, {ElseContentsAst,
                           {ETw, merge_info(LInfo, EInfo), [erl_syntax:tuple([erl_syntax:integer(erlang:phash2(Expr)), EAst])|Acc]} end,
     {TreeWalker1, MergedInfo, Changed} = lists:foldl(ValueAstFun, {TreeWalker, Info,  []}, Values),
     {{erl_syntax:case_expr(erl_syntax:application(erl_syntax:atom(erlydtl_runtime), erl_syntax:atom(ifchanged), [erl_syntax:list(Changed)]),
-			   [erl_syntax:clause([erl_syntax:atom(true)], none,
-					      [IfContentsAst]),
-			    erl_syntax:clause([erl_syntax:underscore()], none,
-					      [ElseContentsAst])
-			   ]), MergedInfo}, TreeWalker1}.
+                           [erl_syntax:clause([erl_syntax:atom(true)], none,
+                                              [IfContentsAst]),
+                            erl_syntax:clause([erl_syntax:underscore()], none,
+                                              [ElseContentsAst])
+                           ]), MergedInfo}, TreeWalker1}.
 
 ifchanged_contents_ast(Contents, {IfContentsAst, IfContentsInfo}, {ElseContentsAst, ElseContentsInfo}, _Context, TreeWalker) ->
     Info = merge_info(IfContentsInfo, ElseContentsInfo),
     Key = erl_syntax:integer(erlang:phash2(Contents)),
     {{erl_syntax:case_expr(erl_syntax:application(erl_syntax:atom(erlydtl_runtime), erl_syntax:atom(ifchanged), [erl_syntax:list([erl_syntax:tuple([Key, IfContentsAst])])]),
-			   [erl_syntax:clause([erl_syntax:atom(true)], none,
-					      [IfContentsAst]),
-			    erl_syntax:clause([erl_syntax:underscore()], none,
-					      [ElseContentsAst])
-			   ]), Info}, TreeWalker}.
+                           [erl_syntax:clause([erl_syntax:atom(true)], none,
+                                              [IfContentsAst]),
+                            erl_syntax:clause([erl_syntax:underscore()], none,
+                                              [ElseContentsAst])
+                           ]), Info}, TreeWalker}.
 
 
 cycle_ast(Names, Context, TreeWalker) ->
     {NamesTuple, VarNames} = lists:mapfoldl(fun
-						({string_literal, _, Str}, VarNamesAcc) ->
-						   {{S, _}, _} = string_ast(unescape_string_literal(Str), Context, TreeWalker),
-						   {S, VarNamesAcc};
-						({variable, _}=Var, VarNamesAcc) ->
-						   {{V, #ast_info{ var_names=[VarName] }}, _} = resolve_variable_ast(Var, Context, TreeWalker, true),
-						   {V, [VarName|VarNamesAcc]};
-						({number_literal, _, Num}, VarNamesAcc) ->
-						   {format(erl_syntax:integer(Num), Context, TreeWalker), VarNamesAcc};
-						(_, VarNamesAcc) ->
-						   {[], VarNamesAcc}
-					   end, [], Names),
+                                                ({string_literal, _, Str}, VarNamesAcc) ->
+                                                   {{S, _}, _} = string_ast(unescape_string_literal(Str), Context, TreeWalker),
+                                                   {S, VarNamesAcc};
+                                                ({variable, _}=Var, VarNamesAcc) ->
+                                                   {{V, #ast_info{ var_names=[VarName] }}, _} = resolve_variable_ast(Var, Context, TreeWalker, true),
+                                                   {V, [VarName|VarNamesAcc]};
+                                                ({number_literal, _, Num}, VarNamesAcc) ->
+                                                   {format(erl_syntax:integer(Num), Context, TreeWalker), VarNamesAcc};
+                                                (_, VarNamesAcc) ->
+                                                   {[], VarNamesAcc}
+                                           end, [], Names),
     {{erl_syntax:application(
         erl_syntax:atom('erlydtl_runtime'), erl_syntax:atom('cycle'),
         [erl_syntax:tuple(NamesTuple), erl_syntax:variable("Counters")]), #ast_info{ var_names = VarNames }}, TreeWalker}.
@@ -1420,19 +1420,19 @@ cycle_ast(Names, Context, TreeWalker) ->
 %% Older Django templates treat cycle with comma-delimited elements as strings
 cycle_compat_ast(Names, Context, TreeWalker) ->
     NamesTuple = lists:map(fun
-			       ({identifier, _, X}) ->
-				  {{S, _}, _} = string_ast(X, Context, TreeWalker),
-				  S
-			  end, Names),
+                               ({identifier, _, X}) ->
+                                  {{S, _}, _} = string_ast(X, Context, TreeWalker),
+                                  S
+                          end, Names),
     {{erl_syntax:application(
         erl_syntax:atom('erlydtl_runtime'), erl_syntax:atom('cycle'),
         [erl_syntax:tuple(NamesTuple), erl_syntax:variable("Counters")]), #ast_info{}}, TreeWalker}.
 
 now_ast(FormatString, Context, TreeWalker) ->
-						% Note: we can't use unescape_string_literal here
-						% because we want to allow escaping in the format string.
-						% We only want to remove the surrounding escapes,
-						% i.e. \"foo\" becomes "foo"
+                                                % Note: we can't use unescape_string_literal here
+                                                % because we want to allow escaping in the format string.
+                                                % We only want to remove the surrounding escapes,
+                                                % i.e. \"foo\" becomes "foo"
     UnescapeOuter = string:strip(FormatString, both, 34),
     {{StringAst, Info}, TreeWalker1} = string_ast(UnescapeOuter, Context, TreeWalker),
     {{erl_syntax:application(
@@ -1443,9 +1443,9 @@ now_ast(FormatString, Context, TreeWalker) ->
 spaceless_ast(Contents, Context, TreeWalker) ->
     {{Ast, Info}, TreeWalker1} = body_ast(Contents, Context, TreeWalker),
     {{erl_syntax:application(
-	erl_syntax:atom(erlydtl_runtime),
-	erl_syntax:atom(spaceless),
-	[Ast]), Info}, TreeWalker1}.
+        erl_syntax:atom(erlydtl_runtime),
+        erl_syntax:atom(spaceless),
+        [Ast]), Info}, TreeWalker1}.
 
 unescape_string_literal(String) ->
     unescape_string_literal(string:strip(String, both, 34), [], noslash).
@@ -1496,27 +1496,27 @@ tag_ast(Name, Args, Context, TreeWalker) ->
 
 custom_tags_modules_ast(Name, InterpretedArgs, #dtl_context{ custom_tags_modules = [], is_compiling_dir = false }) ->
     {erl_syntax:application(none, erl_syntax:atom(render_tag),
-			    [erl_syntax:atom(Name), erl_syntax:list(InterpretedArgs),
-			     erl_syntax:variable("RenderOptions")]),
+                            [erl_syntax:atom(Name), erl_syntax:list(InterpretedArgs),
+                             erl_syntax:variable("RenderOptions")]),
      #ast_info{custom_tags = [Name]}};
 custom_tags_modules_ast(Name, InterpretedArgs, #dtl_context{ custom_tags_modules = [], is_compiling_dir = true, module = Module }) ->
     {erl_syntax:application(erl_syntax:atom(Module), erl_syntax:atom(Name),
-			    [erl_syntax:list(InterpretedArgs), erl_syntax:variable("RenderOptions")]),
+                            [erl_syntax:list(InterpretedArgs), erl_syntax:variable("RenderOptions")]),
      #ast_info{ custom_tags = [Name] }};
 custom_tags_modules_ast(Name, InterpretedArgs, #dtl_context{ custom_tags_modules = [Module|Rest] } = Context) ->
     try lists:max([I || {N,I} <- Module:module_info(exports), N =:= Name]) of
         2 ->
             {erl_syntax:application(erl_syntax:atom(Module), erl_syntax:atom(Name),
-				    [erl_syntax:list(InterpretedArgs),
-				     erl_syntax:variable("RenderOptions")]), #ast_info{}};
+                                    [erl_syntax:list(InterpretedArgs),
+                                     erl_syntax:variable("RenderOptions")]), #ast_info{}};
         1 ->
             {erl_syntax:application(erl_syntax:atom(Module), erl_syntax:atom(Name),
-				    [erl_syntax:list(InterpretedArgs)]), #ast_info{}};
+                                    [erl_syntax:list(InterpretedArgs)]), #ast_info{}};
         I ->
             throw({unsupported_custom_tag_fun, {Module, Name, I}})
     catch _:function_clause ->
-	    custom_tags_modules_ast(Name, InterpretedArgs,
-				    Context#dtl_context{ custom_tags_modules = Rest })
+            custom_tags_modules_ast(Name, InterpretedArgs,
+                                    Context#dtl_context{ custom_tags_modules = Rest })
     end.
 
 print(true, Fmt, Args) ->
@@ -1533,22 +1533,22 @@ call_with_ast(Module, Variable, Context, TreeWalker) ->
 
 call_ast(Module, Variable, AstInfo, TreeWalker) ->
     AppAst = erl_syntax:application(
-	       erl_syntax:atom(Module),
-	       erl_syntax:atom(render),
-	       [Variable, erl_syntax:variable("RenderOptions")]),
+               erl_syntax:atom(Module),
+               erl_syntax:atom(render),
+               [Variable, erl_syntax:variable("RenderOptions")]),
     RenderedAst = erl_syntax:variable("Rendered"),
     OkAst = erl_syntax:clause(
-	      [erl_syntax:tuple([erl_syntax:atom(ok), RenderedAst])], 
-	      none,
-	      [RenderedAst]),
+              [erl_syntax:tuple([erl_syntax:atom(ok), RenderedAst])],
+              none,
+              [RenderedAst]),
     ReasonAst = erl_syntax:variable("Reason"),
     ErrStrAst = erl_syntax:application(
-		  erl_syntax:atom(io_lib),
-		  erl_syntax:atom(format),
-		  [erl_syntax:string("error: ~p"), erl_syntax:list([ReasonAst])]),
+                  erl_syntax:atom(io_lib),
+                  erl_syntax:atom(format),
+                  [erl_syntax:string("error: ~p"), erl_syntax:list([ReasonAst])]),
     ErrorAst = erl_syntax:clause(
-		 [erl_syntax:tuple([erl_syntax:atom(error), ReasonAst])], 
-		 none,
-		 [ErrStrAst]),
-    CallAst = erl_syntax:case_expr(AppAst, [OkAst, ErrorAst]),   
+                 [erl_syntax:tuple([erl_syntax:atom(error), ReasonAst])],
+                 none,
+                 [ErrStrAst]),
+    CallAst = erl_syntax:case_expr(AppAst, [OkAst, ErrorAst]),
     with_dependencies(Module:dependencies(), {{CallAst, AstInfo}, TreeWalker}).

+ 7 - 7
src/erlydtl_contrib_humanize.erl

@@ -3,16 +3,16 @@
 -export([intcomma/1]).
 
 intcomma(Value) when is_integer(Value) ->
-	intcomma(integer_to_list(Value));
+    intcomma(integer_to_list(Value));
 intcomma(Value) ->
-	ValueBin = iolist_to_binary(Value),
-	intcomma(ValueBin, size(ValueBin) rem 3, <<>>).
+    ValueBin = iolist_to_binary(Value),
+    intcomma(ValueBin, size(ValueBin) rem 3, <<>>).
 
 intcomma(<<>>, _, Acc) ->
-	Acc;
+    Acc;
 intcomma(<< C, Rest/bits >>, 0, <<>>) ->
-	intcomma(Rest, 2, << C >>);
+    intcomma(Rest, 2, << C >>);
 intcomma(<< C, Rest/bits >>, 0, Acc) ->
-	intcomma(Rest, 2, << Acc/binary, $,, C >>);
+    intcomma(Rest, 2, << Acc/binary, $,, C >>);
 intcomma(<< C, Rest/bits >>, N, Acc) ->
-	intcomma(Rest, N - 1, << Acc/binary, C >>).
+    intcomma(Rest, N - 1, << Acc/binary, C >>).

+ 3 - 3
src/erlydtl_deps.erl

@@ -3,9 +3,9 @@
 %%% @author    Roberto Saccon <rsaccon@gmail.com> [http://rsaccon.com]
 %%% @author    Evan Miller <emmiller@gmail.com>
 %%% @copyright 2008 Roberto Saccon, Evan Miller
-%%% @doc  
+%%% @doc
 %%% ErlyDTL helper module
-%%% @end  
+%%% @end
 %%%
 %%% The MIT License
 %%%
@@ -53,7 +53,7 @@ get_base_dir(Module) ->
 %%      get_base_dir(?MODULE).
 get_base_dir() ->
     get_base_dir(?MODULE).
-    
+
 %%====================================================================
 %% Internal functions
 %%====================================================================

+ 22 - 22
src/erlydtl_runtime.erl

@@ -35,7 +35,7 @@ find_value(Key, {GBSize, GBData}) when is_integer(GBSize) ->
     end;
 find_value(Key, Tuple) when is_tuple(Tuple) ->
     case element(1, Tuple) of
-        dict -> 
+        dict ->
             case dict:find(Key, Tuple) of
                 {ok, Val} ->
                     Val;
@@ -61,8 +61,8 @@ find_value(Key, Tuple) when is_tuple(Tuple) ->
 
 find_deep_value([Key|Rest],Item) ->
     case find_value(Key,Item) of
-	undefined -> undefined;
-	NewItem -> find_deep_value(Rest,NewItem)
+        undefined -> undefined;
+        NewItem -> find_deep_value(Rest,NewItem)
     end;
 find_deep_value([],Item) -> Item.
 
@@ -226,22 +226,22 @@ init_counter_stats(List) ->
     init_counter_stats(List, undefined).
 
 init_counter_stats(List, Parent) when is_list(List) ->
-    [{counter, 1}, 
-        {counter0, 0}, 
-        {revcounter, length(List)}, 
-        {revcounter0, length(List) - 1}, 
-        {first, true}, 
-        {last, length(List) =:= 1},
-        {parentloop, Parent}].
+    [{counter, 1},
+     {counter0, 0},
+     {revcounter, length(List)},
+     {revcounter0, length(List) - 1},
+     {first, true},
+     {last, length(List) =:= 1},
+     {parentloop, Parent}].
 
 increment_counter_stats([{counter, Counter}, {counter0, Counter0}, {revcounter, RevCounter},
-        {revcounter0, RevCounter0}, {first, _}, {last, _}, {parentloop, Parent}]) ->
+                         {revcounter0, RevCounter0}, {first, _}, {last, _}, {parentloop, Parent}]) ->
     [{counter, Counter + 1},
-        {counter0, Counter0 + 1},
-        {revcounter, RevCounter - 1},
-        {revcounter0, RevCounter0 - 1},
-        {first, false}, {last, RevCounter0 =:= 1},
-        {parentloop, Parent}].
+     {counter0, Counter0 + 1},
+     {revcounter, RevCounter - 1},
+     {revcounter0, RevCounter0 - 1},
+     {first, false}, {last, RevCounter0 =:= 1},
+     {parentloop, Parent}].
 
 forloop(Fun, Acc0, Values) ->
     push_ifchanged_context(),
@@ -251,9 +251,9 @@ forloop(Fun, Acc0, Values) ->
 
 push_ifchanged_context() ->
     IfChangedContextStack = case get(?IFCHANGED_CONTEXT_VARIABLE) of
-        undefined -> [];
-        Stack -> Stack
-    end,
+                                undefined -> [];
+                                Stack -> Stack
+                            end,
     put(?IFCHANGED_CONTEXT_VARIABLE, [[]|IfChangedContextStack]).
 
 pop_ifchanged_context() ->
@@ -296,8 +296,8 @@ spaceless(Contents) ->
 
 read_file(Module, Function, DocRoot, FileName) ->
     AbsName = case filename:absname(FileName) of
-        FileName -> FileName;
-        _ -> filename:join([DocRoot, FileName])
-    end,
+                  FileName -> FileName;
+                  _ -> filename:join([DocRoot, FileName])
+              end,
     {ok, Binary} = Module:Function(AbsName),
     binary_to_list(Binary).

+ 35 - 35
src/erlydtl_unparser.erl

@@ -33,55 +33,55 @@ unparse([{'filter', FilterList, Contents}|Rest], 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), 
-                "{% endfor %}"]|Acc]);
+    unparse(Rest, [["{% for ", unparse_identifier(Identifier), " in ", unparse(IteratorList), " %}",
+                    unparse(Contents),
+                    "{% endfor %}"]|Acc]);
 unparse([{'for', {'in', IteratorList, Identifier}, Contents, EmptyPartsContents}|Rest], Acc) ->
     unparse(Rest, [["{% for ", unparse_identifier(Identifier), " in ", unparse(IteratorList), " %}",
-                unparse(Contents),
-                "{% empty %}",
-                unparse(EmptyPartsContents),
-                "{% endfor %}"]|Acc]);
+                    unparse(Contents),
+                    "{% empty %}",
+                    unparse(EmptyPartsContents),
+                    "{% endfor %}"]|Acc]);
 unparse([{'if', Expression, Contents}|Rest], Acc) ->
     unparse(Rest, [["{% if ", unparse_expression(Expression), " %}",
-                unparse(Contents),
-                "{% endif %}"]|Acc]);
+                    unparse(Contents),
+                    "{% endif %}"]|Acc]);
 unparse([{'ifchanged', Expression, IfContents}|Rest], Acc) ->
     unparse(Rest, [["{% ifchanged ", unparse_expression(Expression), " %}",
-                unparse(IfContents),
-                "{% endifchanged %}"]|Acc]);
+                    unparse(IfContents),
+                    "{% endifchanged %}"]|Acc]);
 unparse([{'ifchangedelse', Expression, IfContents, ElseContents}|Rest], Acc) ->
     unparse(Rest, [["{% ifchanged ", unparse_expression(Expression), " %}",
-                unparse(IfContents),
-                "{% else %}",
-                unparse(ElseContents),
-                "{% endifchanged %}"]|Acc]);
+                    unparse(IfContents),
+                    "{% else %}",
+                    unparse(ElseContents),
+                    "{% endifchanged %}"]|Acc]);
 unparse([{'ifelse', Expression, IfContents, ElseContents}|Rest], Acc) ->
     unparse(Rest, [["{% if ", unparse_expression(Expression), " %}",
-                unparse(IfContents),
-                "{% else %}",
-                unparse(ElseContents),
-                "{% endif %}"]|Acc]);
+                    unparse(IfContents),
+                    "{% else %}",
+                    unparse(ElseContents),
+                    "{% endif %}"]|Acc]);
 unparse([{'ifequal', [Arg1, Arg2], Contents}|Rest], Acc) ->
     unparse(Rest, [["{% ifequal ", unparse_value(Arg1), " ", unparse_value(Arg2), " %}",
-                unparse(Contents),
-                "{% endifequal %}"]|Acc]);
+                    unparse(Contents),
+                    "{% endifequal %}"]|Acc]);
 unparse([{'ifequalelse', [Arg1, Arg2], IfContents, ElseContents}|Rest], Acc) ->
     unparse(Rest, [["{% ifequal ", unparse_value(Arg1), " ", unparse_value(Arg2), " %}",
-                unparse(IfContents),
-                "{% else %}",
-                unparse(ElseContents),
-                "{% endifequal %}"]|Acc]);
+                    unparse(IfContents),
+                    "{% else %}",
+                    unparse(ElseContents),
+                    "{% endifequal %}"]|Acc]);
 unparse([{'ifnotequal', [Arg1, Arg2], Contents}|Rest], Acc) ->
     unparse(Rest, [["{% ifnotequal ", unparse_value(Arg1), " ", unparse_value(Arg2), " %}",
-                unparse(Contents),
-                "{% endifnotequal %}"]|Acc]);
+                    unparse(Contents),
+                    "{% endifnotequal %}"]|Acc]);
 unparse([{'ifnotequalelse', [Arg1, Arg2], IfContents, ElseContents}|Rest], Acc) ->
     unparse(Rest, [["{% ifnotequal ", unparse_value(Arg1), " ", unparse_value(Arg2), " %}",
-                unparse(IfContents),
-                "{% else %}",
-                unparse(ElseContents),
-                "{% endifnotequal %}"]|Acc]);
+                    unparse(IfContents),
+                    "{% else %}",
+                    unparse(ElseContents),
+                    "{% endifnotequal %}"]|Acc]);
 unparse([{'include', Value, []}|Rest], Acc) ->
     unparse(Rest, [["{% include ", unparse_value(Value), " %}"]|Acc]);
 unparse([{'include', Value, Args}|Rest], Acc) ->
@@ -92,8 +92,8 @@ 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),
-                "{% endregroup %}"]|Acc]);
+                    unparse(Contents),
+                    "{% endregroup %}"]|Acc]);
 unparse([{'spaceless', Contents}|Rest], Acc) ->
     unparse(Rest, [["{% spaceless %}", unparse(Contents), "{% endspaceless %}"]|Acc]);
 unparse([{'ssi', Arg}|Rest], Acc) ->
@@ -114,8 +114,8 @@ 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),
-                "{% endwidth %}"]|Acc]);
+                    unparse(Contents),
+                    "{% endwidth %}"]|Acc]);
 unparse([ValueToken|Rest], Acc) ->
     unparse(Rest, [["{{ ", unparse_value(ValueToken), " }}"]|Acc]).
 

+ 196 - 196
src/filter_lib/erlydtl_dateformat.erl

@@ -2,70 +2,70 @@
 -export([format/1, format/2]).
 
 -define(TAG_SUPPORTED(C),
-    C =:= $a orelse
-    C =:= $A orelse
-    C =:= $b orelse
-    C =:= $B orelse
-    C =:= $c orelse
-    C =:= $d orelse
-    C =:= $D orelse
-    C =:= $f orelse
-    C =:= $F orelse
-    C =:= $g orelse
-    C =:= $G orelse
-    C =:= $h orelse
-    C =:= $H orelse
-    C =:= $i orelse
-    C =:= $I orelse
-    C =:= $j orelse
-    C =:= $l orelse
-    C =:= $L orelse
-    C =:= $m orelse
-    C =:= $M orelse
-    C =:= $n orelse
-    C =:= $N orelse
-    C =:= $O orelse
-    C =:= $P orelse
-    C =:= $r orelse
-    C =:= $s orelse
-    C =:= $S orelse
-    C =:= $t orelse
-    C =:= $T orelse
-    C =:= $U orelse
-    C =:= $w orelse
-    C =:= $W orelse
-    C =:= $y orelse
-    C =:= $Y orelse
-    C =:= $z orelse
-    C =:= $Z orelse
-    C =:= $o
-).
-
-%
-% Format the current date/time
-%
+        C =:= $a orelse
+        C =:= $A orelse
+        C =:= $b orelse
+        C =:= $B orelse
+        C =:= $c orelse
+        C =:= $d orelse
+        C =:= $D orelse
+        C =:= $f orelse
+        C =:= $F orelse
+        C =:= $g orelse
+        C =:= $G orelse
+        C =:= $h orelse
+        C =:= $H orelse
+        C =:= $i orelse
+        C =:= $I orelse
+        C =:= $j orelse
+        C =:= $l orelse
+        C =:= $L orelse
+        C =:= $m orelse
+        C =:= $M orelse
+        C =:= $n orelse
+        C =:= $N orelse
+        C =:= $O orelse
+        C =:= $P orelse
+        C =:= $r orelse
+        C =:= $s orelse
+        C =:= $S orelse
+        C =:= $t orelse
+        C =:= $T orelse
+        C =:= $U orelse
+        C =:= $w orelse
+        C =:= $W orelse
+        C =:= $y orelse
+        C =:= $Y orelse
+        C =:= $z orelse
+        C =:= $Z orelse
+        C =:= $o
+       ).
+
+%%
+%% Format the current date/time
+%%
 format(FormatString) when is_binary(FormatString) ->
     format(binary_to_list(FormatString));
 format(FormatString) ->
     {Date, Time} = erlang:localtime(),
     replace_tags(Date, Time, FormatString).
-%
-% Format a tuple of the form {{Y,M,D},{H,M,S}}
-% This is the format returned by erlang:localtime()
-% and other standard date/time BIFs
-%
+%%
+%% Format a tuple of the form {{Y,M,D},{H,M,S}}
+%% This is the format returned by erlang:localtime()
+%% and other standard date/time BIFs
+%%
 format(DateTime, FormatString) when is_binary(FormatString) ->
     format(DateTime, binary_to_list(FormatString));
 format({{_,_,_} = Date,{_,_,_} = Time}, FormatString) ->
     replace_tags(Date, Time, FormatString);
-%
-% Format a tuple of the form {Y,M,D}
-%
+%%
+%% Format a tuple of the form {Y,M,D}
+%%
 format({_,_,_} = Date, FormatString) ->
-   replace_tags(Date, {0,0,0}, FormatString);
+    replace_tags(Date, {0,0,0}, FormatString);
 format(DateTime, FormatString) ->
-   io:format("Unrecognised date paramater : ~p~n", [DateTime]),
-   FormatString.
+    io:format("Unrecognised date paramater : ~p~n", [DateTime]),
+    FormatString.
 
 replace_tags(Date, Time, Input) ->
     replace_tags(Date, Time, Input, [], noslash).
@@ -73,7 +73,7 @@ replace_tags(_Date, _Time, [], Out, _State) ->
     lists:reverse(Out);
 replace_tags(Date, Time, [C|Rest], Out, noslash) when ?TAG_SUPPORTED(C) ->
     replace_tags(Date, Time, Rest,
-       lists:reverse(tag_to_value(C, Date, Time)) ++ Out, noslash);
+                 lists:reverse(tag_to_value(C, Date, Time)) ++ Out, noslash);
 replace_tags(Date, Time, [$\\|Rest], Out, noslash) ->
     replace_tags(Date, Time, Rest, Out, slash);
 replace_tags(Date, Time, [C|Rest], Out, slash) ->
@@ -82,212 +82,212 @@ replace_tags(Date, Time, [C|Rest], Out, _State) ->
     replace_tags(Date, Time, Rest, [C|Out], noslash).
 
 
-%-----------------------------------------------------------
-% Time formatting
-%-----------------------------------------------------------
+%%-----------------------------------------------------------
+%% Time formatting
+%%-----------------------------------------------------------
 
-% 'a.m.' or 'p.m.'
+%% 'a.m.' or 'p.m.'
 tag_to_value($a, _, {H, _, _}) when H > 11 -> "p.m.";
 tag_to_value($a, _, _) -> "a.m.";
 
-% 'AM' or 'PM'
+%% 'AM' or 'PM'
 tag_to_value($A, _, {H, _, _}) when H > 11 -> "PM";
 tag_to_value($A, _, _) -> "AM";
 
-% Swatch Internet time
+%% Swatch Internet time
 tag_to_value($B, _, _) ->
-   ""; % NotImplementedError
+    ""; %% NotImplementedError
 
-% ISO 8601 Format.
+%% ISO 8601 Format.
 tag_to_value($c, Date, Time) ->
-    tag_to_value($Y, Date, Time) ++ 
-    "-" ++ tag_to_value($m, Date, Time) ++ 
-    "-" ++ tag_to_value($d, Date, Time) ++ 
-    "T" ++ tag_to_value($H, Date, Time) ++
-    ":" ++ tag_to_value($i, Date, Time) ++
-    ":" ++ tag_to_value($s, Date, Time);
-
-%
-% Time, in 12-hour hours and minutes, with minutes
-% left off if they're zero.
-%
-% Examples: '1', '1:30', '2:05', '2'
-%
-% Proprietary extension.
-%
+    tag_to_value($Y, Date, Time) ++
+        "-" ++ tag_to_value($m, Date, Time) ++
+        "-" ++ tag_to_value($d, Date, Time) ++
+        "T" ++ tag_to_value($H, Date, Time) ++
+        ":" ++ tag_to_value($i, Date, Time) ++
+        ":" ++ tag_to_value($s, Date, Time);
+
+%%
+%% Time, in 12-hour hours and minutes, with minutes
+%% left off if they're zero.
+%%
+%% Examples: '1', '1:30', '2:05', '2'
+%%
+%% Proprietary extension.
+%%
 tag_to_value($f, Date, {H, 0, S}) ->
-   % If min is zero then return the hour only
-   tag_to_value($g, Date, {H, 0, S});
+    %% If min is zero then return the hour only
+    tag_to_value($g, Date, {H, 0, S});
 tag_to_value($f, Date, Time) ->
-   % Otherwise return hours and mins
-   tag_to_value($g, Date, Time)
-      ++ ":" ++ tag_to_value($i, Date, Time);
+    %% Otherwise return hours and mins
+    tag_to_value($g, Date, Time)
+        ++ ":" ++ tag_to_value($i, Date, Time);
 
-% Hour, 12-hour format without leading zeros; i.e. '1' to '12'
+%% Hour, 12-hour format without leading zeros; i.e. '1' to '12'
 tag_to_value($g, _, {H,_,_}) ->
-   integer_to_list(hour_24to12(H));
+    integer_to_list(hour_24to12(H));
 
-% Hour, 24-hour format without leading zeros; i.e. '0' to '23'
+%% Hour, 24-hour format without leading zeros; i.e. '0' to '23'
 tag_to_value($G, _, {H,_,_}) ->
-   integer_to_list(H);
+    integer_to_list(H);
 
-% Hour, 12-hour format; i.e. '01' to '12'
+%% Hour, 12-hour format; i.e. '01' to '12'
 tag_to_value($h, _, {H,_,_}) ->
-   integer_to_list_zerofill(hour_24to12(H));
+    integer_to_list_zerofill(hour_24to12(H));
 
-% Hour, 24-hour format; i.e. '00' to '23'
+%% Hour, 24-hour format; i.e. '00' to '23'
 tag_to_value($H, _, {H,_,_}) ->
-   integer_to_list_zerofill(H);
+    integer_to_list_zerofill(H);
 
-% Minutes; i.e. '00' to '59'
+%% Minutes; i.e. '00' to '59'
 tag_to_value($i, _, {_,M,_}) ->
-   integer_to_list_zerofill(M);
+    integer_to_list_zerofill(M);
 
-% Time, in 12-hour hours, minutes and 'a.m.'/'p.m.', with minutes left off
-% if they're zero and the strings 'midnight' and 'noon' if appropriate.
-% Examples: '1 a.m.', '1:30 p.m.', 'midnight', 'noon', '12:30 p.m.'
-% Proprietary extension.
+%% Time, in 12-hour hours, minutes and 'a.m.'/'p.m.', with minutes left off
+%% if they're zero and the strings 'midnight' and 'noon' if appropriate.
+%% Examples: '1 a.m.', '1:30 p.m.', 'midnight', 'noon', '12:30 p.m.'
+%% Proprietary extension.
 tag_to_value($P, _, {0,  0, _}) -> "midnight";
 tag_to_value($P, _, {12, 0, _}) -> "noon";
 tag_to_value($P, Date, Time) ->
-   tag_to_value($f, Date, Time)
-      ++ " " ++ tag_to_value($a, Date, Time);
+    tag_to_value($f, Date, Time)
+        ++ " " ++ tag_to_value($a, Date, Time);
 
-% Seconds; i.e. '00' to '59'
+%% Seconds; i.e. '00' to '59'
 tag_to_value($s, _, {_,_,S}) ->
-   integer_to_list_zerofill(S);
+    integer_to_list_zerofill(S);
 
-%-----------------------------------------------------------
-% Date formatting
-%-----------------------------------------------------------
+%%-----------------------------------------------------------
+%% Date formatting
+%%-----------------------------------------------------------
 
-% Month, textual, 3 letters, lowercase; e.g. 'jan'
+%% Month, textual, 3 letters, lowercase; e.g. 'jan'
 tag_to_value($b, {_,M,_}, _) ->
-   string:sub_string(monthname(M), 1, 3);
+    string:sub_string(monthname(M), 1, 3);
 
-% Day of the month, 2 digits with leading zeros; i.e. '01' to '31'
+%% Day of the month, 2 digits with leading zeros; i.e. '01' to '31'
 tag_to_value($d, {_, _, D}, _) ->
-   integer_to_list_zerofill(D);
+    integer_to_list_zerofill(D);
 
-% Day of the week, textual, 3 letters; e.g. 'Fri'
+%% Day of the week, textual, 3 letters; e.g. 'Fri'
 tag_to_value($D, Date, _) ->
-   Dow = calendar:day_of_the_week(Date),
-   ucfirst(string:sub_string(dayname(Dow), 1, 3));
+    Dow = calendar:day_of_the_week(Date),
+    ucfirst(string:sub_string(dayname(Dow), 1, 3));
 
-% Month, textual, long; e.g. 'January'
+%% Month, textual, long; e.g. 'January'
 tag_to_value($F, {_,M,_}, _) ->
-   ucfirst(monthname(M));
+    ucfirst(monthname(M));
 
-% '1' if Daylight Savings Time, '0' otherwise.
+%% '1' if Daylight Savings Time, '0' otherwise.
 tag_to_value($I, _, _) ->
-   "TODO";
+    "TODO";
 
-% Day of the month without leading zeros; i.e. '1' to '31'
+%% Day of the month without leading zeros; i.e. '1' to '31'
 tag_to_value($j, {_, _, D}, _) ->
-   integer_to_list(D);
+    integer_to_list(D);
 
-% Day of the week, textual, long; e.g. 'Friday'
+%% Day of the week, textual, long; e.g. 'Friday'
 tag_to_value($l, Date, _) ->
-   ucfirst(dayname(calendar:day_of_the_week(Date)));
+    ucfirst(dayname(calendar:day_of_the_week(Date)));
 
-% Boolean for whether it is a leap year; i.e. True or False
+%% Boolean for whether it is a leap year; i.e. True or False
 tag_to_value($L, {Y,_,_}, _) ->
-   case calendar:is_leap_year(Y) of
-   true -> "True";
-   _ -> "False"
-   end;
+    case calendar:is_leap_year(Y) of
+        true -> "True";
+        _ -> "False"
+    end;
 
-% Month; i.e. '01' to '12'
+%% Month; i.e. '01' to '12'
 tag_to_value($m, {_, M, _}, _) ->
-   integer_to_list_zerofill(M);
+    integer_to_list_zerofill(M);
 
-% Month, textual, 3 letters; e.g. 'Jan'
+%% Month, textual, 3 letters; e.g. 'Jan'
 tag_to_value($M, {_,M,_}, _) ->
-   ucfirst(string:sub_string(monthname(M), 1, 3));
+    ucfirst(string:sub_string(monthname(M), 1, 3));
 
-% Month without leading zeros; i.e. '1' to '12'
+%% Month without leading zeros; i.e. '1' to '12'
 tag_to_value($n, {_, M, _}, _) ->
-   integer_to_list(M);
+    integer_to_list(M);
 
-% Month abbreviation in Associated Press style. Proprietary extension.
+%% Month abbreviation in Associated Press style. Proprietary extension.
 tag_to_value($N, {_,M,_}, _) when M =:= 9 ->
-   % Special case - "Sept."
-   ucfirst(string:sub_string(monthname(M), 1, 4)) ++ ".";
+    %% Special case - "Sept."
+    ucfirst(string:sub_string(monthname(M), 1, 4)) ++ ".";
 tag_to_value($N, {_,M,_}, _) when M < 3 orelse M > 7 ->
-   % Jan, Feb, Aug, Oct, Nov, Dec are all
-   % abbreviated with a full-stop appended.
-   ucfirst(string:sub_string(monthname(M), 1, 3)) ++ ".";
+    %% Jan, Feb, Aug, Oct, Nov, Dec are all
+    %% abbreviated with a full-stop appended.
+    ucfirst(string:sub_string(monthname(M), 1, 3)) ++ ".";
 tag_to_value($N, {_,M,_}, _) ->
-   % The rest are the fullname.
-   ucfirst(monthname(M));
+    %% The rest are the fullname.
+    ucfirst(monthname(M));
 
-% Difference to Greenwich time in hours; e.g. '+0200'
+%% Difference to Greenwich time in hours; e.g. '+0200'
 tag_to_value($O, Date, Time) ->
-   Diff = utc_diff(Date, Time),
-   Offset = if
-      Diff < 0 ->
-          io_lib:format("-~4..0w", [abs(Diff)]);
-      true ->
-          io_lib:format("+~4..0w", [Diff])
-   end,
-   lists:flatten(Offset);
-
-% RFC 2822 formatted date; e.g. 'Thu, 21 Dec 2000 16:01:07 +0200'
+    Diff = utc_diff(Date, Time),
+    Offset = if
+                 Diff < 0 ->
+                     io_lib:format("-~4..0w", [abs(Diff)]);
+                 true ->
+                     io_lib:format("+~4..0w", [Diff])
+             end,
+    lists:flatten(Offset);
+
+%% RFC 2822 formatted date; e.g. 'Thu, 21 Dec 2000 16:01:07 +0200'
 tag_to_value($r, Date, Time) ->
-   replace_tags(Date, Time, "D, j M Y H:i:s O");
+    replace_tags(Date, Time, "D, j M Y H:i:s O");
 
-% English ordinal suffix for the day of the month, 2 characters;
-% i.e. 'st', 'nd', 'rd' or 'th'
+%% English ordinal suffix for the day of the month, 2 characters;
+%% i.e. 'st', 'nd', 'rd' or 'th'
 tag_to_value($S, {_, _, D}, _) when
-   D rem 100 =:= 11 orelse
-   D rem 100 =:= 12 orelse
-   D rem 100 =:= 13 -> "th";
+      D rem 100 =:= 11 orelse
+      D rem 100 =:= 12 orelse
+      D rem 100 =:= 13 -> "th";
 tag_to_value($S, {_, _, D}, _) when D rem 10 =:= 1 -> "st";
 tag_to_value($S, {_, _, D}, _) when D rem 10 =:= 2 -> "nd";
 tag_to_value($S, {_, _, D}, _) when D rem 10 =:= 3 -> "rd";
 tag_to_value($S, _, _) -> "th";
 
-% Number of days in the given month; i.e. '28' to '31'
+%% Number of days in the given month; i.e. '28' to '31'
 tag_to_value($t, {Y,M,_}, _) ->
-   integer_to_list(calendar:last_day_of_the_month(Y,M));
+    integer_to_list(calendar:last_day_of_the_month(Y,M));
 
-% Time zone of this machine; e.g. 'EST' or 'MDT'
+%% Time zone of this machine; e.g. 'EST' or 'MDT'
 tag_to_value($T, _, _) ->
-   "TODO";
+    "TODO";
 
-% Seconds since the Unix epoch (January 1 1970 00:00:00 GMT)
+%% Seconds since the Unix epoch (January 1 1970 00:00:00 GMT)
 tag_to_value($U, Date, Time) ->
     EpochSecs = calendar:datetime_to_gregorian_seconds({Date, Time})
-       - calendar:datetime_to_gregorian_seconds({{1970,1,1},{0,0,0}}),
+        - calendar:datetime_to_gregorian_seconds({{1970,1,1},{0,0,0}}),
     integer_to_list(EpochSecs);
 
-% Day of the week, numeric, i.e. '0' (Sunday) to '6' (Saturday)
+%% Day of the week, numeric, i.e. '0' (Sunday) to '6' (Saturday)
 tag_to_value($w, Date, _) ->
-   % Note: calendar:day_of_the_week returns
-   %   1 | .. | 7. Monday = 1, Tuesday = 2, ..., Sunday = 7
-   integer_to_list(calendar:day_of_the_week(Date) rem 7);
+    %% Note: calendar:day_of_the_week returns
+    %%   1 | .. | 7. Monday = 1, Tuesday = 2, ..., Sunday = 7
+    integer_to_list(calendar:day_of_the_week(Date) rem 7);
 
-% ISO-8601 week number of year, weeks starting on Monday
+%% ISO-8601 week number of year, weeks starting on Monday
 tag_to_value($W, {Y,M,D}, _) ->
-   integer_to_list(year_weeknum(Y,M,D));
+    integer_to_list(year_weeknum(Y,M,D));
 
-% Year, 2 digits; e.g. '99'
+%% Year, 2 digits; e.g. '99'
 tag_to_value($y, {Y, _, _}, _) ->
-   string:sub_string(integer_to_list(Y), 3);
+    string:sub_string(integer_to_list(Y), 3);
 
-% Year, 4 digits; e.g. '1999'
+%% Year, 4 digits; e.g. '1999'
 tag_to_value($Y, {Y, _, _}, _) ->
-   integer_to_list(Y);
+    integer_to_list(Y);
 
-% Day of the year; i.e. '0' to '365'
+%% Day of the year; i.e. '0' to '365'
 tag_to_value($z, {Y,M,D}, _) ->
     integer_to_list(day_of_year(Y,M,D));
 
-% Time zone offset in seconds (i.e. '-43200' to '43200'). The offset for
-% timezones west of UTC is always negative, and for those east of UTC is
-% always positive.
+%% Time zone offset in seconds (i.e. '-43200' to '43200'). The offset for
+%% timezones west of UTC is always negative, and for those east of UTC is
+%% always positive.
 tag_to_value($Z, _, _) ->
-   "TODO";
+    "TODO";
 
 %% o – the ISO 8601 year number
 tag_to_value($o, {Y,M,D}, _) ->
@@ -295,35 +295,35 @@ tag_to_value($o, {Y,M,D}, _) ->
 
 tag_to_value(C, Date, Time) ->
     io:format("Unimplemented tag : ~p [Date : ~p] [Time : ~p]",
-        [C, Date, Time]),
+              [C, Date, Time]),
     "".
 
-% Date helper functions
+%% Date helper functions
 day_of_year(Y,M,D) ->
-   day_of_year(Y,M,D,0).
+    day_of_year(Y,M,D,0).
 day_of_year(_Y,M,D,Count) when M =< 1 ->
-   D + Count;
+    D + Count;
 day_of_year(Y,M,D,Count) when M =< 12 ->
-   day_of_year(Y, M - 1, D, Count + calendar:last_day_of_the_month(Y,M));
+    day_of_year(Y, M - 1, D, Count + calendar:last_day_of_the_month(Y,M));
 day_of_year(Y,_M,D,_Count) ->
-   day_of_year(Y, 12, D, 0).
+    day_of_year(Y, 12, D, 0).
 
 hour_24to12(0) -> 12;
 hour_24to12(H) when H < 13 -> H;
 hour_24to12(H) when H < 24 -> H - 12;
 hour_24to12(H) -> H.
 
-year_weeknum(Y,M,D) -> 
+year_weeknum(Y,M,D) ->
     First = (calendar:day_of_the_week(Y, 1, 1) rem 7) - 1,
     Wk = ((((calendar:date_to_gregorian_days(Y, M, D) -
-            calendar:date_to_gregorian_days(Y, 1, 1)) + First) div 7)
-           + (case First < 4 of true -> 1; _ -> 0 end)),
+                 calendar:date_to_gregorian_days(Y, 1, 1)) + First) div 7)
+          + (case First < 4 of true -> 1; _ -> 0 end)),
     case Wk of
-       0 -> weeks_in_year(Y - 1);
-       _ -> case weeks_in_year(Y) of
-              WksInThisYear when Wk > WksInThisYear -> 1;
-              _ -> Wk
-            end
+        0 -> weeks_in_year(Y - 1);
+        _ -> case weeks_in_year(Y) of
+                 WksInThisYear when Wk > WksInThisYear -> 1;
+                 _ -> Wk
+             end
     end.
 
 weeknum_year(Y,M,D) ->
@@ -335,7 +335,7 @@ weeknum_year(Y,M,D) ->
         {12, 2} -> Y + 1;
         _ -> Y
     end.
-            
+
 weeks_in_year(Y) ->
     D1 = calendar:day_of_the_week(Y, 1, 1),
     D2 = calendar:day_of_the_week(Y, 12, 31),
@@ -344,11 +344,11 @@ weeks_in_year(Y) ->
 utc_diff({Y, M, D}, Time) when Y < 1970->
     utc_diff({1970, M, D}, Time);
 utc_diff(Date, Time) ->
-   LTime = {Date, Time},
-   UTime = erlang:localtime_to_universaltime(LTime),
-   DiffSecs = calendar:datetime_to_gregorian_seconds(LTime) - 
-       calendar:datetime_to_gregorian_seconds(UTime),
-   trunc((DiffSecs / 3600) * 100).
+    LTime = {Date, Time},
+    UTime = erlang:localtime_to_universaltime(LTime),
+    DiffSecs = calendar:datetime_to_gregorian_seconds(LTime) -
+        calendar:datetime_to_gregorian_seconds(UTime),
+    trunc((DiffSecs / 3600) * 100).
 
 dayname(1) -> "monday";
 dayname(2) -> "tuesday";
@@ -373,7 +373,7 @@ monthname(11) -> "november";
 monthname(12) -> "december";
 monthname(_) -> "???".
 
-% Utility functions
+%% Utility functions
 integer_to_list_zerofill(N) when is_float(N) ->
     integer_to_list_zerofill(erlang:round(N));
 integer_to_list_zerofill(N) when N < 10 ->

+ 71 - 71
src/filter_lib/erlydtl_slice.erl

@@ -7,94 +7,94 @@
 -endif.
 -define(TEST,"").
 -define(NOTEST,1).
-% remark out NODEBUG when running tests; unremark when debugging indivdual use cases
+%% remark out NODEBUG when running tests; unremark when debugging indivdual use cases
 -define(NODEBUG,1).
 -include_lib("eunit/include/eunit.hrl").
 
 slice(List,":") ->
     List;
 slice(List,Index) ->
-    ListLength = erlang:length(List), 
-    {Start,End,C1,C2,Step} = parse_index(Index), 
+    ListLength = erlang:length(List),
+    {Start,End,C1,C2,Step} = parse_index(Index),
     try
-      slice_input_cases(List,ListLength,Start,C1,End,C2,Step)
+        slice_input_cases(List,ListLength,Start,C1,End,C2,Step)
     catch
-      throw:outOfBounds ->
-	  [];
-      throw:indexError ->
-	  indexError
+        throw:outOfBounds ->
+            [];
+        throw:indexError ->
+            indexError
     end.
 
 slice_input_cases(_List,ListLength,Start,false,[],false,[]) when Start > 0, Start >= ListLength ->
     throw(indexError);
 slice_input_cases(_List,ListLength,Start,false,[],false,[]) when Start < 0, Start < -ListLength ->
     throw(indexError);
-%[-1]
+%%[-1]
 slice_input_cases(List,ListLength,Start,false,[],false,[]) when Start<0 ->
-    S = start_transform(ListLength,Start+ListLength+1),   
-    LowerBound = single_index_bounds(S), 
-    ?debugFmt("slice_transform exit: ~p, ~p, ~p~n",[List,S,LowerBound]), 
-    %[Result] = lists:sublist(List,LowerBound,Step),
+    S = start_transform(ListLength,Start+ListLength+1),
+    LowerBound = single_index_bounds(S),
+    ?debugFmt("slice_transform exit: ~p, ~p, ~p~n",[List,S,LowerBound]),
+    %%[Result] = lists:sublist(List,LowerBound,Step),
     lists:nth(LowerBound,List);
-%[1]
+%%[1]
 slice_input_cases(List,ListLength,Start,false,[],false,[]) ->
-    %S = start_transform(ListLength,Start+1), 
-    %E = end_transform(ListLength,Start+2), 
+    %%S = start_transform(ListLength,Start+1),
+    %%E = end_transform(ListLength,Start+2),
     Step = 1,
     End = Start + 1,
     {Start1,End1,Step1} = index_defaults(ListLength,Start,End,Step),
-    S = start_transform(ListLength,Start1), 
-    E = end_transform(ListLength,End1), 
+    S = start_transform(ListLength,Start1),
+    E = end_transform(ListLength,End1),
     ?debugFmt("slice_transform: S,E,Step1: ~p,~p,~p~n",[S,E,Step1]),
     [Result] = slice_list(List,ListLength,S,false,E,false,Step1),
     Result;
-%slice_transform(List, ListLength, Start, C1, End, C2, Step) when End < 0, Step > 0 ->
-%    [];
-%slice_transform(List, ListLength, Start, C1, End, C2, Step) when End > 0, Step < 0 ->
-%    [];
-%[::-1]
+%%slice_transform(List, ListLength, Start, C1, End, C2, Step) when End < 0, Step > 0 ->
+%%    [];
+%%slice_transform(List, ListLength, Start, C1, End, C2, Step) when End > 0, Step < 0 ->
+%%    [];
+%%[::-1]
 slice_input_cases(List,ListLength,[],true,[],true,Step) when Step < 0 ->
-    ?debugMsg("here"), 
+    ?debugMsg("here"),
     slice_transform(List,ListLength,ListLength,true,-2*(ListLength+1),true,Step);
-%[::1]
+%%[::1]
 slice_input_cases(List,ListLength,[],true,[],true,Step) when Step > 0 ->
     slice_transform(List,ListLength,0,true,ListLength,true,Step);
 slice_input_cases(List,ListLength,Start,C1,End,C2,Step) ->
     slice_transform(List,ListLength,Start,C1,End,C2,Step).
 
-%[N:N:N]
+%%[N:N:N]
 slice_transform(List,ListLength,Start,C1,End,C2,Step) ->
     {Start1,End1,Step1} = index_defaults(ListLength,Start,End,Step),
-    S = start_transform(ListLength,Start1), 
-    E = end_transform(ListLength,End1), 
+    S = start_transform(ListLength,Start1),
+    E = end_transform(ListLength,End1),
     ?debugFmt("slice_transform: S,C1,E,C2,Step1: ~p,~p,~p,~p,~p~n",[S,C1,E,C2,Step1]),
     slice_list(List,ListLength,S,C1,E,C2,Step1).
 
-%[N:N:N]
+%%[N:N:N]
 slice_list(_List,_ListLength,Start,_C1,End,_C2,Step) when Start > End, Step > 0 ->
     throw(outOfBounds);
 slice_list(_List,_ListLength,Start,_C1,End,_C2,Step) when Start < End andalso Step < 0 ->
-	  throw(outOfBounds); 
+    throw(outOfBounds);
 slice_list(_List,_ListLength,Start,_C1,End,_C2,_Step) when Start < 0 andalso End < 0 ->
-	  throw(outOfBounds);
+    throw(outOfBounds);
 slice_list(_List,ListLength,Start,_C1,End,_C2,_Step) when Start > ListLength andalso End > ListLength-1 ->
-	  throw(outOfBounds);
+    throw(outOfBounds);
 slice_list(List,ListLength,Start,_C1,End,_C2,Step) when Step > 0 ->
-    {LowerBound,UpperBound} = index_bounds(Step,ListLength,Start,End), 
-    ?debugFmt("LowerBound+1, UpperBound+1, UpperBound - LowerBound + 1: ~p, ~p, ~p~n",[LowerBound+1,UpperBound,UpperBound-LowerBound]), 
-    BoundList = lists:sublist(List,LowerBound+1,UpperBound-LowerBound), 
-    SequenceList = lists:seq(1,erlang:length(BoundList),Step), 
+    {LowerBound,UpperBound} = index_bounds(Step,ListLength,Start,End),
+    ?debugFmt("LowerBound+1, UpperBound+1, UpperBound - LowerBound + 1: ~p, ~p, ~p~n",[LowerBound+1,UpperBound,UpperBound-LowerBound]),
+    BoundList = lists:sublist(List,LowerBound+1,UpperBound-LowerBound),
+    SequenceList = lists:seq(1,erlang:length(BoundList),Step),
     lists:map(fun (N) -> lists:nth(N,BoundList) end,SequenceList);
-slice_list(List,ListLength,Start,_C1,End,_C2,Step) when Step < 0 ->    
+slice_list(List,ListLength,Start,_C1,End,_C2,Step) when Step < 0 ->
     {LowerBound,UpperBound} = index_bounds(Step,ListLength,Start,End),
-    %S1 = S0 - 1,
+    %%S1 = S0 - 1,
     ?debugFmt("Start,End: ~p, ~p~n",[Start,End]),
     case erlang:abs(End) > ListLength of
         true ->
-            ?debugFmt("LowerBound, UpperBound, UpperBound - LowerBound + 1: ~p, ~p, ~p~n",[LowerBound+1,UpperBound,UpperBound-LowerBound+1]), 
+            ?debugFmt("LowerBound, UpperBound, UpperBound - LowerBound + 1: ~p, ~p, ~p~n",[LowerBound+1,UpperBound,UpperBound-LowerBound+1]),
             BoundList = lists:sublist(List, LowerBound+1, UpperBound - LowerBound + 1);
         false ->
-            ?debugFmt("LowerBound+2, UpperBound, UpperBound - LowerBound: ~p, ~p, ~p~n",[LowerBound+2,UpperBound,UpperBound-LowerBound]), 
+            ?debugFmt("LowerBound+2, UpperBound, UpperBound - LowerBound: ~p, ~p, ~p~n",[LowerBound+2,UpperBound,UpperBound-LowerBound]),
             BoundList = lists:sublist(List, LowerBound+2, UpperBound - LowerBound)
     end,
     ?debugFmt("BoundList: ~p~n",[BoundList]),
@@ -104,53 +104,53 @@ slice_list(List,ListLength,Start,_C1,End,_C2,Step) when Step < 0 ->
 
 index_defaults(ListLength, Start, End, Step) ->
     case Start==[] of
-      true -> Start1 = 0;
-      false -> Start1 = Start
-    end, 
+        true -> Start1 = 0;
+        false -> Start1 = Start
+    end,
     case End==[] of
-      true -> End1 = ListLength;
-      false -> End1 = End
-    end, 
+        true -> End1 = ListLength;
+        false -> End1 = End
+    end,
     case Step==[] of
-      true -> Step1 = 1;
-      false -> Step1 = Step
-    end, 
+        true -> Step1 = 1;
+        false -> Step1 = Step
+    end,
     {Start1, End1, Step1}.
 
 single_index_bounds(S) ->
-    if 
-       S >= 0 -> LowerBound = S;
-       S < 0 -> LowerBound = 0
-    end,    
+    if
+        S >= 0 -> LowerBound = S;
+        S < 0 -> LowerBound = 0
+    end,
     LowerBound.
 
 index_bounds(Step1, ListLength, S, E) ->
     AbsListLength = erlang:abs(ListLength),
-    case Step1 < 0 of 
+    case Step1 < 0 of
         true ->
-            ?debugMsg("true"),       
-            if 
+            ?debugMsg("true"),
+            if
                 S > AbsListLength -> UpperBound = ListLength;
                 S =< AbsListLength -> UpperBound = S
             end,
-            if 
-                E >= 0 -> 
+            if
+                E >= 0 ->
                     LowerBound = E;
-                    %List1 = tl(List);
-                E < 0 -> 
+                %%List1 = tl(List);
+                E < 0 ->
                     LowerBound = 0
-                    %List1 = List
+                    %%List1 = List
             end;
         false ->
             ?debugMsg("false"),
-            if 
+            if
                 S >= 0 -> LowerBound = S;
                 S < 0 -> LowerBound = 0
             end,
-            if 
+            if
                 E > AbsListLength -> UpperBound = ListLength;
                 E =< AbsListLength -> UpperBound = E
-            end            
+            end
     end,
     ?debugFmt("index_bounds: LowerBound,UpperBound: ~p,~p~n",[LowerBound,UpperBound]),
     {LowerBound, UpperBound}.
@@ -161,7 +161,7 @@ parse_index(Index) ->
     [Start, D1, End, D2, Step] = ParsedIndex1,
     Start1 = cast_to_integer(Start),
     End1 = cast_to_integer(End),
-    C1 = parse_colon(D1),    
+    C1 = parse_colon(D1),
     C2 = parse_colon(D2),
     Step1 = cast_to_integer(Step),
     ?debugFmt("Parsed: Start1, End1, C1, C2, Step1: ~p, ~p, ~p, ~p, ~p~n",[Start1, End1, C1, C2, Step1]),
@@ -196,12 +196,12 @@ end_transform(ListLength, End) ->
 cast_to_integer([]) ->
     [];
 cast_to_integer(Input) when is_list(Input)->
-        case lists:member($., Input) of
-                true ->
-                        erlang:round(erlang:list_to_float(Input));
-                false ->       
-                        erlang:list_to_integer(Input)
-        end.
+    case lists:member($., Input) of
+        true ->
+            erlang:round(erlang:list_to_float(Input));
+        false ->
+            erlang:list_to_integer(Input)
+    end.
 
 parse_colon([]) ->
     false;

+ 1099 - 1099
tests/src/erlydtl_unittests.erl

@@ -5,281 +5,281 @@
 tests() ->
     [
      {"vars", [
-	       {"string",
-		<<"String value is: {{ var1 }}">>,
-		[{var1, "foo"}], <<"String value is: foo">>},
-	       {"int",
-		<<"The magic number is: {{ var1 }}">>,
-		[{var1, 42}], <<"The magic number is: 42">>},
-	       {"float",
-		<<"The price of milk is: {{ var1 }}">>,
-		[{var1, 0.42}], <<"The price of milk is: 0.42">>},
-	       {"No spaces",
-		<<"{{var1}}">>,
-		[{var1, "foo"}], <<"foo">>},
-	       {"Variable name is a tag name",
-		<<"{{ comment }}">>,
-		[{comment, "Nice work!"}], <<"Nice work!">>}
-	      ]},
+               {"string",
+                <<"String value is: {{ var1 }}">>,
+                [{var1, "foo"}], <<"String value is: foo">>},
+               {"int",
+                <<"The magic number is: {{ var1 }}">>,
+                [{var1, 42}], <<"The magic number is: 42">>},
+               {"float",
+                <<"The price of milk is: {{ var1 }}">>,
+                [{var1, 0.42}], <<"The price of milk is: 0.42">>},
+               {"No spaces",
+                <<"{{var1}}">>,
+                [{var1, "foo"}], <<"foo">>},
+               {"Variable name is a tag name",
+                <<"{{ comment }}">>,
+                [{comment, "Nice work!"}], <<"Nice work!">>}
+              ]},
      {"comment", [
-		  {"comment block is excised",
-		   <<"bob {% comment %}(moron){% endcomment %} loblaw">>,
-		   [], <<"bob  loblaw">>},
-		  {"inline comment is excised",
-		   <<"you're {# not #} a very nice person">>,
-		   [], <<"you're  a very nice person">>}
-		 ]},
+                  {"comment block is excised",
+                   <<"bob {% comment %}(moron){% endcomment %} loblaw">>,
+                   [], <<"bob  loblaw">>},
+                  {"inline comment is excised",
+                   <<"you're {# not #} a very nice person">>,
+                   [], <<"you're  a very nice person">>}
+                 ]},
      {"autoescape", [
-		     {"Autoescape works",
-		      <<"{% autoescape on %}{{ var1 }}{% endautoescape %}">>,
-		      [{var1, "<b>bold</b>"}], <<"&lt;b&gt;bold&lt;/b&gt;">>},
-		     {"Nested autoescape",
-		      <<"{% autoescape on %}{{ var1 }}{% autoescape off %}{{ var1 }}{% endautoescape %}{% endautoescape %}">>,
-		      [{var1, "<b>"}], <<"&lt;b&gt;<b>">>}
-		    ]},
+                     {"Autoescape works",
+                      <<"{% autoescape on %}{{ var1 }}{% endautoescape %}">>,
+                      [{var1, "<b>bold</b>"}], <<"&lt;b&gt;bold&lt;/b&gt;">>},
+                     {"Nested autoescape",
+                      <<"{% autoescape on %}{{ var1 }}{% autoescape off %}{{ var1 }}{% endautoescape %}{% endautoescape %}">>,
+                      [{var1, "<b>"}], <<"&lt;b&gt;<b>">>}
+                    ]},
      {"string literal", [
-			 {"Render literal",
-			  <<"{{ \"foo\" }} is my name">>, [], <<"foo is my name">>},
-			 {"Newlines are escaped",
-			  <<"{{ \"foo\\n\" }}">>, [], <<"foo\n">>}
-			]},
+                         {"Render literal",
+                          <<"{{ \"foo\" }} is my name">>, [], <<"foo is my name">>},
+                         {"Newlines are escaped",
+                          <<"{{ \"foo\\n\" }}">>, [], <<"foo\n">>}
+                        ]},
      {"cycle", [
                 {"Cycling through quoted strings",
-		 <<"{% for i in test %}{% cycle 'a' 'b' %}{{ i }},{% endfor %}">>,
-		 [{test, ["0", "1", "2", "3", "4"]}], <<"a0,b1,a2,b3,a4,">>},
+                 <<"{% for i in test %}{% cycle 'a' 'b' %}{{ i }},{% endfor %}">>,
+                 [{test, ["0", "1", "2", "3", "4"]}], <<"a0,b1,a2,b3,a4,">>},
                 {"Cycling through normal variables",
-		 <<"{% for i in test %}{% cycle aye bee %}{{ i }},{% endfor %}">>,
-		 [{test, ["0", "1", "2", "3", "4"]}, {aye, "a"}, {bee, "b"}],
-		 <<"a0,b1,a2,b3,a4,">>}
-	       ]},
+                 <<"{% for i in test %}{% cycle aye bee %}{{ i }},{% endfor %}">>,
+                 [{test, ["0", "1", "2", "3", "4"]}, {aye, "a"}, {bee, "b"}],
+                 <<"a0,b1,a2,b3,a4,">>}
+               ]},
      {"number literal", [
-			 {"Render integer",
-			  <<"{{ 5 }}">>, [], <<"5">>}
-			]},
+                         {"Render integer",
+                          <<"{{ 5 }}">>, [], <<"5">>}
+                        ]},
      {"variable", [
-		   {"Render variable",
+                   {"Render variable",
                     <<"{{ var1 }} is my game">>, [{var1, "bar"}], <<"bar is my game">>},
-		   {"Render variable with attribute",
+                   {"Render variable with attribute",
                     <<"I enjoy {{ var1.game }}">>, [{var1, [{game, "Othello"}]}], <<"I enjoy Othello">>},
-		   {"Render variable with string-key attribute",
+                   {"Render variable with string-key attribute",
                     <<"I also enjoy {{ var1.game }}">>, [{var1, [{"game", "Parcheesi"}]}], <<"I also enjoy Parcheesi">>},
-		   {"Render variable with binary-key attribute",
+                   {"Render variable with binary-key attribute",
                     <<"I also enjoy {{ var1.game }}">>, [{var1, [{<<"game">>, "Parcheesi"}]}], <<"I also enjoy Parcheesi">>},
-		   {"Render variable in dict",
+                   {"Render variable in dict",
                     <<"{{ var1 }}">>, dict:store(var1, "bar", dict:new()), <<"bar">>},
-           {"Render variable with missing attribute in dict",
+                   {"Render variable with missing attribute in dict",
                     <<"{{ var1.foo }}">>, [{var1, dict:store(bar, "Othello", dict:new())}], <<"">>},
-		   {"Render variable in gb_tree",
+                   {"Render variable in gb_tree",
                     <<"{{ var1 }}">>, gb_trees:insert(var1, "bar", gb_trees:empty()), <<"bar">>},
-		   {"Render variable in arity-1 func",
+                   {"Render variable in arity-1 func",
                     <<"I enjoy {{ var1 }}">>, fun (var1) -> "Othello" end, <<"I enjoy Othello">>},
-		   {"Render variable with attribute in dict",
+                   {"Render variable with attribute in dict",
                     <<"{{ var1.attr }}">>, [{var1, dict:store(attr, "Othello", dict:new())}], <<"Othello">>},
-		   {"Render variable with attribute in gb_tree",
+                   {"Render variable with attribute in gb_tree",
                     <<"{{ var1.attr }}">>, [{var1, gb_trees:insert(attr, "Othello", gb_trees:empty())}], <<"Othello">>},
-		   {"Render variable with attribute in arity-1 func",
+                   {"Render variable with attribute in arity-1 func",
                     <<"I enjoy {{ var1.game }}">>, [{var1, fun (game) -> "Othello" end}], <<"I enjoy Othello">>},
-		   {"Render variable in parameterized module",
+                   {"Render variable in parameterized module",
                     <<"{{ var1.some_var }}">>, [{var1, erlydtl_example_variable_storage:new("foo")}], <<"foo">>},
-		   {"Nested attributes",
+                   {"Nested attributes",
                     <<"{{ person.city.state.country }}">>, [{person, [{city, [{state, [{country, "Italy"}]}]}]}],
                     <<"Italy">>}
-		  ]},
+                  ]},
      {"now", [
-	      {"now functional",
-	       <<"It is the {% now \"jS \\o\\f F Y\" %}.">>, [{var1, ""}], generate_test_date()}
-	     ]},
+              {"now functional",
+               <<"It is the {% now \"jS \\o\\f F Y\" %}.">>, [{var1, ""}], generate_test_date()}
+             ]},
      {"if", [
-	     {"If/else",
-	      <<"{% if var1 %}boo{% else %}yay{% endif %}">>, [{var1, ""}], <<"yay">>},
-	     {"If elif",
-	      <<"{% if var1 %}boo{% elif var2 %}yay{% endif %}">>, [{var1, ""}, {var2, "happy"}], <<"yay">>},
-	     {"If elif/else",
-	      <<"{% if var1 %}boo{% elif var2 %}sad{% else %}yay{% endif %}">>, [{var1, ""}, {var2, ""}], <<"yay">>},
-	     {"If elif/elif/else",
-	      <<"{% if var1 %}boo{% elif var2 %}yay{% elif var3 %}sad{% else %}noo{% endif %}">>, [{var1, ""},
-												   {var2, "happy"}, {var3, "not_taken"}], <<"yay">>},
-	     {"If",
-	      <<"{% if var1 %}boo{% endif %}">>, [{var1, ""}], <<>>},
-	     {"If not",
-	      <<"{% if not var1 %}yay{% endif %}">>, [{var1, ""}], <<"yay">>},
-	     {"If \"0\"",
-	      <<"{% if var1 %}boo{% endif %}">>, [{var1, "0"}], <<>>},
-	     {"If false",
-	      <<"{% if var1 %}boo{% endif %}">>, [{var1, false}], <<>>},
-	     {"If false string",
-	      <<"{% if var1 %}boo{% endif %}">>, [{var1, "false"}], <<"boo">>},
-	     {"If undefined",
-	      <<"{% if var1 %}boo{% endif %}">>, [{var1, undefined}], <<>>},
-	     {"If other atom",
-	      <<"{% if var1 %}yay{% endif %}">>, [{var1, foobar}], <<"yay">>},
-	     {"If non-empty string",
-	      <<"{% if var1 %}yay{% endif %}">>, [{var1, "hello"}], <<"yay">>},
-	     {"If proplist",
-	      <<"{% if var1 %}yay{% endif %}">>, [{var1, [{foo, "bar"}]}], <<"yay">>},
-	     {"If complex",
-	      <<"{% if foo.bar.baz %}omgwtfbbq{% endif %}">>, [], <<"">>}
+             {"If/else",
+              <<"{% if var1 %}boo{% else %}yay{% endif %}">>, [{var1, ""}], <<"yay">>},
+             {"If elif",
+              <<"{% if var1 %}boo{% elif var2 %}yay{% endif %}">>, [{var1, ""}, {var2, "happy"}], <<"yay">>},
+             {"If elif/else",
+              <<"{% if var1 %}boo{% elif var2 %}sad{% else %}yay{% endif %}">>, [{var1, ""}, {var2, ""}], <<"yay">>},
+             {"If elif/elif/else",
+              <<"{% if var1 %}boo{% elif var2 %}yay{% elif var3 %}sad{% else %}noo{% endif %}">>, [{var1, ""},
+                                                                                                   {var2, "happy"}, {var3, "not_taken"}], <<"yay">>},
+             {"If",
+              <<"{% if var1 %}boo{% endif %}">>, [{var1, ""}], <<>>},
+             {"If not",
+              <<"{% if not var1 %}yay{% endif %}">>, [{var1, ""}], <<"yay">>},
+             {"If \"0\"",
+              <<"{% if var1 %}boo{% endif %}">>, [{var1, "0"}], <<>>},
+             {"If false",
+              <<"{% if var1 %}boo{% endif %}">>, [{var1, false}], <<>>},
+             {"If false string",
+              <<"{% if var1 %}boo{% endif %}">>, [{var1, "false"}], <<"boo">>},
+             {"If undefined",
+              <<"{% if var1 %}boo{% endif %}">>, [{var1, undefined}], <<>>},
+             {"If other atom",
+              <<"{% if var1 %}yay{% endif %}">>, [{var1, foobar}], <<"yay">>},
+             {"If non-empty string",
+              <<"{% if var1 %}yay{% endif %}">>, [{var1, "hello"}], <<"yay">>},
+             {"If proplist",
+              <<"{% if var1 %}yay{% endif %}">>, [{var1, [{foo, "bar"}]}], <<"yay">>},
+             {"If complex",
+              <<"{% if foo.bar.baz %}omgwtfbbq{% endif %}">>, [], <<"">>}
             ]},
      {"if .. in ..", [
-		      {"If substring in string",
-		       <<"{% if var1 in var2 %}yay{% endif %}">>, [{var1, "rook"}, {var2, "Crooks"}], <<"yay">>},
-		      {"If substring in string (false)",
-		       <<"{% if var1 in var2 %}boo{% endif %}">>, [{var1, "Cook"}, {var2, "Crooks"}], <<>>},
-		      {"If substring not in string",
-		       <<"{% if var1 not in var2 %}yay{% endif %}">>, [{var1, "Cook"}, {var2, "Crooks"}], <<"yay">>},
-		      {"If substring not in string (false)",
-		       <<"{% if var1 not in var2 %}boo{% endif %}">>, [{var1, "rook"}, {var2, "Crooks"}], <<>>},
-		      {"If literal substring in string",
-		       <<"{% if \"man\" in \"Ottoman\" %}yay{% endif %}">>, [], <<"yay">>},
-		      {"If literal substring in string (false)",
-		       <<"{% if \"woman\" in \"Ottoman\" %}boo{% endif %}">>, [], <<>>},
-		      {"If element in list",
-		       <<"{% if var1 in var2 %}yay{% endif %}">>, [{var1, "foo"}, {var2, ["bar", "foo", "baz"]}], <<"yay">>},
-		      {"If element in list (false)",
-		       <<"{% if var1 in var2 %}boo{% endif %}">>, [{var1, "FOO"}, {var2, ["bar", "foo", "baz"]}], <<>>}
-		     ]},
+                      {"If substring in string",
+                       <<"{% if var1 in var2 %}yay{% endif %}">>, [{var1, "rook"}, {var2, "Crooks"}], <<"yay">>},
+                      {"If substring in string (false)",
+                       <<"{% if var1 in var2 %}boo{% endif %}">>, [{var1, "Cook"}, {var2, "Crooks"}], <<>>},
+                      {"If substring not in string",
+                       <<"{% if var1 not in var2 %}yay{% endif %}">>, [{var1, "Cook"}, {var2, "Crooks"}], <<"yay">>},
+                      {"If substring not in string (false)",
+                       <<"{% if var1 not in var2 %}boo{% endif %}">>, [{var1, "rook"}, {var2, "Crooks"}], <<>>},
+                      {"If literal substring in string",
+                       <<"{% if \"man\" in \"Ottoman\" %}yay{% endif %}">>, [], <<"yay">>},
+                      {"If literal substring in string (false)",
+                       <<"{% if \"woman\" in \"Ottoman\" %}boo{% endif %}">>, [], <<>>},
+                      {"If element in list",
+                       <<"{% if var1 in var2 %}yay{% endif %}">>, [{var1, "foo"}, {var2, ["bar", "foo", "baz"]}], <<"yay">>},
+                      {"If element in list (false)",
+                       <<"{% if var1 in var2 %}boo{% endif %}">>, [{var1, "FOO"}, {var2, ["bar", "foo", "baz"]}], <<>>}
+                     ]},
      {"if .. and ..", [
-		       {"If true and true",
-			<<"{% if var1 and var2 %}yay{% endif %}">>, [{var1, true}, {var2, true}], <<"yay">>},
-		       {"If true and false",
-			<<"{% if var1 and var2 %}yay{% endif %}">>, [{var1, true}, {var2, false}], <<"">>},
-		       {"If false and true",
-			<<"{% if var1 and var2 %}yay{% endif %}">>, [{var1, false}, {var2, true}], <<"">>},
-		       {"If false and false ",
-			<<"{% if var1 and var2 %}yay{% endif %}">>, [{var1, false}, {var2, false}], <<"">>}
-		      ]},
+                       {"If true and true",
+                        <<"{% if var1 and var2 %}yay{% endif %}">>, [{var1, true}, {var2, true}], <<"yay">>},
+                       {"If true and false",
+                        <<"{% if var1 and var2 %}yay{% endif %}">>, [{var1, true}, {var2, false}], <<"">>},
+                       {"If false and true",
+                        <<"{% if var1 and var2 %}yay{% endif %}">>, [{var1, false}, {var2, true}], <<"">>},
+                       {"If false and false ",
+                        <<"{% if var1 and var2 %}yay{% endif %}">>, [{var1, false}, {var2, false}], <<"">>}
+                      ]},
      {"if .. or ..", [
-		      {"If true or true",
-		       <<"{% if var1 or var2 %}yay{% endif %}">>, [{var1, true}, {var2, true}], <<"yay">>},
-		      {"If true or false",
-		       <<"{% if var1 or var2 %}yay{% endif %}">>, [{var1, true}, {var2, false}], <<"yay">>},
-		      {"If false or true",
-		       <<"{% if var1 or var2 %}yay{% endif %}">>, [{var1, false}, {var2, true}], <<"yay">>},
-		      {"If false or false ",
-		       <<"{% if var1 or var2 %}yay{% endif %}">>, [{var1, false}, {var2, false}], <<"">>}
-		     ]},
+                      {"If true or true",
+                       <<"{% if var1 or var2 %}yay{% endif %}">>, [{var1, true}, {var2, true}], <<"yay">>},
+                      {"If true or false",
+                       <<"{% if var1 or var2 %}yay{% endif %}">>, [{var1, true}, {var2, false}], <<"yay">>},
+                      {"If false or true",
+                       <<"{% if var1 or var2 %}yay{% endif %}">>, [{var1, false}, {var2, true}], <<"yay">>},
+                      {"If false or false ",
+                       <<"{% if var1 or var2 %}yay{% endif %}">>, [{var1, false}, {var2, false}], <<"">>}
+                     ]},
      {"if equality", [
-		      {"If int equals number literal",
-		       <<"{% if var1 == 2 %}yay{% endif %}">>, [{var1, 2}], <<"yay">>},
-		      {"If int equals number literal (false)",
-		       <<"{% if var1 == 2 %}yay{% endif %}">>, [{var1, 3}], <<"">>},
-		      {"If string equals string literal",
-		       <<"{% if var1 == \"2\" %}yay{% endif %}">>, [{var1, "2"}], <<"yay">>},
-		      {"If string equals string literal (false)",
-		       <<"{% if var1 == \"2\" %}yay{% endif %}">>, [{var1, "3"}], <<"">>},
-		      {"If int not equals number literal",
-		       <<"{% if var1 != 2 %}yay{% endif %}">>, [{var1, 3}], <<"yay">>},
-		      {"If string not equals string literal",
-		       <<"{% if var1 != \"2\" %}yay{% endif %}">>, [{var1, "3"}], <<"yay">>},
-		      {"If filter result equals number literal",
-		       <<"{% if var1|length == 2 %}yay{% endif %}">>, [{var1, ["fo", "bo"]}], <<"yay">>},
-		      {"If filter result equals string literal",
-		       <<"{% if var1|capfirst == \"Foo\" %}yay{% endif %}">>, [{var1, "foo"}], <<"yay">>}
-		     ]},
+                      {"If int equals number literal",
+                       <<"{% if var1 == 2 %}yay{% endif %}">>, [{var1, 2}], <<"yay">>},
+                      {"If int equals number literal (false)",
+                       <<"{% if var1 == 2 %}yay{% endif %}">>, [{var1, 3}], <<"">>},
+                      {"If string equals string literal",
+                       <<"{% if var1 == \"2\" %}yay{% endif %}">>, [{var1, "2"}], <<"yay">>},
+                      {"If string equals string literal (false)",
+                       <<"{% if var1 == \"2\" %}yay{% endif %}">>, [{var1, "3"}], <<"">>},
+                      {"If int not equals number literal",
+                       <<"{% if var1 != 2 %}yay{% endif %}">>, [{var1, 3}], <<"yay">>},
+                      {"If string not equals string literal",
+                       <<"{% if var1 != \"2\" %}yay{% endif %}">>, [{var1, "3"}], <<"yay">>},
+                      {"If filter result equals number literal",
+                       <<"{% if var1|length == 2 %}yay{% endif %}">>, [{var1, ["fo", "bo"]}], <<"yay">>},
+                      {"If filter result equals string literal",
+                       <<"{% if var1|capfirst == \"Foo\" %}yay{% endif %}">>, [{var1, "foo"}], <<"yay">>}
+                     ]},
      {"if size comparison", [
-			     {"If int greater than number literal",
-			      <<"{% if var1 > 2 %}yay{% endif %}">>, [{var1, 3}], <<"yay">>},
-			     {"If int greater than negative number literal",
-			      <<"{% if var1 > -2 %}yay{% endif %}">>, [{var1, -1}], <<"yay">>},
-			     {"If int greater than number literal (false)",
-			      <<"{% if var1 > 2 %}yay{% endif %}">>, [{var1, 2}], <<"">>},
+                             {"If int greater than number literal",
+                              <<"{% if var1 > 2 %}yay{% endif %}">>, [{var1, 3}], <<"yay">>},
+                             {"If int greater than negative number literal",
+                              <<"{% if var1 > -2 %}yay{% endif %}">>, [{var1, -1}], <<"yay">>},
+                             {"If int greater than number literal (false)",
+                              <<"{% if var1 > 2 %}yay{% endif %}">>, [{var1, 2}], <<"">>},
 
-			     {"If int greater than or equal to number literal",
-			      <<"{% if var1 >= 2 %}yay{% endif %}">>, [{var1, 3}], <<"yay">>},
-			     {"If int greater than or equal to number literal (2)",
-			      <<"{% if var1 >= 2 %}yay{% endif %}">>, [{var1, 2}], <<"yay">>},
-			     {"If int greater than or equal to number literal (false)",
-			      <<"{% if var1 >= 2 %}yay{% endif %}">>, [{var1, 1}], <<"">>},
+                             {"If int greater than or equal to number literal",
+                              <<"{% if var1 >= 2 %}yay{% endif %}">>, [{var1, 3}], <<"yay">>},
+                             {"If int greater than or equal to number literal (2)",
+                              <<"{% if var1 >= 2 %}yay{% endif %}">>, [{var1, 2}], <<"yay">>},
+                             {"If int greater than or equal to number literal (false)",
+                              <<"{% if var1 >= 2 %}yay{% endif %}">>, [{var1, 1}], <<"">>},
 
-			     {"If int less than number literal",
-			      <<"{% if var1 < 2 %}yay{% endif %}">>, [{var1, 1}], <<"yay">>},
-			     {"If int less than number literal (false)",
-			      <<"{% if var1 < 2 %}yay{% endif %}">>, [{var1, 2}], <<"">>},
+                             {"If int less than number literal",
+                              <<"{% if var1 < 2 %}yay{% endif %}">>, [{var1, 1}], <<"yay">>},
+                             {"If int less than number literal (false)",
+                              <<"{% if var1 < 2 %}yay{% endif %}">>, [{var1, 2}], <<"">>},
 
-			     {"If int less than or equal to number literal",
-			      <<"{% if var1 <= 2 %}yay{% endif %}">>, [{var1, 1}], <<"yay">>},
-			     {"If int less than or equal to number literal",
-			      <<"{% if var1 <= 2 %}yay{% endif %}">>, [{var1, 2}], <<"yay">>},
-			     {"If int less than or equal to number literal (false)",
-			      <<"{% if var1 <= 2 %}yay{% endif %}">>, [{var1, 3}], <<"">>}
-			    ]},
+                             {"If int less than or equal to number literal",
+                              <<"{% if var1 <= 2 %}yay{% endif %}">>, [{var1, 1}], <<"yay">>},
+                             {"If int less than or equal to number literal",
+                              <<"{% if var1 <= 2 %}yay{% endif %}">>, [{var1, 2}], <<"yay">>},
+                             {"If int less than or equal to number literal (false)",
+                              <<"{% if var1 <= 2 %}yay{% endif %}">>, [{var1, 3}], <<"">>}
+                            ]},
      {"if complex bool", [
-			  {"If (true or false) and true",
-			   <<"{% if (var1 or var2) and var3 %}yay{% endif %}">>,
-			   [{var1, true}, {var2, false}, {var3, true}], <<"yay">>},
-			  {"If true or (false and true)",
-			   <<"{% if var1 or (var2 and var3) %}yay{% endif %}">>,
-			   [{var1, true}, {var2, false}, {var3, true}], <<"yay">>}
-			 ]},
+                          {"If (true or false) and true",
+                           <<"{% if (var1 or var2) and var3 %}yay{% endif %}">>,
+                           [{var1, true}, {var2, false}, {var3, true}], <<"yay">>},
+                          {"If true or (false and true)",
+                           <<"{% if var1 or (var2 and var3) %}yay{% endif %}">>,
+                           [{var1, true}, {var2, false}, {var3, true}], <<"yay">>}
+                         ]},
      {"for", [
-	      {"Simple loop",
-	       <<"{% for x in list %}{{ x }}{% endfor %}">>, [{'list', ["1", "2", "3"]}],
-	       <<"123">>},
-	      {"Reversed loop",
-	       <<"{% for x in list reversed %}{{ x }}{% endfor %}">>, [{'list', ["1", "2", "3"]}],
-	       <<"321">>},
-	      {"Expand list",
-	       <<"{% for x, y in list %}{{ x }},{{ y }}\n{% endfor %}">>, [{'list', [["X", "1"], ["X", "2"]]}],
-	       <<"X,1\nX,2\n">>},
-	      {"Expand tuple",
-	       <<"{% for x, y in list %}{{ x }},{{ y }}\n{% endfor %}">>, [{'list', [{"X", "1"}, {"X", "2"}]}],
-	       <<"X,1\nX,2\n">>},
-	      {"Resolve variable attribute",
-	       <<"{% for number in person.numbers %}{{ number }}\n{% endfor %}">>, [{person, [{numbers, ["411", "911"]}]}],
-	       <<"411\n911\n">>},
-	      {"Resolve nested variable attribute",
-	       <<"{% for number in person.home.numbers %}{{ number }}\n{% endfor %}">>, [{person, [{home, [{numbers, ["411", "911"]}]}]}],
-	       <<"411\n911\n">>},
-	      {"Counter0",
-	       <<"{% for number in numbers %}{{ forloop.counter0 }}. {{ number }}\n{% endfor %}">>,
-	       [{numbers, ["Zero", "One", "Two"]}], <<"0. Zero\n1. One\n2. Two\n">>},
-	      {"Counter",
-	       <<"{% for number in numbers %}{{ forloop.counter }}. {{ number }}\n{% endfor %}">>,
-	       [{numbers, ["One", "Two", "Three"]}], <<"1. One\n2. Two\n3. Three\n">>},
-	      {"Reverse Counter0",
-	       <<"{% for number in numbers %}{{ forloop.revcounter0 }}. {{ number }}\n{% endfor %}">>,
-	       [{numbers, ["Two", "One", "Zero"]}], <<"2. Two\n1. One\n0. Zero\n">>},
-	      {"Reverse Counter",
-	       <<"{% for number in numbers %}{{ forloop.revcounter }}. {{ number }}\n{% endfor %}">>,
-	       [{numbers, ["Three", "Two", "One"]}], <<"3. Three\n2. Two\n1. One\n">>},
-	      {"Counter \"first\"",
-	       <<"{% for number in numbers %}{% if forloop.first %}{{ number }}{% endif %}{% endfor %}">>,
-	       [{numbers, ["One", "Two", "Three"]}], <<"One">>},
-	      {"Counter \"last\"",
-	       <<"{% for number in numbers %}{% if forloop.last %}{{ number }}{% endif %}{% endfor %}">>,
-	       [{numbers, ["One", "Two", "Three"]}], <<"Three">>},
-	      {"Nested for loop",
-	       <<"{% for outer in list %}{% for inner in outer %}{{ inner }}\n{% endfor %}{% endfor %}">>,
-	       [{'list', [["Al", "Albert"], ["Jo", "Joseph"]]}],
-	       <<"Al\nAlbert\nJo\nJoseph\n">>},
-	      {"Access parent loop counters",
-	       <<"{% for outer in list %}{% for inner in outer %}({{ forloop.parentloop.counter0 }}, {{ forloop.counter0 }})\n{% endfor %}{% endfor %}">>,
-	       [{'list', [["One", "two"], ["One", "two"]]}], <<"(0, 0)\n(0, 1)\n(1, 0)\n(1, 1)\n">>},
-	      {"If changed",
-	       <<"{% for x in list %}{% ifchanged %}{{ x }}\n{% endifchanged %}{% endfor %}">>,
-	       [{'list', ["one", "two", "two", "three", "three", "three"]}], <<"one\ntwo\nthree\n">>},
-	      {"If changed/2",
-	       <<"{% for x, y in list %}{% ifchanged %}{{ x|upper }}{% endifchanged %}{% ifchanged %}{{ y|lower }}{% endifchanged %}\n{% endfor %}">>,
-	       [{'list', [["one", "a"], ["two", "A"], ["two", "B"], ["three", "b"], ["three", "c"], ["Three", "b"]]}], <<"ONEa\nTWO\nb\nTHREE\nc\nb\n">>},
-	      {"If changed/else",
-	       <<"{% for x in list %}{% ifchanged %}{{ x }}\n{% else %}foo\n{% endifchanged %}{% endfor %}">>,
-	       [{'list', ["one", "two", "two", "three", "three", "three"]}], <<"one\ntwo\nfoo\nthree\nfoo\nfoo\n">>},
-	      {"If changed/param",
-	       <<"{% for date in list %}{% ifchanged date.month %} {{ date.month }}:{{ date.day }}{% else %},{{ date.day }}{% endifchanged %}{% endfor %}\n">>,
-	       [{'list', [[{month,"Jan"},{day,1}],[{month,"Jan"},{day,2}],[{month,"Apr"},{day,10}],
-			  [{month,"Apr"},{day,11}],[{month,"May"},{day,4}]]}], 
-	       <<" Jan:1,2 Apr:10,11 May:4\n">>},
-	      {"If changed/param2",
-	       <<"{% for x, y in list %}{% ifchanged y|upper %}{{ x|upper }}{% endifchanged %}\n{% endfor %}">>,
-	       [{'list', [["one", "a"], ["two", "A"], ["two", "B"], ["three", "b"], ["three", "c"], ["Three", "b"]]}], <<"ONE\n\nTWO\n\nTHREE\nTHREE\n">>},
-	      {"If changed/param2 combined",
-	       <<"{% for x, y in list %}{% ifchanged x y|upper %}{{ x }}{% endifchanged %}\n{% endfor %}">>,
-	       [{'list', [["one", "a"], ["two", "A"], ["two", "B"], ["three", "b"], ["three", "B"], ["three", "c"]]}], <<"one\ntwo\ntwo\nthree\n\nthree\n">>},
-	      {"If changed/resolve",
-	       <<"{% for x in list %}{% ifchanged x.name|first %}{{ x.value }}{% endifchanged %}\n{% endfor %}">>,
-	       [{'list', [[{"name", ["nA","nB"]},{"value","1"}],[{"name", ["nA","nC"]},{"value","2"}],
-			  [{"name", ["nB","nC"]},{"value","3"}],[{"name", ["nB","nA"]},{"value","4"}]]}],
-	       <<"1\n\n3\n\n">>},
+              {"Simple loop",
+               <<"{% for x in list %}{{ x }}{% endfor %}">>, [{'list', ["1", "2", "3"]}],
+               <<"123">>},
+              {"Reversed loop",
+               <<"{% for x in list reversed %}{{ x }}{% endfor %}">>, [{'list', ["1", "2", "3"]}],
+               <<"321">>},
+              {"Expand list",
+               <<"{% for x, y in list %}{{ x }},{{ y }}\n{% endfor %}">>, [{'list', [["X", "1"], ["X", "2"]]}],
+               <<"X,1\nX,2\n">>},
+              {"Expand tuple",
+               <<"{% for x, y in list %}{{ x }},{{ y }}\n{% endfor %}">>, [{'list', [{"X", "1"}, {"X", "2"}]}],
+               <<"X,1\nX,2\n">>},
+              {"Resolve variable attribute",
+               <<"{% for number in person.numbers %}{{ number }}\n{% endfor %}">>, [{person, [{numbers, ["411", "911"]}]}],
+               <<"411\n911\n">>},
+              {"Resolve nested variable attribute",
+               <<"{% for number in person.home.numbers %}{{ number }}\n{% endfor %}">>, [{person, [{home, [{numbers, ["411", "911"]}]}]}],
+               <<"411\n911\n">>},
+              {"Counter0",
+               <<"{% for number in numbers %}{{ forloop.counter0 }}. {{ number }}\n{% endfor %}">>,
+               [{numbers, ["Zero", "One", "Two"]}], <<"0. Zero\n1. One\n2. Two\n">>},
+              {"Counter",
+               <<"{% for number in numbers %}{{ forloop.counter }}. {{ number }}\n{% endfor %}">>,
+               [{numbers, ["One", "Two", "Three"]}], <<"1. One\n2. Two\n3. Three\n">>},
+              {"Reverse Counter0",
+               <<"{% for number in numbers %}{{ forloop.revcounter0 }}. {{ number }}\n{% endfor %}">>,
+               [{numbers, ["Two", "One", "Zero"]}], <<"2. Two\n1. One\n0. Zero\n">>},
+              {"Reverse Counter",
+               <<"{% for number in numbers %}{{ forloop.revcounter }}. {{ number }}\n{% endfor %}">>,
+               [{numbers, ["Three", "Two", "One"]}], <<"3. Three\n2. Two\n1. One\n">>},
+              {"Counter \"first\"",
+               <<"{% for number in numbers %}{% if forloop.first %}{{ number }}{% endif %}{% endfor %}">>,
+               [{numbers, ["One", "Two", "Three"]}], <<"One">>},
+              {"Counter \"last\"",
+               <<"{% for number in numbers %}{% if forloop.last %}{{ number }}{% endif %}{% endfor %}">>,
+               [{numbers, ["One", "Two", "Three"]}], <<"Three">>},
+              {"Nested for loop",
+               <<"{% for outer in list %}{% for inner in outer %}{{ inner }}\n{% endfor %}{% endfor %}">>,
+               [{'list', [["Al", "Albert"], ["Jo", "Joseph"]]}],
+               <<"Al\nAlbert\nJo\nJoseph\n">>},
+              {"Access parent loop counters",
+               <<"{% for outer in list %}{% for inner in outer %}({{ forloop.parentloop.counter0 }}, {{ forloop.counter0 }})\n{% endfor %}{% endfor %}">>,
+               [{'list', [["One", "two"], ["One", "two"]]}], <<"(0, 0)\n(0, 1)\n(1, 0)\n(1, 1)\n">>},
+              {"If changed",
+               <<"{% for x in list %}{% ifchanged %}{{ x }}\n{% endifchanged %}{% endfor %}">>,
+               [{'list', ["one", "two", "two", "three", "three", "three"]}], <<"one\ntwo\nthree\n">>},
+              {"If changed/2",
+               <<"{% for x, y in list %}{% ifchanged %}{{ x|upper }}{% endifchanged %}{% ifchanged %}{{ y|lower }}{% endifchanged %}\n{% endfor %}">>,
+               [{'list', [["one", "a"], ["two", "A"], ["two", "B"], ["three", "b"], ["three", "c"], ["Three", "b"]]}], <<"ONEa\nTWO\nb\nTHREE\nc\nb\n">>},
+              {"If changed/else",
+               <<"{% for x in list %}{% ifchanged %}{{ x }}\n{% else %}foo\n{% endifchanged %}{% endfor %}">>,
+               [{'list', ["one", "two", "two", "three", "three", "three"]}], <<"one\ntwo\nfoo\nthree\nfoo\nfoo\n">>},
+              {"If changed/param",
+               <<"{% for date in list %}{% ifchanged date.month %} {{ date.month }}:{{ date.day }}{% else %},{{ date.day }}{% endifchanged %}{% endfor %}\n">>,
+               [{'list', [[{month,"Jan"},{day,1}],[{month,"Jan"},{day,2}],[{month,"Apr"},{day,10}],
+                          [{month,"Apr"},{day,11}],[{month,"May"},{day,4}]]}],
+               <<" Jan:1,2 Apr:10,11 May:4\n">>},
+              {"If changed/param2",
+               <<"{% for x, y in list %}{% ifchanged y|upper %}{{ x|upper }}{% endifchanged %}\n{% endfor %}">>,
+               [{'list', [["one", "a"], ["two", "A"], ["two", "B"], ["three", "b"], ["three", "c"], ["Three", "b"]]}], <<"ONE\n\nTWO\n\nTHREE\nTHREE\n">>},
+              {"If changed/param2 combined",
+               <<"{% for x, y in list %}{% ifchanged x y|upper %}{{ x }}{% endifchanged %}\n{% endfor %}">>,
+               [{'list', [["one", "a"], ["two", "A"], ["two", "B"], ["three", "b"], ["three", "B"], ["three", "c"]]}], <<"one\ntwo\ntwo\nthree\n\nthree\n">>},
+              {"If changed/resolve",
+               <<"{% for x in list %}{% ifchanged x.name|first %}{{ x.value }}{% endifchanged %}\n{% endfor %}">>,
+               [{'list', [[{"name", ["nA","nB"]},{"value","1"}],[{"name", ["nA","nC"]},{"value","2"}],
+                          [{"name", ["nB","nC"]},{"value","3"}],[{"name", ["nB","nA"]},{"value","4"}]]}],
+               <<"1\n\n3\n\n">>},
 
               {"Loop undefined var",
                <<"{% for i in undef %}i = {{ i }}.\n{% endfor %}">>,
@@ -289,909 +289,909 @@ tests() ->
                <<"{% for x in 123|make_list %}{% if not forloop.first %}, {% endif %}{{ x }}{% endfor %}">>,
                [],
                <<"1, 2, 3">>}
-	     ]},
+             ]},
      {"for/empty", [
-		    {"Simple loop",
-		     <<"{% for x in list %}{{ x }}{% empty %}shucks{% endfor %}">>, [{'list', ["1", "2", "3"]}],
-		     <<"123">>},
-		    {"Simple loop (empty)",
-		     <<"{% for x in list %}{{ x }}{% empty %}shucks{% endfor %}">>, [{'list', []}],
-		     <<"shucks">>}
-		   ]},
+                    {"Simple loop",
+                     <<"{% for x in list %}{{ x }}{% empty %}shucks{% endfor %}">>, [{'list', ["1", "2", "3"]}],
+                     <<"123">>},
+                    {"Simple loop (empty)",
+                     <<"{% for x in list %}{{ x }}{% empty %}shucks{% endfor %}">>, [{'list', []}],
+                     <<"shucks">>}
+                   ]},
      {"ifequal", [
-		  {"Compare variable to literal",
-		   <<"{% ifequal var1 \"foo\" %}yay{% endifequal %}">>,
-		   [{var1, "foo"}], <<"yay">>},
-		  {"Compare variable to unequal literal",
-		   <<"{% ifequal var1 \"foo\" %}boo{% endifequal %}">>,
-		   [{var1, "bar"}], <<>>},
-		  {"Compare literal to variable",
-		   <<"{% ifequal \"foo\" var1 %}yay{% endifequal %}">>,
-		   [{var1, "foo"}], <<"yay">>},
-		  {"Compare literal to unequal variable",
-		   <<"{% ifequal \"foo\" var1 %}boo{% endifequal %}">>,
-		   [{var1, "bar"}], <<>>},
-		  {"Compare variable to literal (int string)",
-		   <<"{% ifequal var1 \"2\" %}yay{% else %}boo{% endifequal %}">>,
-		   [{var1, "2"}], <<"yay">>},
-		  {"Compare variable to literal (int)",
-		   <<"{% ifequal var1 2 %}yay{% else %}boo{% endifequal %}">>,
-		   [{var1, 2}], <<"yay">>},
-		  {"Compare variable to unequal literal (int)",
-		   <<"{% ifequal var1 2 %}boo{% else %}yay{% endifequal %}">>,
-		   [{var1, 3}], <<"yay">>},
-		  {"Compare variable to equal literal (atom)",
-		   <<"{% ifequal var1 \"foo\"%}yay{% endifequal %}">>,
-		   [{var1, foo}], <<"yay">>},
-		  {"Compare variable to unequal literal (atom)",
-		   <<"{% ifequal var1 \"foo\"%}yay{% else %}boo{% endifequal %}">>,
-		   [{var1, bar}], <<"boo">>}
-		 ]},
+                  {"Compare variable to literal",
+                   <<"{% ifequal var1 \"foo\" %}yay{% endifequal %}">>,
+                   [{var1, "foo"}], <<"yay">>},
+                  {"Compare variable to unequal literal",
+                   <<"{% ifequal var1 \"foo\" %}boo{% endifequal %}">>,
+                   [{var1, "bar"}], <<>>},
+                  {"Compare literal to variable",
+                   <<"{% ifequal \"foo\" var1 %}yay{% endifequal %}">>,
+                   [{var1, "foo"}], <<"yay">>},
+                  {"Compare literal to unequal variable",
+                   <<"{% ifequal \"foo\" var1 %}boo{% endifequal %}">>,
+                   [{var1, "bar"}], <<>>},
+                  {"Compare variable to literal (int string)",
+                   <<"{% ifequal var1 \"2\" %}yay{% else %}boo{% endifequal %}">>,
+                   [{var1, "2"}], <<"yay">>},
+                  {"Compare variable to literal (int)",
+                   <<"{% ifequal var1 2 %}yay{% else %}boo{% endifequal %}">>,
+                   [{var1, 2}], <<"yay">>},
+                  {"Compare variable to unequal literal (int)",
+                   <<"{% ifequal var1 2 %}boo{% else %}yay{% endifequal %}">>,
+                   [{var1, 3}], <<"yay">>},
+                  {"Compare variable to equal literal (atom)",
+                   <<"{% ifequal var1 \"foo\"%}yay{% endifequal %}">>,
+                   [{var1, foo}], <<"yay">>},
+                  {"Compare variable to unequal literal (atom)",
+                   <<"{% ifequal var1 \"foo\"%}yay{% else %}boo{% endifequal %}">>,
+                   [{var1, bar}], <<"boo">>}
+                 ]},
      {"ifequal/else", [
-		       {"Compare variable to literal",
-			<<"{% ifequal var1 \"foo\" %}yay{% else %}boo{% endifequal %}">>,
-			[{var1, "foo"}], <<"yay">>},
-		       {"Compare variable to unequal literal",
-			<<"{% ifequal var1 \"foo\" %}boo{% else %}yay{% endifequal %}">>,
-			[{var1, "bar"}], <<"yay">>},
-		       {"Compare literal to variable",
-			<<"{% ifequal \"foo\" var1 %}yay{% else %}boo{% endifequal %}">>,
-			[{var1, "foo"}], <<"yay">>},
-		       {"Compare literal to unequal variable",
-			<<"{% ifequal \"foo\" var1 %}boo{% else %}yay{% endifequal %}">>,
-			[{var1, "bar"}], <<"yay">>}
-		      ]},
+                       {"Compare variable to literal",
+                        <<"{% ifequal var1 \"foo\" %}yay{% else %}boo{% endifequal %}">>,
+                        [{var1, "foo"}], <<"yay">>},
+                       {"Compare variable to unequal literal",
+                        <<"{% ifequal var1 \"foo\" %}boo{% else %}yay{% endifequal %}">>,
+                        [{var1, "bar"}], <<"yay">>},
+                       {"Compare literal to variable",
+                        <<"{% ifequal \"foo\" var1 %}yay{% else %}boo{% endifequal %}">>,
+                        [{var1, "foo"}], <<"yay">>},
+                       {"Compare literal to unequal variable",
+                        <<"{% ifequal \"foo\" var1 %}boo{% else %}yay{% endifequal %}">>,
+                        [{var1, "bar"}], <<"yay">>}
+                      ]},
      {"ifnotequal", [
-		     {"Compare variable to literal",
-		      <<"{% ifnotequal var1 \"foo\" %}boo{% endifnotequal %}">>,
-		      [{var1, "foo"}], <<>>},
-		     {"Compare variable to unequal literal",
-		      <<"{% ifnotequal var1 \"foo\" %}yay{% endifnotequal %}">>,
-		      [{var1, "bar"}], <<"yay">>},
-		     {"Compare literal to variable",
-		      <<"{% ifnotequal \"foo\" var1 %}boo{% endifnotequal %}">>,
-		      [{var1, "foo"}], <<>>},
-		     {"Compare literal to unequal variable",
-		      <<"{% ifnotequal \"foo\" var1 %}yay{% endifnotequal %}">>,
-		      [{var1, "bar"}], <<"yay">>}
-		    ]},
+                     {"Compare variable to literal",
+                      <<"{% ifnotequal var1 \"foo\" %}boo{% endifnotequal %}">>,
+                      [{var1, "foo"}], <<>>},
+                     {"Compare variable to unequal literal",
+                      <<"{% ifnotequal var1 \"foo\" %}yay{% endifnotequal %}">>,
+                      [{var1, "bar"}], <<"yay">>},
+                     {"Compare literal to variable",
+                      <<"{% ifnotequal \"foo\" var1 %}boo{% endifnotequal %}">>,
+                      [{var1, "foo"}], <<>>},
+                     {"Compare literal to unequal variable",
+                      <<"{% ifnotequal \"foo\" var1 %}yay{% endifnotequal %}">>,
+                      [{var1, "bar"}], <<"yay">>}
+                    ]},
      {"ifnotequal/else", [
-			  {"Compare variable to literal",
-			   <<"{% ifnotequal var1 \"foo\" %}boo{% else %}yay{% endifnotequal %}">>,
-			   [{var1, "foo"}], <<"yay">>},
-			  {"Compare variable to unequal literal",
-			   <<"{% ifnotequal var1 \"foo\" %}yay{% else %}boo{% endifnotequal %}">>,
-			   [{var1, "bar"}], <<"yay">>},
-			  {"Compare literal to variable",
-			   <<"{% ifnotequal \"foo\" var1 %}boo{% else %}yay{% endifnotequal %}">>,
-			   [{var1, "foo"}], <<"yay">>},
-			  {"Compare literal to unequal variable",
-			   <<"{% ifnotequal \"foo\" var1 %}yay{% else %}boo{% endifnotequal %}">>,
-			   [{var1, "bar"}], <<"yay">>}
-			 ]},
+                          {"Compare variable to literal",
+                           <<"{% ifnotequal var1 \"foo\" %}boo{% else %}yay{% endifnotequal %}">>,
+                           [{var1, "foo"}], <<"yay">>},
+                          {"Compare variable to unequal literal",
+                           <<"{% ifnotequal var1 \"foo\" %}yay{% else %}boo{% endifnotequal %}">>,
+                           [{var1, "bar"}], <<"yay">>},
+                          {"Compare literal to variable",
+                           <<"{% ifnotequal \"foo\" var1 %}boo{% else %}yay{% endifnotequal %}">>,
+                           [{var1, "foo"}], <<"yay">>},
+                          {"Compare literal to unequal variable",
+                           <<"{% ifnotequal \"foo\" var1 %}yay{% else %}boo{% endifnotequal %}">>,
+                           [{var1, "bar"}], <<"yay">>}
+                         ]},
      {"filter tag", [
-		     {"Apply a filter",
-		      <<"{% filter escape %}&{% endfilter %}">>, [], <<"&amp;">>},
-		     {"Chained filters",
-		      <<"{% filter linebreaksbr|escape %}\n{% endfilter %}">>, [], <<"&lt;br /&gt;">>}
-		    ]},
+                     {"Apply a filter",
+                      <<"{% filter escape %}&{% endfilter %}">>, [], <<"&amp;">>},
+                     {"Chained filters",
+                      <<"{% filter linebreaksbr|escape %}\n{% endfilter %}">>, [], <<"&lt;br /&gt;">>}
+                    ]},
      {"filters", [
-		  {"Filter a literal",
-		   <<"{{ \"pop\"|capfirst }}">>, [],
-		   <<"Pop">>},
-		  {"Filters applied in order",
-		   <<"{{ var1|force_escape|length }}">>, [{var1, <<"&">>}],
-		   <<"5">>},
-		  {"Escape is applied last",
-		   <<"{{ var1|escape|linebreaksbr }}">>, [{var1, <<"\n">>}],
-		   <<"&lt;br /&gt;">>},
-		  {"add; lhs number, rhs number",
-		   <<"{{ one|add:4}}">>, [{one, 1}],
-		   <<"5">>},
-		  {"add; lhs numeric string, rhs number",
-		   <<"{{ one|add:4}}">>, [{one, "1"}],
-		   <<"5">>},
-		  {"add; lhs number, rhs numeric string",
-		   <<"{{ one|add:'4'}}">>, [{one, 1}],
-		   <<"5">>},
-		  {"add; lhs non-numeric string, rhs number",
-		   <<"{{ one|add:4}}">>, [{one, "foo"}],
-		   <<"foo4">>},
-		  {"add; lhs number, rhs non-numeric string",
-		   <<"{{ one|add:'foo'}}">>, [{one, 1}],
-		   <<"1foo">>},
-		  {"add; lhs non-numeric string, rhs non-numeric string",
-		   <<"{{ one|add:'bar'}}">>, [{one, "foo"}],
-		   <<"foobar">>},
-		  {"add; lhs numeric string, rhs numeric string",
-		   <<"{{ one|add:'4'}}">>, [{one, "1"}],
-		   <<"5">>},
-		  {"|addslashes",
-		   <<"{{ var1|addslashes }}">>, [{var1, "Jimmy's \"great\" meats'n'things"}],
-		   <<"Jimmy\\'s \\\"great\\\" meats\\'n\\'things">>},
-		  {"|capfirst",
-		   <<"{{ var1|capfirst }}">>, [{var1, "dana boyd"}],
-		   <<"Dana boyd">>},
-		  {"|center:10",
-		   <<"{{ var1|center:10 }}">>, [{var1, "MB"}],
-		   <<"    MB    ">>},
-		  {"|center:1",
-		   <<"{{ var1|center:1 }}">>, [{var1, "KBR"}],
-		   <<"B">>},
-		  {"|cut:\" \"",
-		   <<"{{ var1|cut:\" \" }}">>, [{var1, "String with spaces"}],
-		   <<"Stringwithspaces">>},
-		  {"|date 1",
+                  {"Filter a literal",
+                   <<"{{ \"pop\"|capfirst }}">>, [],
+                   <<"Pop">>},
+                  {"Filters applied in order",
+                   <<"{{ var1|force_escape|length }}">>, [{var1, <<"&">>}],
+                   <<"5">>},
+                  {"Escape is applied last",
+                   <<"{{ var1|escape|linebreaksbr }}">>, [{var1, <<"\n">>}],
+                   <<"&lt;br /&gt;">>},
+                  {"add; lhs number, rhs number",
+                   <<"{{ one|add:4}}">>, [{one, 1}],
+                   <<"5">>},
+                  {"add; lhs numeric string, rhs number",
+                   <<"{{ one|add:4}}">>, [{one, "1"}],
+                   <<"5">>},
+                  {"add; lhs number, rhs numeric string",
+                   <<"{{ one|add:'4'}}">>, [{one, 1}],
+                   <<"5">>},
+                  {"add; lhs non-numeric string, rhs number",
+                   <<"{{ one|add:4}}">>, [{one, "foo"}],
+                   <<"foo4">>},
+                  {"add; lhs number, rhs non-numeric string",
+                   <<"{{ one|add:'foo'}}">>, [{one, 1}],
+                   <<"1foo">>},
+                  {"add; lhs non-numeric string, rhs non-numeric string",
+                   <<"{{ one|add:'bar'}}">>, [{one, "foo"}],
+                   <<"foobar">>},
+                  {"add; lhs numeric string, rhs numeric string",
+                   <<"{{ one|add:'4'}}">>, [{one, "1"}],
+                   <<"5">>},
+                  {"|addslashes",
+                   <<"{{ var1|addslashes }}">>, [{var1, "Jimmy's \"great\" meats'n'things"}],
+                   <<"Jimmy\\'s \\\"great\\\" meats\\'n\\'things">>},
+                  {"|capfirst",
+                   <<"{{ var1|capfirst }}">>, [{var1, "dana boyd"}],
+                   <<"Dana boyd">>},
+                  {"|center:10",
+                   <<"{{ var1|center:10 }}">>, [{var1, "MB"}],
+                   <<"    MB    ">>},
+                  {"|center:1",
+                   <<"{{ var1|center:1 }}">>, [{var1, "KBR"}],
+                   <<"B">>},
+                  {"|cut:\" \"",
+                   <<"{{ var1|cut:\" \" }}">>, [{var1, "String with spaces"}],
+                   <<"Stringwithspaces">>},
+                  {"|date 1",
                    <<"{{ var1|date:\"jS F Y H:i\" }}">>,
                    [{var1, {1975,7,24}}],
                    <<"24th July 1975 00:00">>},
-		  {"|date 2",
+                  {"|date 2",
                    <<"{{ var1|date:\"jS F Y H:i\" }}">>,
                    [{var1, {{1975,7,24}, {7,13,1}}}],
                    <<"24th July 1975 07:13">>},
-		  {"|date 3",
+                  {"|date 3",
                    <<"{{ var1|date }}">>,
                    [{var1, {{1975,7,24}, {7,13,1}}}],
                    <<"July 24, 1975">>},
-		  {"|default:\"foo\" 1",
+                  {"|default:\"foo\" 1",
                    <<"{{ var1|default:\"foo\" }}">>, [], <<"foo">>},
-		  {"|default:\"foo\" 2",
-		   <<"{{ var1|default:\"foo\" }}">>, [{var1, "bar"}], <<"bar">>},
-		  {"|default:\"foo\" 3",
-		   <<"{{ var1|default:\"foo\" }}">>, [{var1, "0"}], <<"foo">>},
-		  {"|default_if_none:\"foo\"",
+                  {"|default:\"foo\" 2",
+                   <<"{{ var1|default:\"foo\" }}">>, [{var1, "bar"}], <<"bar">>},
+                  {"|default:\"foo\" 3",
+                   <<"{{ var1|default:\"foo\" }}">>, [{var1, "0"}], <<"foo">>},
+                  {"|default_if_none:\"foo\"",
                    <<"{{ var1|default_if_none:\"foo\" }}">>, [], <<"foo">>},
-		  {"|default_if_none:\"foo\" 2",
-		   <<"{{ var1|default_if_none:\"foo\" }}">>, [{var1, "bar"}], <<"bar">>},
-		  {"|dictsort 1",
-		   <<"{{ var1|dictsort:\"foo\" }}">>,
-		   [{var1,[[{foo,2}],[{foo,1}]]}], <<"{foo,1}{foo,2}">>},
-		  {"|dictsort 2",
-		   <<"{{ var1|dictsort:\"foo.bar\" }}">>,
-		   [{var1,[[{foo,[{bar,2}]}],[{foo,[{bar,1}]}]]}],
-		   <<"{foo,[{bar,1}]}{foo,[{bar,2}]}">>},
-		  {"|divisibleby:\"3\"",
-		   <<"{% if var1|divisibleby:\"3\" %}yay{% endif %}">>, [{var1, 21}], <<"yay">>},
-		  {"|divisibleby:\"3\"",
-		   <<"{% if var1|divisibleby:\"3\" %}yay{% endif %}">>, [{var1, 22}], <<"">>},
-		  {"|escape",
-		   <<"{% autoescape on %}{{ var1|escape|escape|escape }}{% endautoescape %}">>, [{var1, ">&1"}], <<"&gt;&amp;1">>},
-		  {"|escapejs",
-		   <<"{{ var1|escapejs }}">>, [{var1, "testing\r\njavascript 'string\" <b>escaping</b>"}],
-		   <<"testing\\u000D\\u000Ajavascript \\u0027string\\u0022 \\u003Cb\\u003Eescaping\\u003C/b\\u003E">>},
-		  {"|filesizeformat (bytes)",
-		   <<"{{ var1|filesizeformat }}">>, [{var1, 1023}], <<"1023 bytes">>},
-		  {"|filesizeformat (KB)",
-		   <<"{{ var1|filesizeformat }}">>, [{var1, 3487}], <<"3.4 KB">>},
-		  {"|filesizeformat (MB)",
-		   <<"{{ var1|filesizeformat }}">>, [{var1, 6277098}], <<"6.0 MB">>},
-		  {"|filesizeformat (GB)",
-		   <<"{{ var1|filesizeformat }}">>, [{var1, 1024 * 1024 * 1024}], <<"1.0 GB">>},
-		  {"|first",
-		   <<"{{ var1|first }}">>, [{var1, "James"}],
-		   <<"J">>},
-		  {"|fix_ampersands",
-		   <<"{{ var1|fix_ampersands }}">>, [{var1, "Ben & Jerry's"}],
-		   <<"Ben &amp; Jerry's">>},
+                  {"|default_if_none:\"foo\" 2",
+                   <<"{{ var1|default_if_none:\"foo\" }}">>, [{var1, "bar"}], <<"bar">>},
+                  {"|dictsort 1",
+                   <<"{{ var1|dictsort:\"foo\" }}">>,
+                   [{var1,[[{foo,2}],[{foo,1}]]}], <<"{foo,1}{foo,2}">>},
+                  {"|dictsort 2",
+                   <<"{{ var1|dictsort:\"foo.bar\" }}">>,
+                   [{var1,[[{foo,[{bar,2}]}],[{foo,[{bar,1}]}]]}],
+                   <<"{foo,[{bar,1}]}{foo,[{bar,2}]}">>},
+                  {"|divisibleby:\"3\"",
+                   <<"{% if var1|divisibleby:\"3\" %}yay{% endif %}">>, [{var1, 21}], <<"yay">>},
+                  {"|divisibleby:\"3\"",
+                   <<"{% if var1|divisibleby:\"3\" %}yay{% endif %}">>, [{var1, 22}], <<"">>},
+                  {"|escape",
+                   <<"{% autoescape on %}{{ var1|escape|escape|escape }}{% endautoescape %}">>, [{var1, ">&1"}], <<"&gt;&amp;1">>},
+                  {"|escapejs",
+                   <<"{{ var1|escapejs }}">>, [{var1, "testing\r\njavascript 'string\" <b>escaping</b>"}],
+                   <<"testing\\u000D\\u000Ajavascript \\u0027string\\u0022 \\u003Cb\\u003Eescaping\\u003C/b\\u003E">>},
+                  {"|filesizeformat (bytes)",
+                   <<"{{ var1|filesizeformat }}">>, [{var1, 1023}], <<"1023 bytes">>},
+                  {"|filesizeformat (KB)",
+                   <<"{{ var1|filesizeformat }}">>, [{var1, 3487}], <<"3.4 KB">>},
+                  {"|filesizeformat (MB)",
+                   <<"{{ var1|filesizeformat }}">>, [{var1, 6277098}], <<"6.0 MB">>},
+                  {"|filesizeformat (GB)",
+                   <<"{{ var1|filesizeformat }}">>, [{var1, 1024 * 1024 * 1024}], <<"1.0 GB">>},
+                  {"|first",
+                   <<"{{ var1|first }}">>, [{var1, "James"}],
+                   <<"J">>},
+                  {"|fix_ampersands",
+                   <<"{{ var1|fix_ampersands }}">>, [{var1, "Ben & Jerry's"}],
+                   <<"Ben &amp; Jerry's">>},
 
-		  {"|floatformat:\"-1\"",
-		   <<"{{ var1|floatformat:\"-1\" }}">>, [{var1, 34.23234}],
-		   <<"34.2">>},
-          {"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">>},
+                  {"|floatformat:\"-1\"",
+                   <<"{{ var1|floatformat:\"-1\" }}">>, [{var1, 34.23234}],
+                   <<"34.2">>},
+                  {"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">>},
+                  %% 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;">>},
-		  {"iolist |force_escape",
-		   <<"{{ var1|force_escape }}">>, [{var1, ["'a'"]}],
-		   <<"&#039;a&#039;">>},
-		  {"nested iolist |force_escape",
-		   <<"{{ var1|force_escape }}">>, [{var1, ["a'", <<"b">>, [<<"<c">>, "d", ["e>"]]]}],
-		   <<"a&#039;b&lt;cde&gt;">>},
-		  {"|format_integer",
-		   <<"{{ var1|format_integer }}">>, [{var1, 28}], <<"28">>},
-		  {"|format_number 1",
-		   <<"{{ var1|format_number }}">>, [{var1, 28}], <<"28">>},
-		  {"|format_number 2",
-		   <<"{{ var1|format_number }}">>, [{var1, 23.77}], <<"23.77">>},
-		  {"|format_number 3",
-		   <<"{{ var1|format_number }}">>, [{var1, "28.77"}], <<"28.77">>},
-		  {"|format_number 4",
-		   <<"{{ var1|format_number }}">>, [{var1, "23.77"}], <<"23.77">>},
-		  {"|format_number 5",
-		   <<"{{ var1|format_number }}">>, [{var1, fun() -> 29 end}], <<"29">>},
-		  {"|format_number 6",
-		   <<"{{ var1|format_number }}">>, [{var1, fun() -> fun() -> 31 end end}], <<"31">>},
-		  {"|get_digit:\"2\"",
-		   <<"{{ var1|get_digit:\"2\" }}">>, [{var1, 42}], <<"4">>},
-		  {"|iriencode",
-		   <<"{{ url|iriencode }}">>, [{url, "You #$*@!!"}], <<"You+#$*@!!">>},
-		  {"|join:\", \" (list)",
-		   <<"{{ var1|join:\", \" }}">>, [{var1, ["Liberte", "Egalite", "Fraternite"]}],
-		   <<"Liberte, Egalite, Fraternite">>},
-		  {"|join:\", \" (binary)",
-		   <<"{{ var1|join:\", \" }}">>, [{var1, [<<"Liberte">>, "Egalite", <<"Fraternite">>]}],
-		   <<"Liberte, Egalite, Fraternite">>},
-		  {"|last",
-		   <<"{{ var1|last }}">>, [{var1, "XYZ"}],
-		   <<"Z">>},
-		  {"|length",
-		   <<"{{ var1|length }}">>, [{var1, "antidisestablishmentarianism"}],
-		   <<"28">>},
-		  {"|linebreaks",
-		   <<"{{ var1|linebreaks }}">>, [{var1, "Joel\nis a slug"}],
-		   <<"<p>Joel<br />is a slug</p>">>},               
-		  {"|linebreaks",
-		   <<"{{ var1|linebreaks }}">>, [{var1, "Joel\n\n\n\nis a slug"}],
-		   <<"<p>Joel</p><p>is a slug</p>">>},               
-		  {"|linebreaks",
-		   <<"{{ var1|linebreaks }}">>, [{var1, "Joel\n\nis a \nslug"}],
-		   <<"<p>Joel</p><p>is a <br />slug</p>">>},               
-		  {"|linebreaksbr",
-		   <<"{{ var1|linebreaksbr }}">>, [{var1, "One\nTwo\n\nThree\n\n\n"}],
-		   <<"One<br />Two<br /><br />Three<br /><br /><br />">>},
-		  {"|linebreaksbr",
-		   <<"{{ \"One\\nTwo\\n\\nThree\\n\\n\\n\"|linebreaksbr }}">>, [],
-		   <<"One<br />Two<br /><br />Three<br /><br /><br />">>},             
-		  {"|linenumbers",
-		   <<"{{ var1|linenumbers }}">>, [{var1, "a\nb\nc"}],
-		   <<"1. a\n2. b\n3. c">>},
-		  {"|linenumbers",
-		   <<"{{ var1|linenumbers }}">>, [{var1, "a"}],
-		   <<"1. a">>},
-		  {"|linenumbers",
-		   <<"{{ var1|linenumbers }}">>, [{var1, "a\n"}],
-		   <<"1. a\n2. ">>},
-		  {"|ljust:10",
-		   <<"{{ var1|ljust:10 }}">>, [{var1, "Gore"}],
-		   <<"Gore      ">>},
-		  {"|lower",
-		   <<"{{ var1|lower }}">>, [{var1, "E. E. Cummings"}],
-		   <<"e. e. cummings">>},
-		  {"|makelist",
-		   <<"{{ list|make_list }}">>, [{list, "Joel"}],
-		   <<"J","o","e","l">>},
-		  {"|pluralize",
-		   <<"{{ num|pluralize }}">>, [{num, 1}],
-		   <<"">>},
-		  {"|pluralize",
-		   <<"{{ num|pluralize }}">>, [{num, 2}],
-		   <<"s">>},
-		  {"|pluralize:\"s\"",
-		   <<"{{ num|pluralize }}">>, [{num, 1}],
-		   <<"">>},
-		  {"|pluralize:\"s\"",
-		   <<"{{ num|pluralize }}">>, [{num, 2}],
-		   <<"s">>},
-		  {"|pluralize:\"y,es\" (list)",
-		   <<"{{ num|pluralize:\"y,es\" }}">>, [{num, 1}],
-		   <<"y">>},
-		  {"|pluralize:\"y,es\" (list)",
-		   <<"{{ num|pluralize:\"y,es\" }}">>, [{num, 2}],
-		   <<"es">>},
-		  {"|random",
-		   <<"{{ var1|random }}">>, [{var1, ["foo", "foo", "foo"]}],
-		   <<"foo">>},
-		  {"|removetags:\"b span\"",
-		   <<"{{ var1|removetags:\"b span\" }}">>, [{var1, "<B>Joel</B> <button>is</button> a <span>slug</span>"}],
-		   <<"<B>Joel</B> <button>is</button> a slug">>},
-		  {"|rjust:10",
-		   <<"{{ var1|rjust:10 }}">>, [{var1, "Bush"}],
-		   <<"      Bush">>},
-		  {"|safe",
-		   <<"{% autoescape on %}{{ var1|safe|escape }}{% endautoescape %}">>, [{var1, "&"}],
-		   <<"&">>},
-		  %%python/django slice is zero based, erlang lists are 1 based
-		  %%first number included, second number not
-		  %%negative numbers are allowed
-		  %%regex to convert from erlydtl_filters_tests:
-						% for slice: \?assert.*\( \[(.*)\], erlydtl_filters:(.*)\((.*),"(.*)"\)\),
-						% {"|slice:\"$4\"", <<"{{ var|$2:\"$4\" }}">>, [{var, $3}],<<$1>>},
-						% \t\t{"|slice:\"$4\"",\n\t\t\t\t\t <<"{{ var|$2:\"$4\" }}">>, [{var, $3}],\n\t\t\t\t\t<<$1>>},
-						%
-						% for stringformat: 
-						% \?assert.*\( (.*), erlydtl_filters:(.*)\((.*), "(.*)"\) \)
-						% \t\t{"|stringformat:\"$4\"",\n\t\t\t\t\t <<"{{ var|$2:\"$4\" }}">>, [{var, $3}],\n\t\t\t\t\t<<$1>>}
+                  {"|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;">>},
+                  {"iolist |force_escape",
+                   <<"{{ var1|force_escape }}">>, [{var1, ["'a'"]}],
+                   <<"&#039;a&#039;">>},
+                  {"nested iolist |force_escape",
+                   <<"{{ var1|force_escape }}">>, [{var1, ["a'", <<"b">>, [<<"<c">>, "d", ["e>"]]]}],
+                   <<"a&#039;b&lt;cde&gt;">>},
+                  {"|format_integer",
+                   <<"{{ var1|format_integer }}">>, [{var1, 28}], <<"28">>},
+                  {"|format_number 1",
+                   <<"{{ var1|format_number }}">>, [{var1, 28}], <<"28">>},
+                  {"|format_number 2",
+                   <<"{{ var1|format_number }}">>, [{var1, 23.77}], <<"23.77">>},
+                  {"|format_number 3",
+                   <<"{{ var1|format_number }}">>, [{var1, "28.77"}], <<"28.77">>},
+                  {"|format_number 4",
+                   <<"{{ var1|format_number }}">>, [{var1, "23.77"}], <<"23.77">>},
+                  {"|format_number 5",
+                   <<"{{ var1|format_number }}">>, [{var1, fun() -> 29 end}], <<"29">>},
+                  {"|format_number 6",
+                   <<"{{ var1|format_number }}">>, [{var1, fun() -> fun() -> 31 end end}], <<"31">>},
+                  {"|get_digit:\"2\"",
+                   <<"{{ var1|get_digit:\"2\" }}">>, [{var1, 42}], <<"4">>},
+                  {"|iriencode",
+                   <<"{{ url|iriencode }}">>, [{url, "You #$*@!!"}], <<"You+#$*@!!">>},
+                  {"|join:\", \" (list)",
+                   <<"{{ var1|join:\", \" }}">>, [{var1, ["Liberte", "Egalite", "Fraternite"]}],
+                   <<"Liberte, Egalite, Fraternite">>},
+                  {"|join:\", \" (binary)",
+                   <<"{{ var1|join:\", \" }}">>, [{var1, [<<"Liberte">>, "Egalite", <<"Fraternite">>]}],
+                   <<"Liberte, Egalite, Fraternite">>},
+                  {"|last",
+                   <<"{{ var1|last }}">>, [{var1, "XYZ"}],
+                   <<"Z">>},
+                  {"|length",
+                   <<"{{ var1|length }}">>, [{var1, "antidisestablishmentarianism"}],
+                   <<"28">>},
+                  {"|linebreaks",
+                   <<"{{ var1|linebreaks }}">>, [{var1, "Joel\nis a slug"}],
+                   <<"<p>Joel<br />is a slug</p>">>},
+                  {"|linebreaks",
+                   <<"{{ var1|linebreaks }}">>, [{var1, "Joel\n\n\n\nis a slug"}],
+                   <<"<p>Joel</p><p>is a slug</p>">>},
+                  {"|linebreaks",
+                   <<"{{ var1|linebreaks }}">>, [{var1, "Joel\n\nis a \nslug"}],
+                   <<"<p>Joel</p><p>is a <br />slug</p>">>},
+                  {"|linebreaksbr",
+                   <<"{{ var1|linebreaksbr }}">>, [{var1, "One\nTwo\n\nThree\n\n\n"}],
+                   <<"One<br />Two<br /><br />Three<br /><br /><br />">>},
+                  {"|linebreaksbr",
+                   <<"{{ \"One\\nTwo\\n\\nThree\\n\\n\\n\"|linebreaksbr }}">>, [],
+                   <<"One<br />Two<br /><br />Three<br /><br /><br />">>},
+                  {"|linenumbers",
+                   <<"{{ var1|linenumbers }}">>, [{var1, "a\nb\nc"}],
+                   <<"1. a\n2. b\n3. c">>},
+                  {"|linenumbers",
+                   <<"{{ var1|linenumbers }}">>, [{var1, "a"}],
+                   <<"1. a">>},
+                  {"|linenumbers",
+                   <<"{{ var1|linenumbers }}">>, [{var1, "a\n"}],
+                   <<"1. a\n2. ">>},
+                  {"|ljust:10",
+                   <<"{{ var1|ljust:10 }}">>, [{var1, "Gore"}],
+                   <<"Gore      ">>},
+                  {"|lower",
+                   <<"{{ var1|lower }}">>, [{var1, "E. E. Cummings"}],
+                   <<"e. e. cummings">>},
+                  {"|makelist",
+                   <<"{{ list|make_list }}">>, [{list, "Joel"}],
+                   <<"J","o","e","l">>},
+                  {"|pluralize",
+                   <<"{{ num|pluralize }}">>, [{num, 1}],
+                   <<"">>},
+                  {"|pluralize",
+                   <<"{{ num|pluralize }}">>, [{num, 2}],
+                   <<"s">>},
+                  {"|pluralize:\"s\"",
+                   <<"{{ num|pluralize }}">>, [{num, 1}],
+                   <<"">>},
+                  {"|pluralize:\"s\"",
+                   <<"{{ num|pluralize }}">>, [{num, 2}],
+                   <<"s">>},
+                  {"|pluralize:\"y,es\" (list)",
+                   <<"{{ num|pluralize:\"y,es\" }}">>, [{num, 1}],
+                   <<"y">>},
+                  {"|pluralize:\"y,es\" (list)",
+                   <<"{{ num|pluralize:\"y,es\" }}">>, [{num, 2}],
+                   <<"es">>},
+                  {"|random",
+                   <<"{{ var1|random }}">>, [{var1, ["foo", "foo", "foo"]}],
+                   <<"foo">>},
+                  {"|removetags:\"b span\"",
+                   <<"{{ var1|removetags:\"b span\" }}">>, [{var1, "<B>Joel</B> <button>is</button> a <span>slug</span>"}],
+                   <<"<B>Joel</B> <button>is</button> a slug">>},
+                  {"|rjust:10",
+                   <<"{{ var1|rjust:10 }}">>, [{var1, "Bush"}],
+                   <<"      Bush">>},
+                  {"|safe",
+                   <<"{% autoescape on %}{{ var1|safe|escape }}{% endautoescape %}">>, [{var1, "&"}],
+                   <<"&">>},
+                  %%python/django slice is zero based, erlang lists are 1 based
+                  %%first number included, second number not
+                  %%negative numbers are allowed
+                  %%regex to convert from erlydtl_filters_tests:
+                                                % for slice: \?assert.*\( \[(.*)\], erlydtl_filters:(.*)\((.*),"(.*)"\)\),
+                                                % {"|slice:\"$4\"", <<"{{ var|$2:\"$4\" }}">>, [{var, $3}],<<$1>>},
+                                                % \t\t{"|slice:\"$4\"",\n\t\t\t\t\t <<"{{ var|$2:\"$4\" }}">>, [{var, $3}],\n\t\t\t\t\t<<$1>>},
+                                                %
+                                                % for stringformat:
+                                                % \?assert.*\( (.*), erlydtl_filters:(.*)\((.*), "(.*)"\) \)
+                                                % \t\t{"|stringformat:\"$4\"",\n\t\t\t\t\t <<"{{ var|$2:\"$4\" }}">>, [{var, $3}],\n\t\t\t\t\t<<$1>>}
 
-		  {"|slice:\":\"",
-		   <<"{{ var|slice:\":\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<1,2,3,4,5,6,7,8,9>>},
-		  {"|slice:\"1\"", 
-		   <<"{{ var|slice:\"1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<"2">>},
-		  {"|slice:\"100\"", 
-		   <<"{{ var|slice:\"100\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<"indexError">>},
-		  {"|slice:\"-1\"", 
-		   <<"{{ var|slice:\"-1\" }}">>, [{var, ["a","b","c","d","e","f","g","h","i"]}],
-		   <<"i">>},
-		  {"|slice:\"-1\"", 
-		   <<"{{ var|slice:\"-1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<"9">>},
-		  {"|slice:\"-100\"", 
-		   <<"{{ var|slice:\"-100\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<"indexError">>},
-		  {"|slice:\"1:\"",
-		   <<"{{ var|slice:\"1:\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<2,3,4,5,6,7,8,9>>},
-		  {"|slice:\"100:\"",
-		   <<"{{ var|slice:\"100:\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<>>},
-		  {"|slice:\"-1:\"",
-		   <<"{{ var|slice:\"-1:\" }}">>, [{var, ["a","b","c","d","e","f","h","i","j"]}],
-		   <<"j">>},
-		  {"|slice:\"-1:\"",
-		   <<"{{ var|slice:\"-1:\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<9>>},
-		  {"|slice:\"-100:\"",
-		   <<"{{ var|slice:\"-100:\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<1,2,3,4,5,6,7,8,9>>},
+                  {"|slice:\":\"",
+                   <<"{{ var|slice:\":\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<1,2,3,4,5,6,7,8,9>>},
+                  {"|slice:\"1\"",
+                   <<"{{ var|slice:\"1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<"2">>},
+                  {"|slice:\"100\"",
+                   <<"{{ var|slice:\"100\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<"indexError">>},
+                  {"|slice:\"-1\"",
+                   <<"{{ var|slice:\"-1\" }}">>, [{var, ["a","b","c","d","e","f","g","h","i"]}],
+                   <<"i">>},
+                  {"|slice:\"-1\"",
+                   <<"{{ var|slice:\"-1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<"9">>},
+                  {"|slice:\"-100\"",
+                   <<"{{ var|slice:\"-100\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<"indexError">>},
+                  {"|slice:\"1:\"",
+                   <<"{{ var|slice:\"1:\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<2,3,4,5,6,7,8,9>>},
+                  {"|slice:\"100:\"",
+                   <<"{{ var|slice:\"100:\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<>>},
+                  {"|slice:\"-1:\"",
+                   <<"{{ var|slice:\"-1:\" }}">>, [{var, ["a","b","c","d","e","f","h","i","j"]}],
+                   <<"j">>},
+                  {"|slice:\"-1:\"",
+                   <<"{{ var|slice:\"-1:\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<9>>},
+                  {"|slice:\"-100:\"",
+                   <<"{{ var|slice:\"-100:\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<1,2,3,4,5,6,7,8,9>>},
 
-		  {"|slice:\":1\"",
-		   <<"{{ var|slice:\":1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<1>>},
-		  {"|slice:\":100\"",
-		   <<"{{ var|slice:\":100\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<1,2,3,4,5,6,7,8,9>>},
-		  {"|slice:\":-1\"",
-		   <<"{{ var|slice:\":-1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<1,2,3,4,5,6,7,8>>},
-		  {"|slice:\":-100\"",
-		   <<"{{ var|slice:\":-100\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<>>},
+                  {"|slice:\":1\"",
+                   <<"{{ var|slice:\":1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<1>>},
+                  {"|slice:\":100\"",
+                   <<"{{ var|slice:\":100\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<1,2,3,4,5,6,7,8,9>>},
+                  {"|slice:\":-1\"",
+                   <<"{{ var|slice:\":-1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<1,2,3,4,5,6,7,8>>},
+                  {"|slice:\":-100\"",
+                   <<"{{ var|slice:\":-100\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<>>},
 
-		  {"|slice:\"-1:-1\"",
-		   <<"{{ var|slice:\"-1:-1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<>>},
-		  {"|slice:\"1:1\"",
-		   <<"{{ var|slice:\"1:1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<>>},
-		  {"|slice:\"1:-1\"",
-		   <<"{{ var|slice:\"1:-1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<2,3,4,5,6,7,8>>},
-		  {"|slice:\"-1:1\"",
-		   <<"{{ var|slice:\"-1:1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<>>},
+                  {"|slice:\"-1:-1\"",
+                   <<"{{ var|slice:\"-1:-1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<>>},
+                  {"|slice:\"1:1\"",
+                   <<"{{ var|slice:\"1:1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<>>},
+                  {"|slice:\"1:-1\"",
+                   <<"{{ var|slice:\"1:-1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<2,3,4,5,6,7,8>>},
+                  {"|slice:\"-1:1\"",
+                   <<"{{ var|slice:\"-1:1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<>>},
 
-		  {"|slice:\"-100:-100\"",
-		   <<"{{ var|slice:\"-100:-100\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<>>},
-		  {"|slice:\"100:100\"",
-		   <<"{{ var|slice:\"100:100\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<>>},
-		  {"|slice:\"100:-100\"",
-		   <<"{{ var|slice:\"100:-100\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<>>},
-		  {"|slice:\"-100:100\"",
-		   <<"{{ var|slice:\"-100:100\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<1,2,3,4,5,6,7,8,9>>},
+                  {"|slice:\"-100:-100\"",
+                   <<"{{ var|slice:\"-100:-100\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<>>},
+                  {"|slice:\"100:100\"",
+                   <<"{{ var|slice:\"100:100\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<>>},
+                  {"|slice:\"100:-100\"",
+                   <<"{{ var|slice:\"100:-100\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<>>},
+                  {"|slice:\"-100:100\"",
+                   <<"{{ var|slice:\"-100:100\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<1,2,3,4,5,6,7,8,9>>},
 
 
-		  {"|slice:\"1:3\"",
-		   <<"{{ var|slice:\"1:3\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<2,3>>},
+                  {"|slice:\"1:3\"",
+                   <<"{{ var|slice:\"1:3\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<2,3>>},
 
-		  {"|slice:\"::\"",
-		   <<"{{ var|slice:\"::\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<1,2,3,4,5,6,7,8,9>>},
-		  {"|slice:\"1:9:1\"",
-		   <<"{{ var|slice:\"1:9:1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<2,3,4,5,6,7,8,9>>},
-		  {"|slice:\"10:1:-1\"",
-		   <<"{{ var|slice:\"10:1:-1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<9,8,7,6,5,4,3>>},
-		  {"|slice:\"-111:-1:1\"",
-		   <<"{{ var|slice:\"-111:-1:1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<1,2,3,4,5,6,7,8>>},
+                  {"|slice:\"::\"",
+                   <<"{{ var|slice:\"::\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<1,2,3,4,5,6,7,8,9>>},
+                  {"|slice:\"1:9:1\"",
+                   <<"{{ var|slice:\"1:9:1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<2,3,4,5,6,7,8,9>>},
+                  {"|slice:\"10:1:-1\"",
+                   <<"{{ var|slice:\"10:1:-1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<9,8,7,6,5,4,3>>},
+                  {"|slice:\"-111:-1:1\"",
+                   <<"{{ var|slice:\"-111:-1:1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<1,2,3,4,5,6,7,8>>},
 
-		  {"|slice:\"-111:-111:1\"",
-		   <<"{{ var|slice:\"-111:-111:1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<>>},
-		  {"|slice:\"111:111:1\"",
-		   <<"{{ var|slice:\"111:111:1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<>>},
-		  {"|slice:\"-111:111:1\"",
-		   <<"{{ var|slice:\"-111:111:1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<1,2,3,4,5,6,7,8,9>>},
-		  {"|slice:\"111:-111:1\"",
-		   <<"{{ var|slice:\"111:-111:1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<>>},
+                  {"|slice:\"-111:-111:1\"",
+                   <<"{{ var|slice:\"-111:-111:1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<>>},
+                  {"|slice:\"111:111:1\"",
+                   <<"{{ var|slice:\"111:111:1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<>>},
+                  {"|slice:\"-111:111:1\"",
+                   <<"{{ var|slice:\"-111:111:1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<1,2,3,4,5,6,7,8,9>>},
+                  {"|slice:\"111:-111:1\"",
+                   <<"{{ var|slice:\"111:-111:1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<>>},
 
-		  {"|slice:\"-111:-111:-1\"",
-		   <<"{{ var|slice:\"-111:-111:-1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<>>},
-		  {"|slice:\"111:111:-1\"",
-		   <<"{{ var|slice:\"111:111:-1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<>>},
-		  {"|slice:\"-111:111:-1\"",
-		   <<"{{ var|slice:\"-111:111:-1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<>>},
-		  {"|slice:\"111:-111:-1\"",
-		   <<"{{ var|slice:\"111:-111:-1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
-		   <<9,8,7,6,5,4,3,2,1>>},              {"|phone2numeric",
-							 <<"{{ var1|phone2numeric }}">>, [{var1, "1-800-COLLECT"}],
-							 <<"1-800-2655328">>},
-		  {"|slugify",
-		   <<"{{ var1|slugify }}">>, [{var1, "What The $#_! Was He Thinking?"}],
-		   <<"what-the-_-was-he-thinking">>},
-		  {"|slice:\"s\"",
-		   <<"{{ var|stringformat:\"s\" }}">>, [{var, "test"}],
-		   <<"test">>},
-		  {"|stringformat:\"s\"",
-		   <<"{{ var|stringformat:\"s\" }}">>, [{var, "test"}],
-		   <<"test">>},
-		  {"|stringformat:\"s\"",
-		   <<"{{ var|stringformat:\"s\" }}">>, [{var, "1"}],
-		   <<"1">>},
-		  {"|stringformat:\"s\"",
-		   <<"{{ var|stringformat:\"s\" }}">>, [{var, "test"}],
-		   <<"test">>},
-		  {"|stringformat:\"10s\"",
-		   <<"{{ var|stringformat:\"10s\" }}">>, [{var, "test"}],
-		   <<"      test">>},
-		  {"|stringformat:\"-10s\"",
-		   <<"{{ var|stringformat:\"-10s\" }}">>, [{var, "test"}],
-		   <<"test      ">>},
+                  {"|slice:\"-111:-111:-1\"",
+                   <<"{{ var|slice:\"-111:-111:-1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<>>},
+                  {"|slice:\"111:111:-1\"",
+                   <<"{{ var|slice:\"111:111:-1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<>>},
+                  {"|slice:\"-111:111:-1\"",
+                   <<"{{ var|slice:\"-111:111:-1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<>>},
+                  {"|slice:\"111:-111:-1\"",
+                   <<"{{ var|slice:\"111:-111:-1\" }}">>, [{var, [1,2,3,4,5,6,7,8,9]}],
+                   <<9,8,7,6,5,4,3,2,1>>},              {"|phone2numeric",
+                                                         <<"{{ var1|phone2numeric }}">>, [{var1, "1-800-COLLECT"}],
+                                                         <<"1-800-2655328">>},
+                  {"|slugify",
+                   <<"{{ var1|slugify }}">>, [{var1, "What The $#_! Was He Thinking?"}],
+                   <<"what-the-_-was-he-thinking">>},
+                  {"|slice:\"s\"",
+                   <<"{{ var|stringformat:\"s\" }}">>, [{var, "test"}],
+                   <<"test">>},
+                  {"|stringformat:\"s\"",
+                   <<"{{ var|stringformat:\"s\" }}">>, [{var, "test"}],
+                   <<"test">>},
+                  {"|stringformat:\"s\"",
+                   <<"{{ var|stringformat:\"s\" }}">>, [{var, "1"}],
+                   <<"1">>},
+                  {"|stringformat:\"s\"",
+                   <<"{{ var|stringformat:\"s\" }}">>, [{var, "test"}],
+                   <<"test">>},
+                  {"|stringformat:\"10s\"",
+                   <<"{{ var|stringformat:\"10s\" }}">>, [{var, "test"}],
+                   <<"      test">>},
+                  {"|stringformat:\"-10s\"",
+                   <<"{{ var|stringformat:\"-10s\" }}">>, [{var, "test"}],
+                   <<"test      ">>},
 
-		  {"|stringformat:\"d\"",
-		   <<"{{ var|stringformat:\"d\" }}">>, [{var, "90"}],
-		   <<"90">>},  
-		  {"|stringformat:\"10d\"",
-		   <<"{{ var|stringformat:\"10d\" }}">>, [{var, "90"}],
-		   <<"        90">>},
-		  {"|stringformat:\"-10d\"",
-		   <<"{{ var|stringformat:\"-10d\" }}">>, [{var, "90"}],
-		   <<"90        ">>},
-		  {"|stringformat:\"i\"",
-		   <<"{{ var|stringformat:\"i\" }}">>, [{var, "90"}],
-		   <<"90">>},  
-		  {"|stringformat:\"10i\"",
-		   <<"{{ var|stringformat:\"10i\" }}">>, [{var, "90"}],
-		   <<"        90">>},
-		  {"|stringformat:\"-10i\"",
-		   <<"{{ var|stringformat:\"-10i\" }}">>, [{var, "90"}],
-		   <<"90        ">>},
-		  {"|stringformat:\"0.2d\"",
-		   <<"{{ var|stringformat:\"0.2d\" }}">>, [{var, "9"}],
-		   <<"09">>},    
-		  {"|stringformat:\"10.4d\"",
-		   <<"{{ var|stringformat:\"10.4d\" }}">>, [{var, "9"}],
-		   <<"      0009">>},
-		  {"|stringformat:\"-10.4d\"",
-		   <<"{{ var|stringformat:\"-10.4d\" }}">>, [{var, "9"}],
-		   <<"0009      ">>},
+                  {"|stringformat:\"d\"",
+                   <<"{{ var|stringformat:\"d\" }}">>, [{var, "90"}],
+                   <<"90">>},
+                  {"|stringformat:\"10d\"",
+                   <<"{{ var|stringformat:\"10d\" }}">>, [{var, "90"}],
+                   <<"        90">>},
+                  {"|stringformat:\"-10d\"",
+                   <<"{{ var|stringformat:\"-10d\" }}">>, [{var, "90"}],
+                   <<"90        ">>},
+                  {"|stringformat:\"i\"",
+                   <<"{{ var|stringformat:\"i\" }}">>, [{var, "90"}],
+                   <<"90">>},
+                  {"|stringformat:\"10i\"",
+                   <<"{{ var|stringformat:\"10i\" }}">>, [{var, "90"}],
+                   <<"        90">>},
+                  {"|stringformat:\"-10i\"",
+                   <<"{{ var|stringformat:\"-10i\" }}">>, [{var, "90"}],
+                   <<"90        ">>},
+                  {"|stringformat:\"0.2d\"",
+                   <<"{{ var|stringformat:\"0.2d\" }}">>, [{var, "9"}],
+                   <<"09">>},
+                  {"|stringformat:\"10.4d\"",
+                   <<"{{ var|stringformat:\"10.4d\" }}">>, [{var, "9"}],
+                   <<"      0009">>},
+                  {"|stringformat:\"-10.4d\"",
+                   <<"{{ var|stringformat:\"-10.4d\" }}">>, [{var, "9"}],
+                   <<"0009      ">>},
 
-		  {"|stringformat:\"f\"",
-		   <<"{{ var|stringformat:\"f\" }}">>, [{var, "1"}],
-		   <<"1.000000">>},                    
-		  {"|stringformat:\".2f\"",
-		   <<"{{ var|stringformat:\".2f\" }}">>, [{var, "1"}],
-		   <<"1.00">>},
-		  {"|stringformat:\"0.2f\"",
-		   <<"{{ var|stringformat:\"0.2f\" }}">>, [{var, "1"}],
-		   <<"1.00">>},
-		  {"|stringformat:\"-0.2f\"",
-		   <<"{{ var|stringformat:\"-0.2f\" }}">>, [{var, "1"}],
-		   <<"1.00">>},
-		  {"|stringformat:\"10.2f\"",
-		   <<"{{ var|stringformat:\"10.2f\" }}">>, [{var, "1"}],
-		   <<"      1.00">>},
-		  {"|stringformat:\"-10.2f\"",
-		   <<"{{ var|stringformat:\"-10.2f\" }}">>, [{var, "1"}],
-		   <<"1.00      ">>},                                                                                  
-		  {"|stringformat:\".2f\"",
-		   <<"{{ var|stringformat:\".2f\" }}">>, [{var, "1"}],
-		   <<"1.00">>},                          
-		  {"|stringformat:\"x\"",
-		   <<"{{ var|stringformat:\"x\" }}">>, [{var, "90"}],
-		   <<"5a">>},
-		  {"|stringformat:\"X\"",
-		   <<"{{ var|stringformat:\"X\" }}">>, [{var, "90"}],
-		   <<"5A">>},
+                  {"|stringformat:\"f\"",
+                   <<"{{ var|stringformat:\"f\" }}">>, [{var, "1"}],
+                   <<"1.000000">>},
+                  {"|stringformat:\".2f\"",
+                   <<"{{ var|stringformat:\".2f\" }}">>, [{var, "1"}],
+                   <<"1.00">>},
+                  {"|stringformat:\"0.2f\"",
+                   <<"{{ var|stringformat:\"0.2f\" }}">>, [{var, "1"}],
+                   <<"1.00">>},
+                  {"|stringformat:\"-0.2f\"",
+                   <<"{{ var|stringformat:\"-0.2f\" }}">>, [{var, "1"}],
+                   <<"1.00">>},
+                  {"|stringformat:\"10.2f\"",
+                   <<"{{ var|stringformat:\"10.2f\" }}">>, [{var, "1"}],
+                   <<"      1.00">>},
+                  {"|stringformat:\"-10.2f\"",
+                   <<"{{ var|stringformat:\"-10.2f\" }}">>, [{var, "1"}],
+                   <<"1.00      ">>},
+                  {"|stringformat:\".2f\"",
+                   <<"{{ var|stringformat:\".2f\" }}">>, [{var, "1"}],
+                   <<"1.00">>},
+                  {"|stringformat:\"x\"",
+                   <<"{{ var|stringformat:\"x\" }}">>, [{var, "90"}],
+                   <<"5a">>},
+                  {"|stringformat:\"X\"",
+                   <<"{{ var|stringformat:\"X\" }}">>, [{var, "90"}],
+                   <<"5A">>},
 
-		  {"|stringformat:\"o\"",
-		   <<"{{ var|stringformat:\"o\" }}">>, [{var, "90"}],
-		   <<"132">>}, 
+                  {"|stringformat:\"o\"",
+                   <<"{{ var|stringformat:\"o\" }}">>, [{var, "90"}],
+                   <<"132">>},
 
-		  {"|stringformat:\"e\"",
-		   <<"{{ var|stringformat:\"e\" }}">>, [{var, "90"}],
-		   <<"9.000000e+01">>}, 
-		  {"|stringformat:\"e\"",
-		   <<"{{ var|stringformat:\"e\" }}">>, [{var, "90000000000"}],
-		   <<"9.000000e+10">>},
-		  {"|stringformat:\"E\"",
-		   <<"{{ var|stringformat:\"E\" }}">>, [{var, "90"}],
-		   <<"9.000000E+01">>},
-		  {"|striptags",
-		   <<"{{ var|striptags }}">>, [{var, "<b>Joel</b> <button>is</button> a <span>slug</span>"}],
-		   <<"Joel is a slug">>},
-		  {"|striptags",
-		   <<"{{ var|striptags }}">>, [{var, "<B>Joel</B> <button>is</button> a <span>slug</Span>"}],
-		   <<"Joel is a slug">>},
-		  {"|striptags",
-		   <<"{{ var|striptags }}">>, [{var, "Check out <a href=\"http://www.djangoproject.com\" rel=\"nofollow\">http://www.djangoproject.com</a>"}],
-		   <<"Check out http://www.djangoproject.com">>},
-		  {"|time:\"H:i\"",
-		   <<"{{ var|time:\"H:i\" }}">>, [{var, {{2010,12,1}, {10,11,12}} }],
-		   <<"10:11">>},
-		  {"|time",
-		   <<"{{ var|time }}">>, [{var, {{2010,12,1}, {10,11,12}} }],
-		   <<"10:11 a.m.">>},
-		  {"|timesince:from_date",
-		   <<"{{ from_date|timesince:conference_date }}">>, [{conference_date, {{2006,6,1},{8,0,0}} }, {from_date, {{2006,6,1},{0,0,0}} }],
+                  {"|stringformat:\"e\"",
+                   <<"{{ var|stringformat:\"e\" }}">>, [{var, "90"}],
+                   <<"9.000000e+01">>},
+                  {"|stringformat:\"e\"",
+                   <<"{{ var|stringformat:\"e\" }}">>, [{var, "90000000000"}],
+                   <<"9.000000e+10">>},
+                  {"|stringformat:\"E\"",
+                   <<"{{ var|stringformat:\"E\" }}">>, [{var, "90"}],
+                   <<"9.000000E+01">>},
+                  {"|striptags",
+                   <<"{{ var|striptags }}">>, [{var, "<b>Joel</b> <button>is</button> a <span>slug</span>"}],
+                   <<"Joel is a slug">>},
+                  {"|striptags",
+                   <<"{{ var|striptags }}">>, [{var, "<B>Joel</B> <button>is</button> a <span>slug</Span>"}],
+                   <<"Joel is a slug">>},
+                  {"|striptags",
+                   <<"{{ var|striptags }}">>, [{var, "Check out <a href=\"http://www.djangoproject.com\" rel=\"nofollow\">http://www.djangoproject.com</a>"}],
+                   <<"Check out http://www.djangoproject.com">>},
+                  {"|time:\"H:i\"",
+                   <<"{{ var|time:\"H:i\" }}">>, [{var, {{2010,12,1}, {10,11,12}} }],
+                   <<"10:11">>},
+                  {"|time",
+                   <<"{{ var|time }}">>, [{var, {{2010,12,1}, {10,11,12}} }],
+                   <<"10:11 a.m.">>},
+                  {"|timesince:from_date",
+                   <<"{{ from_date|timesince:conference_date }}">>, [{conference_date, {{2006,6,1},{8,0,0}} }, {from_date, {{2006,6,1},{0,0,0}} }],
                    <<"8 hours">>},
-		  {"|timesince:from_date",
-		   <<"{{ from_date|timesince:conference_date }}">>, [{conference_date, {{2010,6,1},{8,0,0}} },{from_date, {{2006,6,1},{0,0,0}} }],
-		   <<"4 years, 1 day">>}, % leap year
-		  {"|timesince:from_date",
-		   <<"{{ from_date|timesince:conference_date }}">>, [{conference_date, {{2006,7,15},{8,0,0}} },{from_date, {{2006,6,1},{0,0,0}} }],
-		   <<"1 month, 2 weeks">>},
-		  {"|timeuntil:from_date",
-		   <<"{{ conference_date|timeuntil:from_date }}">>, [{conference_date, {{2006,6,1},{8,0,0}} }, {from_date, {{2006,6,1},{0,0,0}} }],
-		   <<"8 hours">>},
-		  {"|timeuntil:from_date",
-		   <<"{{ conference_date|timeuntil:from_date }}">>, [{conference_date, {{2010,6,1},{8,0,0}} },{from_date, {{2006,6,1},{0,0,0}} }],
-		   <<"4 years, 1 day">>},
-		  {"|timeuntil:from_date",
-		   <<"{{ conference_date|timeuntil:from_date }}">>, [{conference_date, {{2006,7,15},{8,0,0}} },{from_date, {{2006,6,1},{0,0,0}} }],
-		   <<"1 month, 2 weeks">>},
-		  {"|title",
-		   <<"{{ \"my title case\"|title }}">>, [],
-		   <<"My Title Case">>},
-		  {"|title (pre-formatted)",
-		   <<"{{ \"My Title Case\"|title }}">>, [],
-		   <<"My Title Case">>},
-		  {"|title (wacky separators)",
-		   <<"{{ \"my-title!case\"|title }}">>, [],
-		   <<"My-Title!Case">>},
-		  {"|title (numbers)",
-		   <<"{{ \"my-title123CaSe\"|title }}">>, [],
-		   <<"My-Title123case">>},
-		  {"|title (Irish names)",
-		   <<"{{ \"who's o'malley?\"|title }}">>, [],
-		   <<"Who's O'Malley?">>},
-		  {"|truncatechars:0",
-		   <<"{{ var1|truncatechars:0 }}">>, [{var1, "Empty Me"}],
-		   <<"...">>},
-		  {"|truncatechars:14",
-		   <<"{{ var1|truncatechars:14 }}">>, [{var1, "Truncate Me Please"}],
-		   <<"Truncate Me...">>},
-		  {"|truncatechars:17",
-		   <<"{{ var1|truncatechars:17 }}">>, [{var1, "Don't Truncate Me"}],
-		   <<"Don't Truncate Me">>},
-		  {"|truncatechars:4 (UTF-8)",
-		   <<"{{ var1|truncatechars:4 }}">>, [{var1, "\x{E2}\x{82}\x{AC}1.99"}],
-		   <<"\x{E2}\x{82}\x{AC}...">>},
-		  {"|truncatechars:5 (UTF-8)",
-		   <<"{{ var1|truncatechars:5 }}">>, [{var1, "\x{E2}\x{82}\x{AC} 1.99"}],
-		   <<"\x{E2}\x{82}\x{AC} ...">>},
-		  {"|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">>},
-		  {"|truncatewords_html:4",
-		   <<"{{ var1|truncatewords_html:4 }}">>, [{var1, "<p>The <strong>Long and <em>Winding</em> Road</strong> is too long</p>"}],
-		   <<"<p>The <strong>Long and <em>Winding</em>...</strong></p>">>},
-		  {"|unordered_list",
-		   <<"{{ var1|unordered_list }}">>, [{var1, ["States", ["Kansas", ["Lawrence", "Topeka"], "Illinois"]]}],
-		   <<"<li>States<ul><li>Kansas<ul><li>Lawrence</li><li>Topeka</li></ul></li><li>Illinois</li></ul></li>">>},
-		  {"|upper",
-		   <<"{{ message|upper }}">>, [{message, "That man has a gun."}],
-		   <<"THAT MAN HAS A GUN.">>},
-		  {"|urlencode",
-		   <<"{{ url|urlencode }}">>, [{url, "You #$*@!!"}],
-		   <<"You%20%23%24%2A%40%21%21">>},
-		  {"|urlencode",
-		   <<"{{ url|urlencode }}">>, [{url, "http://www.example.org/foo?a=b&c=d"}],
-		   <<"http%3A//www.example.org/foo%3Fa%3Db%26c%3Dd">>},
-		  {"|urlencode",
-		   <<"{{ url|urlencode:\"\" }}">>, [{url, "http://www.example.org/foo?a=b&c=d"}],
-		   <<"http%3A%2F%2Fwww.example.org%2Ffoo%3Fa%3Db%26c%3Dd">>},
-		  {"|urlencode",
-		   <<"{{ url|urlencode:\":/?=&\" }}">>, [{url, "http://www.example.org/foo?a=b&c=d"}],
-		   <<"http://www.example.org/foo?a=b&c=d">>},
-		  {"|urlize",    
-		   <<"{{ var|urlize }}">>, [{var, "Check out www.djangoproject.com"}],
-		   <<"Check out <a href=\"http://www.djangoproject.com\" rel=\"nofollow\">www.djangoproject.com</a>">>},
-		  {"|urlize",    
-		   <<"{{ var|urlize }}">>, [{var, "Check out http://www.djangoproject.com"}],
-		   <<"Check out <a href=\"http://www.djangoproject.com\" rel=\"nofollow\">http://www.djangoproject.com</a>">>},
-		  {"|urlize",    
-		   <<"{{ var|urlize }}">>, [{var, "Check out \"http://www.djangoproject.com\""}],
-		   <<"Check out \"<a href=\"http://www.djangoproject.com\" rel=\"nofollow\">http://www.djangoproject.com</a>\"">>},
-		  {"|urlizetrunc:15",    
-		   <<"{{ var|urlizetrunc:15 }}">>, [{var, "Check out www.djangoproject.com"}],
-		   <<"Check out <a href=\"http://www.djangoproject.com\" rel=\"nofollow\">www.djangopr...</a>">>},    
-		  {"|wordcount",
-		   <<"{{ words|wordcount }}">>, [{words, "Why Hello There!"}],
-		   <<"3">>},
-		  {"|wordwrap:2",
-		   <<"{{ words|wordwrap:2 }}">>, [{words, "this is"}],
-		   <<"this \nis">>},
-		  {"|wordwrap:100",
-		   <<"{{ words|wordwrap:100 }}">>, [{words, "testing    testing"}],
-		   <<"testing    testing">>},
-		  {"|wordwrap:10",
-		   <<"{{ words|wordwrap:10 }}">>, [{words, ""}],
-		   <<"">>},
-		  {"|wordwrap:1",
-		   <<"{{ words|wordwrap:1 }}">>, [{words, "two"}],
-		   <<"two">>},
-						% yesno match: \?assert.*\( (.*), erlydtl_filters:(.*)\((.*), "(.*)"\)\)
-						% yesno replace: \t\t{"|$2:\"$4\"",\n\t\t\t\t\t <<"{{ var|$2:\"$4\" }}">>, [{var, $3}],\n\t\t\t\t\t<<$1>>}
-		  {"|yesno:\"yeah,no,maybe\"",
-		   <<"{{ var|yesno:\"yeah,no,maybe\" }}">>, [{var, true}],
-		   <<"yeah">>},
-		  {"|yesno:\"yeah,no,maybe\"",
-		   <<"{{ var|yesno:\"yeah,no,maybe\" }}">>, [{var, false}],
-		   <<"no">>},
-		  {"|yesno:\"yeah,no\"",
-		   <<"{{ var|yesno:\"yeah,no\" }}">>, [{var, undefined}],
-		   <<"no">>},
-		  {"|yesno:\"yeah,no,maybe\"",
-		   <<"{{ var|yesno:\"yeah,no,maybe\" }}">>, [{var, undefined}],
-		   <<"maybe">>},
+                  {"|timesince:from_date",
+                   <<"{{ from_date|timesince:conference_date }}">>, [{conference_date, {{2010,6,1},{8,0,0}} },{from_date, {{2006,6,1},{0,0,0}} }],
+                   <<"4 years, 1 day">>}, % leap year
+                  {"|timesince:from_date",
+                   <<"{{ from_date|timesince:conference_date }}">>, [{conference_date, {{2006,7,15},{8,0,0}} },{from_date, {{2006,6,1},{0,0,0}} }],
+                   <<"1 month, 2 weeks">>},
+                  {"|timeuntil:from_date",
+                   <<"{{ conference_date|timeuntil:from_date }}">>, [{conference_date, {{2006,6,1},{8,0,0}} }, {from_date, {{2006,6,1},{0,0,0}} }],
+                   <<"8 hours">>},
+                  {"|timeuntil:from_date",
+                   <<"{{ conference_date|timeuntil:from_date }}">>, [{conference_date, {{2010,6,1},{8,0,0}} },{from_date, {{2006,6,1},{0,0,0}} }],
+                   <<"4 years, 1 day">>},
+                  {"|timeuntil:from_date",
+                   <<"{{ conference_date|timeuntil:from_date }}">>, [{conference_date, {{2006,7,15},{8,0,0}} },{from_date, {{2006,6,1},{0,0,0}} }],
+                   <<"1 month, 2 weeks">>},
+                  {"|title",
+                   <<"{{ \"my title case\"|title }}">>, [],
+                   <<"My Title Case">>},
+                  {"|title (pre-formatted)",
+                   <<"{{ \"My Title Case\"|title }}">>, [],
+                   <<"My Title Case">>},
+                  {"|title (wacky separators)",
+                   <<"{{ \"my-title!case\"|title }}">>, [],
+                   <<"My-Title!Case">>},
+                  {"|title (numbers)",
+                   <<"{{ \"my-title123CaSe\"|title }}">>, [],
+                   <<"My-Title123case">>},
+                  {"|title (Irish names)",
+                   <<"{{ \"who's o'malley?\"|title }}">>, [],
+                   <<"Who's O'Malley?">>},
+                  {"|truncatechars:0",
+                   <<"{{ var1|truncatechars:0 }}">>, [{var1, "Empty Me"}],
+                   <<"...">>},
+                  {"|truncatechars:14",
+                   <<"{{ var1|truncatechars:14 }}">>, [{var1, "Truncate Me Please"}],
+                   <<"Truncate Me...">>},
+                  {"|truncatechars:17",
+                   <<"{{ var1|truncatechars:17 }}">>, [{var1, "Don't Truncate Me"}],
+                   <<"Don't Truncate Me">>},
+                  {"|truncatechars:4 (UTF-8)",
+                   <<"{{ var1|truncatechars:4 }}">>, [{var1, "\x{E2}\x{82}\x{AC}1.99"}],
+                   <<"\x{E2}\x{82}\x{AC}...">>},
+                  {"|truncatechars:5 (UTF-8)",
+                   <<"{{ var1|truncatechars:5 }}">>, [{var1, "\x{E2}\x{82}\x{AC} 1.99"}],
+                   <<"\x{E2}\x{82}\x{AC} ...">>},
+                  {"|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">>},
+                  {"|truncatewords_html:4",
+                   <<"{{ var1|truncatewords_html:4 }}">>, [{var1, "<p>The <strong>Long and <em>Winding</em> Road</strong> is too long</p>"}],
+                   <<"<p>The <strong>Long and <em>Winding</em>...</strong></p>">>},
+                  {"|unordered_list",
+                   <<"{{ var1|unordered_list }}">>, [{var1, ["States", ["Kansas", ["Lawrence", "Topeka"], "Illinois"]]}],
+                   <<"<li>States<ul><li>Kansas<ul><li>Lawrence</li><li>Topeka</li></ul></li><li>Illinois</li></ul></li>">>},
+                  {"|upper",
+                   <<"{{ message|upper }}">>, [{message, "That man has a gun."}],
+                   <<"THAT MAN HAS A GUN.">>},
+                  {"|urlencode",
+                   <<"{{ url|urlencode }}">>, [{url, "You #$*@!!"}],
+                   <<"You%20%23%24%2A%40%21%21">>},
+                  {"|urlencode",
+                   <<"{{ url|urlencode }}">>, [{url, "http://www.example.org/foo?a=b&c=d"}],
+                   <<"http%3A//www.example.org/foo%3Fa%3Db%26c%3Dd">>},
+                  {"|urlencode",
+                   <<"{{ url|urlencode:\"\" }}">>, [{url, "http://www.example.org/foo?a=b&c=d"}],
+                   <<"http%3A%2F%2Fwww.example.org%2Ffoo%3Fa%3Db%26c%3Dd">>},
+                  {"|urlencode",
+                   <<"{{ url|urlencode:\":/?=&\" }}">>, [{url, "http://www.example.org/foo?a=b&c=d"}],
+                   <<"http://www.example.org/foo?a=b&c=d">>},
+                  {"|urlize",
+                   <<"{{ var|urlize }}">>, [{var, "Check out www.djangoproject.com"}],
+                   <<"Check out <a href=\"http://www.djangoproject.com\" rel=\"nofollow\">www.djangoproject.com</a>">>},
+                  {"|urlize",
+                   <<"{{ var|urlize }}">>, [{var, "Check out http://www.djangoproject.com"}],
+                   <<"Check out <a href=\"http://www.djangoproject.com\" rel=\"nofollow\">http://www.djangoproject.com</a>">>},
+                  {"|urlize",
+                   <<"{{ var|urlize }}">>, [{var, "Check out \"http://www.djangoproject.com\""}],
+                   <<"Check out \"<a href=\"http://www.djangoproject.com\" rel=\"nofollow\">http://www.djangoproject.com</a>\"">>},
+                  {"|urlizetrunc:15",
+                   <<"{{ var|urlizetrunc:15 }}">>, [{var, "Check out www.djangoproject.com"}],
+                   <<"Check out <a href=\"http://www.djangoproject.com\" rel=\"nofollow\">www.djangopr...</a>">>},
+                  {"|wordcount",
+                   <<"{{ words|wordcount }}">>, [{words, "Why Hello There!"}],
+                   <<"3">>},
+                  {"|wordwrap:2",
+                   <<"{{ words|wordwrap:2 }}">>, [{words, "this is"}],
+                   <<"this \nis">>},
+                  {"|wordwrap:100",
+                   <<"{{ words|wordwrap:100 }}">>, [{words, "testing    testing"}],
+                   <<"testing    testing">>},
+                  {"|wordwrap:10",
+                   <<"{{ words|wordwrap:10 }}">>, [{words, ""}],
+                   <<"">>},
+                  {"|wordwrap:1",
+                   <<"{{ words|wordwrap:1 }}">>, [{words, "two"}],
+                   <<"two">>},
+                                                % yesno match: \?assert.*\( (.*), erlydtl_filters:(.*)\((.*), "(.*)"\)\)
+                                                % yesno replace: \t\t{"|$2:\"$4\"",\n\t\t\t\t\t <<"{{ var|$2:\"$4\" }}">>, [{var, $3}],\n\t\t\t\t\t<<$1>>}
+                  {"|yesno:\"yeah,no,maybe\"",
+                   <<"{{ var|yesno:\"yeah,no,maybe\" }}">>, [{var, true}],
+                   <<"yeah">>},
+                  {"|yesno:\"yeah,no,maybe\"",
+                   <<"{{ var|yesno:\"yeah,no,maybe\" }}">>, [{var, false}],
+                   <<"no">>},
+                  {"|yesno:\"yeah,no\"",
+                   <<"{{ var|yesno:\"yeah,no\" }}">>, [{var, undefined}],
+                   <<"no">>},
+                  {"|yesno:\"yeah,no,maybe\"",
+                   <<"{{ var|yesno:\"yeah,no,maybe\" }}">>, [{var, undefined}],
+                   <<"maybe">>},
 
-		  {"string |yesno:\"yeah,no,maybe\"",
-		   <<"{{ var|yesno:\"yeah,no,maybe\" }}">>, [{var, "non-empty string"}],
-		   <<"yeah">>},
-		  {"binary |yesno:\"yeah,no,maybe\"",
-		   <<"{{ var|yesno:\"yeah,no,maybe\" }}">>, [{var, <<"non-empty binary">>}],
-		   <<"yeah">>},
-		  {"empty string |yesno:\"yeah,no,maybe\"",
-		   <<"{{ var|yesno:\"yeah,no,maybe\" }}">>, [{var, ""}],
-		   <<"no">>},
-		  {"empty binary |yesno:\"yeah,no\"",
-		   <<"{{ var|yesno:\",no\" }}">>, [{var, <<"">>}],
-		   <<"no">>},
-		  {"term |yesno:\"yeah,,maybe\"",
-		   <<"{{ var|yesno:\"yeah,no,maybe\" }}">>, [{var, {my, [term, "test"]}}],
-		   <<"yeah">>},
-		  {"|yesno:\"yeah,\"",
-		   <<"{{ var|yesno:\"yeah,\" }}">>, [{var, false}],
-		   <<"">>},
-		  {"|yesno:\"yeah,,maybe\"",
-		   <<"{{ var|yesno:\"yeah,,maybe\" }}">>, [{var, false}],
-		   <<"">>},
-		  {"|yesno:\"missing_false_choice\"",
-		   <<"{{ var|yesno:\"missing_false_choice\" }}">>, [{var, true}],
-		   {error, {yesno, choices}}}
-		 ]},
+                  {"string |yesno:\"yeah,no,maybe\"",
+                   <<"{{ var|yesno:\"yeah,no,maybe\" }}">>, [{var, "non-empty string"}],
+                   <<"yeah">>},
+                  {"binary |yesno:\"yeah,no,maybe\"",
+                   <<"{{ var|yesno:\"yeah,no,maybe\" }}">>, [{var, <<"non-empty binary">>}],
+                   <<"yeah">>},
+                  {"empty string |yesno:\"yeah,no,maybe\"",
+                   <<"{{ var|yesno:\"yeah,no,maybe\" }}">>, [{var, ""}],
+                   <<"no">>},
+                  {"empty binary |yesno:\"yeah,no\"",
+                   <<"{{ var|yesno:\",no\" }}">>, [{var, <<"">>}],
+                   <<"no">>},
+                  {"term |yesno:\"yeah,,maybe\"",
+                   <<"{{ var|yesno:\"yeah,no,maybe\" }}">>, [{var, {my, [term, "test"]}}],
+                   <<"yeah">>},
+                  {"|yesno:\"yeah,\"",
+                   <<"{{ var|yesno:\"yeah,\" }}">>, [{var, false}],
+                   <<"">>},
+                  {"|yesno:\"yeah,,maybe\"",
+                   <<"{{ var|yesno:\"yeah,,maybe\" }}">>, [{var, false}],
+                   <<"">>},
+                  {"|yesno:\"missing_false_choice\"",
+                   <<"{{ var|yesno:\"missing_false_choice\" }}">>, [{var, true}],
+                   {error, {yesno, choices}}}
+                 ]},
      {"filters_if", [
-		     {"Filter if 1.1",
-		      <<"{% if var1|length_is:0 %}Y{% else %}N{% endif %}">>,
-		      [{var1, []}],
-		      <<"Y">>},
-		     {"Filter if 1.2",
-		      <<"{% if var1|length_is:1 %}Y{% else %}N{% endif %}">>,
-		      [{var1, []}],
-		      <<"N">>},
-		     {"Filter if 1.3",
-		      <<"{% if var1|length_is:7 %}Y{% else %}N{% endif %}">>,
-		      [{var1, []}],
-		      <<"N">>},
-		     {"Filter if 2.1",
-		      <<"{% if var1|length_is:0 %}Y{% else %}N{% endif %}">>,
-		      [{var1, ["foo"]}],
-		      <<"N">>},
-		     {"Filter if 2.2",
-		      <<"{% if var1|length_is:1 %}Y{% else %}N{% endif %}">>,
-		      [{var1, ["foo"]}],
-		      <<"Y">>},
-		     {"Filter if 2.3",
-		      <<"{% if var1|length_is:7 %}Y{% else %}N{% endif %}">>,
-		      [{var1, ["foo"]}],
-		      <<"N">>},
-		     {"Filter if 3.1",
-		      <<"{% ifequal var1|length 0 %}Y{% else %}N{% endifequal %}">>,
-		      [{var1, []}],
-		      <<"Y">>},
-		     {"Filter if 3.2",
-		      <<"{% ifequal var1|length 1 %}Y{% else %}N{% endifequal %}">>,
-		      [{var1, []}],
-		      <<"N">>},
-		     {"Filter if 4.1",
-		      <<"{% ifequal var1|length 3 %}Y{% else %}N{% endifequal %}">>,
-		      [{var1, ["foo", "bar", "baz"]}],
-		      <<"Y">>},
-		     {"Filter if 4.2",
-		      <<"{% ifequal var1|length 0 %}Y{% else %}N{% endifequal %}">>,
-		      [{var1, ["foo", "bar", "baz"]}],
-		      <<"N">>},
-		     {"Filter if 4.3",
-		      <<"{% ifequal var1|length 1 %}Y{% else %}N{% endifequal %}">>,
-		      [{var1, ["foo", "bar", "baz"]}],
-		      <<"N">>}
-		    ]},
+                     {"Filter if 1.1",
+                      <<"{% if var1|length_is:0 %}Y{% else %}N{% endif %}">>,
+                      [{var1, []}],
+                      <<"Y">>},
+                     {"Filter if 1.2",
+                      <<"{% if var1|length_is:1 %}Y{% else %}N{% endif %}">>,
+                      [{var1, []}],
+                      <<"N">>},
+                     {"Filter if 1.3",
+                      <<"{% if var1|length_is:7 %}Y{% else %}N{% endif %}">>,
+                      [{var1, []}],
+                      <<"N">>},
+                     {"Filter if 2.1",
+                      <<"{% if var1|length_is:0 %}Y{% else %}N{% endif %}">>,
+                      [{var1, ["foo"]}],
+                      <<"N">>},
+                     {"Filter if 2.2",
+                      <<"{% if var1|length_is:1 %}Y{% else %}N{% endif %}">>,
+                      [{var1, ["foo"]}],
+                      <<"Y">>},
+                     {"Filter if 2.3",
+                      <<"{% if var1|length_is:7 %}Y{% else %}N{% endif %}">>,
+                      [{var1, ["foo"]}],
+                      <<"N">>},
+                     {"Filter if 3.1",
+                      <<"{% ifequal var1|length 0 %}Y{% else %}N{% endifequal %}">>,
+                      [{var1, []}],
+                      <<"Y">>},
+                     {"Filter if 3.2",
+                      <<"{% ifequal var1|length 1 %}Y{% else %}N{% endifequal %}">>,
+                      [{var1, []}],
+                      <<"N">>},
+                     {"Filter if 4.1",
+                      <<"{% ifequal var1|length 3 %}Y{% else %}N{% endifequal %}">>,
+                      [{var1, ["foo", "bar", "baz"]}],
+                      <<"Y">>},
+                     {"Filter if 4.2",
+                      <<"{% ifequal var1|length 0 %}Y{% else %}N{% endifequal %}">>,
+                      [{var1, ["foo", "bar", "baz"]}],
+                      <<"N">>},
+                     {"Filter if 4.3",
+                      <<"{% ifequal var1|length 1 %}Y{% else %}N{% endifequal %}">>,
+                      [{var1, ["foo", "bar", "baz"]}],
+                      <<"N">>}
+                    ]},
      {"firstof", [
-		  {"Firstof first",
-		   <<"{% firstof foo bar baz %}">>,
-		   [{foo, "1"},{bar, "2"}],
-		   <<"1">>},
-		  {"Firstof second",
-		   <<"{% firstof foo bar baz %}">>,
-		   [{bar, "2"}],
-		   <<"2">>},
-		  {"Firstof none",
-		   <<"{% firstof foo bar baz %}">>,
-		   [],
-		   <<"">>},
-		  {"Firstof complex",
-		   <<"{% firstof foo.bar.baz bar %}">>,
-		   [{foo, [{bar, [{baz, "quux"}]}]}],
-		   <<"quux">>},
-		  {"Firstof undefined complex",
-		   <<"{% firstof foo.bar.baz bar %}">>,
-		   [{bar, "bar"}],
-		   <<"bar">>},
-		  {"Firstof literal",
-		   <<"{% firstof foo bar \"baz\" %}">>,
-		   [],
-		   <<"baz">>}
-		 ]},
+                  {"Firstof first",
+                   <<"{% firstof foo bar baz %}">>,
+                   [{foo, "1"},{bar, "2"}],
+                   <<"1">>},
+                  {"Firstof second",
+                   <<"{% firstof foo bar baz %}">>,
+                   [{bar, "2"}],
+                   <<"2">>},
+                  {"Firstof none",
+                   <<"{% firstof foo bar baz %}">>,
+                   [],
+                   <<"">>},
+                  {"Firstof complex",
+                   <<"{% firstof foo.bar.baz bar %}">>,
+                   [{foo, [{bar, [{baz, "quux"}]}]}],
+                   <<"quux">>},
+                  {"Firstof undefined complex",
+                   <<"{% firstof foo.bar.baz bar %}">>,
+                   [{bar, "bar"}],
+                   <<"bar">>},
+                  {"Firstof literal",
+                   <<"{% firstof foo bar \"baz\" %}">>,
+                   [],
+                   <<"baz">>}
+                 ]},
      {"regroup", [
-		  {"Ordered", <<"{% regroup people by gender as gender_list %}{% for gender in gender_list %}{{ gender.grouper }}\n{% for item in gender.list %}{{ item.first_name }}\n{% endfor %}{% endfor %}{% endregroup %}">>, 
-		   [{people, [[{first_name, "George"}, {gender, "Male"}], [{first_name, "Bill"}, {gender, "Male"}],
-			      [{first_name, "Margaret"}, {gender, "Female"}], [{first_name, "Condi"}, {gender, "Female"}]]}],
-		   <<"Male\nGeorge\nBill\nFemale\nMargaret\nCondi\n">>},
-		  {"Unordered", <<"{% regroup people by gender as gender_list %}{% for gender in gender_list %}{{ gender.grouper }}\n{% for item in gender.list %}{{ item.first_name }}\n{% endfor %}{% endfor %}{% endregroup %}">>, 
-		   [{people, [[{first_name, "George"}, {gender, "Male"}], 
-			      [{first_name, "Margaret"}, {gender, "Female"}], 
-			      [{first_name, "Condi"}, {gender, "Female"}],
-			      [{first_name, "Bill"}, {gender, "Male"}]
-			     ]}],
-		   <<"Male\nGeorge\nFemale\nMargaret\nCondi\nMale\nBill\n">>},
-		  {"NestedOrdered", <<"{% regroup people by name.last as lastname_list %}{% for lastname in lastname_list %}{{ lastname.grouper }}\n{% for item in lastname.list %}{{ item.name.first }}\n{% endfor %}{% endfor %}{% endregroup %}">>,
-		   [{people, [[{name, [{first,"George"},{last,"Costanza"}]}],
-			      [{name, [{first,"Margaret"},{last,"Costanza"}]}],
-			      [{name, [{first,"Bill"},{last,"Buffalo"}]}],
-			      [{name, [{first,"Condi"},{last,"Buffalo"}]}]]}],
-		   <<"Costanza\nGeorge\nMargaret\nBuffalo\nBill\nCondi\n">>},
-		  {"NestedUnordered", <<"{% regroup people by name.last as lastname_list %}{% for lastname in lastname_list %}{{ lastname.grouper }}\n{% for item in lastname.list %}{{ item.name.first }}\n{% endfor %}{% endfor %}{% endregroup %}">>,
-		   [{people, [[{name, [{first,"George"},{last,"Costanza"}]}],
-			      [{name, [{first,"Bill"},{last,"Buffalo"}]}],
-			      [{name, [{first,"Margaret"},{last,"Costanza"}]}],
-			      [{name, [{first,"Condi"},{last,"Buffalo"}]}]]}],
-		   <<"Costanza\nGeorge\nBuffalo\nBill\nCostanza\nMargaret\nBuffalo\nCondi\n">>},
-		  {"Filter", <<"{% regroup people|dictsort:\"name.last\" by name.last as lastname_list %}{% for lastname in lastname_list %}{{ lastname.grouper }}\n{% for item in lastname.list %}{{ item.name.first }}\n{% endfor %}{% endfor %}{% endregroup %}">>,
-		   [{people, [[{name, [{first,"George"},{last,"Costanza"}]}],
-			      [{name, [{first,"Bill"},{last,"Buffalo"}]}],
-			      [{name, [{first,"Margaret"},{last,"Costanza"}]}],
-			      [{name, [{first,"Condi"},{last,"Buffalo"}]}]]}],
-		   <<"Buffalo\nBill\nCondi\nCostanza\nGeorge\nMargaret\n">>}
-		 ]},
+                  {"Ordered", <<"{% regroup people by gender as gender_list %}{% for gender in gender_list %}{{ gender.grouper }}\n{% for item in gender.list %}{{ item.first_name }}\n{% endfor %}{% endfor %}{% endregroup %}">>,
+                   [{people, [[{first_name, "George"}, {gender, "Male"}], [{first_name, "Bill"}, {gender, "Male"}],
+                              [{first_name, "Margaret"}, {gender, "Female"}], [{first_name, "Condi"}, {gender, "Female"}]]}],
+                   <<"Male\nGeorge\nBill\nFemale\nMargaret\nCondi\n">>},
+                  {"Unordered", <<"{% regroup people by gender as gender_list %}{% for gender in gender_list %}{{ gender.grouper }}\n{% for item in gender.list %}{{ item.first_name }}\n{% endfor %}{% endfor %}{% endregroup %}">>,
+                   [{people, [[{first_name, "George"}, {gender, "Male"}],
+                              [{first_name, "Margaret"}, {gender, "Female"}],
+                              [{first_name, "Condi"}, {gender, "Female"}],
+                              [{first_name, "Bill"}, {gender, "Male"}]
+                             ]}],
+                   <<"Male\nGeorge\nFemale\nMargaret\nCondi\nMale\nBill\n">>},
+                  {"NestedOrdered", <<"{% regroup people by name.last as lastname_list %}{% for lastname in lastname_list %}{{ lastname.grouper }}\n{% for item in lastname.list %}{{ item.name.first }}\n{% endfor %}{% endfor %}{% endregroup %}">>,
+                   [{people, [[{name, [{first,"George"},{last,"Costanza"}]}],
+                              [{name, [{first,"Margaret"},{last,"Costanza"}]}],
+                              [{name, [{first,"Bill"},{last,"Buffalo"}]}],
+                              [{name, [{first,"Condi"},{last,"Buffalo"}]}]]}],
+                   <<"Costanza\nGeorge\nMargaret\nBuffalo\nBill\nCondi\n">>},
+                  {"NestedUnordered", <<"{% regroup people by name.last as lastname_list %}{% for lastname in lastname_list %}{{ lastname.grouper }}\n{% for item in lastname.list %}{{ item.name.first }}\n{% endfor %}{% endfor %}{% endregroup %}">>,
+                   [{people, [[{name, [{first,"George"},{last,"Costanza"}]}],
+                              [{name, [{first,"Bill"},{last,"Buffalo"}]}],
+                              [{name, [{first,"Margaret"},{last,"Costanza"}]}],
+                              [{name, [{first,"Condi"},{last,"Buffalo"}]}]]}],
+                   <<"Costanza\nGeorge\nBuffalo\nBill\nCostanza\nMargaret\nBuffalo\nCondi\n">>},
+                  {"Filter", <<"{% regroup people|dictsort:\"name.last\" by name.last as lastname_list %}{% for lastname in lastname_list %}{{ lastname.grouper }}\n{% for item in lastname.list %}{{ item.name.first }}\n{% endfor %}{% endfor %}{% endregroup %}">>,
+                   [{people, [[{name, [{first,"George"},{last,"Costanza"}]}],
+                              [{name, [{first,"Bill"},{last,"Buffalo"}]}],
+                              [{name, [{first,"Margaret"},{last,"Costanza"}]}],
+                              [{name, [{first,"Condi"},{last,"Buffalo"}]}]]}],
+                   <<"Buffalo\nBill\nCondi\nCostanza\nGeorge\nMargaret\n">>}
+                 ]},
      {"spaceless", [
-		    {"Beginning", <<"{% spaceless %}    <b>foo</b>{% endspaceless %}">>, [], <<"<b>foo</b>">>},
-		    {"Middle", <<"{% spaceless %}<b>foo</b>  <b>bar</b>{% endspaceless %}">>, [], <<"<b>foo</b><b>bar</b>">>},
-		    {"End", <<"{% spaceless %}<b>foo</b>  {% endspaceless %}">>, [], <<"<b>foo</b>">>},
-		    {"NewLine", <<"{% spaceless %}\n<div> \n <b>foo</b> \n </div>\n {% endspaceless %}">>, [], <<"<div><b>foo</b></div>">>}
-		   ]},
+                    {"Beginning", <<"{% spaceless %}    <b>foo</b>{% endspaceless %}">>, [], <<"<b>foo</b>">>},
+                    {"Middle", <<"{% spaceless %}<b>foo</b>  <b>bar</b>{% endspaceless %}">>, [], <<"<b>foo</b><b>bar</b>">>},
+                    {"End", <<"{% spaceless %}<b>foo</b>  {% endspaceless %}">>, [], <<"<b>foo</b>">>},
+                    {"NewLine", <<"{% spaceless %}\n<div> \n <b>foo</b> \n </div>\n {% endspaceless %}">>, [], <<"<div><b>foo</b></div>">>}
+                   ]},
      {"templatetag", [
-		      {"openblock", <<"{% templatetag openblock %}">>, [], <<"{%">>},
-		      {"closeblock", <<"{% templatetag closeblock %}">>, [], <<"%}">>},
-		      {"openvariable", <<"{% templatetag openvariable %}">>, [], <<"{{">>},
-		      {"closevariable", <<"{% templatetag closevariable %}">>, [], <<"}}">>},
-		      {"openbrace", <<"{% templatetag openbrace %}">>, [], <<"{">>},
-		      {"closebrace", <<"{% templatetag closebrace %}">>, [], <<"}">>},
-		      {"opencomment", <<"{% templatetag opencomment %}">>, [], <<"{#">>},
-		      {"closecomment", <<"{% templatetag closecomment %}">>, [], <<"#}">>}
-		     ]},
+                      {"openblock", <<"{% templatetag openblock %}">>, [], <<"{%">>},
+                      {"closeblock", <<"{% templatetag closeblock %}">>, [], <<"%}">>},
+                      {"openvariable", <<"{% templatetag openvariable %}">>, [], <<"{{">>},
+                      {"closevariable", <<"{% templatetag closevariable %}">>, [], <<"}}">>},
+                      {"openbrace", <<"{% templatetag openbrace %}">>, [], <<"{">>},
+                      {"closebrace", <<"{% templatetag closebrace %}">>, [], <<"}">>},
+                      {"opencomment", <<"{% templatetag opencomment %}">>, [], <<"{#">>},
+                      {"closecomment", <<"{% templatetag closecomment %}">>, [], <<"#}">>}
+                     ]},
      {"trans",
       [
        {"trans functional default locale",
-	<<"Hello {% trans \"Hi\" %}">>, [], <<"Hello Hi">>
+        <<"Hello {% trans \"Hi\" %}">>, [], <<"Hello Hi">>
        },
        {"trans functional reverse locale",
-	<<"Hello {% trans \"Hi\" %}">>, [], [], [{locale, "reverse"}], <<"Hello iH">>
+        <<"Hello {% trans \"Hi\" %}">>, [], [], [{locale, "reverse"}], <<"Hello iH">>
        },
        {"trans literal at run-time",
-	<<"Hello {% trans \"Hi\" %}">>, [], [{translation_fun, fun("Hi") -> "Konichiwa" end}], [],
-	<<"Hello Konichiwa">>},
+        <<"Hello {% trans \"Hi\" %}">>, [], [{translation_fun, fun("Hi") -> "Konichiwa" end}], [],
+        <<"Hello Konichiwa">>},
        {"trans variable at run-time",
-	<<"Hello {% trans var1 %}">>, [{var1, <<"Hi">>}], [{translation_fun, fun(<<"Hi">>) -> <<"Konichiwa">> end}], [],
-	<<"Hello Konichiwa">>},
+        <<"Hello {% trans var1 %}">>, [{var1, <<"Hi">>}], [{translation_fun, fun(<<"Hi">>) -> <<"Konichiwa">> end}], [],
+        <<"Hello Konichiwa">>},
        {"trans literal at run-time: No-op",
-	<<"Hello {% trans \"Hi\" noop %}">>, [], [{translation_fun, fun("Hi") -> <<"Konichiwa">> end}], [],
-	<<"Hello Hi">>},
+        <<"Hello {% trans \"Hi\" noop %}">>, [], [{translation_fun, fun("Hi") -> <<"Konichiwa">> end}], [],
+        <<"Hello Hi">>},
        {"trans variable at run-time: No-op",
-	<<"Hello {% trans var1 noop %}">>, [{var1, <<"Hi">>}], [{translation_fun, fun(<<"Hi">>) -> <<"Konichiwa">> end}], [],
-	<<"Hello Hi">>}
+        <<"Hello {% trans var1 noop %}">>, [{var1, <<"Hi">>}], [{translation_fun, fun(<<"Hi">>) -> <<"Konichiwa">> end}], [],
+        <<"Hello Hi">>}
       ]},
      {"blocktrans",
       [
        {"blocktrans default locale",
-	<<"{% blocktrans %}Hello{% endblocktrans %}">>, [], <<"Hello">>},
+        <<"{% blocktrans %}Hello{% endblocktrans %}">>, [], <<"Hello">>},
        {"blocktrans choose locale",
-	<<"{% blocktrans %}Hello, {{ name }}{% endblocktrans %}">>, [{name, "Mr. President"}], [{locale, "de"}],
-	[{blocktrans_locales, ["de"]}, {blocktrans_fun, fun("Hello, {{ name }}", "de") -> <<"Guten tag, {{ name }}">> end}], <<"Guten tag, Mr. President">>},
+        <<"{% blocktrans %}Hello, {{ name }}{% endblocktrans %}">>, [{name, "Mr. President"}], [{locale, "de"}],
+        [{blocktrans_locales, ["de"]}, {blocktrans_fun, fun("Hello, {{ name }}", "de") -> <<"Guten tag, {{ name }}">> end}], <<"Guten tag, Mr. President">>},
        {"blocktrans with args",
-	<<"{% blocktrans with var1=foo %}{{ var1 }}{% endblocktrans %}">>, [{foo, "Hello"}], <<"Hello">>}
+        <<"{% blocktrans with var1=foo %}{{ var1 }}{% endblocktrans %}">>, [{foo, "Hello"}], <<"Hello">>}
       ]},
      {"verbatim", [
-		   {"Plain verbatim",
-		    <<"{% verbatim %}{{ oh no{% foobar %}{% endverbatim %}">>, [],
-		    <<"{{ oh no{% foobar %}">>},
-		   {"Named verbatim",
-		    <<"{% verbatim foobar %}{% verbatim %}{% endverbatim foobar2 %}{% endverbatim foobar %}">>, [],
-		    <<"{% verbatim %}{% endverbatim foobar2 %}">>}
-		  ]},
+                   {"Plain verbatim",
+                    <<"{% verbatim %}{{ oh no{% foobar %}{% endverbatim %}">>, [],
+                    <<"{{ oh no{% foobar %}">>},
+                   {"Named verbatim",
+                    <<"{% verbatim foobar %}{% verbatim %}{% endverbatim foobar2 %}{% endverbatim foobar %}">>, [],
+                    <<"{% verbatim %}{% endverbatim foobar2 %}">>}
+                  ]},
      {"widthratio", [
-		     {"Literals", <<"{% widthratio 5 10 100 %}">>, [], <<"50">>},
-		     {"Rounds up", <<"{% widthratio a b 100 %}">>, [{a, 175}, {b, 200}], <<"88">>}
-		    ]},
+                     {"Literals", <<"{% widthratio 5 10 100 %}">>, [], <<"50">>},
+                     {"Rounds up", <<"{% widthratio a b 100 %}">>, [{a, 175}, {b, 200}], <<"88">>}
+                    ]},
      {"with", [
-	       {"Cache literal",
+               {"Cache literal",
                 <<"{% with a=1 %}{{ a }}{% endwith %}">>, [], <<"1">>},
-	       {"Cache variable",
+               {"Cache variable",
                 <<"{% with a=b %}{{ a }}{% endwith %}">>, [{b, "foo"}], <<"foo">>},
-	       {"Cache variable with attribute",
-		<<"I enjoy {% with a = var1 %}{{ a.game }}{% endwith %}">>, [{var1, [{game, "Othello"}]}], <<"I enjoy Othello">>},
-	       {"Cache variable attribute",
-		<<"I enjoy {% with a = var1.game %}{{ a }}{% endwith %}">>, [{var1, [{game, "Othello"}]}], <<"I enjoy Othello">>},
-	       {"Cache multiple",
+               {"Cache variable with attribute",
+                <<"I enjoy {% with a = var1 %}{{ a.game }}{% endwith %}">>, [{var1, [{game, "Othello"}]}], <<"I enjoy Othello">>},
+               {"Cache variable attribute",
+                <<"I enjoy {% with a = var1.game %}{{ a }}{% endwith %}">>, [{var1, [{game, "Othello"}]}], <<"I enjoy Othello">>},
+               {"Cache multiple",
                 <<"{% with alpha=1 beta=b %}{{ alpha }}/{{ beta }}{% endwith %}">>, [{b, 2}], <<"1/2">>}
-	      ]},
+              ]},
      {"unicode", [
-		  {"(tm) somewhere",
-		   <<"™">>, [], <<"™">>}
-		 ]},
+                  {"(tm) somewhere",
+                   <<"™">>, [], <<"™">>}
+                 ]},
      {"contrib_humanize", [
-			   {"intcomma",
-			    <<"{{ a|intcomma }} {{ b|intcomma }} {{ c|intcomma }} {{ d|intcomma }}">>,
-			    [{a, 999}, {b, 123456789}, {c, 12345}, {d, 1234567890}],
-			    <<"999 123,456,789 12,345 1,234,567,890">>}
-			  ]},
+                           {"intcomma",
+                            <<"{{ a|intcomma }} {{ b|intcomma }} {{ c|intcomma }} {{ d|intcomma }}">>,
+                            [{a, 999}, {b, 123456789}, {c, 12345}, {d, 1234567890}],
+                            <<"999 123,456,789 12,345 1,234,567,890">>}
+                          ]},
      %% custom syntax stuff
      {"extension_module",
       [ %% the erlydtl_extension_test module replaces a foo identifier with bar when hitting a # following foo.
@@ -1348,33 +1348,33 @@ process_unit_test({Name, DTL, Vars, RenderOpts, CompilerOpts, Output}) ->
 
 vars_to_binary(Vars) when is_list(Vars) ->
     lists:map(fun
-		  ({Key, [H|_] = Value}) when is_tuple(H) ->
-		     {Key, vars_to_binary(Value)};
-		  ({Key, [H|_] = Value}) when is_integer(H) ->
-		     {Key, list_to_binary(Value)};
-		  ({Key, Value}) ->
-		     {Key, Value}
-	     end, Vars);
+                  ({Key, [H|_] = Value}) when is_tuple(H) ->
+                     {Key, vars_to_binary(Value)};
+                  ({Key, [H|_] = Value}) when is_integer(H) ->
+                     {Key, list_to_binary(Value)};
+                  ({Key, Value}) ->
+                     {Key, Value}
+             end, Vars);
 vars_to_binary(Vars) ->
     Vars.
 
 generate_test_date() ->
     {{Y,M,D}, _} = erlang:localtime(),
     MonthName = [
-		 "January", "February", "March", "April",
-		 "May", "June", "July", "August", "September",
-		 "October", "November", "December"
-		],
+                 "January", "February", "March", "April",
+                 "May", "June", "July", "August", "September",
+                 "October", "November", "December"
+                ],
     OrdinalSuffix = [
-		     "st","nd","rd","th","th","th","th","th","th","th", % 1-10
-		     "th","th","th","th","th","th","th","th","th","th", % 10-20
-		     "st","nd","rd","th","th","th","th","th","th","th", % 20-30
-		     "st"
-		    ],
+                     "st","nd","rd","th","th","th","th","th","th","th", % 1-10
+                     "th","th","th","th","th","th","th","th","th","th", % 10-20
+                     "st","nd","rd","th","th","th","th","th","th","th", % 20-30
+                     "st"
+                    ],
     list_to_binary([
-		    "It is the ",
-		    integer_to_list(D),
-		    lists:nth(D, OrdinalSuffix),
-		    " of ", lists:nth(M, MonthName),
-		    " ", integer_to_list(Y), "."
-		   ]).
+                    "It is the ",
+                    integer_to_list(D),
+                    lists:nth(D, OrdinalSuffix),
+                    " of ", lists:nth(M, MonthName),
+                    " ", integer_to_list(Y), "."
+                   ]).