mirror of
https://github.com/haml/haml.git
synced 2022-11-09 12:33:31 -05:00
[Haml] [html2haml] Use Erubis and ruby_parser to figure out where ERB blocks start and end.
This commit is contained in:
parent
a6d42ba7f3
commit
642e9de2cf
2 changed files with 89 additions and 22 deletions
|
@ -122,8 +122,8 @@ module Haml
|
|||
Haml::Util.check_encoding(template) {|msg, line| raise Haml::Error.new(msg, line)}
|
||||
|
||||
if @options[:erb]
|
||||
match_to_html(template, /<%=(.*?)-?%>/m, 'loud')
|
||||
match_to_html(template, /<%-?(.*?)-?%>/m, 'silent')
|
||||
require 'haml/html/erb'
|
||||
template = ERB.compile(template)
|
||||
end
|
||||
|
||||
method = @options[:xhtml] ? Hpricot.method(:XML) : method(:Hpricot)
|
||||
|
@ -228,7 +228,15 @@ module Haml
|
|||
|
||||
output = tabulate(tabs)
|
||||
if options[:erb] && name[0...5] == 'haml:'
|
||||
return output + send("haml_tag_#{name[5..-1]}", CGI.unescapeHTML(self.inner_text))
|
||||
case name[5..-1]
|
||||
when "loud"
|
||||
return output + "= #{CGI.unescapeHTML(inner_text).gsub(/\n\s*/, ' ').strip}\n"
|
||||
when "silent"
|
||||
return output + CGI.unescapeHTML(inner_text).split("\n").
|
||||
map {|line| "- #{line.strip}\n"}.join
|
||||
when "block"
|
||||
return render_children("", tabs, options)
|
||||
end
|
||||
end
|
||||
|
||||
output << "%#{name}" unless name == 'div' &&
|
||||
|
@ -265,12 +273,16 @@ module Haml
|
|||
end
|
||||
end
|
||||
|
||||
(self.children || []).inject(output + "\n") do |output, child|
|
||||
output + child.to_haml(tabs + 1, options)
|
||||
end
|
||||
render_children(output + "\n", tabs, options)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def render_children(so_far, tabs, options)
|
||||
(self.children || []).inject(so_far) do |output, child|
|
||||
output + child.to_haml(tabs + 1, options)
|
||||
end
|
||||
end
|
||||
|
||||
def dynamic_attributes
|
||||
@dynamic_attributes ||= begin
|
||||
|
@ -305,14 +317,6 @@ module Haml
|
|||
"#{tabulate(tabs)}:javascript\n#{content}"
|
||||
end
|
||||
|
||||
def haml_tag_loud(text)
|
||||
"= #{text.gsub(/\n\s*/, ' ').strip}\n"
|
||||
end
|
||||
|
||||
def haml_tag_silent(text)
|
||||
text.split("\n").map { |line| "- #{line.strip}\n" }.join
|
||||
end
|
||||
|
||||
def static_attribute?(name, options)
|
||||
attributes[name] and !dynamic_attribute?(name, options)
|
||||
end
|
||||
|
@ -340,13 +344,5 @@ module Haml
|
|||
"{#{attrs.join(', ')}}"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def match_to_html(string, regex, tag)
|
||||
string.gsub!(regex) do
|
||||
"<haml:#{tag}>#{CGI.escapeHTML($1)}</haml:#{tag}>"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
71
lib/haml/html/erb.rb
Normal file
71
lib/haml/html/erb.rb
Normal file
|
@ -0,0 +1,71 @@
|
|||
require 'cgi'
|
||||
require 'erubis'
|
||||
require 'ruby_parser'
|
||||
|
||||
module Haml
|
||||
class HTML
|
||||
class ERB < Erubis::Basic::Engine
|
||||
def self.compile(template)
|
||||
new(template).src
|
||||
end
|
||||
|
||||
def escaped_expr(code)
|
||||
raise "html2haml doesn't support escaped expressions."
|
||||
end
|
||||
|
||||
def add_preamble(src); end
|
||||
def add_postamble(src); end
|
||||
|
||||
def add_text(src, text)
|
||||
src << text
|
||||
end
|
||||
|
||||
def add_stmt(src, code)
|
||||
src << '</haml:block>' if block_closer?(code) || mid_block?(code)
|
||||
src << '<haml:silent>' << h(code) << '</haml:silent>' unless code.strip == "end"
|
||||
src << '<haml:block>' if block_opener?(code) || mid_block?(code)
|
||||
end
|
||||
|
||||
def add_expr_literal(src, code)
|
||||
src << '<haml:loud>' << h(code) << '</haml:loud>'
|
||||
src << '<haml:block>' if block_opener?(code)
|
||||
end
|
||||
|
||||
def add_expr_debug(src, code)
|
||||
raise "html2haml doesn't support debugging expressions."
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def h(code)
|
||||
CGI.escapeHTML(code)
|
||||
end
|
||||
|
||||
# Returns whether the code is valid Ruby code on its own
|
||||
def valid_ruby?(code)
|
||||
RubyParser.new.parse(code)
|
||||
rescue Racc::ParseError => e
|
||||
false
|
||||
end
|
||||
|
||||
# Checks if the Ruby code opens a block
|
||||
def block_opener?(code)
|
||||
valid_ruby?(code + "\nend") ||
|
||||
valid_ruby?(code + "\nwhen foo\nend")
|
||||
end
|
||||
|
||||
# Checks if the Ruby code closes a block
|
||||
def block_closer?(code)
|
||||
valid_ruby?("begin\n" + code)
|
||||
end
|
||||
|
||||
# Checks if the Ruby code comes in the middle of a block
|
||||
def mid_block?(code)
|
||||
return if valid_ruby?(code)
|
||||
valid_ruby?("if foo\n#{code}\nend") || # else, elsif
|
||||
valid_ruby?("begin\n#{code}\nend") || # rescue, ensure
|
||||
valid_ruby?("case foo\n#{code}\nend") # when
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Add table
Reference in a new issue