Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #14 from carloslima/add-line-number-to-tape

Add line number to tape
  • Loading branch information...
commit 683ebdaa1aaf61fe38d1d7cc68b0681ac546530c 2 parents 3c6de74 + 6574664
@vti authored
Showing with 284 additions and 220 deletions.
  1. +13 −1 lib/Text/Haml.pm
  2. +271 −219 t/parse.t
View
14 lib/Text/Haml.pm
@@ -262,7 +262,7 @@ sub parse {
$level = 0;
}
- my $el = {level => $level, type => 'text', line => $line};
+ my $el = {level => $level, type => 'text', line => $line, lineno => $i+1};
# Haml comment
if ($line =~ m/^$comment_token(?: (.*))?/) {
@@ -281,6 +281,7 @@ sub parse {
$prev->{text} .= "\n" if $prev->{text};
$prev->{text} .= $line;
$prev->{line} .= "\n" . (' ' x $el->{level}) . $el->{line};
+ _update_lineno($prev, $i);
next;
}
}
@@ -402,6 +403,7 @@ sub parse {
if (!$line) {
$line = $lines[++$i] || last;
$el->{line} .= "\n$line";
+ _update_lineno($el, $i);
}
elsif ($type eq 'perl' && $line =~ s/^$attributes_end//) {
last;
@@ -510,6 +512,7 @@ sub parse {
my $prev_stack_el = $tape->[-1];
push @{$prev_stack_el->{text}}, $line;
$prev_stack_el->{line} .= "\n" . $line . "$1|";
+ _update_lineno($prev_stack_el, $i);
}
}
@@ -527,6 +530,15 @@ sub parse {
}
}
+# Updates lineno entry on the tape element
+# for itens spanning more than one line
+sub _update_lineno {
+ my ($el, $lineno) = @_;
+ $lineno++; # report line numbers starting at 1 instead of 0
+ $el->{lineno} =~ s/^(\d+)(?:-\d+)?/$1-$lineno/;
+ return;
+}
+
sub build {
my $self = shift;
my %vars = @_;
View
490 t/parse.t
@@ -18,15 +18,16 @@ is_deeply($haml->tape, []);
$haml->parse(' ');
is_deeply(
$haml->tape,
- [ { 'level' => 3,
- 'type' => 'text',
- 'line' => ''
+ [ { 'level' => 3,
+ 'type' => 'text',
+ 'line' => '',
+ 'lineno' => 1,
}
]
);
$haml->parse("\n");
-is_deeply($haml->tape, [{type => 'text', level => 0, line => ''}]);
+is_deeply($haml->tape, [{type => 'text', level => 0, line => '', lineno => 1}]);
$haml->parse(<<'EOF');
%a{href => 'foo', target => "_blank", title => help_me, do => true}
@@ -35,29 +36,31 @@ $haml->parse(<<'EOF');
EOF
is_deeply(
$haml->tape,
- [ { type => 'tag',
- level => 0,
- name => 'a',
- attrs => [
+ [ { type => 'tag',
+ level => 0,
+ name => 'a',
+ attrs => [
href => {type => 'text', text => 'foo'},
target => {type => 'text', text => '_blank'},
title => {type => 'expr', text => 'help_me'},
do => {type => 'boolean', text => 1}
],
- line =>
- qq/%a{href => 'foo', target => "_blank", title => help_me, do => true}/
+ line =>
+ qq/%a{href => 'foo', target => "_blank", title => help_me, do => true}/,
+ lineno => 1,
},
- { type => 'tag',
- level => 0,
- name => 'script',
- attrs => [
+ { type => 'tag',
+ level => 0,
+ name => 'script',
+ attrs => [
type => {type => 'text', text => 'text/javascript'},
src => {type => 'text', text => 'javascripts/script.js'}
],
- line =>
- qq|%script{:type => "text/javascript",\n :src => "javascripts/script.js"}|
+ line =>
+ qq|%script{:type => "text/javascript",\n :src => "javascripts/script.js"}|,
+ lineno => '2-3',
},
- {type => 'text', level => 0, line => ''}
+ {type => 'text', level => 0, line => '', lineno => 4}
]
);
@@ -68,29 +71,31 @@ $haml->parse(<<'EOF');
EOF
is_deeply(
$haml->tape,
- [ { type => 'tag',
- level => 0,
- name => 'a',
- attrs => [
+ [ { type => 'tag',
+ level => 0,
+ name => 'a',
+ attrs => [
href => {type => 'text', text => 'foo'},
target => {type => 'text', text => '_blank'},
title => {type => 'expr', text => 'help_me'},
do => {type => 'boolean', text => 1}
],
- line =>
- qq/%a(href = 'foo' target = "_blank" title = help_me do = true)/
+ line =>
+ qq/%a(href = 'foo' target = "_blank" title = help_me do = true)/,
+ lineno => 1,
},
- { type => 'tag',
- level => 0,
- name => 'script',
- attrs => [
+ { type => 'tag',
+ level => 0,
+ name => 'script',
+ attrs => [
type => {type => 'text', text => 'text/javascript'},
src => {type => 'text', text => 'javascripts/script.js'}
],
- line =>
- qq|%script(type = "text/javascript"\n src = "javascripts/script.js")|
+ line =>
+ qq|%script(type = "text/javascript"\n src = "javascripts/script.js")|,
+ lineno => '2-3',
},
- {type => 'text', level => 0, line => ''}
+ {type => 'text', level => 0, line => '', lineno => 4}
]
);
@@ -102,31 +107,35 @@ $haml->parse(<<'EOF');
EOF
is_deeply(
$haml->tape,
- [ { type => 'tag',
- level => 0,
- name => 'a',
- attrs => [foo => {type => 'text', text => '#{bar}'}],
- line => '%a{:foo => "#{bar}"}'
+ [ { type => 'tag',
+ level => 0,
+ name => 'a',
+ attrs => [foo => {type => 'text', text => '#{bar}'}],
+ line => '%a{:foo => "#{bar}"}',
+ lineno => 1,
},
- { type => 'tag',
- level => 0,
- name => 'a',
- attrs => [bar => {type => 'text', text => "b'az"}],
- line => q/%a{:bar => "b'az"}/
+ { type => 'tag',
+ level => 0,
+ name => 'a',
+ attrs => [bar => {type => 'text', text => "b'az"}],
+ line => q/%a{:bar => "b'az"}/,
+ lineno => 2,
},
- { type => 'tag',
- level => 0,
- name => 'a',
- attrs => [bar => {type => 'text', text => 'b"az'}],
- line => q/%a{:bar => "b\"az"}/
+ { type => 'tag',
+ level => 0,
+ name => 'a',
+ attrs => [bar => {type => 'text', text => 'b"az'}],
+ line => q/%a{:bar => "b\"az"}/,
+ lineno => 3,
},
- { type => 'tag',
- level => 0,
- name => 'a',
- attrs => [bar => {type => 'text', text => 'baz\\'}],
- line => q/%a{:bar => "baz\\"}/
+ { type => 'tag',
+ level => 0,
+ name => 'a',
+ attrs => [bar => {type => 'text', text => 'baz\\'}],
+ line => q/%a{:bar => "baz\\"}/,
+ lineno => 4,
},
- {type => 'text', level => 0, line => ''}
+ {type => 'text', level => 0, line => '', lineno => 5}
]
);
@@ -140,56 +149,62 @@ $haml->parse(<<'EOF');
EOF
is_deeply(
$haml->tape,
- [ {type => 'tag', level => 0, name => 'gee', line => '%gee'},
- { type => 'tag',
- level => 2,
- name => 'div',
- class => [qw/class class2/],
- id => 'id',
- attrs => [foo => {type => 'text', text => 'bar'}],
- line => ".class.class2#id{foo => 'bar'}"
- },
- { type => 'tag',
- level => 4,
- name => 'baz',
- expr => 1,
- text => '1 + 2',
- line => '%baz= 1 + 2'
+ [ {type => 'tag', level => 0, name => 'gee', line => '%gee', lineno => 1},
+ { type => 'tag',
+ level => 2,
+ name => 'div',
+ class => [qw/class class2/],
+ id => 'id',
+ attrs => [foo => {type => 'text', text => 'bar'}],
+ line => ".class.class2#id{foo => 'bar'}",
+ lineno => 2,
+ },
+ { type => 'tag',
+ level => 4,
+ name => 'baz',
+ expr => 1,
+ text => '1 + 2',
+ line => '%baz= 1 + 2',
+ lineno => 3,
},
- { type => 'text',
- level => 6,
- text => 'Wow this is cool!',
- line => 'Wow this is cool!'
- },
- { type => 'tag',
- level => 6,
- name => 'a',
- attrs => [
+ { type => 'text',
+ level => 6,
+ text => 'Wow this is cool!',
+ line => 'Wow this is cool!',
+ lineno => 4,
+ },
+ { type => 'tag',
+ level => 6,
+ name => 'a',
+ attrs => [
href => {type => 'text', text => 'foo'},
name => {
type => 'expr',
text => 'helper'
}
],
- text => 'Link',
- line => "%a{href => 'foo', name => helper} Link"
- },
- { type => 'tag',
- level => 6,
- name => 'a',
- attrs => [
+ text => 'Link',
+ line => "%a{href => 'foo', name => helper} Link",
+ lineno => 5,
+ },
+ { type => 'tag',
+ level => 6,
+ name => 'a',
+ attrs => [
href => {type => 'text', text => 'foo'},
name => {
type => 'expr',
text => 'helper'
}
],
- text => 'Link',
- line => q/%a(href="foo" name=helper) Link/
+ text => 'Link',
+ line => q/%a(href="foo" name=helper) Link/,
+ lineno => 6,
},
- { type => 'text',
- level => 0,
- line => ''
+ { type => 'text',
+ level => 0,
+ line => '',
+ lineno => 7,
}
]
);
@@ -200,21 +215,24 @@ $haml->parse(<<'EOF');
EOF
is_deeply(
$haml->tape,
- [ { type => 'tag',
- level => 0,
- name => 'b',
- attrs => [foo => {type => 'boolean', text => 1}],
- line => q/%b(foo=true)/
+ [ { type => 'tag',
+ level => 0,
+ name => 'b',
+ attrs => [foo => {type => 'boolean', text => 1}],
+ line => q/%b(foo=true)/,
+ lineno => 1,
},
- { type => 'tag',
- level => 0,
- name => 'b',
- attrs => [foo => {type => 'boolean', text => 0}],
- line => q/%b{:foo=>false}/
+ { type => 'tag',
+ level => 0,
+ name => 'b',
+ attrs => [foo => {type => 'boolean', text => 0}],
+ line => q/%b{:foo=>false}/,
+ lineno => 2,
},
- { type => 'text',
- level => 0,
- line => ''
+ { type => 'text',
+ level => 0,
+ line => '',
+ lineno => 3,
}
]
);
@@ -226,27 +244,31 @@ $haml->parse(<<'EOF');
EOF
is_deeply(
$haml->tape,
- [ { type => 'tag',
- level => 0,
- name => 'blockquote',
- trim_in => 1,
- line => '%blockquote<'
+ [ { type => 'tag',
+ level => 0,
+ name => 'blockquote',
+ trim_in => 1,
+ line => '%blockquote<',
+ lineno => 1,
},
- { type => 'tag',
- level => 2,
- name => 'foo',
- line => '%foo'
+ { type => 'tag',
+ level => 2,
+ name => 'foo',
+ line => '%foo',
+ lineno => 2,
},
{ type => 'tag',
level => 2,
name => 'bar',
trim_out => 1,
text => 'trim out',
- line => '%bar> trim out'
+ line => '%bar> trim out',
+ lineno => 3,
},
- { type => 'text',
- level => 0,
- line => ''
+ { type => 'text',
+ level => 0,
+ line => '',
+ lineno => 4,
}
]
);
@@ -259,30 +281,35 @@ $haml->parse(<<'EOF');
EOF
is_deeply(
$haml->tape,
- [ { type => 'comment',
- level => 0,
- text => 'haml comment',
- line => '-# haml comment'
- },
- { type => 'text',
- level => 2,
- text => '= "just text"',
- line => '\= "just text"'
- },
- { type => 'html_comment',
- level => 2,
- text => 'html comment',
- line => '/ html comment'
+ [ { type => 'comment',
+ level => 0,
+ text => 'haml comment',
+ line => '-# haml comment',
+ lineno => 1,
},
- { type => 'html_comment',
- level => 2,
- if => 'IE',
- text => 'if html comment',
- line => '/[if IE] if html comment'
+ { type => 'text',
+ level => 2,
+ text => '= "just text"',
+ line => '\= "just text"',
+ lineno => 2,
+ },
+ { type => 'html_comment',
+ level => 2,
+ text => 'html comment',
+ line => '/ html comment',
+ lineno => 3,
+ },
+ { type => 'html_comment',
+ level => 2,
+ if => 'IE',
+ text => 'if html comment',
+ line => '/[if IE] if html comment',
+ lineno => 4,
},
- { type => 'text',
- level => 0,
- line => ''
+ { type => 'text',
+ level => 0,
+ line => '',
+ lineno => 5,
}
]
);
@@ -295,19 +322,22 @@ normal
EOF
is_deeply(
$haml->tape,
- [ { type => 'text',
- level => 0,
- text => 'multiline comment parsing',
- line => "multiline |\ncomment |\nparsing |"
+ [ { type => 'text',
+ level => 0,
+ text => 'multiline comment parsing',
+ line => "multiline |\ncomment |\nparsing |",
+ lineno => '1-3',
},
- { type => 'text',
- level => 0,
- text => 'normal',
- line => 'normal'
+ { type => 'text',
+ level => 0,
+ text => 'normal',
+ line => 'normal',
+ lineno => 4,
},
- { type => 'text',
- level => 0,
- line => ''
+ { type => 'text',
+ level => 0,
+ line => '',
+ lineno => 5,
}
]
);
@@ -320,20 +350,23 @@ normal
EOF
is_deeply(
$haml->tape,
- [ { type => 'tag',
- level => 0,
- name => 'p',
- text => 'multiline comment parsing',
- line => "%p multiline |\ncomment |\nparsing |"
+ [ { type => 'tag',
+ level => 0,
+ name => 'p',
+ text => 'multiline comment parsing',
+ line => "%p multiline |\ncomment |\nparsing |",
+ lineno => '1-3',
},
- { type => 'text',
- level => 0,
- text => 'normal',
- line => 'normal'
+ { type => 'text',
+ level => 0,
+ text => 'normal',
+ line => 'normal',
+ lineno => 4,
},
- { type => 'text',
- level => 0,
- line => ''
+ { type => 'text',
+ level => 0,
+ line => '',
+ lineno => 5,
}
]
);
@@ -348,17 +381,20 @@ is_deeply(
level => 0,
name => 'img',
autoclose => 1,
- line => '%img'
+ line => '%img',
+ lineno => 1,
},
{ type => 'tag',
level => 0,
name => 'a',
autoclose => 1,
- line => '%a/'
+ line => '%a/',
+ lineno => 2,
},
- { type => 'text',
- level => 0,
- line => ''
+ { type => 'text',
+ level => 0,
+ line => '',
+ lineno => 3,
}
]
);
@@ -371,33 +407,38 @@ $haml->parse(<<'EOF');
EOF
is_deeply(
$haml->tape,
- [ { type => 'text',
- level => 0,
- expr => 1,
- text => '1 + 2',
- line => '= 1 + 2'
+ [ { type => 'text',
+ level => 0,
+ expr => 1,
+ text => '1 + 2',
+ line => '= 1 + 2',
+ lineno => 1,
},
- { type => 'block',
- level => 0,
- text => '"foo"',
- line => '- "foo"'
+ { type => 'block',
+ level => 0,
+ text => '"foo"',
+ line => '- "foo"',
+ lineno => 2,
},
- { type => 'text',
- level => 0,
- expr => 1,
- text => '$foo->{bar}',
- line => '= $foo->{bar}'
+ { type => 'text',
+ level => 0,
+ expr => 1,
+ text => '$foo->{bar}',
+ line => '= $foo->{bar}',
+ lineno => 3,
},
- { type => 'tag',
- level => 0,
- name => 'p',
- expr => 1,
- text => '$i',
- line => '%p= $i'
+ { type => 'tag',
+ level => 0,
+ name => 'p',
+ expr => 1,
+ text => '$i',
+ line => '%p= $i',
+ lineno => 4,
},
- { type => 'text',
- level => 0,
- line => ''
+ { type => 'text',
+ level => 0,
+ line => '',
+ lineno => 5,
}
]
);
@@ -409,29 +450,33 @@ $haml->parse(<<'EOF');
EOF
is_deeply(
$haml->tape,
- [ { type => 'text',
- level => 0,
- expr => 1,
- text => "'foo' if 1",
- line => "= 'foo' if 1"
+ [ { type => 'text',
+ level => 0,
+ expr => 1,
+ text => "'foo' if 1",
+ line => "= 'foo' if 1",
+ lineno => 1,
},
{ type => 'text',
level => 0,
expr => 1,
escape => 1,
text => "'<escape>'",
- line => "&= '<escape>'"
+ line => "&= '<escape>'",
+ lineno => 2,
},
{ type => 'text',
level => 0,
expr => 1,
escape => 0,
text => "'<noescape>'",
- line => "!= '<noescape>'"
+ line => "!= '<noescape>'",
+ lineno => 3,
},
- { type => 'text',
- level => 0,
- line => ''
+ { type => 'text',
+ level => 0,
+ line => '',
+ lineno => 4,
}
]
);
@@ -443,15 +488,17 @@ $haml->parse(<<'EOF');
EOF
is_deeply(
$haml->tape,
- [ {type => 'tag', level => 0, name => 'foo', line => '%foo'},
- { type => 'text',
- level => 0,
- line => ''
+ [ {type => 'tag', level => 0, name => 'foo', line => '%foo', lineno => 1},
+ { type => 'text',
+ level => 0,
+ line => '',
+ lineno => 2,
},
- {type => 'tag', level => 0, name => 'bar', line => '%bar'},
- { type => 'text',
- level => 0,
- line => ''
+ {type => 'tag', level => 0, name => 'bar', line => '%bar', lineno => 3},
+ { type => 'text',
+ level => 0,
+ line => '',
+ lineno => 4,
}
]
);
@@ -466,11 +513,13 @@ is_deeply(
text => '"Foo\n<pre>Bar\nBaz</pre>"',
expr => 1,
preserve_whitespace => 1,
- line => '~ "Foo\n<pre>Bar\nBaz</pre>"'
+ line => '~ "Foo\n<pre>Bar\nBaz</pre>"',
+ lineno => 1,
},
{ type => 'text',
level => 0,
- line => ''
+ line => '',
+ lineno=> 2,
}
]
);
@@ -485,21 +534,24 @@ $haml->parse(<<'EOF');
EOF
is_deeply(
$haml->tape,
- [ { type => 'filter',
- level => 0,
- name => 'escaped',
- text => '<foo>',
- line => ":escaped\n <foo>"
+ [ { type => 'filter',
+ level => 0,
+ name => 'escaped',
+ text => '<foo>',
+ line => ":escaped\n <foo>",
+ lineno => '1-2',
},
- { type => 'filter',
- level => 0,
- name => 'preserve',
- text => "Hello\n\nthere.",
- line => ":preserve\n Hello\n\n there."
+ { type => 'filter',
+ level => 0,
+ name => 'preserve',
+ text => "Hello\n\nthere.",
+ line => ":preserve\n Hello\n\n there.",
+ lineno => '3-6',
},
- { type => 'text',
- level => 0,
- line => ''
+ { type => 'text',
+ level => 0,
+ line => '',
+ lineno => 7,
}
]
);
Please sign in to comment.
Something went wrong with that request. Please try again.