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

New option for 0-based tuple access (#156)

Andreas Stenius 11 лет назад
Родитель
Сommit
ad43f6ed7e

+ 1 - 1
NEWS.md

@@ -6,4 +6,4 @@ Standards](http://www.gnu.org/prep/standards/html_node/NEWS-File.html#NEWS-File)
 
 ## master (upcoming release)
 
-* New option for 0-based list access (#156) (see README for details).
+* New option for 0-based list/tuple access (#156) (see README for details).

+ 16 - 2
README.markdown

@@ -181,7 +181,8 @@ Options is a proplist possibly containing:
 * `lists_0_based` - **Compatibility warning** Defaults to `false`,
   giving 1-based list access, as is common practice in Erlang. Set it
   to `true` to get 1-based access as in Django, or to `defer` to not
-  decide until render time, using the render option `lists_0_based`.
+  decide until render time, using the render option
+  `lists_0_based`. See also `tuples_0_based`.
 
 * `locale` **deprecated** - The same as {blocktrans_locales, [Val]}.
 
@@ -220,6 +221,13 @@ Options is a proplist possibly containing:
 
 * `report_errors` - Print errors as they occur.
 
+* `tuples_0_based` - **Compatibility warning** Defaults to `false`,
+  giving 1-based tuple access, as is common practice in Erlang. Set it
+  to `true` to get 1-based access as in Django, or to `defer` to not
+  decide until render time, using the render option
+  `tuples_0_based`. See also `lists_0_based`.
+
+
 * `vars` - Variables (and their values) to evaluate at compile-time
   rather than render-time. (Currently not strictly true, see
   [#61](https://github.com/erlydtl/erlydtl/issues/61))
@@ -291,11 +299,17 @@ Same as `render/1`, but with the following options:
 
 * `lists_0_based` - If the compile option `lists_0_based` was set to
   `defer`, pass this option (or set it to true, `{lists_0_based,
-  true}`) to get 0-based list indexing when rendering the template.
+  true}`) to get 0-based list indexing when rendering the
+  template. See also `tuples_0_based`.
 
 * `locale` - A string specifying the current locale, for use with the
   `blocktrans_fun` compile-time option.
 
+* `tuples_0_based` - If the compile option `tuples_0_based` was set to
+  `defer`, pass this option (or set it to true, `{tuples_0_based,
+  true}`) to get 0-based tuple indexing when rendering the
+  template. See also `lists_0_based`.
+
 
 ### translatable_strings/0
 

+ 2 - 1
include/erlydtl_ext.hrl

@@ -33,7 +33,8 @@
           errors = #error_info{},
           warnings = #error_info{},
           bin = undefined,
-          lists_0_based = false
+          lists_0_based = false,
+          tuples_0_based = false
          }).
 
 -record(ast_info, {

+ 7 - 1
src/erlydtl_beam_compiler.erl

@@ -1118,12 +1118,18 @@ resolve_variable_ast(VarTuple, FinderFunction, TreeWalker) ->
 
 resolve_variable_ast1({attribute, {{_, Pos, Attr}, Variable}}, {Runtime, Finder}=FinderFunction, TreeWalker) ->
     {{VarAst, VarInfo}, TreeWalker1} = resolve_variable_ast(Variable, FinderFunction, TreeWalker),
-    #treewalker{ context=#dtl_context{ lists_0_based = Lists0Based } } = TreeWalker,
+    #treewalker{
+       context=#dtl_context{
+                  lists_0_based = Lists0Based,
+                  tuples_0_based = Tuples0Based
+                 }
+      } = TreeWalker,
     FileName = get_current_file(TreeWalker1),
     {{?Q(["'@Runtime@':'@Finder@'(",
           "  _@Attr@, _@VarAst,",
           "  [",
           "   {lists_0_based, _@Lists0Based@},",
+          "   {tuples_0_based, _@Tuples0Based@},",
           "   {render_options, RenderOptions},",
           "   {record_info, _RecordInfo},",
           "   {filename, _@FileName@},",

+ 2 - 1
src/erlydtl_compiler.erl

@@ -254,7 +254,8 @@ init_context(ParseTrail, DefDir, Module, Options) ->
                           || {R, I} <- proplists:get_value(record_info, Options, Ctx#dtl_context.record_info)],
            errors = init_error_info(errors, Ctx#dtl_context.errors, Options),
            warnings = init_error_info(warnings, Ctx#dtl_context.warnings, Options),
-           lists_0_based = proplists:get_value(lists_0_based, Options, Ctx#dtl_context.lists_0_based)
+           lists_0_based = proplists:get_value(lists_0_based, Options, Ctx#dtl_context.lists_0_based),
+           tuples_0_based = proplists:get_value(tuples_0_based, Options, Ctx#dtl_context.tuples_0_based)
           },
     Context = load_libraries(proplists:get_value(default_libraries, Options, []), Context0),
     case call_extension(Context, init_context, [Context]) of

+ 2 - 0
src/erlydtl_runtime.erl

@@ -19,6 +19,8 @@ find_value(Key, Data, Options) when is_atom(Key), is_tuple(Data) ->
     end;
 find_value(Key, Data, Options) when is_integer(Key), is_list(Data) ->
     find_value(adjust_index(Key, 1, lists_0_based, Options), Data);
+find_value(Key, Data, Options) when is_integer(Key), is_tuple(Data) ->
+    find_value(adjust_index(Key, 1, tuples_0_based, Options), Data);
 find_value(Key, Data, _Options) ->
     find_value(Key, Data).
 

+ 19 - 3
test/erlydtl_test_defs.erl

@@ -112,17 +112,33 @@ all_test_defs() ->
         <<"{{ var1.1 }},{{ var1.2 }},{{ var1.3 }}.">>,
         [{var1, [a, b, c]}],
         <<"a,b,c.">>},
-       {"Index all elements 0-based (selected at compile time)",
+       {"Index all list elements 0-based (selected at compile time)",
         <<"{{ var1.0 }},{{ var1.1 }},{{ var1.2 }}.">>,
         [{var1, [a, b, c]}], [], [lists_0_based],
         <<"a,b,c.">>},
-       {"Index all elements 0-based (selected at render time)",
+       {"Index all list elements 0-based (selected at render time)",
         <<"{{ var1.0 }},{{ var1.1 }},{{ var1.2 }}.">>,
         [{var1, [a, b, c]}], [lists_0_based], [{lists_0_based, defer}],
         <<"a,b,c.">>},
-       {"Index all elements 1-based (selected at render time)",
+       {"Index all list elements 1-based (selected at render time)",
         <<"{{ var1.1 }},{{ var1.2 }},{{ var1.3 }}.">>,
         [{var1, [a, b, c]}], [], [{lists_0_based, defer}],
+        <<"a,b,c.">>},
+       {"Index all elements of tuple (default, 1-based)",
+        <<"{{ var1.1 }},{{ var1.2 }},{{ var1.3 }}.">>,
+        [{var1, {a, b, c}}],
+        <<"a,b,c.">>},
+       {"Index all tuple elements 0-based (selected at compile time)",
+        <<"{{ var1.0 }},{{ var1.1 }},{{ var1.2 }}.">>,
+        [{var1, {a, b, c}}], [], [tuples_0_based],
+        <<"a,b,c.">>},
+       {"Index all tuple elements 0-based (selected at render time)",
+        <<"{{ var1.0 }},{{ var1.1 }},{{ var1.2 }}.">>,
+        [{var1, {a, b, c}}], [tuples_0_based], [{tuples_0_based, defer}],
+        <<"a,b,c.">>},
+       {"Index all tuple elements 1-based (selected at render time)",
+        <<"{{ var1.1 }},{{ var1.2 }},{{ var1.3 }}.">>,
+        [{var1, {a, b, c}}], [], [{tuples_0_based, defer}],
         <<"a,b,c.">>}
       ]},
      {"now",