[Haml] [HTML] Work even if Hpricot is loaded first.

Closes gh-324
Closes gh-322
This commit is contained in:
Nathan Weizenbaum 2010-12-06 20:48:49 -08:00
parent 85310a3723
commit f42f60ca6e
2 changed files with 74 additions and 63 deletions

View File

@ -3,6 +3,10 @@
* Table of contents
{:toc}
## 3.0.25 (Unreleased)
* HTML-to-Haml conversion now works within Ruby even if Hpricot is loaded before `haml/html`.
## 3.0.24
[Tagged on GitHub](http://github.com/nex3/haml/commit/3.0.24).

View File

@ -3,82 +3,91 @@ require File.dirname(__FILE__) + '/../haml'
require 'haml/engine'
require 'rubygems'
require 'cgi'
require 'hpricot'
module Haml
class HTML
# A module containing utility methods that every Hpricot node
# should have.
module Node
# Whether this node has already been converted to Haml.
# Only used for text nodes and elements.
#
# @return [Boolean]
attr_accessor :converted_to_haml
# We have to do everything in `#included`
# rather than including the methods in the module itself
# because if we do that, they don't propagate to the already-defined subclasses
# of the modules including this.
def self.included(base)
base.class_eval do
# Whether this node has already been converted to Haml.
# Only used for text nodes and elements.
#
# @return [Boolean]
attr_accessor :converted_to_haml
# Returns the Haml representation of the given node.
#
# @param tabs [Fixnum] The indentation level of the resulting Haml.
# @option options (see Haml::HTML#initialize)
def to_haml(tabs, options)
return "" if converted_to_haml || to_s.strip.empty?
text = uninterp(self.to_s)
node = next_node
while node.is_a?(::Hpricot::Elem) && node.name == "haml:loud"
node.converted_to_haml = true
text << '#{' <<
CGI.unescapeHTML(node.inner_text).gsub(/\n\s*/, ' ').strip << '}'
# Returns the Haml representation of the given node.
#
# @param tabs [Fixnum] The indentation level of the resulting Haml.
# @option options (see Haml::HTML#initialize)
def to_haml(tabs, options)
return "" if converted_to_haml || to_s.strip.empty?
text = uninterp(self.to_s)
node = next_node
while node.is_a?(::Hpricot::Elem) && node.name == "haml:loud"
node.converted_to_haml = true
text << '#{' <<
CGI.unescapeHTML(node.inner_text).gsub(/\n\s*/, ' ').strip << '}'
if node.next_node.is_a?(::Hpricot::Text)
node = node.next_node
text << uninterp(node.to_s)
node.converted_to_haml = true
if node.next_node.is_a?(::Hpricot::Text)
node = node.next_node
text << uninterp(node.to_s)
node.converted_to_haml = true
end
node = node.next_node
end
return parse_text_with_interpolation(text, tabs)
end
node = node.next_node
end
return parse_text_with_interpolation(text, tabs)
end
private
private
def erb_to_interpolation(text, options)
return text unless options[:erb]
text = CGI.escapeHTML(uninterp(text))
%w[<haml:loud> </haml:loud>].each {|str| text.gsub!(CGI.escapeHTML(str), str)}
::Hpricot::XML(text).children.inject("") do |str, elem|
if elem.is_a?(::Hpricot::Text)
str + CGI.unescapeHTML(elem.to_s)
else # <haml:loud> element
str + '#{' + CGI.unescapeHTML(elem.innerText.strip) + '}'
end
end
end
def erb_to_interpolation(text, options)
return text unless options[:erb]
text = CGI.escapeHTML(uninterp(text))
%w[<haml:loud> </haml:loud>].each {|str| text.gsub!(CGI.escapeHTML(str), str)}
::Hpricot::XML(text).children.inject("") do |str, elem|
if elem.is_a?(::Hpricot::Text)
str + CGI.unescapeHTML(elem.to_s)
else # <haml:loud> element
str + '#{' + CGI.unescapeHTML(elem.innerText.strip) + '}'
def tabulate(tabs)
' ' * tabs
end
def uninterp(text)
text.gsub('#{', '\#{') #'
end
def attr_hash
attributes.to_hash
end
def parse_text(text, tabs)
parse_text_with_interpolation(uninterp(text), tabs)
end
def parse_text_with_interpolation(text, tabs)
text.strip!
return "" if text.empty?
text.split("\n").map do |line|
line.strip!
"#{tabulate(tabs)}#{'\\' if Haml::Engine::SPECIAL_CHARACTERS.include?(line[0])}#{line}\n"
end.join
end
end
end
def tabulate(tabs)
' ' * tabs
end
def uninterp(text)
text.gsub('#{', '\#{') #'
end
def attr_hash
attributes.to_hash
end
def parse_text(text, tabs)
parse_text_with_interpolation(uninterp(text), tabs)
end
def parse_text_with_interpolation(text, tabs)
text.strip!
return "" if text.empty?
text.split("\n").map do |line|
line.strip!
"#{tabulate(tabs)}#{'\\' if Haml::Engine::SPECIAL_CHARACTERS.include?(line[0])}#{line}\n"
end.join
end
end
end
end
@ -98,8 +107,6 @@ module Hpricot
end
end
require 'hpricot'
# @private
HAML_TAGS = %w[haml:block haml:loud haml:silent]