haml2erb 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,58 @@
1
+ = haml2erb Rails Plugin
2
+
3
+ haml2erb is a tool for converting {Haml markup}[http://haml-lang.com/] to Erb markup.
4
+
5
+ <b>Latest version:</b> 0.2.0
6
+
7
+ * API documentation (coming soon)
8
+ * {Source code} [http://github.com/cgoddard/haml2erb/]
9
+ * {Bug tracker} [http://github.com/cgoddard/haml2erb/issues]
10
+
11
+ Tested on Ruby 1.9.1 and Ruby 1.8.7
12
+
13
+ === Installing and loading haml2erb
14
+
15
+ haml2erb is currently distributed as a Rails plugin.
16
+
17
+ Simply move the main haml2erb directory into the vendor/plugins directory of your Rails application.
18
+
19
+ === Using haml2erb
20
+
21
+ From the Rails console or application, call the Haml2Erb.convert method to have haml
22
+ markup translated into erb.
23
+
24
+ ==== Example: Simple conversion
25
+ Haml2Erb.convert('.foo')
26
+ # => "<div class='foo'>\n</div>\n"
27
+
28
+ === Not supported yet
29
+
30
+ Parsing of tag internal string interpolations, such as:
31
+ #my_div{ class: "box #{extra_classes}" }
32
+
33
+ Coming soon though ...
34
+
35
+ == Licenses
36
+
37
+ ==== haml2erb code and documentation (MIT license)
38
+
39
+ Copyright (c) 2010 Chris Goddard
40
+
41
+ Permission is hereby granted, free of charge, to any person obtaining
42
+ a copy of this software and associated documentation files (the
43
+ "Software"), to deal in the Software without restriction, including
44
+ without limitation the rights to use, copy, modify, merge, publish,
45
+ distribute, sublicense, and/or sell copies of the Software, and to
46
+ permit persons to whom the Software is furnished to do so, subject to
47
+ the following conditions:
48
+
49
+ The above copyright notice and this permission notice shall be
50
+ included in all copies or substantial portions of the Software.
51
+
52
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
53
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
54
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
55
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
56
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
57
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
58
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib/', __FILE__)
3
+ $:.unshift lib unless $:.include?(lib)
4
+
5
+ require 'haml2erb/version'
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = "haml2erb"
9
+ s.version = Haml2Erb::VERSION
10
+ s.platform = Gem::Platform::RUBY
11
+ s.authors = 'Louis Sivillo'
12
+ s.email = ['louis.sivillo@gmail.com']
13
+
14
+ s.summary = 'Haml to ERB Converter'
15
+ s.description = 'Haml to ERB Converter'
16
+
17
+ s.required_rubygems_version = ">= 1.3.6"
18
+
19
+ s.files = `git ls-files`.split("\n")
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_dependency 'mixology'
23
+ end
@@ -0,0 +1,15 @@
1
+ require 'haml2erb/railtie' if defined?(Rails::Railtie)
2
+ require 'haml2erb/erb_writer'
3
+ require 'haml2erb/parser'
4
+ require 'haml2erb/version'
5
+
6
+ module Haml2Erb
7
+
8
+ def self.convert(text)
9
+ parser = Haml2Erb::HamlParser.new
10
+ writer = Haml2Erb::ErbWriter.new
11
+ parser.parse(text, writer)
12
+ writer.output_to_string
13
+ end
14
+
15
+ end
@@ -0,0 +1,51 @@
1
+ module Haml2Erb
2
+ class ErbWriter
3
+
4
+ def initialize
5
+ @processed = ''
6
+ @tag_stack = [ ]
7
+ end
8
+
9
+ def <<(line_options)
10
+
11
+ close_tags(line_options[:indent])
12
+ @tag_stack.push(line_options[:element_type]) if line_options[:element_type]
13
+
14
+ @processed << (" " * line_options[:indent]) if line_options[:indent]
15
+ @processed << "<#{line_options[:element_type].to_s}" if line_options[:element_type]
16
+ @processed << " id='#{line_options[:element_id].to_s}'" if line_options[:element_id]
17
+ @processed << " class='#{[*line_options[:element_class]].join(' ')}'" if line_options[:element_class]
18
+ line_options[:element_attributes] && line_options[:element_attributes].keys.each do |attribute_key|
19
+ @processed << " #{attribute_key}='#{line_options[:element_attributes][attribute_key]}'"
20
+ end
21
+ @processed << ">" if line_options[:element_type]
22
+
23
+ case(line_options[:content_type])
24
+ when :text
25
+ @processed << (line_options[:contents] || "")
26
+ when :ruby
27
+ @processed << ("<%= " + line_options[:contents] + " %>")
28
+ when :mixed
29
+ @processed << ('<%= "' + line_options[:contents] + '" %>')
30
+ end
31
+
32
+ close_tags(line_options[:indent], :separate_line => false) if line_options[:contents]
33
+ @processed << "\n"
34
+ end
35
+
36
+ def output_to_string
37
+ close_tags(0)
38
+ @processed
39
+ end
40
+
41
+ private
42
+
43
+ def close_tags(current_indent, options = { :separate_line => true })
44
+ while(@tag_stack.size > current_indent)
45
+ @processed << (" " * (@tag_stack.size - 1)) if options[:separate_line] == true
46
+ @processed << "</#{@tag_stack.pop.to_s}>"
47
+ @processed << "\n" if options[:separate_line] == true
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,28 @@
1
+ require 'haml2erb/tokens'
2
+
3
+ module Haml2Erb
4
+ class HamlLexer
5
+
6
+ attr_reader :input
7
+
8
+ def load_input(text)
9
+ @input = text
10
+ end
11
+
12
+ def peek(klass)
13
+ #puts "peek #{klass} #{@input}"
14
+ klass.match(@input)
15
+ end
16
+
17
+ def pop(klass)
18
+ #puts "pop #{klass} #{@input}"
19
+ token = klass.match(@input)
20
+ @input.gsub!(/^#{Regexp.escape(token.matched)}/, '') # removed matched portion from the string
21
+ token
22
+ end
23
+
24
+ def end_input?
25
+ @input.strip.empty? ? true : false
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,22 @@
1
+ module Haml2Erb
2
+ module Mixins
3
+ module CoMerging
4
+ def comerge
5
+ # NOT IMPLEMENTED YET
6
+ fail "comerge command not implemented yet"
7
+ end
8
+
9
+ # inclusive merge that combines results of two hashes when merging
10
+ def comerge! hash_b
11
+ hash_a = self
12
+ hash_b.respond_to?(:each_pair) && hash_b.each_pair do |k,v|
13
+ hash_a[k] = hash_a[k] ?
14
+ (hash_a[k].respond_to?(:push) ?
15
+ hash_a[k].push(v) :
16
+ [ hash_a[k], v ]) :
17
+ v
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,69 @@
1
+ require 'haml2erb/lexer'
2
+ require 'haml2erb/tokens'
3
+ require 'haml2erb/mixins/comerging'
4
+ require 'mixology'
5
+
6
+ module Haml2Erb
7
+ class HamlParser
8
+
9
+ ParsingError = Class.new(StandardError)
10
+
11
+ def initialize
12
+ @lexer = Haml2Erb::HamlLexer.new
13
+ end
14
+
15
+ def parse(unprocessed, writer)
16
+ @line_number = 0
17
+ # process incoming text one line at a time
18
+ unprocessed.each_line do |line|
19
+ @line_number += 1
20
+ options = { }.mixin Haml2Erb::Mixins::CoMerging
21
+ @lexer.load_input(line)
22
+
23
+ # handle indent
24
+ if(@lexer.peek(Haml2Erb::Tokens::Indent))
25
+ options.merge!(@lexer.pop(Haml2Erb::Tokens::Indent).options)
26
+ end
27
+ options.merge!(:indent => 0) unless options[:indent]
28
+
29
+ # handle initial tag attributes
30
+ while(@lexer.peek(Haml2Erb::Tokens::InitialAttribute))
31
+ options.comerge!(@lexer.pop(Haml2Erb::Tokens::InitialAttribute).options)
32
+ end
33
+ options[:element_type] = :div if((options[:element_id] || options[:element_class]) && !options[:element_type])
34
+
35
+ # handle interior element attributes
36
+ if(@lexer.peek(Haml2Erb::Tokens::AttributesStart))
37
+ @lexer.pop(Haml2Erb::Tokens::AttributesStart)
38
+ options[:element_attributes] = { }
39
+ while(!@lexer.peek(Haml2Erb::Tokens::AttributesEnd))
40
+ if(@lexer.peek(Haml2Erb::Tokens::InnerAttributeQuoted))
41
+ options[:element_attributes].merge!(@lexer.pop(Haml2Erb::Tokens::InnerAttributeQuoted).options[:element_attribute])
42
+ elsif(@lexer.peek(Haml2Erb::Tokens::InnerAttributeRuby))
43
+ options[:element_attributes].merge!(@lexer.pop(Haml2Erb::Tokens::InnerAttributeRuby).options[:element_attribute])
44
+ elsif(@lexer.peek(Haml2Erb::Tokens::InnerAttributeNumber))
45
+ options[:element_attributes].merge!(@lexer.pop(Haml2Erb::Tokens::InnerAttributeNumber).options[:element_attribute])
46
+ else
47
+ raise 'unrecognized inner attribute'
48
+ end
49
+ end
50
+ @lexer.pop(Haml2Erb::Tokens::AttributesEnd)
51
+ end
52
+
53
+ # handle element contents
54
+ if(@lexer.peek(Haml2Erb::Tokens::ContentsStart))
55
+ options.merge!(@lexer.pop(Haml2Erb::Tokens::ContentsStart).options)
56
+ end
57
+ options[:content_type] = :text unless options[:content_type]
58
+
59
+ if(@lexer.peek(Haml2Erb::Tokens::Contents))
60
+ options.merge!(:contents => @lexer.pop(Haml2Erb::Tokens::Contents).matched)
61
+ end
62
+
63
+ writer << options
64
+ end
65
+ rescue => error
66
+ raise ParsingError, "Haml2Erb had trouble parsing line #{@line_number} with input '#{@lexer.input}' remaining: #{error.to_s}", error.backtrace
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,7 @@
1
+ module Haml2Erb
2
+ class Railtie < Rails::Railtie
3
+ rake_tasks do
4
+ load File.join(File.dirname(__FILE__), '..', '..', 'tasks/haml2erb.rake')
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,110 @@
1
+ module Haml2Erb
2
+ module Tokens
3
+
4
+ class Token
5
+ attr_reader :options, :matched
6
+
7
+ def initialize(matched, options = {})
8
+ @matched = matched
9
+ @options = options
10
+ end
11
+
12
+ def self.match(text)
13
+ match_data = @regex.match(text)
14
+ match_data ? self.new(match_data.to_s) : nil
15
+ end
16
+ end
17
+
18
+ class Indent < Token
19
+ @regex = /^(\s\s)+/
20
+
21
+ def self.match(text)
22
+ match_data = @regex.match(text)
23
+ match_data ? self.new(match_data.to_s, :indent => (match_data.to_s.size / 2)) : nil
24
+ end
25
+ end
26
+
27
+ class AttributesStart < Token
28
+ @regex = /^\{\s*/
29
+ end
30
+
31
+ class AttributesEnd < Token
32
+ @regex = /^\s*\}/
33
+ end
34
+
35
+ class ContentsStart < Token
36
+ @regex = /^((\s+)|(==\s*)|(=\s*))/
37
+
38
+ def self.match(text)
39
+ match_data = @regex.match(text)
40
+ if match_data
41
+ @return_token = case match_data[1][0,1]
42
+ when ' ' then self.new(match_data.to_s, :content_type => :text)
43
+ when '='
44
+ match_data[1][1,1] == '=' ? self.new(match_data.to_s, :content_type => :mixed) : self.new(match_data.to_s, :content_type => :ruby)
45
+ end
46
+ else
47
+ @return_token = nil
48
+ end
49
+ @return_token
50
+ end
51
+ end
52
+
53
+ class Contents < Token
54
+ @regex = /^.+$/
55
+
56
+ def self.match(text)
57
+ text.gsub!(/\\\-/, "-")
58
+ match_data = @regex.match(text)
59
+ match_data ? self.new(match_data.to_s) : nil
60
+ end
61
+ end
62
+
63
+ class InitialAttribute < Token
64
+ @regex = /^([%#\.])(\w+)/
65
+
66
+ def self.match(text)
67
+ match_data = @regex.match(text)
68
+ if match_data
69
+ @return_token = case match_data[1]
70
+ when '%' then self.new(match_data.to_s, :element_type => match_data[2])
71
+ when '#' then self.new(match_data.to_s, :element_id => match_data[2])
72
+ when '.' then self.new(match_data.to_s, :element_class => match_data[2])
73
+ end
74
+ else
75
+ @return_token = nil
76
+ end
77
+ @return_token
78
+ end
79
+ end
80
+
81
+ class InnerAttributeQuoted < Token
82
+ @regex = /^,?\s*:?['"]?([\w-]+)['"]?(:|(\s*=>))\s*['"]([^'"]+)['"]\s*/
83
+ def self.match(text)
84
+ match_data = @regex.match(text)
85
+ if(match_data)
86
+ value = match_data[4].gsub(/#\{([^\}]+?)\}/, '<%= \1 %>') # replace #{ value } with <%= value %>
87
+ self.new(match_data.to_s, :element_attribute => { match_data[1] => value })
88
+ else
89
+ nil
90
+ end
91
+ end
92
+ end
93
+
94
+ class InnerAttributeRuby < Token
95
+ @regex = /^,?\s*:?['"]?([\w-]+)['"]?(:|(\s*=>))\s*([^'"\s][^,\s]+)\s*/
96
+ def self.match(text)
97
+ match_data = @regex.match(text)
98
+ match_data ? self.new(match_data.to_s, :element_attribute => { match_data[1] => "<%= #{match_data[4]} %>" }) : nil
99
+ end
100
+ end
101
+
102
+ class InnerAttributeNumber < Token
103
+ @regex = /^,?\s*:?['"]?([\w-]+)['"]?(:|(\s*=>))\s*(\d+)\s*/
104
+ def self.match(text)
105
+ match_data = @regex.match(text)
106
+ match_data ? self.new(match_data.to_s, :element_attribute => { match_data[1] => match_data[4] }) : nil
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,3 @@
1
+ module Haml2Erb
2
+ VERSION = "0.2.0"
3
+ end
@@ -0,0 +1,7 @@
1
+ desc "This task will take the supplied .haml input file and convert it to .erb. It will remove the original .haml file and create a new .erb file"
2
+ task :haml2erb, :filename, :needs => :environment do |t, args|
3
+ output_file = args[:filename].gsub(/\.haml/, '.erb')
4
+ p output_file
5
+ File.open(output_file, 'w') { |f| f.write Haml2Erb.convert(File.open(args[:filename], 'r').read) }
6
+ FileUtils.rm_r args[:filename]
7
+ end
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: haml2erb
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 2
8
+ - 0
9
+ version: 0.2.0
10
+ platform: ruby
11
+ authors:
12
+ - Louis Sivillo
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-04-08 00:00:00 -04:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: mixology
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ type: :runtime
32
+ version_requirements: *id001
33
+ description: Haml to ERB Converter
34
+ email:
35
+ - louis.sivillo@gmail.com
36
+ executables: []
37
+
38
+ extensions: []
39
+
40
+ extra_rdoc_files: []
41
+
42
+ files:
43
+ - README.rdoc
44
+ - haml2erb.gemspec
45
+ - lib/haml2erb.rb
46
+ - lib/haml2erb/erb_writer.rb
47
+ - lib/haml2erb/lexer.rb
48
+ - lib/haml2erb/mixins/comerging.rb
49
+ - lib/haml2erb/parser.rb
50
+ - lib/haml2erb/railtie.rb
51
+ - lib/haml2erb/tokens.rb
52
+ - lib/haml2erb/version.rb
53
+ - tasks/haml2erb.rake
54
+ has_rdoc: true
55
+ homepage:
56
+ licenses: []
57
+
58
+ post_install_message:
59
+ rdoc_options: []
60
+
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ segments:
69
+ - 0
70
+ version: "0"
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ segments:
77
+ - 1
78
+ - 3
79
+ - 6
80
+ version: 1.3.6
81
+ requirements: []
82
+
83
+ rubyforge_project:
84
+ rubygems_version: 1.3.7
85
+ signing_key:
86
+ specification_version: 3
87
+ summary: Haml to ERB Converter
88
+ test_files: []
89
+