Dynamic indentation for inline script

This commit is contained in:
Takashi Kokubun 2015-10-24 15:37:07 +09:00
parent 62f11c4aea
commit c462bbf6df
4 changed files with 69 additions and 6 deletions

View File

@ -1,4 +1,5 @@
require 'hamlit/compiler'
require 'pretty_hamlit/compiler/tag_compiler'
require 'pretty_hamlit/filters'
require 'pretty_hamlit/whitespace_compiler'
@ -7,6 +8,7 @@ module PrettyHamlit
def initialize(options = {})
super
@indent_level = 0
@tag_compiler = TagCompiler.new(options)
@filter_compiler = Filters.new(options)
@whitespace_compiler = WhitespaceCompiler.new
@ -31,7 +33,7 @@ module PrettyHamlit
def compile_tag(node)
@indent_level += 1
super
@tag_compiler.compile(node, @indent_level) { |n| compile_children(n) }
ensure
@indent_level -= 1
end

View File

@ -0,0 +1,39 @@
require 'hamlit/compiler/tag_compiler'
module PrettyHamlit
class Compiler < Hamlit::Compiler
class TagCompiler < Hamlit::Compiler::TagCompiler
def initialize(options = {})
super
@buffer = options[:buffer]
end
def compile(node, indent_level, &block)
attrs = compile_attributes(node)
contents = compile_contents(node, indent_level, &block)
[:html, :tag, node.value[:name], attrs, contents]
end
private
def compile_contents(node, indent_level, &block)
case
when !node.children.empty?
yield(node)
when node.value[:value].nil? && self_closing?(node)
nil
when node.value[:parse]
[:multi,
[:code, "#{@buffer} << ::PrettyHamlit::DynamicIndentation.inline_or_expand(#{indent_level}) do |#{@buffer}|"],
[:dynamic, node.value[:value]],
[:code, 'end'],
]
when Haml::Util.contains_interpolation?(node.value[:value])
[:dynamic, node.value[:value]]
else
[:static, node.value[:value]]
end
end
end
end
end

View File

@ -1,10 +1,32 @@
module PrettyHamlit
class DynamicIndentation
class << self
def indent_with(indent_level)
indent = "\n" << ' ' * indent_level
text = yield('')
text.gsub("\n", indent)
def indent_with(indent_level, &block)
text = capture(&block)
insert_indent(text, indent_level)
end
def inline_or_expand(indent_level, &block)
text = capture(&block)
return text unless text.include?("\n")
indent_space(indent_level) <<
insert_indent(text, indent_level) <<
indent_space(indent_level - 1)
end
private
def indent_space(indent_level)
"\n" << ' ' * [indent_level, 0].max
end
def insert_indent(text, indent_level)
text.gsub("\n", indent_space(indent_level))
end
def capture(&block)
block.call([]).compact.join.rstrip
end
end
end

View File

@ -222,7 +222,7 @@ HAML
assert_equal("<p>Hello</p>", render('%p Hello').chomp)
end
def test_one_liner_with_newline_shouldnt_be_one_line; skip # dynamic indentation # script bug
def test_one_liner_with_newline_shouldnt_be_one_line
assert_equal("<p>\n foo\n bar\n</p>", render('%p= "foo\nbar"').chomp)
end