1
0
Fork 0
mirror of https://github.com/haml/haml.git synced 2022-11-09 12:33:31 -05:00

Experimental multi line implementation

This commit is contained in:
Takashi Kokubun 2015-03-10 20:01:33 +09:00
parent 13aef53a7d
commit 50cee5cf13
4 changed files with 51 additions and 3 deletions

View file

@ -30,4 +30,5 @@ Gem::Specification.new do |spec|
spec.add_development_dependency "rspec", ">= 3"
spec.add_development_dependency "slim"
spec.add_development_dependency "tenjin"
spec.add_development_dependency "unindent"
end

View file

@ -5,24 +5,45 @@ module Hamilton
def initialize(options = {})
super
@template_ast = [:multi]
@stack = []
@prev_indent = 0
end
def call(template)
template.each_line do |line|
@template_ast << parse_line(line)
scanner = StringScanner.new(line)
@indent = parse_indent(scanner)
ast = parse_line(scanner)
@stack.push(ast) if ast
@prev_indent = @indent
end
ast = compile_stack
@template_ast << ast if ast
@template_ast
end
private
def parse_line(line)
scanner = StringScanner.new(line)
def parse_indent(scanner)
spaces = scanner.scan(/ +/) || ''
raise SyntaxError if spaces.size.odd?
spaces.size / 2
end
def parse_line(scanner)
case scanner.scan(/./)
when '!'
parse_doctype(scanner)
when '%'
parse_element(scanner)
else
scanner.unscan
parse_text(scanner)
end
end
@ -43,5 +64,23 @@ module Hamilton
end
ast
end
def parse_text(scanner)
text = scanner.scan(/.+/)
return nil unless text
[:static, text]
end
def compile_stack
return nil if @stack.empty?
ast = @stack.pop
while parent = @stack.pop
parent << ast
ast = parent
end
ast
end
end
end

View file

@ -3,5 +3,12 @@ describe Hamilton::Engine do
it 'parses one-line element' do
expect(render_string('%span hello')).to eq('<span>hello</span>')
end
it 'parses multi-line element' do
expect(render_string(<<-HAML.unindent)).to eq("<span>hello</span>")
%span
hello
HAML
end
end
end

View file

@ -1,4 +1,5 @@
require 'hamilton'
require 'unindent'
module HamiltonSpecHelper
def parse_string(str)