From 0722287d6c04831cdb40b64bae2ca55c24c2f555 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Tue, 2 Oct 2012 12:16:42 -0500 Subject: handle inverted sections --- lib/Text/Handlebars.pm | 4 ++ lib/Text/Handlebars/Compiler.pm | 10 ++-- lib/Text/Xslate/Syntax/Handlebars.pm | 88 ++++++++++++++++++++++++------------ 3 files changed, 70 insertions(+), 32 deletions(-) (limited to 'lib') diff --git a/lib/Text/Handlebars.pm b/lib/Text/Handlebars.pm index bad8c64..aa239a0 100644 --- a/lib/Text/Handlebars.pm +++ b/lib/Text/Handlebars.pm @@ -12,6 +12,10 @@ sub default_functions { my ($val) = @_; return ref($val) && ref($val) eq 'ARRAY'; }, + '(is_empty_array)' => sub { + my ($val) = @_; + return @$val == 0; + }, '(make_array)' => sub { my ($length) = @_; return [(undef) x $length]; diff --git a/lib/Text/Handlebars/Compiler.pm b/lib/Text/Handlebars/Compiler.pm index 2150bba..5f112fc 100644 --- a/lib/Text/Handlebars/Compiler.pm +++ b/lib/Text/Handlebars/Compiler.pm @@ -11,10 +11,12 @@ sub _generate_block { my $self = shift; my ($node) = @_; - return ( - $self->_localize_vars($node->first), - (map { $self->compile_ast($_) } @{ $node->second }), - ); + my @compiled = map { $self->compile_ast($_) } @{ $node->second }; + + unshift @compiled, $self->_localize_vars($node->first) + if $node->first; + + return @compiled; } if (0) { diff --git a/lib/Text/Xslate/Syntax/Handlebars.pm b/lib/Text/Xslate/Syntax/Handlebars.pm index 4741d7f..ab46d52 100644 --- a/lib/Text/Xslate/Syntax/Handlebars.pm +++ b/lib/Text/Xslate/Syntax/Handlebars.pm @@ -111,7 +111,7 @@ sub preprocess { elsif ($type eq 'code') { $code .= qq{$content;\n}; $suppress_newline = 1 - if $content =~ m{^[#/]}; + if $content =~ m{^[#^/]}; } elsif ($type eq 'raw_code') { $code .= qq{mark_raw $content;\n}; @@ -144,6 +144,7 @@ sub init_symbols { $self->infix('/', 256, $self->can('led_dot')); $self->symbol('#')->set_std($self->can('std_block')); + $self->symbol('^')->set_std($self->can('std_block')); $self->prefix('/', 0)->is_block_end(1); } @@ -186,6 +187,8 @@ sub std_block { my $self = shift; my ($symbol) = @_; + my $inverted = $symbol->id eq '^'; + if ($self->token->arity ne 'name') { $self->_unexpected("block name", $self->token); } @@ -206,38 +209,67 @@ sub std_block { $self->advance; - my $iterations = $self->make_ternary( - $self->call('(is_array)', $name->clone), - $name->clone, - $self->make_ternary( - $name->clone, - $self->call( - '(make_array)', - $self->symbol('(literal)')->clone(id => 1), - ), - $self->call( - '(make_array)', - $self->symbol('(literal)')->clone(id => 0), - ), - ), - ); + my $iterations = $inverted + ? ($self->make_ternary( + $self->call('(is_array)', $name->clone), + $self->make_ternary( + $self->call('(is_empty_array)', $name->clone), + $self->call( + '(make_array)', + $self->symbol('(literal)')->clone(id => 1), + ), + $self->call( + '(make_array)', + $self->symbol('(literal)')->clone(id => 0), + ), + ), + $self->make_ternary( + $name->clone, + $self->call( + '(make_array)', + $self->symbol('(literal)')->clone(id => 0), + ), + $self->call( + '(make_array)', + $self->symbol('(literal)')->clone(id => 1), + ), + ), + )) + : ($self->make_ternary( + $self->call('(is_array)', $name->clone), + $name->clone, + $self->make_ternary( + $name->clone, + $self->call( + '(make_array)', + $self->symbol('(literal)')->clone(id => 1), + ), + $self->call( + '(make_array)', + $self->symbol('(literal)')->clone(id => 0), + ), + ), + )); my $loop_var = $self->symbol('(variable)')->clone(id => '(block)'); my $body_block = [ $symbol->clone( - arity => 'block', - first => [ - $self->call( - '(new_vars_for)', - $self->symbol('(vars)')->clone(arity => 'vars'), - $name->clone, - $self->symbol('(iterator)')->clone( - id => '$~(block)', - first => $loop_var, - ), - ), - ], + arity => 'block', + first => ($inverted + ? (undef) + : ([ + $self->call( + '(new_vars_for)', + $self->symbol('(vars)')->clone(arity => 'vars'), + $name->clone, + $self->symbol('(iterator)')->clone( + id => '$~(block)', + first => $loop_var, + ), + ), + ]) + ), second => $body, ), ]; -- cgit v1.2.3-54-g00ecf