hamlizer 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm --create 1.9.3@hamlizer
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in hamlizer.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Lilibeth De La Cruz
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # Hamlizer
2
+
3
+ [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/lilibethdlc/hamlizer)
4
+
5
+ HTML/ERB to HAML converter
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'hamlizer'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install hamlizer
20
+
21
+ ## Usage
22
+
23
+ TODO: Write usage instructions here
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ RSpec::Core::RakeTask.new('spec')
4
+
5
+ task default: :spec
data/hamlizer.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'hamlizer/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = 'hamlizer'
8
+ gem.version = Hamlizer::VERSION
9
+ gem.authors = ['Lilibeth De La Cruz', 'Edgar Gonzalez']
10
+ gem.email = ['lilibethdlc@gmail.com', 'edggonzalezg@gmail.com']
11
+ gem.description = %q{Convert your views from HTML/ERB to HAML}
12
+ gem.summary = %q{HTML/ERB to HAML converter}
13
+ gem.homepage = ''
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ['lib']
19
+
20
+ gem.add_dependency 'nokogiri'
21
+
22
+ gem.add_development_dependency 'rspec'
23
+ gem.add_development_dependency 'haml'
24
+ end
data/lib/hamlizer.rb ADDED
@@ -0,0 +1,42 @@
1
+ require 'hamlizer/version'
2
+ require 'hamlizer/html_element'
3
+ require 'hamlizer/element_haml_converter'
4
+ require 'hamlizer/attributes_haml_converter'
5
+ require 'nokogiri'
6
+
7
+ module Hamlizer
8
+ def self.hamlize(html)
9
+ convert_erb_to_parseable_xml!(html)
10
+
11
+ if html.start_with?('<html>')
12
+ root = Nokogiri::HTML.parse(html).root
13
+ else
14
+ root = Nokogiri::HTML::DocumentFragment.parse(html)
15
+ end
16
+
17
+ return '' if root.nil?
18
+
19
+ children_haml = root.children.map { |element| ElementHamlConverter.new(HtmlElement.new(element)).haml }.join("\n")
20
+
21
+ if html.start_with?('<html>')
22
+ haml = "%html"
23
+ haml += "\n #{children_haml}" unless children_haml.empty?
24
+ haml
25
+ else
26
+ children_haml
27
+ end
28
+ end
29
+
30
+ def self.convert_erb_to_parseable_xml!(html)
31
+ remove_erb_printing_code!(html)
32
+ remove_erb_non_printing_code!(html)
33
+ end
34
+
35
+ def self.remove_erb_non_printing_code!(html)
36
+ html.gsub!(/<%(.+?)%>/, '<erb:erb_non_print>\1</erb:erb_non_print>')
37
+ end
38
+
39
+ def self.remove_erb_printing_code!(html)
40
+ html.gsub!(/<%=(.+?)%>/, '<erb:erb_print>\1</erb:erb_print>')
41
+ end
42
+ end
@@ -0,0 +1,38 @@
1
+ class AttributesHamlConverter
2
+ def initialize(element)
3
+ @element = element
4
+ end
5
+
6
+ def haml
7
+ element.has_attributes? ? (id_haml + class_haml + regular_attributes_haml) : ''
8
+ end
9
+
10
+ private
11
+
12
+ attr_reader :element
13
+
14
+ def attribute_haml(name, value)
15
+ if name.match(/^\w+$/)
16
+ attribute_name = "#{name}:"
17
+ else
18
+ attribute_name = "'#{name}' =>"
19
+ end
20
+ "#{attribute_name} '#{value}'"
21
+ end
22
+
23
+ def class_haml
24
+ element.html_class ? ".#{element.html_class.gsub(/\s+/, '.')}" : ''
25
+ end
26
+
27
+ def id_haml
28
+ element.id ? "##{element.id}" : ''
29
+ end
30
+
31
+ def regular_attributes_haml
32
+ attributes_haml = element.regular_attributes.map do |name, value|
33
+ attribute_haml name, value
34
+ end.compact.join(', ')
35
+
36
+ attributes_haml.empty? ? '' : "{ #{attributes_haml} }"
37
+ end
38
+ end
@@ -0,0 +1,75 @@
1
+ class ElementHamlConverter
2
+ def initialize(element, level = 1)
3
+ @element = element
4
+ @level = level
5
+ end
6
+
7
+ def haml
8
+ element_name_haml + attributes_haml + element_content_haml
9
+ end
10
+
11
+ private
12
+
13
+ attr_reader :element, :level
14
+
15
+ def attributes_haml
16
+ attributes_haml_converter.haml
17
+ end
18
+
19
+ def attributes_haml_converter
20
+ AttributesHamlConverter.new(element)
21
+ end
22
+
23
+ def element_content_haml
24
+ content_haml = element.children.map do |child|
25
+ if child.name == 'erb_print'
26
+ erb_print_haml(child)
27
+ elsif child.name == 'erb_non_print'
28
+ erb_non_print_haml(child)
29
+ elsif child.name == 'text'
30
+ text_haml(child)
31
+ else
32
+ "\n#{level_spacing}#{ElementHamlConverter.new(child, level + 1).haml}"
33
+ end
34
+ end.join
35
+
36
+ content_haml
37
+ end
38
+
39
+ def element_name_haml
40
+ should_include_name_in_haml? ? "%#{element.name}" : ''
41
+ end
42
+
43
+ def child_content(child)
44
+ child.content.gsub("\n", ' ').strip
45
+ end
46
+
47
+ def child_haml(child, code = nil)
48
+ if child.only_child?
49
+ "#{code} #{child_content(child)}"
50
+ else
51
+ code += ' ' if code
52
+ "\n#{level_spacing}#{code}#{child_content(child)}"
53
+ end
54
+ end
55
+
56
+ def erb_non_print_haml(element)
57
+ child_haml(element, '-')
58
+ end
59
+
60
+ def erb_print_haml(element)
61
+ child_haml(element, '=')
62
+ end
63
+
64
+ def level_spacing
65
+ ' ' * level
66
+ end
67
+
68
+ def should_include_name_in_haml?
69
+ (!element.div? || (element.has_id? && element.has_class?))
70
+ end
71
+
72
+ def text_haml(element)
73
+ child_haml(element)
74
+ end
75
+ end
@@ -0,0 +1,60 @@
1
+ require 'nokogiri'
2
+
3
+ class HtmlElement
4
+ def initialize(element)
5
+ @element = element
6
+ end
7
+
8
+ def children
9
+ element.children.map { |child| HtmlElement.new child }
10
+ end
11
+
12
+ def content
13
+ element.content
14
+ end
15
+
16
+ def div?
17
+ element.name == 'div'
18
+ end
19
+
20
+ def has_attributes?
21
+ element.attributes.any?
22
+ end
23
+
24
+ def has_class?
25
+ html_class.nil?
26
+ end
27
+
28
+ def has_content?
29
+ content && !content.empty?
30
+ end
31
+
32
+ def has_id?
33
+ id.nil?
34
+ end
35
+
36
+ def only_child?
37
+ element.parent.children.count == 1
38
+ end
39
+
40
+ def html_class
41
+ @class ||= element['class']
42
+ end
43
+
44
+ def id
45
+ @id ||= element['id']
46
+ end
47
+
48
+ def name
49
+ element.name
50
+ end
51
+
52
+ def regular_attributes
53
+ Hash[element.attributes.select { |name, _| !%w(id class).include? name }]
54
+ end
55
+
56
+ private
57
+
58
+ attr_reader :element, :parent
59
+ end
60
+
@@ -0,0 +1,3 @@
1
+ module Hamlizer
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,113 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hamlizer do
4
+ describe '.hamlize' do
5
+
6
+ it 'leaves an empty string alone' do
7
+ expect(hamlize('')).to eq ''
8
+ end
9
+
10
+ it 'returns empty string for whitespace' do
11
+ expect(hamlize(' ')).to eq ''
12
+ expect(hamlize("\n\n\n\n")).to eq ''
13
+ end
14
+
15
+ it 'converts an empty tag correctly' do
16
+ expect(hamlize('<br/>')).to eq '%br'
17
+ expect(hamlize('<br>')).to eq '%br'
18
+ end
19
+
20
+ it 'converts html standard layout tags correctly' do
21
+ expect(hamlize('<html></html>')).to eq '%html'
22
+ expect(hamlize('<html><body></body></html>')).to eq "%html\n %body"
23
+ end
24
+
25
+ it 'converts a tag with no content' do
26
+ expect(hamlize('<span></span>')).to eq '%span'
27
+ end
28
+
29
+ it 'converts a tag with text content' do
30
+ text = 'abc'
31
+ expect(hamlize("<span>#{text}</span>")).to eq "%span #{text}"
32
+ expect(hamlize("<span>#{text}\n#{text}</span>")).to eq "%span #{text} #{text}"
33
+ end
34
+
35
+ it 'converts multiple tags on the same level' do
36
+ expect(hamlize('<br/><br/><br/>')).to eq "%br\n%br\n%br"
37
+ text = 'hello'
38
+ expect(hamlize("<span>#{text}</span><span/>")).to eq "%span #{text}\n%span"
39
+ end
40
+
41
+ it 'converts nested tags' do
42
+ expect(hamlize('<div><span></span></div>')).to eq "%div\n %span"
43
+ expect(hamlize('<div><p><span></span></p></div>')).to eq "%div\n %p\n %span"
44
+ end
45
+
46
+ it 'converts nested tags with content' do
47
+ expect(hamlize('<div>abc<span>abc</span></div>')).to eq "%div\n abc\n %span abc"
48
+ expect(hamlize('<div>abc<p>hello<span>abc</span></p></div>')).to eq "%div\n abc\n %p\n hello\n %span abc"
49
+ end
50
+
51
+ it 'converts a tag with attributes' do
52
+ title = 'El Titulo'
53
+ source = 'La Fuente'
54
+
55
+ expect(hamlize("<span title='#{title}'></span>")).to eq "%span{ title: '#{title}' }"
56
+ expect(hamlize("<span title='#{title}' source='#{source}'></span>")).to eq "%span{ title: '#{title}', source: '#{source}' }"
57
+ expect(hamlize("<span title='#{title}' data-source='#{source}'></span>")).to eq "%span{ title: '#{title}', 'data-source' => '#{source}' }"
58
+ end
59
+
60
+ it 'uses the "#id" syntax for the id attribute' do
61
+ id = 'el_identificador'
62
+ title = 'El Titulo'
63
+
64
+ expect(hamlize("<span id='#{id}'></span>")).to eq "%span##{id}"
65
+ expect(hamlize("<span id='#{id}' title='#{title}'></span>")).to eq "%span##{id}{ title: '#{title}' }"
66
+ end
67
+
68
+ it 'uses the ".class" syntax for the class attribute' do
69
+ html_class = 'la_clase'
70
+ title = 'El Titulo'
71
+
72
+ expect(hamlize("<span class='#{html_class}'></span>")).to eq "%span.#{html_class}"
73
+ expect(hamlize("<span class='#{html_class}' title='#{title}'></span>")).to eq "%span.#{html_class}{ title: '#{title}' }"
74
+
75
+ html_classes = %w(una_clase otra_clase)
76
+ expect(hamlize("<span class='#{html_classes.join(' ')}' title='#{title}'></span>")).to eq "%span.#{html_classes.join('.')}{ title: '#{title}' }"
77
+ expect(hamlize("<span class='#{html_classes.join(' ')}' title='#{title}'></span>")).to eq "%span.#{html_classes.join('.')}{ title: '#{title}' }"
78
+ end
79
+
80
+ it 'does not use %div for divs that have an id or a class' do
81
+ id = 'el_identificador'
82
+ html_class = 'la_clase'
83
+ title = 'El Titulo'
84
+
85
+ expect(hamlize('<div></div>')).to eq '%div'
86
+ expect(hamlize("<div title='#{title}'></div>")).to eq "%div{ title: '#{title}' }"
87
+ expect(hamlize("<div id='#{id}'></div>")).to eq "##{id}"
88
+ expect(hamlize("<div class='#{html_class}'></div>")).to eq ".#{html_class}"
89
+ end
90
+
91
+ it 'parses erb printing code', :focus do
92
+ expect(hamlize('<strong><%= item.title %></strong>')).to eq '%strong= item.title'
93
+ expect(hamlize('<p><%= hello %><strong><%= item.title %></strong></p>')).to eq "%p\n = hello\n %strong= item.title"
94
+ expect(hamlize('<p><% hello %><strong><%= item.title %></strong></p>')).to eq "%p\n - hello\n %strong= item.title"
95
+ end
96
+
97
+ it 'parses erb non-printing code' do
98
+ expect(hamlize('<div><% a = 2 + 2 %></div>')).to eq '%div- a = 2 + 2'
99
+ end
100
+ end
101
+
102
+ def hamlize(html)
103
+ haml = Hamlizer.hamlize(html)
104
+
105
+ begin
106
+ Haml::Engine.new(haml).to_html
107
+ rescue Exception => e
108
+ raise e.class, "#{e.message}\nIn: #{haml}" unless [NameError, NoMethodError].include? e.class
109
+ end
110
+
111
+ haml
112
+ end
113
+ end
@@ -0,0 +1,13 @@
1
+ require 'hamlizer'
2
+ require 'rspec'
3
+ require 'haml'
4
+
5
+ RSpec.configure do |config|
6
+ config.color_enabled = true
7
+ config.formatter = :documentation
8
+ config.order = :random
9
+ config.treat_symbols_as_metadata_keys_with_true_values = true
10
+ config.expect_with :rspec do |c|
11
+ c.syntax = :expect
12
+ end
13
+ end
metadata ADDED
@@ -0,0 +1,111 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hamlizer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Lilibeth De La Cruz
9
+ - Edgar Gonzalez
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2013-01-23 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: nokogiri
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ! '>='
29
+ - !ruby/object:Gem::Version
30
+ version: '0'
31
+ - !ruby/object:Gem::Dependency
32
+ name: rspec
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ type: :development
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: haml
49
+ requirement: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ description: Convert your views from HTML/ERB to HAML
64
+ email:
65
+ - lilibethdlc@gmail.com
66
+ - edggonzalezg@gmail.com
67
+ executables: []
68
+ extensions: []
69
+ extra_rdoc_files: []
70
+ files:
71
+ - .gitignore
72
+ - .rvmrc
73
+ - Gemfile
74
+ - LICENSE.txt
75
+ - README.md
76
+ - Rakefile
77
+ - hamlizer.gemspec
78
+ - lib/hamlizer.rb
79
+ - lib/hamlizer/attributes_haml_converter.rb
80
+ - lib/hamlizer/element_haml_converter.rb
81
+ - lib/hamlizer/html_element.rb
82
+ - lib/hamlizer/version.rb
83
+ - spec/lib/hamlizer_spec.rb
84
+ - spec/spec_helper.rb
85
+ homepage: ''
86
+ licenses: []
87
+ post_install_message:
88
+ rdoc_options: []
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ none: false
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ! '>='
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ requirements: []
104
+ rubyforge_project:
105
+ rubygems_version: 1.8.24
106
+ signing_key:
107
+ specification_version: 3
108
+ summary: HTML/ERB to HAML converter
109
+ test_files:
110
+ - spec/lib/hamlizer_spec.rb
111
+ - spec/spec_helper.rb