Skip to content

Commit

Permalink
Merge pull request #140 from josh/parser-line-offsets
Browse files Browse the repository at this point in the history
Add line offsets to parser ast
  • Loading branch information
pvande committed Jul 24, 2012
2 parents 228bea9 + cc9c518 commit 69702ca
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 14 deletions.
10 changes: 5 additions & 5 deletions lib/mustache/generator.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def compile!(exp)


# Callback fired when the compiler finds a section token. We're # Callback fired when the compiler finds a section token. We're
# passed the section name and the array of tokens. # passed the section name and the array of tokens.
def on_section(name, content, raw, delims) def on_section(name, offset, content, raw, delims)
# Convert the tokenized content of this section into a Ruby # Convert the tokenized content of this section into a Ruby
# string we can use. # string we can use.
code = compile(content) code = compile(content)
Expand Down Expand Up @@ -121,7 +121,7 @@ def t.tokens(src=@source)


# Fired when we find an inverted section. Just like `on_section`, # Fired when we find an inverted section. Just like `on_section`,
# we're passed the inverted section name and the array of tokens. # we're passed the inverted section name and the array of tokens.
def on_inverted_section(name, content, raw, _) def on_inverted_section(name, offset, content, raw, delims)
# Convert the tokenized content of this section into a Ruby # Convert the tokenized content of this section into a Ruby
# string we can use. # string we can use.
code = compile(content) code = compile(content)
Expand All @@ -139,12 +139,12 @@ def on_inverted_section(name, content, raw, _)
# Fired when the compiler finds a partial. We want to return code # Fired when the compiler finds a partial. We want to return code
# which calls a partial at runtime instead of expanding and # which calls a partial at runtime instead of expanding and
# including the partial's body to allow for recursive partials. # including the partial's body to allow for recursive partials.
def on_partial(name, indentation) def on_partial(name, offset, indentation)
ev("ctx.partial(#{name.to_sym.inspect}, #{indentation.inspect})") ev("ctx.partial(#{name.to_sym.inspect}, #{indentation.inspect})")
end end


# An unescaped tag. # An unescaped tag.
def on_utag(name) def on_utag(name, offset)
ev(<<-compiled) ev(<<-compiled)
v = #{compile!(name)} v = #{compile!(name)}
if v.is_a?(Proc) if v.is_a?(Proc)
Expand All @@ -155,7 +155,7 @@ def on_utag(name)
end end


# An escaped tag. # An escaped tag.
def on_etag(name) def on_etag(name, offset)
ev(<<-compiled) ev(<<-compiled)
v = #{compile!(name)} v = #{compile!(name)}
if v.is_a?(Proc) if v.is_a?(Proc)
Expand Down
14 changes: 9 additions & 5 deletions lib/mustache/parser.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -146,12 +146,12 @@ def scan_tags
case type case type
when '#' when '#'
block = [:multi] block = [:multi]
@result << [:mustache, :section, fetch, block] @result << [:mustache, :section, fetch, offset, block]
@sections << [content, position, @result] @sections << [content, position, @result]
@result = block @result = block
when '^' when '^'
block = [:multi] block = [:multi]
@result << [:mustache, :inverted_section, fetch, block] @result << [:mustache, :inverted_section, fetch, offset, block]
@sections << [content, position, @result] @sections << [content, position, @result]
@result = block @result = block
when '/' when '/'
Expand All @@ -169,14 +169,14 @@ def scan_tags
when '=' when '='
self.otag, self.ctag = content.split(' ', 2) self.otag, self.ctag = content.split(' ', 2)
when '>', '<' when '>', '<'
@result << [:mustache, :partial, content, padding] @result << [:mustache, :partial, content, offset, padding]
when '{', '&' when '{', '&'
# The closing } in unescaped tags is just a hack for # The closing } in unescaped tags is just a hack for
# aesthetics. # aesthetics.
type = "}" if type == "{" type = "}" if type == "{"
@result << [:mustache, :utag, fetch] @result << [:mustache, :utag, fetch, offset]
else else
@result << [:mustache, :etag, fetch] @result << [:mustache, :etag, fetch, offset]
end end


# Skip whitespace and any balancing sigils after the content # Skip whitespace and any balancing sigils after the content
Expand Down Expand Up @@ -234,6 +234,10 @@ def scan_until_exclusive(regexp)
end end
end end


def offset
position[0, 2]
end

# Returns [lineno, column, line] # Returns [lineno, column, line]
def position def position
# The rest of the current line # The rest of the current line
Expand Down
13 changes: 9 additions & 4 deletions test/parser_test.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -22,29 +22,32 @@ def test_parser


expected = [:multi, expected = [:multi,
[:static, "<h1>"], [:static, "<h1>"],
[:mustache, :etag, [:mustache, :fetch, ["header"]]], [:mustache, :etag, [:mustache, :fetch, ["header"]], [1, 11]],
[:static, "</h1>\n"], [:static, "</h1>\n"],
[:mustache, [:mustache,
:section, :section,
[:mustache, :fetch, ["items"]], [:mustache, :fetch, ["items"]],
[2, 7],
[:multi, [:multi,
[:mustache, [:mustache,
:section, :section,
[:mustache, :fetch, ["first"]], [:mustache, :fetch, ["first"]],
[3, 7],
[:multi, [:multi,
[:static, " <li><strong>"], [:static, " <li><strong>"],
[:mustache, :etag, [:mustache, :fetch, ["name"]]], [:mustache, :etag, [:mustache, :fetch, ["name"]], [4, 19]],
[:static, "</strong></li>\n"]], [:static, "</strong></li>\n"]],
%Q' <li><strong>{{name}}</strong></li>\n', %Q' <li><strong>{{name}}</strong></li>\n',
%w[{{ }}]], %w[{{ }}]],
[:mustache, [:mustache,
:section, :section,
[:mustache, :fetch, ["link"]], [:mustache, :fetch, ["link"]],
[6, 6],
[:multi, [:multi,
[:static, " <li><a href=\""], [:static, " <li><a href=\""],
[:mustache, :etag, [:mustache, :fetch, ["url"]]], [:mustache, :etag, [:mustache, :fetch, ["url"]], [7, 19]],
[:static, "\">"], [:static, "\">"],
[:mustache, :etag, [:mustache, :fetch, ["name"]]], [:mustache, :etag, [:mustache, :fetch, ["name"]], [7, 29]],
[:static, "</a></li>\n"]], [:static, "</a></li>\n"]],
%Q' <li><a href="{{url}}">{{name}}</a></li>\n', %Q' <li><a href="{{url}}">{{name}}</a></li>\n',
%w[{{ }}]]], %w[{{ }}]]],
Expand All @@ -54,6 +57,7 @@ def test_parser
[:mustache, [:mustache,
:section, :section,
[:mustache, :fetch, ["empty"]], [:mustache, :fetch, ["empty"]],
[11, 7],
[:multi, [:static, "<p>The list is empty.</p>\n"]], [:multi, [:static, "<p>The list is empty.</p>\n"]],
%Q'<p>The list is empty.</p>\n', %Q'<p>The list is empty.</p>\n',
%w[{{ }}]]] %w[{{ }}]]]
Expand All @@ -69,6 +73,7 @@ def test_raw_content_and_whitespace
[:mustache, [:mustache,
:section, :section,
[:mustache, :fetch, ["list"]], [:mustache, :fetch, ["list"]],
[1, 6],
[:multi, [:static, "\t"]], [:multi, [:static, "\t"]],
"\t", "\t",
%w[{{ }}]]] %w[{{ }}]]]
Expand Down

0 comments on commit 69702ca

Please sign in to comment.