lib/faml/parser.rb in faml-0.2.6 vs lib/faml/parser.rb in faml-0.2.7
- old
+ new
@@ -16,11 +16,11 @@
end
def call(template_str)
@ast = Ast::Root.new
@stack = []
- @line_parser = LineParser.new(template_str)
+ @line_parser = LineParser.new(@filename, template_str)
@indent_tracker = IndentTracker.new(on_enter: method(:indent_enter), on_leave: method(:indent_leave))
@filter_parser = FilterParser.new(@indent_tracker)
while @line_parser.has_next?
line = @line_parser.next_line
@@ -61,16 +61,16 @@
def parse_line(line)
text, indent = @indent_tracker.process(line, @line_parser.lineno)
if text.empty?
- @ast << Ast::Empty.new
+ @ast << create_node(Ast::Empty)
return
end
if @ast.is_a?(Ast::HamlComment)
- @ast << Ast::Text.new(text)
+ @ast << create_node(Ast::Text) { |t| t.text = text }
return
end
case text[0]
when ESCAPE_PREFIX
@@ -99,16 +99,16 @@
parse_script(text)
end
end
def parse_doctype(text)
- @ast << Ast::Doctype.new(text[3 .. -1].strip)
+ @ast << create_node(Ast::Doctype) { |d| d.doctype = text[3 .. -1].strip }
end
def parse_comment(text)
text = text[1, text.size-1].strip
- comment = Ast::HtmlComment.new
+ comment = create_node(Ast::HtmlComment)
comment.comment = text
if text[0] == '['
comment.conditional, rest = parse_conditional_comment(text)
text.replace(rest)
end
@@ -126,11 +126,11 @@
syntax_error!('Unmatched brackets in conditional comment')
end
end
def parse_plain(text)
- @ast << Ast::Text.new(text)
+ @ast << create_node(Ast::Text) { |t| t.text = text }
end
def parse_element(text)
@ast << ElementParser.new(@line_parser).parse(text)
end
@@ -139,27 +139,28 @@
@ast << ScriptParser.new(@line_parser).parse(text)
end
def parse_silent_script(text)
if text.start_with?('-#')
- @ast << Ast::HamlComment.new
+ @ast << create_node(Ast::HamlComment)
return
end
- script = text[/\A- *(.*)\z/, 1]
- if script.empty?
+ node = create_node(Ast::SilentScript)
+ node.script = text[/\A- *(.*)\z/, 1]
+ if node.script.empty?
syntax_error!("No Ruby code to evaluate")
end
- script += RubyMultiline.read(@line_parser, script)
- @ast << Ast::SilentScript.new([], script)
+ node.script += RubyMultiline.read(@line_parser, node.script)
+ @ast << node
end
def parse_filter(text)
filter_name = text[/\A#{FILTER_PREFIX}(\w+)\z/, 1]
unless filter_name
syntax_error!("Invalid filter name: #{text}")
end
- @filter_parser.start(filter_name)
+ @filter_parser.start(filter_name, @line_parser.filename, @line_parser.lineno)
end
def indent_enter(_, text)
empty_lines = []
while @ast.children.last.is_a?(Ast::Empty)
@@ -211,8 +212,18 @@
MID_BLOCK_KEYWORDS.include?(block_keyword(text))
end
def syntax_error!(message)
raise SyntaxError.new(message, @line_parser.lineno)
+ end
+
+ def create_node(klass, &block)
+ klass.new.tap do |node|
+ node.filename = @line_parser.filename
+ node.lineno = @line_parser.lineno
+ if block
+ block.call(node)
+ end
+ end
end
end
end