html2haml-1.0.1/ 0000755 0001750 0001750 00000000000 12147506116 012422 5 ustar gwolf gwolf html2haml-1.0.1/bin/ 0000755 0001750 0001750 00000000000 12147506116 013172 5 ustar gwolf gwolf html2haml-1.0.1/bin/html2haml 0000755 0001750 0001750 00000000234 12147506116 015007 0 ustar gwolf gwolf #!/usr/bin/env ruby
require File.dirname(__FILE__) + '/../lib/html2haml'
require 'html2haml/exec'
opts = Html2haml::Exec::HTML2Haml.new(ARGV)
opts.parse!
html2haml-1.0.1/lib/ 0000755 0001750 0001750 00000000000 12147506116 013170 5 ustar gwolf gwolf html2haml-1.0.1/lib/html2haml/ 0000755 0001750 0001750 00000000000 12147506116 015060 5 ustar gwolf gwolf html2haml-1.0.1/lib/html2haml/html/ 0000755 0001750 0001750 00000000000 12147506116 016024 5 ustar gwolf gwolf html2haml-1.0.1/lib/html2haml/html/erb.rb 0000644 0001750 0001750 00000012762 12147506116 017131 0 ustar gwolf gwolf 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 ` ... `.
# `<%= ... %>` is converted into ` ... `.
# Finally, if either of these opens a Ruby 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 `` tag,
# and may close and/or open a Ruby block with the `` 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 << '' if block_closer?(code) || mid_block?(code)
src << '' << h(code) << '' unless code.strip == "end"
src << '' 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 `` tag,
# and may open a Ruby block with the `` 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 << '' << h(code) << ''
src << '' 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, RubyParser::SyntaxError
false
end
# Returns whether the code has any content
# This is used to test whether lines have been removed by erubis, such as comments
#
# @param code [String] Ruby code to check
# @return [Boolean]
def has_code?(code)
code != "\n"
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)
return unless has_code?(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)
return unless has_code?(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 unless has_code?(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
html2haml-1.0.1/lib/html2haml/exec.rb 0000644 0001750 0001750 00000020244 12147506116 016333 0 ustar gwolf gwolf require 'optparse'
require 'fileutils'
require 'rbconfig'
module Html2haml
# This module handles the various Haml executables (`haml` and `haml-convert`).
module Exec
# An abstract class that encapsulates the executable code for all three executables.
class Generic
# @param args [Array] The command-line arguments
def initialize(args)
@args = args
@options = {:for_engine => {}}
end
# Parses the command-line arguments and runs the executable.
# Calls `Kernel#exit` at the end, so it never returns.
#
# @see #parse
def parse!
begin
parse
rescue Exception => e
raise e if @options[:trace] || e.is_a?(SystemExit)
$stderr.print "#{e.class}: " unless e.class == RuntimeError
$stderr.puts "#{e.message}"
$stderr.puts " Use --trace for backtrace."
exit 1
end
exit 0
end
# Parses the command-line arguments and runs the executable.
# This does not handle exceptions or exit the program.
#
# @see #parse!
def parse
@opts = OptionParser.new(&method(:set_opts))
@opts.parse!(@args)
process_result
@options
end
# @return [String] A description of the executable
def to_s
@opts.to_s
end
protected
# Finds the line of the source template
# on which an exception was raised.
#
# @param exception [Exception] The exception
# @return [String] The line number
def get_line(exception)
# SyntaxErrors have weird line reporting
# when there's trailing whitespace,
# which there is for Haml documents.
return (exception.message.scan(/:(\d+)/).first || ["??"]).first if exception.is_a?(::SyntaxError)
(exception.backtrace[0].scan(/:(\d+)/).first || ["??"]).first
end
# Tells optparse how to parse the arguments
# available for all executables.
#
# This is meant to be overridden by subclasses
# so they can add their own options.
#
# @param opts [OptionParser]
def set_opts(opts)
opts.on('-s', '--stdin', :NONE, 'Read input from standard input instead of an input file') do
@options[:input] = $stdin
end
opts.on('--trace', :NONE, 'Show a full traceback on error') do
@options[:trace] = true
end
opts.on('--unix-newlines', 'Use Unix-style newlines in written files.') do
# Note that this is the preferred way to check for Windows, since
# JRuby and Rubinius also run there.
if RbConfig::CONFIG['host_os'] =~ /mswin|windows|mingw/i
@options[:unix_newlines] = true
end
end
opts.on_tail("-?", "-h", "--help", "Show this message") do
puts opts
exit
end
opts.on_tail("-v", "--version", "Print version") do
puts("html2haml #{::Html2haml::VERSION}")
exit
end
end
# Processes the options set by the command-line arguments.
# In particular, sets `@options[:input]` and `@options[:output]`
# to appropriate IO streams.
#
# This is meant to be overridden by subclasses
# so they can run their respective programs.
def process_result
input, output = @options[:input], @options[:output]
args = @args.dup
input ||=
begin
filename = args.shift
@options[:filename] = filename
open_file(filename) || $stdin
end
output ||= open_file(args.shift, 'w') || $stdout
@options[:input], @options[:output] = input, output
end
COLORS = { :red => 31, :green => 32, :yellow => 33 }
# Prints a status message about performing the given action,
# colored using the given color (via terminal escapes) if possible.
#
# @param name [#to_s] A short name for the action being performed.
# Shouldn't be longer than 11 characters.
# @param color [Symbol] The name of the color to use for this action.
# Can be `:red`, `:green`, or `:yellow`.
def puts_action(name, color, arg)
return if @options[:for_engine][:quiet]
printf color(color, "%11s %s\n"), name, arg
end
# Same as `Kernel.puts`, but doesn't print anything if the `--quiet` option is set.
#
# @param args [Array] Passed on to `Kernel.puts`
def puts(*args)
return if @options[:for_engine][:quiet]
Kernel.puts(*args)
end
# Wraps the given string in terminal escapes
# causing it to have the given color.
# If terminal esapes aren't supported on this platform,
# just returns the string instead.
#
# @param color [Symbol] The name of the color to use.
# Can be `:red`, `:green`, or `:yellow`.
# @param str [String] The string to wrap in the given color.
# @return [String] The wrapped string.
def color(color, str)
raise "[BUG] Unrecognized color #{color}" unless COLORS[color]
# Almost any real Unix terminal will support color,
# so we just filter for Windows terms (which don't set TERM)
# and not-real terminals, which aren't ttys.
return str if ENV["TERM"].nil? || ENV["TERM"].empty? || !STDOUT.tty?
return "\e[#{COLORS[color]}m#{str}\e[0m"
end
private
def open_file(filename, flag = 'r')
return if filename.nil?
flag = 'wb' if @options[:unix_newlines] && flag == 'w'
File.open(filename, flag)
end
def handle_load_error(err)
dep = err.message[/^no such file to load -- (.*)/, 1]
raise err if @options[:trace] || dep.nil? || dep.empty?
$stderr.puts <] 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 = < 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
html2haml-1.0.1/lib/html2haml/html.rb 0000644 0001750 0001750 00000032623 12147506116 016357 0 ustar gwolf gwolf require 'cgi'
require 'hpricot'
require 'html2haml/html/erb'
# 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[].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::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("Blat").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 'html2haml/html/erb'
template = ERB.compile(template)
end
method = @options[:xhtml] ? Hpricot.method(:XML) : method(:Hpricot)
@template = method.call(template.gsub('&', '&'))
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(\[[^\]]+\])>(.*) 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") || text.empty?
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{\s*(.+?)\s*}) 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))
else
# Indentation is inconsistent. Strip whitespace from start and indent all
# to ensure valid Haml.
content.lstrip!
content.gsub!(/^/, tabulate(tabs + 1))
end
content.rstrip!
content << "\n"
"#{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
html2haml-1.0.1/lib/html2haml/version.rb 0000644 0001750 0001750 00000000051 12147506116 017066 0 ustar gwolf gwolf module Html2haml
VERSION = "1.0.1"
end
html2haml-1.0.1/lib/html2haml.rb 0000644 0001750 0001750 00000000321 12147506116 015401 0 ustar gwolf gwolf require "rubygems"
gem "haml", ">= 3.2"
require File.expand_path("../html2haml/version", __FILE__)
require "haml/util"
require "haml/parser"
require "haml/error"
require "html2haml/html"
module Html2haml
end
html2haml-1.0.1/test/ 0000755 0001750 0001750 00000000000 12147506116 013401 5 ustar gwolf gwolf html2haml-1.0.1/test/html2haml_test.rb 0000644 0001750 0001750 00000020135 12147506116 016656 0 ustar gwolf gwolf require 'test_helper'
class Html2HamlTest < MiniTest::Unit::TestCase
def test_empty_render_should_remain_empty
assert_equal '', render('')
end
def test_doctype
assert_equal '!!!', render("")
assert_equal '!!! 1.1', render('')
assert_equal '!!! Strict', render('')
assert_equal '!!! Frameset', render('')
assert_equal '!!! Mobile 1.2', render('')
assert_equal '!!! Basic 1.1', render('')
assert_equal '!!!', render('')
assert_equal '!!! Strict', render('')
assert_equal '!!! Frameset', render('')
assert_equal '!!!', render('')
end
def test_id_and_class_should_be_removed_from_hash
assert_equal '%span#foo.bar', render('')
end
def test_no_tag_name_for_div_if_class_or_id_is_present
assert_equal '#foo', render('
')
assert_equal '.foo', render('
')
end
def test_multiple_class_names
assert_equal '.foo.bar.baz', render('
HTML
end
def test_self_closing_tag
assert_equal("%foo/", render(""))
end
def test_inline_text
assert_equal("%p foo", render("
foo
"))
end
def test_inline_comment
assert_equal("/ foo", render(""))
assert_equal(<
bar
HTML
end
def test_non_inline_comment
assert_equal(<
HTML
end
def test_non_inline_text
assert_equal(<
foo
HTML
assert_equal(<
foo
HTML
assert_equal(<foo
HTML
end
def test_script_tag
assert_equal(<
function foo() {
return "12" & "13";
}
HTML
end
def test_script_tag_with_cdata
assert_equal(<
HTML
end
def test_pre
assert_equal(<foo
bar
baz
HTML
end
def test_pre_code
assert_equal(<foo
bar
baz
HTML
end
def test_code_without_pre
assert_equal(<foo
bar
baz
HTML
end
def test_conditional_comment
assert_equal(<
bar
baz
HTML
end
def test_style_to_css_filter
assert_equal(<
foo {
bar: baz;
}
HTML
end
def test_style_to_css_filter_with_following_content
assert_equal(<
Hello
HTML
end
def test_filter_with_inconsistent_indentation
assert_equal(<
foo {
badly: indented;
}
HTML
end
def test_inline_conditional_comment
assert_equal(< bar baz
HTML
end
def test_minus_in_tag
assert_equal("%p - foo bar -", render("
- foo bar -
"))
end
def test_equals_in_tag
assert_equal("%p = foo bar =", render("
= foo bar =
"))
end
def test_hash_in_tag
assert_equal("%p # foo bar #", render("
# foo bar #
"))
end
def test_comma_post_tag
assert_equal(< Foo
,
%span bar
Foo
%span> bar
,
%span baz
HAML
Foo, bar
Foobar, baz
HTML
end
def test_comma_post_tag_with_text_before
assert_equal(<
Batch
Foo, Bar
HTML
end
def test_haml_tags_should_be_on_new_line_after_tag_with_blank_content
xml = "\n102"
haml = "%weight\n%pages 102"
assert_equal haml, render(xml)
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
end
end
html2haml-1.0.1/test/erb_test.rb 0000644 0001750 0001750 00000021412 12147506116 015535 0 ustar gwolf gwolf require 'test_helper'
class ErbTest < MiniTest::Unit::TestCase
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("
<%= foo %>
"))
end
def test_non_inline_erb
assert_equal(<
<%= foo %>
HTML
assert_equal(<
<%= foo %>
HTML
assert_equal(<<%= foo %>
HTML
end
def test_erb_in_cdata
assert_equal(< baz]]>
HTML
end
def test_erb_in_script
assert_equal(<
function foo() {
return <%= foo.to_json %>;
}
HTML
end
def test_erb_in_style
assert_equal(<
foo {
bar: <%= "baz" %>;
}
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('
I have a dynamic attribute
')
end
def test_erb_in_id_attribute
assert_equal "%div{:id => dyna_id} I have a dynamic attribute",
render_erb('
ERB
end
def test_multiline_erb_but_really_single_line
assert_equal(<
<%=
foo
%>
foo
ERB
end
### Block Parsing
def test_block_parsing
assert_equal(<
bar
<% end %>
ERB
end
def test_block_parsing_with_args
assert_equal(<
bar
<% end %>
ERB
end
def test_block_parsing_with_equals
assert_equal(<
bar
<% end %>
ERB
end
def test_block_parsing_with_modified_end
assert_equal(<
blah
<% end.bip %>
ERB
end
def test_block_parsing_with_modified_end_with_block
assert_equal(<
blah
<% end.bip do %>
brang
<% end %>
ERB
end
def test_multiline_block_opener
assert_equal(<
foo
<% end %>
ERB
end
def test_if_elsif_else_parsing
assert_equal(<
bar
<% elsif bar.foo("zip") %>
baz
<% else %>
bibble
<% end %>
ERB
end
def test_case_when_parsing
assert_equal(<
<% when "bip" %>
bip
<% when "bop" %>
BOP
<% when bizzle.bang.boop.blip %>
BIZZLE BANG BOOP BLIP
<% end %>
ERB
assert_equal(<
bip
<% when "bop" %>
BOP
<% when bizzle.bang.boop.blip %>
BIZZLE BANG BOOP BLIP
<% end %>
ERB
end
def test_begin_rescue_ensure
assert_equal(< e
%p b
- ensure
%p c
HAML
<% begin %>
a
<% rescue FooException => e %>
b
<% ensure %>
c
<% end %>
ERB
end
# Regression
def test_tag_inside_block
assert_equal(<
<% foo.each do %>
<% end %>
ERB
end
def test_silent_inside_block_inside_tag
assert_equal(<
<% foo.each do %>
<% haml_puts "foo" %>
<% end %>
ERB
end
def test_commented_erb_should_not_cause_indentation
assert_equal(<
html2haml and multiline titles
<%=# stylesheet_link_tag :first %>
<%#= stylesheet_link_tag :second %>
<%# stylesheet_link_tag :third %>
<%= stylesheet_link_tag 'another file' %>
ERB
end
def test_can_parse_ruby_19_hashes_as_arguments
erb = "<%= foobar 'foo', {bar: 'baz'} %>"
begin
Haml::HTML::ERB.new(erb)
rescue
flunk "should not raise an error"
end
end
def test_should_wrap_in_silent
assert_equal(< some_variable_or_function \n
HTML
<% some_variable_or_function %>
ERB
end
#comment content is removed by erubis
def test_should_wrap_process_comments_as_empty_lines
assert_equal(<\n
HTML
<%# some_variable_or_function %>
ERB
end
end
html2haml-1.0.1/test/test_helper.rb 0000644 0001750 0001750 00000000624 12147506116 016246 0 ustar gwolf gwolf require "rubygems"
if ENV["COVERAGE"]
require "simplecov"
SimpleCov.start
end
require "bundler/setup"
require "minitest/autorun"
require "html2haml"
require 'html2haml/html'
require 'html2haml/html/erb'
class MiniTest::Unit::TestCase
protected
def render(text, options = {})
Haml::HTML.new(text, options).render.rstrip
end
def render_erb(text)
render(text, :erb => true)
end
end
html2haml-1.0.1/MIT-LICENSE 0000644 0001750 0001750 00000002113 12147506116 014053 0 ustar gwolf gwolf Copyright (c) 2006-2013 Hampton Catlin, Nathan Weizenbaum and Norman Clarke
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. html2haml-1.0.1/README.md 0000644 0001750 0001750 00000004552 12147506116 013707 0 ustar gwolf gwolf # Html2haml
Converts HTML to Haml.
## Installation
Add this line to your application's Gemfile:
gem 'html2haml'
And then execute:
$ bundle
Or install it yourself as:
$ gem install html2haml
## Usage
See `html2haml --help`:
Usage: html2haml [options] [INPUT] [OUTPUT]
Description: Transforms an HTML file into corresponding Haml code.
Options:
-e, --erb Parse ERb tags.
--no-erb Don't parse ERb tags.
-r, --rhtml Deprecated; same as --erb.
--no-rhtml Deprecated; same as --no-erb.
-x, --xhtml Parse the input using the more strict XHTML parser.
--html-attributes Use HTML style attributes instead of Ruby hash style.
-E ex[:in] Specify the default external and internal character encodings.
-s, --stdin Read input from standard input instead of an input file
--trace Show a full traceback on error
--unix-newlines Use Unix-style newlines in written files.
-?, -h, --help Show this message
-v, --version Print version
## License
Copyright (c) 2006-2013 Hampton Catlin, Nathan Weizenbaum and Norman Clarke
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
html2haml-1.0.1/Rakefile 0000644 0001750 0001750 00000001056 12147506116 014071 0 ustar gwolf gwolf require "rake/clean"
require "rake/testtask"
require "rubygems/package_task"
task :default => :test
CLEAN.replace %w(pkg doc coverage .yardoc)
Rake::TestTask.new do |t|
t.libs << 'lib' << 'test'
t.test_files = Dir["test/**/*_test.rb"]
t.verbose = true
end
task :set_coverage_env do
ENV["COVERAGE"] = "true"
end
desc "Run Simplecov (only works on 1.9)"
task :coverage => [:set_coverage_env, :test]
gemspec = File.expand_path("../html2haml.gemspec", __FILE__)
if File.exist? gemspec
Gem::PackageTask.new(eval(File.read(gemspec))) { |pkg| }
end
html2haml-1.0.1/Changelog.markdown 0000644 0001750 0001750 00000000343 12147506116 016055 0 ustar gwolf gwolf # HTML2Haml Changelog
## 1.0.1
Rescue from `RubyParser::SyntaxError` in check for valid ruby.
## 1.0.0
* Extracted from Haml and released as an independent gem. For changes from
previous versions, see the Haml changelog.
html2haml-1.0.1/.gitignore 0000644 0001750 0001750 00000000117 12147506116 014411 0 ustar gwolf gwolf /.yardoc
/coverage
/doc
/pkg
*.rbc
.rbenv-version
Gemfile.lock
.rvmrc
.rbx
tmp
html2haml-1.0.1/.travis.yml 0000644 0001750 0001750 00000000220 12147506116 014525 0 ustar gwolf gwolf rvm:
- 1.8.7
- 1.9.3
- jruby-18mode
- rbx-18mode
gemfile:
- Gemfile
branches:
only:
- master
script: "bundle exec rake test"
html2haml-1.0.1/Gemfile 0000644 0001750 0001750 00000000050 12147506116 013710 0 ustar gwolf gwolf source 'https://rubygems.org'
gemspec
html2haml-1.0.1/metadata.yml 0000644 0001750 0001750 00000007055 12147506116 014734 0 ustar gwolf gwolf --- !ruby/object:Gem::Specification
name: html2haml
version: !ruby/object:Gem::Version
prerelease: false
segments:
- 1
- 0
- 1
version: 1.0.1
platform: ruby
authors:
- Norman Clarke
autorequire:
bindir: bin
cert_chain: []
date: 2013-02-16 00:00:00 -03:00
default_executable:
dependencies:
- !ruby/object:Gem::Dependency
name: hpricot
prerelease: false
requirement: &id001 !ruby/object:Gem::Requirement
requirements:
- - ~>
- !ruby/object:Gem::Version
segments:
- 0
- 8
- 6
version: 0.8.6
type: :runtime
version_requirements: *id001
- !ruby/object:Gem::Dependency
name: erubis
prerelease: false
requirement: &id002 !ruby/object:Gem::Requirement
requirements:
- - ~>
- !ruby/object:Gem::Version
segments:
- 2
- 7
- 0
version: 2.7.0
type: :runtime
version_requirements: *id002
- !ruby/object:Gem::Dependency
name: ruby_parser
prerelease: false
requirement: &id003 !ruby/object:Gem::Requirement
requirements:
- - ~>
- !ruby/object:Gem::Version
segments:
- 3
- 1
- 1
version: 3.1.1
type: :runtime
version_requirements: *id003
- !ruby/object:Gem::Dependency
name: haml
prerelease: false
requirement: &id004 !ruby/object:Gem::Requirement
requirements:
- - ">="
- !ruby/object:Gem::Version
segments:
- 4
- 0
- 0
- rc
- 1
version: 4.0.0.rc.1
type: :runtime
version_requirements: *id004
- !ruby/object:Gem::Dependency
name: simplecov
prerelease: false
requirement: &id005 !ruby/object:Gem::Requirement
requirements:
- - ~>
- !ruby/object:Gem::Version
segments:
- 0
- 7
- 1
version: 0.7.1
type: :development
version_requirements: *id005
- !ruby/object:Gem::Dependency
name: minitest
prerelease: false
requirement: &id006 !ruby/object:Gem::Requirement
requirements:
- - ~>
- !ruby/object:Gem::Version
segments:
- 4
- 4
- 0
version: 4.4.0
type: :development
version_requirements: *id006
- !ruby/object:Gem::Dependency
name: rake
prerelease: false
requirement: &id007 !ruby/object:Gem::Requirement
requirements:
- - ">="
- !ruby/object:Gem::Version
segments:
- 0
version: "0"
type: :development
version_requirements: *id007
description: Converts HTML into Haml
email:
- norman@njclarke.com
executables:
- html2haml
extensions: []
extra_rdoc_files: []
files:
- .gitignore
- .travis.yml
- Changelog.markdown
- Gemfile
- MIT-LICENSE
- README.md
- Rakefile
- bin/html2haml
- html2haml.gemspec
- lib/html2haml.rb
- lib/html2haml/exec.rb
- lib/html2haml/html.rb
- lib/html2haml/html/erb.rb
- lib/html2haml/version.rb
- test/erb_test.rb
- test/html2haml_test.rb
- test/test_helper.rb
has_rdoc: true
homepage: http://haml.info
licenses: []
post_install_message:
rdoc_options: []
require_paths:
- lib
required_ruby_version: !ruby/object:Gem::Requirement
requirements:
- - ">="
- !ruby/object:Gem::Version
segments:
- 0
version: "0"
required_rubygems_version: !ruby/object:Gem::Requirement
requirements:
- - ">="
- !ruby/object:Gem::Version
segments:
- 0
version: "0"
requirements: []
rubyforge_project:
rubygems_version: 1.3.6
signing_key:
specification_version: 3
summary: Converts HTML into Haml
test_files:
- test/erb_test.rb
- test/html2haml_test.rb
- test/test_helper.rb
html2haml-1.0.1/html2haml.gemspec 0000644 0001750 0001750 00000001722 12147506116 015661 0 ustar gwolf gwolf # -*- encoding: utf-8 -*-
require File.expand_path('../lib/html2haml/version', __FILE__)
Gem::Specification.new do |gem|
gem.authors = ["Norman Clarke"]
gem.email = ["norman@njclarke.com"]
gem.description = %q{Converts HTML into Haml}
gem.summary = %q{Converts HTML into Haml}
gem.homepage = "http://haml.info"
gem.files = `git ls-files`.split($\)
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
gem.name = "html2haml"
gem.require_paths = ["lib"]
gem.version = Html2haml::VERSION
gem.add_dependency 'hpricot', '~> 0.8.6'
gem.add_dependency 'erubis', '~> 2.7.0'
gem.add_dependency 'ruby_parser', '~> 3.1.1'
gem.add_dependency 'haml', '>= 4.0.0.rc.1'
gem.add_development_dependency 'simplecov', '~> 0.7.1'
gem.add_development_dependency 'minitest', '~> 4.4.0'
gem.add_development_dependency 'rake'
end