Parse the given ‘source` into one or more Inversion::Template::Nodes and return it as an Array.
def parse( source, inherited_state=nil )
state = nil
if inherited_state
inherited_state.template = @template
state = inherited_state
else
state = Inversion::Parser::State.new( @template, self.options )
end
self.log.debug "Starting parse of template source (%0.2fK, %s)" %
[ source.bytesize/1024.0, source.encoding ]
t0 = Time.now
last_pos = last_linenum = last_colnum = 0
source.scan( TAG_PATTERN ) do |*|
match = Regexp.last_match
start_pos, end_pos = match.offset( 0 )
linenum = match.pre_match.count( "\n" ) + 1
colnum = match.pre_match.length - (match.pre_match.rindex("\n") || -1)
unless match[:tagend] == MATCHING_BRACKETS[match[:tagstart]]
raise Inversion::ParseError,
"malformed tag %p: mismatched start and end brackets at line %d, column %d" %
[ match[0], linenum, colnum ]
end
if match[0].index( TAG_OPEN, 2 )
raise Inversion::ParseError, "unclosed or nested tag %p at line %d, column %d" %
[ match[0], linenum, colnum ]
end
unless last_pos == start_pos
text = match.pre_match[ last_pos..-1 ]
state << Inversion::Template::TextNode.new( text, last_linenum, last_colnum )
end
tag = Inversion::Template::Tag.create( match[:tagname], match[:body], linenum, colnum )
if tag.nil?
unless state.options[ :ignore_unknown_tags ]
raise Inversion::ParseError, "Unknown tag %p at line %d, column %d" %
[ match[:tagname], linenum, colnum ]
end
tag = Inversion::Template::TextNode.new( match[0], linenum, colnum )
end
state << tag
last_pos = end_pos
last_linenum = linenum + match[0].count( "\n" )
last_colnum = match[0].length - ( match[0].rindex("\n") || -1 )
end
remainder = source[ last_pos..-1 ]
if remainder && !remainder.empty?
if remainder.index( "<?" ) || remainder.index( "[?" )
raise Inversion::ParseError,
"unclosed tag after line %d, column %d" % [ last_linenum, last_colnum ]
end
state << Inversion::Template::TextNode.new( remainder, last_linenum, last_colnum )
end
self.log.debug " done parsing: %0.5fs" % [ Time.now - t0 ]
return state.tree
end