summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2012-10-05 11:48:54 -0500
committerJesse Luehrs <doy@tozt.net>2012-10-05 11:52:55 -0500
commitd6ad2d3c6ee63fc8493b47e4f4b82e1804bfac5f (patch)
tree12477aa52988a5873aeb774d9af92bd695498bf1
parent4954d01527cc7f33dfd906faf2f1941d63055c4c (diff)
downloadtext-handlebars-d6ad2d3c6ee63fc8493b47e4f4b82e1804bfac5f.tar.gz
text-handlebars-d6ad2d3c6ee63fc8493b47e4f4b82e1804bfac5f.zip
support {{@index}}
-rw-r--r--lib/Text/Xslate/Syntax/Handlebars.pm41
-rw-r--r--t/blocks.t14
2 files changed, 48 insertions, 7 deletions
diff --git a/lib/Text/Xslate/Syntax/Handlebars.pm b/lib/Text/Xslate/Syntax/Handlebars.pm
index 85dc0a0..ee4639c 100644
--- a/lib/Text/Xslate/Syntax/Handlebars.pm
+++ b/lib/Text/Xslate/Syntax/Handlebars.pm
@@ -14,7 +14,7 @@ my $nl = qr/\x0d?\x0a/;
my $bracket_string = qr/\[ [^\]]* \]/xms;
my $STRING = qr/(?: $Text::Xslate::Util::STRING | $bracket_string )/xms;
-my $single_char = '[.#^/>&;]';
+my $single_char = '[.#^/>&;@]';
my $OPERATOR_TOKEN = sprintf(
"(?:%s|$single_char)",
join('|', map{ quotemeta } qw(..))
@@ -242,6 +242,8 @@ sub init_symbols {
$self->prefix('&', 0)->set_nud($self->can('nud_mark_raw'));
$self->prefix('..', 0)->set_nud($self->can('nud_uplevel'));
+
+ $self->prefix('@', 0)->set_nud($self->can('nud_iterator'));
}
# copied from Text::Xslate::Parser, but using different definitions of
@@ -491,7 +493,7 @@ sub std_block {
),
));
- my $loop_var = $self->symbol('(variable)')->clone(id => '(block)');
+ my $loop_var = $self->symbol('(block)')->clone(arity => 'variable');
my $body_block = [
$symbol->clone(
@@ -503,11 +505,7 @@ sub std_block {
'(new_vars_for)',
$self->vars,
$name->clone,
- $self->symbol('(iterator)')->clone(
- arity => 'iterator',
- id => '$~(block)',
- first => $loop_var,
- ),
+ $self->iterator_index,
),
])
),
@@ -573,6 +571,25 @@ sub std_partial {
);
}
+sub nud_iterator {
+ my $self = shift;
+ my ($symbol) = @_;
+
+ my $token = $self->token;
+ if ($token->arity ne 'variable') {
+ $self->_unexpected('iterator variable', $token);
+ }
+
+ $self->advance;
+
+ if ($token->id eq 'index') {
+ return $self->iterator_index;
+ }
+ else {
+ $self->_error("Unknown iterator variable " . $token->id);
+ }
+}
+
sub undefined_name {
my $self = shift;
my ($name) = @_;
@@ -675,6 +692,16 @@ sub vars {
return $self->symbol('(vars)')->clone(arity => 'vars');
}
+sub iterator_index {
+ my $self = shift;
+
+ return $self->symbol('(iterator)')->clone(
+ arity => 'iterator',
+ id => '$~(block)',
+ first => $self->symbol('(block)'),
+ ),
+}
+
sub _field_to_string {
my $self = shift;
my ($symbol) = @_;
diff --git a/t/blocks.t b/t/blocks.t
index 7cc68fe..8b44e9d 100644
--- a/t/blocks.t
+++ b/t/blocks.t
@@ -47,4 +47,18 @@ render_ok(
"nested array of hashes block variable"
);
+render_ok(
+ '{{#goodbyes}}{{@index}}. {{text}}! {{/goodbyes}}cruel {{world}}!',
+ {
+ goodbyes => [
+ { text => 'goodbye' },
+ { text => 'Goodbye' },
+ { text => 'GOODBYE' },
+ ],
+ world => 'world',
+ },
+ '0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!',
+ "\@index variable"
+);
+
done_testing;