Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Extracted html2haml to its own gem.

  • Loading branch information...
commit 8030deb1fb7a653269d0e29f0411b39b042f4bcf 1 parent c94794f
@norman norman authored
View
2  CHANGELOG.md
@@ -2,6 +2,8 @@
## 3.2.0 (Unreleased)
+* HTML2Haml has been extracted to a separate gem, creatively named "html2haml".
+
* Haml now supports only Rails 3 and above, and Ruby 1.8.7 and above. If you
still need support for Rails 2 and Ruby 1.8.6, please use Haml 3.1.x which
will continue to be maintained for bug fixes.
View
7 bin/html2haml
@@ -1,7 +0,0 @@
-#!/usr/bin/env ruby
-
-require File.dirname(__FILE__) + '/../lib/haml'
-require 'haml/exec'
-
-opts = Haml::Exec::HTML2Haml.new(ARGV)
-opts.parse!
View
4 haml.gemspec
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
spec.email = ['haml@googlegroups.com', 'norman@njclarke.com']
readmes = Dir['*'].reject{ |x| x =~ /(^|[^.a-z])[a-z]+/ || x == "TODO" }
- spec.executables = ['haml', 'html2haml']
+ spec.executables = ['haml']
spec.files = Dir['rails/init.rb', 'lib/**/*', 'bin/*', 'test/**/*',
'extra/**/*', 'Rakefile', 'init.rb', '.yardopts'] + readmes
spec.homepage = 'http://haml.info/'
@@ -20,9 +20,7 @@ Gem::Specification.new do |spec|
spec.add_development_dependency 'yard', '>= 0.5.3'
spec.add_development_dependency 'maruku', '>= 0.5.9'
- spec.add_development_dependency 'hpricot'
spec.add_development_dependency 'rails', '>= 3.0.0'
- spec.add_development_dependency 'ruby_parser'
spec.add_development_dependency 'rbench'
spec.add_development_dependency 'minitest'
spec.add_development_dependency 'json'
View
77 lib/haml/exec.rb
@@ -298,82 +298,5 @@ def process_result
output.close() if output.is_a? File
end
end
-
- # The `html2haml` executable.
- class HTML2Haml < Generic
- # @param args [Array<String>] The command-line arguments
- def initialize(args)
- super
- @module_opts = {}
- end
-
- # Tells optparse how to parse the arguments.
- #
- # @param opts [OptionParser]
- def set_opts(opts)
- opts.banner = <<END
-Usage: html2haml [options] [INPUT] [OUTPUT]
-
-Description: Transforms an HTML file into corresponding Haml code.
-
-Options:
-END
-
- opts.on('-e', '--erb', 'Parse ERb tags.') do
- @module_opts[:erb] = true
- end
-
- opts.on('--no-erb', "Don't parse ERb tags.") do
- @options[:no_erb] = true
- end
-
- opts.on('-r', '--rhtml', 'Deprecated; same as --erb.') do
- @module_opts[:erb] = true
- end
-
- opts.on('--no-rhtml', "Deprecated; same as --no-erb.") do
- @options[:no_erb] = true
- end
-
- opts.on('-x', '--xhtml', 'Parse the input using the more strict XHTML parser.') do
- @module_opts[:xhtml] = true
- end
-
- opts.on("--html-attributes", "Use HTML style attributes instead of Ruby hash style.") do
- @module_opts[:html_style_attributes] = true
- end
-
- unless RUBY_VERSION < "1.9"
- opts.on('-E ex[:in]', 'Specify the default external and internal character encodings.') do |encoding|
- external, internal = encoding.split(':')
- Encoding.default_external = external if external && !external.empty?
- Encoding.default_internal = internal if internal && !internal.empty?
- end
- end
-
- super
- end
-
- # Processes the options set by the command-line arguments,
- # and runs the HTML compiler appropriately.
- def process_result
- super
-
- require 'haml/html'
-
- input = @options[:input]
- output = @options[:output]
-
- @module_opts[:erb] ||= input.respond_to?(:path) && input.path =~ /\.(rhtml|erb)$/
- @module_opts[:erb] &&= @options[:no_erb] != false
-
- output.write(::Haml::HTML.new(input, @module_opts).render)
- rescue ::Haml::Error => e
- raise "#{e.is_a?(::Haml::SyntaxError) ? "Syntax error" : "Error"} on line " +
- "#{get_line e}: #{e.message}"
- rescue LoadError => err
- handle_load_error(err)
- end
- end
end
end
View
425 lib/haml/html.rb
@@ -1,425 +0,0 @@
-require File.dirname(__FILE__) + '/../haml'
-
-require 'haml/engine'
-require 'rubygems'
-require 'cgi'
-require 'hpricot'
-
-# Haml monkeypatches various Hpricot classes
-# to add methods for conversion to Haml.
-# @private
-module Hpricot
- # @see Hpricot
- 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
-
- # 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[<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 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::Parser::SPECIAL_CHARACTERS.include?(line[0])}#{line}\n"
- end.join
- end
- end
-end
-
-# @private
-HAML_TAGS = %w[haml:block haml:loud haml:silent]
-
-HAML_TAGS.each do |t|
- Hpricot::ElementContent[t] = {}
- Hpricot::ElementContent.keys.each do |key|
- Hpricot::ElementContent[t][key.hash] = true
- end
-end
-
-Hpricot::ElementContent.keys.each do |k|
- HAML_TAGS.each do |el|
- val = Hpricot::ElementContent[k]
- val[el.hash] = true if val.is_a?(Hash)
- end
-end
-
-module Haml
- # Converts HTML documents into Haml templates.
- # Depends on [Hpricot](http://github.com/whymirror/hpricot) for HTML parsing.
- # If ERB conversion is being used, also depends on
- # [Erubis](http://www.kuwata-lab.com/erubis) to parse the ERB
- # and [ruby_parser](http://parsetree.rubyforge.org/) to parse the Ruby code.
- #
- # Example usage:
- #
- # Haml::HTML.new("<a href='http://google.com'>Blat</a>").render
- # #=> "%a{:href => 'http://google.com'} Blat"
- class HTML
- # @param template [String, Hpricot::Node] The HTML template to convert
- # @option options :erb [Boolean] (false) Whether or not to parse
- # ERB's `<%= %>` and `<% %>` into Haml's `=` and `-`
- # @option options :xhtml [Boolean] (false) Whether or not to parse
- # the HTML strictly as XHTML
- def initialize(template, options = {})
- @options = options
-
- if template.is_a? Hpricot::Node
- @template = template
- else
- if template.is_a? IO
- template = template.read
- end
-
- template = Haml::Util.check_encoding(template) {|msg, line| raise Haml::Error.new(msg, line)}
-
- if @options[:erb]
- require 'haml/html/erb'
- template = ERB.compile(template)
- end
-
- method = @options[:xhtml] ? Hpricot.method(:XML) : method(:Hpricot)
- @template = method.call(template.gsub('&', '&amp;'))
- end
- end
-
- # Processes the document and returns the result as a string
- # containing the Haml template.
- def render
- @template.to_haml(0, @options)
- end
- alias_method :to_haml, :render
-
- TEXT_REGEXP = /^(\s*).*$/
-
- # @see Hpricot
- # @private
- class ::Hpricot::Doc
- # @see Haml::HTML::Node#to_haml
- def to_haml(tabs, options)
- (children || []).inject('') {|s, c| s << c.to_haml(0, options)}
- end
- end
-
- # @see Hpricot
- # @private
- class ::Hpricot::XMLDecl
- # @see Haml::HTML::Node#to_haml
- def to_haml(tabs, options)
- "#{tabulate(tabs)}!!! XML\n"
- end
- end
-
- # @see Hpricot
- # @private
- class ::Hpricot::CData
- # @see Haml::HTML::Node#to_haml
- def to_haml(tabs, options)
- content = parse_text_with_interpolation(
- erb_to_interpolation(self.content, options), tabs + 1)
- "#{tabulate(tabs)}:cdata\n#{content}"
- end
- end
-
- # @see Hpricot
- # @private
- class ::Hpricot::DocType
- # @see Haml::HTML::Node#to_haml
- def to_haml(tabs, options)
- attrs = public_id.nil? ? ["", "", ""] :
- public_id.scan(/DTD\s+([^\s]+)\s*([^\s]*)\s*([^\s]*)\s*\/\//)[0]
- raise Haml::SyntaxError.new("Invalid doctype") if attrs == nil
-
- type, version, strictness = attrs.map { |a| a.downcase }
- if type == "html"
- version = ""
- strictness = "strict" if strictness == ""
- end
-
- if version == "1.0" || version.empty?
- version = nil
- end
-
- if strictness == 'transitional' || strictness.empty?
- strictness = nil
- end
-
- version = " #{version.capitalize}" if version
- strictness = " #{strictness.capitalize}" if strictness
-
- "#{tabulate(tabs)}!!!#{version}#{strictness}\n"
- end
- end
-
- # @see Hpricot
- # @private
- class ::Hpricot::Comment
- # @see Haml::HTML::Node#to_haml
- def to_haml(tabs, options)
- content = self.content
- if content =~ /\A(\[[^\]]+\])>(.*)<!\[endif\]\z/m
- condition = $1
- content = $2
- end
-
- if content.include?("\n")
- "#{tabulate(tabs)}/#{condition}\n#{parse_text(content, tabs + 1)}"
- else
- "#{tabulate(tabs)}/#{condition} #{content.strip}\n"
- end
- end
- end
-
- # @see Hpricot
- # @private
- class ::Hpricot::Elem
- # @see Haml::HTML::Node#to_haml
- def to_haml(tabs, options)
- return "" if converted_to_haml
- if name == "script" &&
- (attr_hash['type'].nil? || attr_hash['type'] == "text/javascript") &&
- (attr_hash.keys - ['type']).empty?
- return to_haml_filter(:javascript, tabs, options)
- elsif name == "style" &&
- (attr_hash['type'].nil? || attr_hash['type'] == "text/css") &&
- (attr_hash.keys - ['type']).empty?
- return to_haml_filter(:css, tabs, options)
- end
-
- output = tabulate(tabs)
- if options[:erb] && name[0...5] == 'haml:'
- case name[5..-1]
- when "loud"
- lines = CGI.unescapeHTML(inner_text).split("\n").
- map {|s| s.rstrip}.reject {|s| s.strip.empty?}
- lines.first.gsub!(/^[ \t]*/, "= ")
-
- if lines.size > 1 # Multiline script block
- # Normalize the indentation so that the last line is the base
- indent_str = lines.last[/^[ \t]*/]
- indent_re = /^[ \t]{0,#{indent_str.count(" ") + 8 * indent_str.count("\t")}}/
- lines.map! {|s| s.gsub!(indent_re, '')}
-
- # Add an extra " " to make it indented relative to "= "
- lines[1..-1].each {|s| s.gsub!(/^/, " ")}
-
- # Add | at the end, properly aligned
- length = lines.map {|s| s.size}.max + 1
- lines.map! {|s| "%#{-length}s|" % s}
-
- if next_sibling && next_sibling.is_a?(Hpricot::Elem) && next_sibling.name == "haml:loud" &&
- next_sibling.inner_text.split("\n").reject {|s| s.strip.empty?}.size > 1
- lines << "-#"
- end
- end
- return lines.map {|s| output + s + "\n"}.join
- when "silent"
- return CGI.unescapeHTML(inner_text).split("\n").map do |line|
- next "" if line.strip.empty?
- "#{output}- #{line.strip}\n"
- end.join
- when "block"
- return render_children("", tabs, options)
- end
- end
-
- if self.next && self.next.text? && self.next.content =~ /\A[^\s]/
- if self.previous.nil? || self.previous.text? &&
- (self.previous.content =~ /[^\s]\Z/ ||
- self.previous.content =~ /\A\s*\Z/ && self.previous.previous.nil?)
- nuke_outer_whitespace = true
- else
- output << "= succeed #{self.next.content.slice!(/\A[^\s]+/).dump} do\n"
- tabs += 1
- output << tabulate(tabs)
- end
- end
-
- output << "%#{name}" unless name == 'div' &&
- (static_id?(options) ||
- static_classname?(options) &&
- attr_hash['class'].split(' ').any?(&method(:haml_css_attr?)))
-
- if attr_hash
- if static_id?(options)
- output << "##{attr_hash['id']}"
- remove_attribute('id')
- end
- if static_classname?(options)
- leftover = attr_hash['class'].split(' ').reject do |c|
- next unless haml_css_attr?(c)
- output << ".#{c}"
- end
- remove_attribute('class')
- set_attribute('class', leftover.join(' ')) unless leftover.empty?
- end
- output << haml_attributes(options) if attr_hash.length > 0
- end
-
- output << ">" if nuke_outer_whitespace
- output << "/" if empty? && !etag
-
- if children && children.size == 1
- child = children.first
- if child.is_a?(::Hpricot::Text)
- if !child.to_s.include?("\n")
- text = child.to_haml(tabs + 1, options)
- return output + " " + text.lstrip.gsub(/^\\/, '') unless text.chomp.include?("\n")
- return output + "\n" + text
- elsif ["pre", "textarea"].include?(name) ||
- (name == "code" && parent.is_a?(::Hpricot::Elem) && parent.name == "pre")
- return output + "\n#{tabulate(tabs + 1)}:preserve\n" +
- innerText.gsub(/^/, tabulate(tabs + 2))
- end
- elsif child.is_a?(::Hpricot::Elem) && child.name == "haml:loud"
- return output + child.to_haml(tabs + 1, options).lstrip
- end
- 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
- Hash[attr_hash.map do |name, value|
- next if value.empty?
- full_match = nil
- ruby_value = value.gsub(%r{<haml:loud>\s*(.+?)\s*</haml:loud>}) do
- full_match = $`.empty? && $'.empty?
- CGI.unescapeHTML(full_match ? $1: "\#{#{$1}}")
- end
- next if ruby_value == value
- [name, full_match ? ruby_value : %("#{ruby_value}")]
- end]
- end
- end
-
- def to_haml_filter(filter, tabs, options)
- content =
- if children.first.is_a?(::Hpricot::CData)
- children.first.content
- else
- CGI.unescapeHTML(self.innerText)
- end
-
- content = erb_to_interpolation(content, options)
- content.gsub!(/\A\s*\n(\s*)/, '\1')
- original_indent = content[/\A(\s*)/, 1]
- if content.split("\n").all? {|l| l.strip.empty? || l =~ /^#{original_indent}/}
- content.gsub!(/^#{original_indent}/, tabulate(tabs + 1))
- end
-
- "#{tabulate(tabs)}:#{filter}\n#{content}"
- end
-
- def static_attribute?(name, options)
- attr_hash[name] && !dynamic_attribute?(name, options)
- end
-
- def dynamic_attribute?(name, options)
- options[:erb] and dynamic_attributes.key?(name)
- end
-
- def static_id?(options)
- static_attribute?('id', options) && haml_css_attr?(attr_hash['id'])
- end
-
- def static_classname?(options)
- static_attribute?('class', options)
- end
-
- def haml_css_attr?(attr)
- attr =~ /^[-:\w]+$/
- end
-
- # Returns a string representation of an attributes hash
- # that's prettier than that produced by Hash#inspect
- def haml_attributes(options)
- attrs = attr_hash.sort.map do |name, value|
- haml_attribute_pair(name, value, options)
- end
- if options[:html_style_attributes]
- "(#{attrs.join(' ')})"
- else
- "{#{attrs.join(', ')}}"
- end
- end
-
- # Returns the string representation of a single attribute key value pair
- def haml_attribute_pair(name, value, options)
- value = dynamic_attribute?(name, options) ? dynamic_attributes[name] : value.inspect
- if options[:html_style_attributes]
- "#{name}=#{value}"
- else
- name = name.index(/\W/) ? name.inspect : ":#{name}"
- "#{name} => #{value}"
- end
- end
- end
- end
-end
View
141 lib/haml/html/erb.rb
@@ -1,141 +0,0 @@
-require 'cgi'
-require 'erubis'
-require 'ruby_parser'
-
-module Haml
- class HTML
- # A class for converting ERB code into a format that's easier
- # for the {Haml::HTML} Hpricot-based parser to understand.
- #
- # Uses [Erubis](http://www.kuwata-lab.com/erubis)'s extensible parsing powers
- # to parse the ERB in a reliable way,
- # and [ruby_parser](http://parsetree.rubyforge.org/)'s Ruby knowledge
- # to figure out whether a given chunk of Ruby code starts a block or not.
- #
- # The ERB tags are converted to HTML tags in the following way.
- # `<% ... %>` is converted into `<haml:silent> ... </haml:silent>`.
- # `<%= ... %>` is converted into `<haml:loud> ... </haml:loud>`.
- # Finally, if either of these opens a Ruby block,
- # `<haml:block> ... </haml:block>` will wrap the entire contents of the block -
- # that is, everything that should be indented beneath the previous silent or loud tag.
- class ERB < Erubis::Basic::Engine
- # Compiles an ERB template into a HTML document containing `haml:` tags.
- #
- # @param template [String] The ERB template
- # @return [String] The output document
- # @see Haml::HTML::ERB
- def self.compile(template)
- new(template).src
- end
-
- # `html2haml` doesn't support HTML-escaped expressions.
- def escaped_expr(code)
- raise Haml::Error.new("html2haml doesn't support escaped expressions.")
- end
-
- # The ERB-to-Hamlized-HTML conversion has no preamble.
- def add_preamble(src); end
-
- # The ERB-to-Hamlized-HTML conversion has no postamble.
- def add_postamble(src); end
-
- # Concatenates the text onto the source buffer.
- #
- # @param src [String] The source buffer
- # @param text [String] The raw text to add to the buffer
- def add_text(src, text)
- src << text
- end
-
- # Concatenates a silent Ruby statement onto the source buffer.
- # This uses the `<haml:silent>` tag,
- # and may close and/or open a Ruby block with the `<haml:block>` tag.
- #
- # In particular, a block is closed if this statement is some form of `end`,
- # opened if it's a block opener like `do`, `if`, or `begin`,
- # and both closed and opened if it's a mid-block keyword
- # like `else` or `when`.
- #
- # @param src [String] The source buffer
- # @param code [String] The Ruby statement to add to the buffer
- 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
-
- # Concatenates a Ruby expression that's printed to the document
- # onto the source buffer.
- # This uses the `<haml:silent>` tag,
- # and may open a Ruby block with the `<haml:block>` tag.
- # An expression never closes a block.
- #
- # @param src [String] The source buffer
- # @param code [String] The Ruby expression to add to the buffer
- def add_expr_literal(src, code)
- src << '<haml:loud>' << h(code) << '</haml:loud>'
- src << '<haml:block>' if block_opener?(code)
- end
-
- # `html2haml` doesn't support debugging expressions.
- def add_expr_debug(src, code)
- raise Haml::Error.new("html2haml doesn't support debugging expressions.")
- end
-
- private
-
- # HTML-escaped some text (in practice, always Ruby code).
- # A utility method.
- #
- # @param text [String] The text to escape
- # @return [String] The escaped text
- def h(text)
- CGI.escapeHTML(text)
- end
-
- # Returns whether the code is valid Ruby code on its own.
- #
- # @param code [String] Ruby code to check
- # @return [Boolean]
- def valid_ruby?(code)
- RubyParser.new.parse(code)
- rescue Racc::ParseError
- false
- end
-
- # Checks if a string of Ruby code opens a block.
- # This could either be something like `foo do |a|`
- # or a keyword that requires a matching `end`
- # like `if`, `begin`, or `case`.
- #
- # @param code [String] Ruby code to check
- # @return [Boolean]
- def block_opener?(code)
- valid_ruby?(code + "\nend") ||
- valid_ruby?(code + "\nwhen foo\nend")
- end
-
- # Checks if a string of Ruby code closes a block.
- # This is always `end` followed optionally by some method calls.
- #
- # @param code [String] Ruby code to check
- # @return [Boolean]
- def block_closer?(code)
- valid_ruby?("begin\n" + code)
- end
-
- # Checks if a string of Ruby code comes in the middle of a block.
- # This could be a keyword like `else`, `rescue`, or `when`,
- # or even `end` with a method call that takes a block.
- #
- # @param code [String] Ruby code to check
- # @return [Boolean]
- 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
View
440 test/html2haml/erb_tests.rb
@@ -1,440 +0,0 @@
-module ErbTests
- def test_erb
- assert_equal '- foo = bar', render_erb('<% foo = bar %>')
- assert_equal '- foo = bar', render_erb('<% foo = bar -%>')
- assert_equal '= h @item.title', render_erb('<%=h @item.title %>')
- assert_equal '= h @item.title', render_erb('<%=h @item.title -%>')
- end
-
- def test_inline_erb
- assert_equal("%p= foo", render_erb("<p><%= foo %></p>"))
- end
-
- def test_non_inline_erb
- assert_equal(<<HAML.rstrip, render_erb(<<HTML))
-%p
- = foo
-HAML
-<p>
- <%= foo %>
-</p>
-HTML
- assert_equal(<<HAML.rstrip, render_erb(<<HTML))
-%p
- = foo
-HAML
-<p>
- <%= foo %></p>
-HTML
- assert_equal(<<HAML.rstrip, render_erb(<<HTML))
-%p
- = foo
-HAML
-<p><%= foo %>
-</p>
-HTML
- end
-
- def test_erb_in_cdata
- assert_equal(<<HAML.rstrip, render_erb(<<HTML))
-:cdata
- Foo \#{bar} baz
-HAML
-<![CDATA[Foo <%= bar %> baz]]>
-HTML
- end
-
- def test_erb_in_script
- assert_equal(<<HAML.rstrip, render_erb(<<HTML))
-:javascript
- function foo() {
- return \#{foo.to_json};
- }
-HAML
-<script type="text/javascript">
- function foo() {
- return <%= foo.to_json %>;
- }
-</script>
-HTML
- end
-
- def test_erb_in_style
- assert_equal(<<HAML.rstrip, render_erb(<<HTML))
-:css
- foo {
- bar: \#{"baz"};
- }
-HAML
-<style type="text/css">
- foo {
- bar: <%= "baz" %>;
- }
-</style>
-HTML
- end
-
- def test_erb_in_line
- assert_equal 'foo bar #{baz}', render_erb('foo bar <%= baz %>')
- assert_equal 'foo bar #{baz}! Bang.', render_erb('foo bar <%= baz %>! Bang.')
- end
-
- def test_erb_multi_in_line
- assert_equal('foo bar #{baz}! Bang #{bop}.',
- render_erb('foo bar <%= baz %>! Bang <%= bop %>.'))
- assert_equal('foo bar #{baz}#{bop}!',
- render_erb('foo bar <%= baz %><%= bop %>!'))
- end
-
- def test_erb_with_html_special_chars
- assert_equal '= 3 < 5 ? "OK" : "Your computer is b0rken"',
- render_erb('<%= 3 < 5 ? "OK" : "Your computer is b0rken" %>')
- end
-
- def test_erb_in_class_attribute
- assert_equal "%div{:class => dyna_class} I have a dynamic attribute",
- render_erb('<div class="<%= dyna_class %>">I have a dynamic attribute</div>')
- end
-
- def test_erb_in_id_attribute
- assert_equal "%div{:id => dyna_id} I have a dynamic attribute",
- render_erb('<div id="<%= dyna_id %>">I have a dynamic attribute</div>')
- end
-
- def test_erb_in_attribute_results_in_string_interpolation
- assert_equal('%div{:id => "item_#{i}"} Ruby string interpolation FTW',
- render_erb('<div id="item_<%= i %>">Ruby string interpolation FTW</div>'))
- end
-
- def test_erb_in_attribute_with_trailing_content
- assert_equal('%div{:class => "#{12}!"} Bang!',
- render_erb('<div class="<%= 12 %>!">Bang!</div>'))
- end
-
- def test_erb_in_html_escaped_attribute
- assert_equal '%div{:class => "foo"} Bang!',
- render_erb('<div class="<%= "foo" %>">Bang!</div>')
- end
-
- def test_erb_in_attribute_to_multiple_interpolations
- assert_equal('%div{:class => "#{12} + #{13}"} Math is super',
- render_erb('<div class="<%= 12 %> + <%= 13 %>">Math is super</div>'))
- end
-
- def test_whitespace_eating_erb_tags
- assert_equal '- form_for', render_erb('<%- form_for -%>')
- end
-
- def test_interpolation_in_erb
- assert_equal('= "Foo #{bar} baz"', render_erb('<%= "Foo #{bar} baz" %>'))
- end
-
- def test_interpolation_in_erb_attrs
- assert_equal('%p{:foo => "#{bar} baz"}',
- render_erb('<p foo="<%= "#{bar} baz" %>"></p>'))
- end
-
- def test_multiline_erb_silent_script
- assert_equal(<<HAML.rstrip, render_erb(<<ERB))
-.blah
- - foo
- - bar
- - baz
- %p foo
-HAML
-<div class="blah">
- <%
- foo
- bar
- baz
- %>
- <p>foo</p>
-</div>
-ERB
- end
-
- def test_multiline_erb_loud_script
- assert_equal(<<HAML.rstrip, render_erb(<<ERB))
-.blah
- = foo + |
- bar.baz.bang + |
- baz |
- %p foo
-HAML
-<div class="blah">
- <%=
- foo +
- bar.baz.bang +
- baz
- %>
- <p>foo</p>
-</div>
-ERB
- end
-
- def test_weirdly_indented_multiline_erb_loud_script
- assert_equal(<<HAML.rstrip, render_erb(<<ERB))
-.blah
- = foo + |
- bar.baz.bang + |
- baz |
- %p foo
-HAML
-<div class="blah">
- <%=
- foo +
- bar.baz.bang +
- baz
- %>
- <p>foo</p>
-</div>
-ERB
- end
-
- def test_two_multiline_erb_loud_scripts
- assert_equal(<<HAML.rstrip, render_erb(<<ERB))
-.blah
- = foo + |
- bar.baz.bang + |
- baz |
- -#
- = foo.bar do |
- bang |
- end |
- %p foo
-HAML
-<div class="blah">
- <%=
- foo +
- bar.baz.bang +
- baz
- %>
- <%= foo.bar do
- bang
- end %>
- <p>foo</p>
-</div>
-ERB
- end
-
- def test_multiline_then_single_line_erb_loud_scripts
- assert_equal(<<HAML.rstrip, render_erb(<<ERB))
-.blah
- = foo + |
- bar.baz.bang + |
- baz |
- = foo.bar
- %p foo
-HAML
-<div class="blah">
- <%=
- foo +
- bar.baz.bang +
- baz
- %>
- <%= foo.bar %>
- <p>foo</p>
-</div>
-ERB
- end
-
- def test_multiline_erb_but_really_single_line
- assert_equal(<<HAML.rstrip, render_erb(<<ERB))
-.blah
- = foo
- %p foo
-HAML
-<div class="blah">
- <%=
- foo
- %>
- <p>foo</p>
-</div>
-ERB
- end
-
- ### Block Parsing
-
- def test_block_parsing
- assert_equal(<<HAML.rstrip, render_erb(<<ERB))
-- foo do
- %p bar
-HAML
-<% foo do %>
- <p>bar</p>
-<% end %>
-ERB
- end
-
- def test_block_parsing_with_args
- assert_equal(<<HAML.rstrip, render_erb(<<ERB))
-- foo do |a, b, c|
- %p bar
-HAML
-<% foo do |a, b, c| %>
- <p>bar</p>
-<% end %>
-ERB
- end
-
- def test_block_parsing_with_equals
- assert_equal(<<HAML.rstrip, render_erb(<<ERB))
-= foo do
- %p bar
-HAML
-<%= foo do %>
- <p>bar</p>
-<% end %>
-ERB
- end
-
- def test_block_parsing_with_modified_end
- assert_equal(<<HAML.rstrip, render_erb(<<ERB))
-- foo do
- blah
-- end.bip
-HAML
-<% foo do %>
- blah
-<% end.bip %>
-ERB
- end
-
- def test_block_parsing_with_modified_end_with_block
- assert_equal(<<HAML.rstrip, render_erb(<<ERB))
-- foo do
- blah
-- end.bip do
- brang
-HAML
-<% foo do %>
- blah
-<% end.bip do %>
- brang
-<% end %>
-ERB
- end
-
- def test_multiline_block_opener
- assert_equal(<<HAML.rstrip, render_erb(<<ERB))
-- foo bar
-- baz bang
-- biddle do
- foo
-HAML
-<% foo bar
- baz bang
- biddle do %>
- foo
-<% end %>
-ERB
- end
-
- def test_if_elsif_else_parsing
- assert_equal(<<HAML.rstrip, render_erb(<<ERB))
-- if foo
- %p bar
-- elsif bar.foo("zip")
- #bang baz
-- else
- %strong bibble
-HAML
-<% if foo %>
- <p>bar</p>
-<% elsif bar.foo("zip") %>
- <div id="bang">baz</div>
-<% else %>
- <strong>bibble</strong>
-<% end %>
-ERB
- end
-
- def test_case_when_parsing
- assert_equal(<<HAML.rstrip, render_erb(<<ERB))
-- case foo.bar
-- when "bip"
- %p bip
-- when "bop"
- %p BOP
-- when bizzle.bang.boop.blip
- %em BIZZLE BANG BOOP BLIP
-HAML
-<% case foo.bar %>
-<% when "bip" %>
- <p>bip</p>
-<% when "bop" %>
- <p>BOP</p>
-<% when bizzle.bang.boop.blip %>
- <em>BIZZLE BANG BOOP BLIP</em>
-<% end %>
-ERB
-
- assert_equal(<<HAML.rstrip, render_erb(<<ERB))
-- case foo.bar
-- when "bip"
- %p bip
-- when "bop"
- %p BOP
-- when bizzle.bang.boop.blip
- %em BIZZLE BANG BOOP BLIP
-HAML
-<% case foo.bar
- when "bip" %>
- <p>bip</p>
-<% when "bop" %>
- <p>BOP</p>
-<% when bizzle.bang.boop.blip %>
- <em>BIZZLE BANG BOOP BLIP</em>
-<% end %>
-ERB
- end
-
- def test_begin_rescue_ensure
- assert_equal(<<HAML.rstrip, render_erb(<<ERB))
-- begin
- %p a
-- rescue FooException => e
- %p b
-- ensure
- %p c
-HAML
-<% begin %>
- <p>a</p>
-<% rescue FooException => e %>
- <p>b</p>
-<% ensure %>
- <p>c</p>
-<% end %>
-ERB
- end
-
- # Regression
-
- def test_tag_inside_block
- assert_equal(<<HAML.rstrip, render_erb(<<ERB))
-%table
- - foo.each do
- %tr
-HAML
-<table>
- <% foo.each do %>
- <tr></tr>
- <% end %>
-</table>
-ERB
- end
-
- def test_silent_inside_block_inside_tag
- assert_equal(<<HAML.rstrip, render_erb(<<ERB))
-%table
- - foo.each do
- - haml_puts "foo"
-HAML
-<table>
- <% foo.each do %>
- <% haml_puts "foo" %>
- <% end %>
-</table>
-ERB
- end
-end
View
342 test/html2haml_test.rb
@@ -1,342 +0,0 @@
-require 'test_helper'
-require 'html2haml/erb_tests'
-require 'haml/html'
-
-class Html2HamlTest < MiniTest::Unit::TestCase
- def test_empty_render_should_remain_empty
- assert_equal '', render('')
- end
-
- def test_doctype
- assert_equal '!!!', render("<!DOCTYPE html>")
- assert_equal '!!! 1.1', render('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">')
- assert_equal '!!! Strict', render('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">')
- assert_equal '!!! Frameset', render('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">')
- assert_equal '!!! Mobile 1.2', render('<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">')
- assert_equal '!!! Basic 1.1', render('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">')
- assert_equal '!!!', render('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">')
- assert_equal '!!! Strict', render('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">')
- assert_equal '!!! Frameset', render('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">')
- assert_equal '!!!', render('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">')
- end
-
- def test_id_and_class_should_be_removed_from_hash
- assert_equal '%span#foo.bar', render('<span id="foo" class="bar"> </span>')
- end
-
- def test_no_tag_name_for_div_if_class_or_id_is_present
- assert_equal '#foo', render('<div id="foo"> </div>')
- assert_equal '.foo', render('<div class="foo"> </div>')
- end
-
- def test_multiple_class_names
- assert_equal '.foo.bar.baz', render('<div class=" foo bar baz "> </div>')
- end
-
- def test_should_have_pretty_attributes
- assert_equal('%input{:name => "login", :type => "text"}/',
- render('<input type="text" name="login" />'))
- assert_equal('%meta{:content => "text/html", "http-equiv" => "Content-Type"}/',
- render('<meta http-equiv="Content-Type" content="text/html" />'))
- end
-
- def test_should_have_html_style_attributes
- assert_equal('%input(name="login" type="text")/',
- render('<input type="text" name="login" />', :html_style_attributes => true))
- assert_equal('%meta(content="text/html" http-equiv="Content-Type")/',
- render('<meta http-equiv="Content-Type" content="text/html" />', :html_style_attributes => true))
- end
-
- def test_class_with_dot_and_hash
- assert_equal('%div{:class => "foo.bar"}', render("<div class='foo.bar'></div>"))
- assert_equal('%div{:class => "foo#bar"}', render("<div class='foo#bar'></div>"))
- assert_equal('.foo.bar{:class => "foo#bar foo.bar"}', render("<div class='foo foo#bar bar foo.bar'></div>"))
- end
-
- def test_id_with_dot_and_hash
- assert_equal('%div{:id => "foo.bar"}', render("<div id='foo.bar'></div>"))
- assert_equal('%div{:id => "foo#bar"}', render("<div id='foo#bar'></div>"))
- end
-
- def test_interpolation
- assert_equal('Foo \#{bar} baz', render('Foo #{bar} baz'))
- end
-
- def test_interpolation_in_attrs
- assert_equal('%p{:foo => "\#{bar} baz"}', render('<p foo="#{bar} baz"></p>'))
- end
-
- def test_cdata
- assert_equal(<<HAML.strip, render(<<HTML))
-%p
- :cdata
- <a foo="bar" baz="bang">
- <div id="foo">flop</div>
- </a>
-HAML
-<p><![CDATA[
- <a foo="bar" baz="bang">
- <div id="foo">flop</div>
- </a>
-]]></p>
-HTML
- end
-
- def test_self_closing_tag
- assert_equal("%foo/", render("<foo />"))
- end
-
- def test_inline_text
- assert_equal("%p foo", render("<p>foo</p>"))
- end
-
- def test_inline_comment
- assert_equal("/ foo", render("<!-- foo -->"))
- assert_equal(<<HAML.strip, render(<<HTML))
-/ foo
-%p bar
-HAML
-<!-- foo -->
-<p>bar</p>
-HTML
- end
-
- def test_non_inline_comment
- assert_equal(<<HAML.rstrip, render(<<HTML))
-/
- Foo
- Bar
-HAML
-<!-- Foo
-Bar -->
-HTML
- end
-
- def test_non_inline_text
- assert_equal(<<HAML.rstrip, render(<<HTML))
-%p
- foo
-HAML
-<p>
- foo
-</p>
-HTML
- assert_equal(<<HAML.rstrip, render(<<HTML))
-%p
- foo
-HAML
-<p>
- foo</p>
-HTML
- assert_equal(<<HAML.rstrip, render(<<HTML))
-%p
- foo
-HAML
-<p>foo
-</p>
-HTML
- end
-
- def test_script_tag
- assert_equal(<<HAML.rstrip, render(<<HTML))
-:javascript
- function foo() {
- return "12" & "13";
- }
-HAML
-<script type="text/javascript">
- function foo() {
- return "12" &amp; "13";
- }
-</script>
-HTML
- end
-
- def test_script_tag_with_cdata
- assert_equal(<<HAML.rstrip, render(<<HTML))
-:javascript
- function foo() {
- return "&amp;";
- }
-HAML
-<script type="text/javascript">
- <![CDATA[
- function foo() {
- return "&amp;";
- }
- ]]>
-</script>
-HTML
- end
-
- def test_pre
- assert_equal(<<HAML.rstrip, render(<<HTML))
-%pre
- :preserve
- foo
- bar
- baz
-HAML
-<pre>foo
- bar
-baz</pre>
-HTML
- end
-
- def test_pre_code
- assert_equal(<<HAML.rstrip, render(<<HTML))
-%pre
- %code
- :preserve
- foo
- bar
- baz
-HAML
-<pre><code>foo
- bar
-baz</code></pre>
-HTML
- end
-
- def test_code_without_pre
- assert_equal(<<HAML.rstrip, render(<<HTML))
-%code
- foo
- bar
- baz
-HAML
-<code>foo
- bar
-baz</code>
-HTML
- end
-
- def test_conditional_comment
- assert_equal(<<HAML.rstrip, render(<<HTML))
-/[if foo]
- bar
- baz
-HAML
-<!--[if foo]>
- bar
- baz
-<![endif]-->
-HTML
- end
-
- def test_style_to_css_filter
- assert_equal(<<HAML.rstrip, render(<<HTML))
-:css
- foo {
- bar: baz;
- }
-HAML
-<style type="text/css">
- foo {
- bar: baz;
- }
-</style>
-HTML
- end
-
- def test_inline_conditional_comment
- assert_equal(<<HAML.rstrip, render(<<HTML))
-/[if foo] bar baz
-HAML
-<!--[if foo]> bar baz <![endif]-->
-HTML
- end
-
- def test_minus_in_tag
- assert_equal("%p - foo bar -", render("<p>- foo bar -</p>"))
- end
-
- def test_equals_in_tag
- assert_equal("%p = foo bar =", render("<p>= foo bar =</p>"))
- end
-
- def test_hash_in_tag
- assert_equal("%p # foo bar #", render("<p># foo bar #</p>"))
- end
-
- def test_comma_post_tag
- assert_equal(<<HAML.rstrip, render(<<HTML))
-#foo
- %span> Foo
- ,
- %span bar
- Foo
- %span> bar
- ,
- %span baz
-HAML
-<div id="foo">
- <span>Foo</span>, <span>bar</span>
- Foo<span>bar</span>, <span>baz</span>
-</div>
-HTML
- end
-
- def test_comma_post_tag_with_text_before
- assert_equal(<<HAML.rstrip, render(<<HTML))
-#foo
- Batch
- = succeed "," do
- %span Foo
- %span Bar
-HAML
-<div id="foo">
- Batch
- <span>Foo</span>, <span>Bar</span>
-</div>
-HTML
- end
-
- begin
- require 'haml/html/erb'
- include ErbTests
- rescue LoadError => e
- puts "\n** Couldn't require #{e.message[/-- (.*)$/, 1]}, skipping some tests"
- end
-
- # Encodings
-
- unless RUBY_VERSION < "1.9"
- def test_encoding_error
- render("foo\nbar\nb\xFEaz".force_encoding("utf-8"))
- assert(false, "Expected exception")
- rescue Haml::Error => e
- assert_equal(3, e.line)
- assert_equal('Invalid UTF-8 character "\xFE"', e.message)
- end
-
- def test_ascii_incompatible_encoding_error
- template = "foo\nbar\nb_z".encode("utf-16le")
- template[9] = "\xFE".force_encoding("utf-16le")
- render(template)
- assert(false, "Expected exception")
- rescue Haml::Error => e
- assert_equal(3, e.line)
- assert_equal('Invalid UTF-16LE character "\xFE"', e.message)
- end
- end
-
- # Regression Tests
-
- def test_xhtml_strict_doctype
- assert_equal('!!! Strict', render(<<HTML))
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-HTML
- end
-
- protected
-
- def render(text, options = {})
- Haml::HTML.new(text, options).render.rstrip
- end
-
- def render_erb(text)
- render(text, :erb => true)
- end
-end
View
1  test/test_helper.rb
@@ -11,7 +11,6 @@
require 'action_pack'
require 'action_controller'
require 'action_view'
-require 'hpricot'
require 'rails'
class TestApp < Rails::Application

0 comments on commit 8030deb

Please sign in to comment.
Something went wrong with that request. Please try again.