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)}
|
Haml::Util.check_encoding(template) {|msg, line| raise Haml::Error.new(msg, line)}
|
||||||
|
|
||||||
if @options[:erb]
|
if @options[:erb]
|
||||||
match_to_html(template, /<%=(.*?)-?%>/m, 'loud')
|
require 'haml/html/erb'
|
||||||
match_to_html(template, /<%-?(.*?)-?%>/m, 'silent')
|
template = ERB.compile(template)
|
||||||
end
|
end
|
||||||
|
|
||||||
method = @options[:xhtml] ? Hpricot.method(:XML) : method(:Hpricot)
|
method = @options[:xhtml] ? Hpricot.method(:XML) : method(:Hpricot)
|
||||||
|
@ -228,7 +228,15 @@ module Haml
|
||||||
|
|
||||||
output = tabulate(tabs)
|
output = tabulate(tabs)
|
||||||
if options[:erb] && name[0...5] == 'haml:'
|
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
|
end
|
||||||
|
|
||||||
output << "%#{name}" unless name == 'div' &&
|
output << "%#{name}" unless name == 'div' &&
|
||||||
|
@ -265,12 +273,16 @@ module Haml
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
(self.children || []).inject(output + "\n") do |output, child|
|
render_children(output + "\n", tabs, options)
|
||||||
output + child.to_haml(tabs + 1, options)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
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
|
def dynamic_attributes
|
||||||
@dynamic_attributes ||= begin
|
@dynamic_attributes ||= begin
|
||||||
|
@ -305,14 +317,6 @@ module Haml
|
||||||
"#{tabulate(tabs)}:javascript\n#{content}"
|
"#{tabulate(tabs)}:javascript\n#{content}"
|
||||||
end
|
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)
|
def static_attribute?(name, options)
|
||||||
attributes[name] and !dynamic_attribute?(name, options)
|
attributes[name] and !dynamic_attribute?(name, options)
|
||||||
end
|
end
|
||||||
|
@ -340,13 +344,5 @@ module Haml
|
||||||
"{#{attrs.join(', ')}}"
|
"{#{attrs.join(', ')}}"
|
||||||
end
|
end
|
||||||
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
|
||||||
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