diff --git a/lib/haml/html.rb b/lib/haml/html.rb index b63cb768..7661652b 100644 --- a/lib/haml/html.rb +++ b/lib/haml/html.rb @@ -5,100 +5,82 @@ require 'rubygems' require 'cgi' require 'hpricot' -module Haml - class HTML - # A module containing utility methods that every Hpricot node - # should have. - module Node - # 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 << '}' - - 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 - - private - - def erb_to_interpolation(text, options) - return text unless options[:erb] - text = CGI.escapeHTML(uninterp(text)) - %w[ ].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 # element - str + '#{' + CGI.unescapeHTML(elem.innerText.strip) + '}' - 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 - end -end - # Haml monkeypatches various Hpricot classes # to add methods for conversion to Haml. # @private module Hpricot # @see Hpricot module Node - include Haml::HTML::Node + # 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 << '}' + + 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 + + private + + def erb_to_interpolation(text, options) + return text unless options[:erb] + text = CGI.escapeHTML(uninterp(text)) + %w[ ].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 # element + str + '#{' + CGI.unescapeHTML(elem.innerText.strip) + '}' + 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