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

Parse multiline

This commit is contained in:
Takashi Kokubun 2015-03-16 08:11:07 +09:00
parent 0cd2ee9f02
commit c9bcc34fb3
6 changed files with 130 additions and 2 deletions

View file

@ -6,6 +6,10 @@ module Hamlit
@current_lineno = -1
end
def current_line
@lines[@current_lineno]
end
# Return nearest line ignoring empty lines.
def next_line
lineno = @current_lineno + 1

View file

@ -1,12 +1,14 @@
require 'temple'
require 'hamlit/attribute_compiler'
require 'hamlit/script_compiler'
require 'hamlit/multiline_preprocessor'
require 'hamlit/parser'
require 'hamlit/script_compiler'
module Hamlit
class Engine < Temple::Engine
define_options generator: Temple::Generators::ArrayBuffer
use MultilinePreprocessor
use Parser
use ScriptCompiler
use AttributeCompiler

View file

@ -0,0 +1,56 @@
require 'temple'
require 'hamlit/concerns/line_reader'
module Hamlit
class MultilinePreprocessor < Temple::Parser
include Concerns::LineReader
def call(template)
reset_lines(template.split("\n"))
preprocess_multilines
end
private
def preprocess_multilines
result = []
while @lines[@current_lineno + 1]
@current_lineno += 1
if end_with_pipe?(current_line)
prefix = current_line[/\A */]
lines = scan_multilines
result << prefix + build_multiline(lines)
(lines.length - 1).times { result << '' }
else
result << current_line
end
end
result.map { |line| "#{line}\n" }.join
end
def end_with_pipe?(line)
return false unless line
line.strip =~ / \|\Z/
end
def scan_multilines
lines = []
while end_with_pipe?(current_line)
lines << current_line
@current_lineno += 1
end
@current_lineno -= 1
lines
end
def build_multiline(lines)
lines = lines.map do |line|
line.strip.gsub(/ *\|\Z/, '')
end
lines.join(' ')
end
end
end

View file

@ -39,7 +39,7 @@ module Hamlit
ast = []
while next_indent == @current_indent
@current_lineno += 1
ast << parse_line(@lines[@current_lineno])
ast << parse_line(current_line)
ast << [:static, "\n"] unless skip_newline?(ast.last)
ast << [:newline]
end

View file

@ -0,0 +1,24 @@
describe Hamlit::Engine do
describe 'multiline' do
it 'joins multi-lines ending with pipe' do
assert_render(<<-HAML, <<-HTML)
a |
b |
HAML
a b
HTML
end
it 'renders multi lines' do
assert_render(<<-HAML, <<-HTML)
= 'a' + |
'b' + |
'c' |
'd'
HAML
abc
'd'
HTML
end
end
end

View file

@ -0,0 +1,42 @@
describe Hamlit::MultilinePreprocessor do
describe '#call' do
def assert_multiline_preprocess(before, after)
result = described_class.new.call(before)
expect(result).to eq(after)
end
it 'does not alter normal lines' do
assert_multiline_preprocess(<<-HAML, <<-HAML)
abc
d|
ef
HAML
abc
d|
ef
HAML
end
it 'joins multi-lines' do
assert_multiline_preprocess(<<-HAML, <<-HAML)
abc |
d |
ef
HAML
abc d
ef
HAML
end
it 'joins multi-lines' do
assert_multiline_preprocess(<<-HAML, <<-HAML)
= 'a' + |
'b' |
HAML
= 'a' + 'b'
HAML
end
end
end