├── .gitignore
├── Gemfile
├── README.md
├── Rakefile
├── bin
└── haml2slim
├── haml2slim.gemspec
├── lib
├── haml2slim.rb
└── haml2slim
│ ├── command.rb
│ ├── converter.rb
│ └── version.rb
└── test
├── fixtures
├── _av_partial_1.haml
├── _av_partial_1_ugly.haml
├── _av_partial_2.haml
├── _av_partial_2_ugly.haml
├── _layout_for_partial.haml
├── _partial.haml
├── _text_area.haml
├── breakage.haml
├── content_for_layout.haml
├── eval_suppressed.haml
├── helpers.haml
├── nuke_inner_whitespace.haml
├── nuke_outer_whitespace.haml
├── original_engine.haml
├── partial_layout.haml
├── partialize.haml
├── partials.haml
├── render_layout.haml
├── silent_script.haml
├── standard.haml
├── tag_parsing.haml
└── very_basic.haml
├── helper.rb
└── test_haml2slim.rb
/.gitignore:
--------------------------------------------------------------------------------
1 | pkg/
2 | *.gem
3 | .bundle
4 | Gemfile.lock
5 | .rvmrc
6 | .idea
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | gemspec
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Haml2Slim
2 |
3 | [Haml](https://github.com/nex3/haml) to [Slim](https://github.com/stonean/slim) converter.
4 |
5 | ## Limitation
6 |
7 | Due to the complex logic behind both Haml's and Slim's parsers, there is currently no way of reliably converting between Haml and Slim templates.
8 |
9 | `Haml2Slim` only serves as a preliminary tool for templates conversion. You should __always__ manually verify the converted templates.
10 |
11 | ## Usage
12 |
13 | You may convert files using the included executable `haml2slim`.
14 |
15 | # haml2slim -h
16 |
17 | Usage: haml2slim INPUT_FILENAME_OR_DIRECTORY [OUTPUT_FILENAME_OR_DIRECTORY] [options]
18 | --trace Show a full traceback on error
19 | -d, --delete Delete HAML files
20 | -h, --help Show this message
21 | -v, --version Print version
22 |
23 | Alternatively, to convert files or strings on the fly in your application, you may do so by calling `Haml2Slim.convert!`.
24 |
25 | ## License
26 |
27 | This project is released under the MIT license.
28 |
29 | ## Author
30 |
31 | [Fred Wu](https://github.com/fredwu)
32 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | begin
2 | require 'bundler'
3 | Bundler::GemHelper.install_tasks
4 | rescue Exception => e
5 | end
6 |
7 | require 'rake/testtask'
8 |
9 | Rake::TestTask.new(:test) do |t|
10 | t.libs << 'lib' << 'test'
11 | t.pattern = 'test/**/test_*.rb'
12 | t.verbose = true
13 | end
14 |
15 | task :default => 'test'
16 |
--------------------------------------------------------------------------------
/bin/haml2slim:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 |
3 | $:.unshift File.dirname(__FILE__) + '/../lib'
4 | require 'haml2slim/command'
5 |
6 | cmd = Haml2Slim::Command.new(ARGV)
7 | cmd.run
8 |
--------------------------------------------------------------------------------
/haml2slim.gemspec:
--------------------------------------------------------------------------------
1 | # -*- encoding: utf-8 -*-
2 | require File.expand_path("../lib/haml2slim/version", __FILE__)
3 | require "date"
4 |
5 | Gem::Specification.new do |s|
6 | s.name = "haml2slim"
7 | s.version = Haml2Slim::VERSION
8 | s.date = Date.today.to_s
9 | s.authors = ["Fred Wu"]
10 | s.email = ["ifredwu@gmail.com"]
11 | s.summary = %q{Haml to Slim converter.}
12 | s.description = %q{Convert Haml templates to Slim templates.}
13 | s.homepage = %q{http://github.com/fredwu/haml2slim}
14 | s.extra_rdoc_files = ["README.md"]
15 | s.rdoc_options = ["--charset=UTF-8"]
16 | s.require_paths = ["lib"]
17 | s.files = `git ls-files -- lib/* bin/* README.md`.split("\n")
18 | s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19 |
20 | s.add_dependency "haml", [">= 3.0"]
21 | s.add_dependency "nokogiri"
22 | s.add_dependency "ruby_parser"
23 | s.add_development_dependency 'rake'
24 | s.add_development_dependency "slim", [">= 1.0.0"]
25 | end
26 |
--------------------------------------------------------------------------------
/lib/haml2slim.rb:
--------------------------------------------------------------------------------
1 | require 'haml2slim/version'
2 | require 'haml2slim/converter'
3 |
4 | module Haml2Slim
5 | def self.convert!(input)
6 | Converter.new(input)
7 | end
8 | end
--------------------------------------------------------------------------------
/lib/haml2slim/command.rb:
--------------------------------------------------------------------------------
1 | require 'optparse'
2 | require 'haml2slim'
3 |
4 | module Haml2Slim
5 | class Command
6 | def initialize(args)
7 | @args = args
8 | @options = {}
9 | end
10 |
11 | def run
12 | @opts = OptionParser.new(&method(:set_opts))
13 | @opts.parse!(@args)
14 | process!
15 | exit 0
16 | rescue Exception => ex
17 | raise ex if @options[:trace] || SystemExit === ex
18 | $stderr.print "#{ex.class}: " if ex.class != RuntimeError
19 | $stderr.puts ex.message
20 | $stderr.puts ' Use --trace for backtrace.'
21 | exit 1
22 | end
23 |
24 | protected
25 |
26 | def set_opts(opts)
27 | opts.banner = "Usage: haml2slim INPUT_FILENAME_OR_DIRECTORY [OUTPUT_FILENAME_OR_DIRECTORY] [options]"
28 |
29 | opts.on('--trace', :NONE, 'Show a full traceback on error') do
30 | @options[:trace] = true
31 | end
32 |
33 | opts.on_tail('-h', '--help', 'Show this message') do
34 | puts opts
35 | exit
36 | end
37 |
38 | opts.on_tail('-v', '--version', 'Print version') do
39 | puts "Haml2Slim #{Haml2Slim::VERSION}"
40 | exit
41 | end
42 |
43 | opts.on('-d', '--delete', 'Delete HAML files') do
44 | @options[:delete] = true
45 | end
46 | end
47 |
48 | def process!
49 | args = @args.dup
50 |
51 | @options[:input] = file = args.shift
52 | @options[:output] = destination = args.shift
53 |
54 | @options[:input] = file = "-" unless file
55 |
56 | if File.directory?(@options[:input])
57 | Dir["#{@options[:input]}/**/*.haml"].each { |file| _process(file, destination) }
58 | else
59 | _process(file, destination)
60 | end
61 | end
62 |
63 | private
64 |
65 | def _process(file, destination = nil)
66 | require 'fileutils'
67 | slim_file = file.sub(/\.haml$/, '.slim')
68 |
69 | if File.directory?(@options[:input]) && destination
70 | FileUtils.mkdir_p(File.dirname(slim_file).sub(@options[:input].chomp('/'), destination))
71 | slim_file.sub!(@options[:input].chomp('/'), destination)
72 | else
73 | slim_file = destination || slim_file
74 | end
75 |
76 | in_file = if @options[:input] == "-"
77 | $stdin
78 | else
79 | File.open(file, 'r')
80 | end
81 |
82 | @options[:output] = slim_file && slim_file != '-' ? File.open(slim_file, 'w') : $stdout
83 | @options[:output].puts Haml2Slim.convert!(in_file)
84 | @options[:output].close
85 |
86 | File.delete(file) if @options[:delete]
87 | end
88 | end
89 | end
90 |
--------------------------------------------------------------------------------
/lib/haml2slim/converter.rb:
--------------------------------------------------------------------------------
1 | module Haml2Slim
2 | class Converter
3 | def initialize(haml)
4 | @slim = ""
5 |
6 | haml.each_line do |line|
7 | @slim << parse_line(line)
8 | end
9 | end
10 |
11 | def to_s
12 | @slim
13 | end
14 |
15 | def parse_line(line)
16 | indent = line[/^[ \t]*/]
17 | line.strip!
18 |
19 | # removes the HAML's whitespace removal characters ('>' and '<')
20 | line.gsub!(/(>|<)$/, '')
21 |
22 | converted = case line[0, 2]
23 | when '&=' then line.sub(/^&=/, '==')
24 | when '!=' then line.sub(/^!=/, '==')
25 | when '-#' then line.sub(/^-#/, '/')
26 | when '#{' then line
27 | else
28 | case line[0]
29 | when ?%, ?., ?# then parse_tag(line)
30 | when ?: then "#{line[1..-1]}:"
31 | when ?! then line == "!!!" ? line.sub(/^!!!/, 'doctype html') : line.sub(/^!!!/, 'doctype')
32 | when ?-, ?= then line
33 | when ?~ then line.sub(/^~/, '=')
34 | when ?/ then line.sub(/^\//, '/!')
35 | when ?\ then line.sub(/^\\/, '|')
36 | when nil then ""
37 | else "| #{line}"
38 | end
39 | end
40 |
41 | if converted.chomp!(' |')
42 | converted.sub!(/^\| /, '')
43 | converted << ' \\'
44 | end
45 |
46 | "#{indent}#{converted}\n"
47 | end
48 |
49 | def parse_tag(tag_line)
50 | tag_line.sub!(/^%/, '')
51 | tag_line.sub!(/^(\w+)!=/, '\1==')
52 |
53 | if tag_line_contains_attr = tag_line.match(/([^\{]+)\{(.+)\}(.*)/)
54 | tag, attrs, text = *tag_line_contains_attr[1..3]
55 | "#{tag} #{parse_attrs(attrs)} #{text}"
56 | else
57 | tag_line.sub(/^!=/, '=')
58 | end
59 | end
60 |
61 | def parse_attrs(attrs, key_prefix='')
62 | data_temp = {}
63 | attrs.gsub!(/:data\s*=>\s*\{([^\}]*)\}/) do
64 | key = rand(99999).to_s
65 | data_temp[key] = parse_attrs($1, 'data-')
66 | ":#{key} => #{key}"
67 | end
68 | [
69 | /,?( ?):?"?([^"'{ ]+)"?\s*=>\s*([^,]*)/,
70 | /,?( ?)"?([^"'{ ]+)"?:\s*([^,]*)/
71 | ].each do |regexp|
72 | attrs.gsub!(regexp) do
73 | space = $1
74 | key = $2
75 | value = $3
76 | wrapped_value = value.to_s =~ /\s+/ ? "(#{value})" : value
77 | "#{space}#{key_prefix}#{key}=#{wrapped_value}"
78 | end
79 | end
80 | data_temp.each do |k, v|
81 | attrs.gsub!("#{k}=#{k}", v)
82 | end
83 | attrs
84 | end
85 | end
86 | end
87 |
--------------------------------------------------------------------------------
/lib/haml2slim/version.rb:
--------------------------------------------------------------------------------
1 | module Haml2Slim
2 | VERSION = '0.4.7'
3 | end
4 |
--------------------------------------------------------------------------------
/test/fixtures/_av_partial_1.haml:
--------------------------------------------------------------------------------
1 | %h2 This is a pretty complicated partial
2 | .partial
3 | %p It has several nested partials,
4 | %ul
5 | - 5.times do
6 | %li
7 | %strong Partial:
8 | - @nesting = 5
9 | = render :partial => 'haml/templates/av_partial_2'
--------------------------------------------------------------------------------
/test/fixtures/_av_partial_1_ugly.haml:
--------------------------------------------------------------------------------
1 | %h2 This is a pretty complicated partial
2 | .partial
3 | %p It has several nested partials,
4 | %ul
5 | - 5.times do
6 | %li
7 | %strong Partial:
8 | - @nesting = 5
9 | = render :partial => 'haml/templates/av_partial_2_ugly'
--------------------------------------------------------------------------------
/test/fixtures/_av_partial_2.haml:
--------------------------------------------------------------------------------
1 | - @nesting -= 1
2 | .partial{:level => @nesting}
3 | %h3 This is a crazy deep-nested partial.
4 | %p== Nesting level #{@nesting}
5 | = render :partial => 'haml/templates/av_partial_2' if @nesting > 0
--------------------------------------------------------------------------------
/test/fixtures/_av_partial_2_ugly.haml:
--------------------------------------------------------------------------------
1 | - @nesting -= 1
2 | .partial{:level => @nesting}
3 | %h3 This is a crazy deep-nested partial.
4 | %p== Nesting level #{@nesting}
5 | = render :partial => 'haml/templates/av_partial_2_ugly' if @nesting > 0
--------------------------------------------------------------------------------
/test/fixtures/_layout_for_partial.haml:
--------------------------------------------------------------------------------
1 | .partial-layout
2 | %h2 This is inside a partial layout
3 | = yield
--------------------------------------------------------------------------------
/test/fixtures/_partial.haml:
--------------------------------------------------------------------------------
1 | %p
2 | @foo =
3 | = @foo
4 | - @foo = 'value three'
5 | == Toplevel? #{haml_buffer.toplevel?}
6 | %p
7 | @foo =
8 | = @foo
9 |
--------------------------------------------------------------------------------
/test/fixtures/_text_area.haml:
--------------------------------------------------------------------------------
1 | .text_area_test_area
2 | ~ ""
3 | = ""
4 |
--------------------------------------------------------------------------------
/test/fixtures/breakage.haml:
--------------------------------------------------------------------------------
1 | %p
2 | %h1 Hello!
3 | = "lots of lines"
4 | - raise "Oh no!"
5 | %p
6 | this is after the exception
7 | %strong yes it is!
8 | ho ho ho.
9 |
--------------------------------------------------------------------------------
/test/fixtures/content_for_layout.haml:
--------------------------------------------------------------------------------
1 | !!!
2 | %html
3 | %head
4 | %body
5 | #yieldy
6 | = yield :layout
7 | #nosym
8 | = yield
9 |
--------------------------------------------------------------------------------
/test/fixtures/eval_suppressed.haml:
--------------------------------------------------------------------------------
1 | = "not me!"
2 | = "nor me!"
3 | - haml_concat "not even me!"
4 | %p= "NO!"
5 | %p~ "UH-UH!"
6 | %h1 Me!
7 | #foo
8 | %p#bar All
9 | %br/
10 | %p.baz This
11 | Should render
12 |
--------------------------------------------------------------------------------
/test/fixtures/helpers.haml:
--------------------------------------------------------------------------------
1 | = h("&&&&&&&&&&&") # This is an ActionView Helper... should load
2 | - foo = capture do # This ActionView Helper is designed for ERB, but should work with haml
3 | %div
4 | %p.title Title
5 | %p.text
6 | Woah this is really crazy
7 | I mean wow,
8 | man.
9 | - 3.times do
10 | = foo
11 | %p foo
12 | - tab_up
13 | %p reeeeeeeeeeeeeeeeeeeeeeeeeeeeeeally loooooooooooooooooong
14 | - tab_down
15 | .woah
16 | #funky
17 | = capture_haml do
18 | %div
19 | %h1 Big!
20 | %p Small
21 | / Invisible
22 | = capture do
23 | .dilly
24 | %p foo
25 | %h1 bar
26 | = surround '(', ')' do
27 | %strong parentheses!
28 | = precede '*' do
29 | %span.small Not really
30 | click
31 | = succeed '.' do
32 | %a{:href=>"thing"} here
33 | %p baz
34 | - haml_buffer.tabulation = 10
35 | %p boom
36 | - concat "foo\n"
37 | - haml_buffer.tabulation = 0
38 | = list_of({:google => 'http://www.google.com'}) do |name, link|
39 | %a{ :href => link }= name
40 | %p
41 | - haml_concat "foo"
42 | %div
43 | - haml_concat "bar"
44 | - haml_concat "boom"
45 | baz
46 | - haml_concat "boom, again"
47 | - haml_tag :table do
48 | - haml_tag :tr do
49 | - haml_tag :td, {:class => 'cell'} do
50 | - haml_tag :strong, "strong!"
51 | - haml_concat "data"
52 | - haml_tag :td do
53 | - haml_concat "more_data"
54 | - haml_tag :hr
55 | - haml_tag :div, ''
56 |
--------------------------------------------------------------------------------
/test/fixtures/nuke_inner_whitespace.haml:
--------------------------------------------------------------------------------
1 | %p
2 | %q< Foo
3 | %p
4 | %q{:a => 1 + 1}< Foo
5 | %p
6 | %q<= "Foo\nBar"
7 | %p
8 | %q{:a => 1 + 1}<= "Foo\nBar"
9 | %p
10 | %q<
11 | Foo
12 | Bar
13 | %p
14 | %q{:a => 1 + 1}<
15 | Foo
16 | Bar
17 | %p
18 | %q<
19 | %div
20 | Foo
21 | Bar
22 | %p
23 | %q{:a => 1 + 1}<
24 | %div
25 | Foo
26 | Bar
27 |
28 | -# Regression test
29 | %p
30 | %q<= "foo"
31 | %q{:a => 1 + 1}
32 | bar
33 |
--------------------------------------------------------------------------------
/test/fixtures/nuke_outer_whitespace.haml:
--------------------------------------------------------------------------------
1 | %p
2 | %p
3 | %q>
4 | Foo
5 | %p
6 | %p
7 | %q{:a => 1 + 1}>
8 | Foo
9 | %p
10 | %p
11 | %q> Foo
12 | %p
13 | %p
14 | %q{:a => 1 + 1}> Foo
15 | %p
16 | %p
17 | %q>
18 | = "Foo"
19 | %p
20 | %p
21 | %q{:a => 1 + 1}>
22 | = "Foo"
23 | %p
24 | %p
25 | %q>= "Foo"
26 | %p
27 | %p
28 | %q{:a => 1 + 1}>= "Foo"
29 | %p
30 | %p
31 | %q>
32 | = "Foo\nBar"
33 | %p
34 | %p
35 | %q{:a => 1 + 1}>
36 | = "Foo\nBar"
37 | %p
38 | %p
39 | %q>= "Foo\nBar"
40 | %p
41 | %p
42 | %q{:a => 1 + 1}>= "Foo\nBar"
43 | %p
44 | %p
45 | - tab_up
46 | foo
47 | %q>
48 | Foo
49 | bar
50 | - tab_down
51 | %p
52 | %p
53 | - tab_up
54 | foo
55 | %q{:a => 1 + 1}>
56 | Foo
57 | bar
58 | - tab_down
59 | %p
60 | %p
61 | - tab_up
62 | foo
63 | %q> Foo
64 | bar
65 | - tab_down
66 | %p
67 | %p
68 | - tab_up
69 | foo
70 | %q{:a => 1 + 1}> Foo
71 | bar
72 | - tab_down
73 | %p
74 | %p
75 | - tab_up
76 | foo
77 | %q>
78 | = "Foo"
79 | bar
80 | - tab_down
81 | %p
82 | %p
83 | - tab_up
84 | foo
85 | %q{:a => 1 + 1}>
86 | = "Foo"
87 | bar
88 | - tab_down
89 | %p
90 | %p
91 | - tab_up
92 | foo
93 | %q>= "Foo"
94 | bar
95 | - tab_down
96 | %p
97 | %p
98 | - tab_up
99 | foo
100 | %q{:a => 1 + 1}>= "Foo"
101 | bar
102 | - tab_down
103 | %p
104 | %p
105 | - tab_up
106 | foo
107 | %q>
108 | = "Foo\nBar"
109 | bar
110 | - tab_down
111 | %p
112 | %p
113 | - tab_up
114 | foo
115 | %q{:a => 1 + 1}>
116 | = "Foo\nBar"
117 | bar
118 | - tab_down
119 | %p
120 | %p
121 | - tab_up
122 | foo
123 | %q>= "Foo\nBar"
124 | bar
125 | - tab_down
126 | %p
127 | %p
128 | - tab_up
129 | foo
130 | %q{:a => 1 + 1}>= "Foo\nBar"
131 | bar
132 | - tab_down
133 | %p
134 | %p
135 | %q>
136 | %p
137 | %p
138 | %q>/
139 | %p
140 | %p
141 | %q{:a => 1 + 1}>
142 | %p
143 | %p
144 | %q{:a => 1 + 1}>/
145 |
--------------------------------------------------------------------------------
/test/fixtures/original_engine.haml:
--------------------------------------------------------------------------------
1 | !!!
2 | %html
3 | %head
4 | %title Stop. haml time
5 | #content
6 | %h1 This is a title!
7 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit
8 | %p{:class => 'foo'} Cigarettes!
9 | %h2 Man alive!
10 | %ul.things
11 | %li Slippers
12 | %li Shoes
13 | %li Bathrobe
14 | %li Coffee
15 | %pre
16 | This is some text that's in a pre block!
17 | Let's see what happens when it's rendered! What about now, since we're on a new line?
18 |
--------------------------------------------------------------------------------
/test/fixtures/partial_layout.haml:
--------------------------------------------------------------------------------
1 | %h1 Partial layout used with for block:
2 | - if Haml::Util.ap_geq_3?
3 | = render :layout => 'layout_for_partial.haml' do
4 | %p Some content within a layout
5 | - else
6 | - render :layout => 'layout_for_partial.haml' do
7 | %p Some content within a layout
8 |
--------------------------------------------------------------------------------
/test/fixtures/partialize.haml:
--------------------------------------------------------------------------------
1 | = render :file => "#{name}.haml"
2 |
--------------------------------------------------------------------------------
/test/fixtures/partials.haml:
--------------------------------------------------------------------------------
1 | - @foo = 'value one'
2 | %p
3 | @foo =
4 | = @foo
5 | - @foo = 'value two'
6 | %p
7 | @foo =
8 | = @foo
9 | = test_partial "partial"
10 | %p
11 | @foo =
12 | = @foo
13 |
--------------------------------------------------------------------------------
/test/fixtures/render_layout.haml:
--------------------------------------------------------------------------------
1 | = render :layout => 'layout' do
2 | During
3 |
--------------------------------------------------------------------------------
/test/fixtures/silent_script.haml:
--------------------------------------------------------------------------------
1 | %div
2 | %h1 I can count!
3 | - (1..20).each do |i|
4 | = i
5 | %h1 I know my ABCs!
6 | %ul
7 | - ('a'..'z').each do |i|
8 | %li= i
9 | %h1 I can catch errors!
10 | - begin
11 | - String.silly
12 | - rescue NameError => e
13 | = "Oh no! \"#{e}\" happened!"
14 | %p
15 | "false" is:
16 | - if false
17 | = "true"
18 | - else
19 | = "false"
20 | - if true
21 | - 5.times do |i|
22 | - if i % 2 == 1
23 | Odd!
24 | - else
25 | Even!
26 | - else
27 | = "This can't happen!"
28 | - 13 |
29 | .foo
30 | %strong foobar
31 | - 5.times |
32 | do |
33 | |a| |
34 | %strong= a
35 | .test
36 | - "foo |
37 | bar |
38 | baz" |
39 |
40 | %p boom
41 |
--------------------------------------------------------------------------------
/test/fixtures/standard.haml:
--------------------------------------------------------------------------------
1 | !!!
2 | %html{:xmlns => "http://www.w3.org/1999/xhtml", "xml:lang" => "en-US", "lang" => "en-US"}
3 | %head
4 | %title Hampton Catlin Is Totally Awesome
5 | %meta{"http-equiv" => "Content-Type", :content => "text/html; charset=utf-8"}
6 | %body
7 | / You're In my house now!
8 | .header
9 | Yes, ladies and gentileman. He is just that egotistical.
10 | Fantastic! This should be multi-line output
11 | The question is if this would translate! Ahah!
12 | = 1 + 9 + 8 + 2 #numbers should work and this should be ignored
13 | #body= " Quotes should be loved! Just like people!"
14 | - 120.times do |number|
15 | = number
16 | Wow.|
17 | %p{:code => 1 + 2}
18 | = "Holy cow " + |
19 | "multiline " + |
20 | "tags! " + |
21 | "A pipe (|) even!" |
22 | = [1, 2, 3].collect { |n| "PipesIgnored|" }.join
23 | = [1, 2, 3].collect { |n| |
24 | n.to_s |
25 | }.join("|") |
26 | - bar = 17
27 | %div.silent{:foo => bar}
28 | - foo = String.new
29 | - foo << "this"
30 | - foo << " shouldn't"
31 | - foo << " evaluate"
32 | = foo + " but now it should!"
33 | -# Woah crap a comment!
34 |
35 | -# That was a line that shouldn't close everything.
36 | %ul.really.cool
37 | - ('a'..'f').each do |a|
38 | %li= a
39 | #combo.of_divs_with_underscore= @should_eval = "with this text"
40 | = "foo".each_line do |line|
41 | - nil
42 | .footer
43 | %strong.shout= "This is a really long ruby quote. It should be loved and wrapped because its more than 50 characters. This value may change in the future and this test may look stupid. \nSo, I'm just making it *really* long. God, I hope this works"
44 |
--------------------------------------------------------------------------------
/test/fixtures/tag_parsing.haml:
--------------------------------------------------------------------------------
1 | %div.tags
2 | %foo 1
3 | %FOO 2
4 | %fooBAR 3
5 | %fooBar 4
6 | %foo_bar 5
7 | %foo-bar 6
8 | %foo:bar 7
9 | %foo.bar 8
10 | %fooBAr_baz:boom_bar 9
11 | %foo13 10
12 | %foo2u 11
13 | %div.classes
14 | %p.foo.bar#baz
15 | .fooBar a
16 | .foo-bar b
17 | .foo_bar c
18 | .FOOBAR d
19 | .foo16 e
20 | .123 f
21 | .foo2u g
22 |
--------------------------------------------------------------------------------
/test/fixtures/very_basic.haml:
--------------------------------------------------------------------------------
1 | !!!
2 | %html
3 | %head
4 | %body
5 |
--------------------------------------------------------------------------------
/test/helper.rb:
--------------------------------------------------------------------------------
1 | require 'rubygems'
2 | require 'minitest/unit'
3 | require 'slim'
4 | require 'haml2slim'
5 |
6 | MiniTest::Unit.autorun
--------------------------------------------------------------------------------
/test/test_haml2slim.rb:
--------------------------------------------------------------------------------
1 | require 'helper'
2 | require 'tmpdir'
3 |
4 | class TestHaml2Slim < MiniTest::Unit::TestCase
5 | def setup
6 | create_haml_file
7 | end
8 |
9 | def teardown
10 | cleanup_tmp_files
11 | end
12 |
13 | Dir.glob("test/fixtures/*.haml").each do |file|
14 | define_method("test_template_#{File.basename(file, '.haml')}") do
15 | assert_valid?(file)
16 | end
17 | end
18 |
19 | def test_convert_file
20 | `bin/haml2slim #{haml_file}`
21 | assert_equal true, slim_file?
22 | end
23 |
24 | def test_convert_file_to_destination
25 | slim_path = File.join(tmp_dir, "a.slim")
26 | `bin/haml2slim #{haml_file} #{slim_path}`
27 | assert_equal true, slim_file?(slim_path)
28 | end
29 |
30 | def test_convert_file_to_stdout
31 | File.open(haml_file, "w") do |f|
32 | f.puts "%p\n %h1 Hello"
33 | end
34 |
35 | IO.popen("bin/haml2slim #{haml_file} -", "r") do |f|
36 | assert_equal "p\n h1 Hello\n", f.read
37 | end
38 | end
39 |
40 | def test_convert_stdin_to_stdout
41 | File.open(haml_file, "w") do |f|
42 | f.puts "%p\n %h1 Hello"
43 | end
44 |
45 | IO.popen("cat #{haml_file} | bin/haml2slim", "r") do |f|
46 | assert_equal "p\n h1 Hello\n", f.read
47 | end
48 | end
49 |
50 | def test_convert_directory
51 | `bin/haml2slim #{tmp_dir}`
52 | assert_equal true, slim_file?
53 | end
54 |
55 | def test_convert_directory_to_destination
56 | slim_path = Dir.mktmpdir("haml2slim_2.")
57 | `bin/haml2slim #{tmp_dir} #{slim_path}`
58 | assert_equal true, slim_file?(File.join(slim_path, "dummy.slim"))
59 | FileUtils.rm_rf(slim_path)
60 | end
61 |
62 | def test_delete_haml_file
63 | `bin/haml2slim #{haml_file} -d`
64 | assert_equal false, File.exist?(haml_file)
65 | end
66 |
67 | def test_hash_convert
68 | haml = '%a{:title => 1 + 1, :href => "/#{test_obj.method}", :height => "50px", :width => "50px"}'
69 | slim = 'a title=(1 + 1) href="/#{test_obj.method}" height="50px" width="50px"'
70 | assert_haml_to_slim haml, slim
71 | end
72 |
73 | def test_data_attributes_convert
74 | haml = '%a{:href => "test", :data => {:param1 => var, :param2 => 1 + 1, :param3 => "string"}}'
75 | slim = 'a href="test" data-param1=var data-param2=(1 + 1) data-param3="string"'
76 | assert_haml_to_slim haml, slim
77 | end
78 |
79 | def test_new_syntax_hash_convert
80 | haml = '%a{title: 1 + 1, href: "/#{test_obj.method}", height: "50px", width: "50px"}'
81 | slim = 'a title=(1 + 1) href="/#{test_obj.method}" height="50px" width="50px"'
82 | assert_haml_to_slim haml, slim
83 | end
84 |
85 | def test_no_html_escape_predicate
86 | haml = '!= method_call'
87 | slim = '== method_call'
88 | assert_haml_to_slim haml, slim
89 | end
90 |
91 | def test_no_html_escape_predicate2
92 | haml = '%span!= method_call'
93 | slim = 'span== method_call'
94 | assert_haml_to_slim haml, slim
95 | end
96 |
97 | private
98 |
99 | def assert_haml_to_slim(actual_haml, expected_slim)
100 | File.open(haml_file, "w") do |f|
101 | f.puts actual_haml
102 | end
103 |
104 | IO.popen("cat #{haml_file} | bin/haml2slim", "r") do |f|
105 | assert_equal expected_slim, f.read.strip
106 | end
107 | end
108 |
109 | def tmp_dir
110 | @tmp_dir ||= Dir.mktmpdir("haml2slim.")
111 | end
112 |
113 | def create_haml_file
114 | `touch #{haml_file}`
115 | end
116 |
117 | def haml_file
118 | File.join(tmp_dir, "dummy.haml")
119 | end
120 |
121 | def slim_file?(path = nil)
122 | File.file?(path || File.join(tmp_dir, "dummy.slim"))
123 | end
124 |
125 | def cleanup_tmp_files
126 | FileUtils.rm_rf(tmp_dir)
127 | end
128 |
129 | def assert_valid?(source)
130 | haml = File.open(source)
131 | slim = Haml2Slim.convert!(haml)
132 | assert_instance_of String, Slim::Engine.new.call(slim.to_s)
133 | end
134 | end
135 |
--------------------------------------------------------------------------------