ouvrages-haml2erb 0.3

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2006-2011 Chris Goddard, Louis Sivillo
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -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,68 @@
1
+ module Haml2Erb
2
+ class ErbWriter
3
+
4
+ def initialize
5
+ @processed = ''
6
+ @tag_stack = [ ]
7
+ end
8
+
9
+ def <<(line_options)
10
+
11
+ else_block = (line_options[:content_type] == :ruby_run and (line_options[:contents] =~ /^\s*else\s*$/ or line_options[:contents] =~ /^\s*elsif\s/))
12
+ ruby_block = (line_options[:content_type] == :ruby_run and (line_options[:contents] =~ / do(\s*\|[\w\d_,\s]+\|)?$/ or line_options[:contents] =~ /^\s*if / or else_block))
13
+ close_tags(line_options[:indent], :incoming_else_block => else_block)
14
+ @tag_stack.push(line_options[:element_type]) if line_options[:element_type] and !line_options[:self_closing_tag]
15
+ @tag_stack.push(:ruby_block) if ruby_block
16
+
17
+ @processed << (" " * line_options[:indent]) if line_options[:indent]
18
+ @processed << "<#{line_options[:element_type].to_s}" if line_options[:element_type]
19
+ @processed << " id=\"#{line_options[:element_id].to_s}\"" if line_options[:element_id]
20
+ @processed << " class=\"#{[*line_options[:element_class]].join(' ')}\"" if line_options[:element_class]
21
+ line_options[:element_attributes] && line_options[:element_attributes].keys.each do |attribute_key|
22
+ @processed << " #{attribute_key}=\"#{line_options[:element_attributes][attribute_key]}\""
23
+ end
24
+ @processed << " /" if line_options[:self_closing_tag]
25
+ @processed << ">" if line_options[:element_type]
26
+
27
+ case(line_options[:content_type])
28
+ when :text
29
+ @processed << (line_options[:contents] || "")
30
+ when :ruby
31
+ @processed << ("<%= " + line_options[:contents] + " %>")
32
+ when :ruby_run
33
+ @processed << ("<% " + line_options[:contents] + " %>")
34
+ when :mixed
35
+ @processed << ('<%= "' + line_options[:contents] + '" %>')
36
+ end
37
+
38
+ close_tags(line_options[:indent], :separate_line => false) if line_options[:contents] and !line_options[:self_closing_tag] and !ruby_block
39
+ @processed << "\n"
40
+ end
41
+
42
+ def output_to_string
43
+ close_tags(0)
44
+ @processed
45
+ end
46
+
47
+ private
48
+
49
+ def close_tags(current_indent, options = {})
50
+ options = { :separate_line => true }.merge(options)
51
+ while(@tag_stack.size > current_indent)
52
+ indent = @tag_stack.size - 1
53
+ stack_item = @tag_stack.pop
54
+ if stack_item == :ruby_block
55
+ unless options[:incoming_else_block]
56
+ @processed << (" " * (indent)) if options[:separate_line] == true
57
+ @processed << "<% end %>"
58
+ @processed << "\n" if options[:separate_line] == true
59
+ end
60
+ else
61
+ @processed << (" " * (indent)) if options[:separate_line] == true
62
+ @processed << "</#{stack_item.to_s}>"
63
+ @processed << "\n" if options[:separate_line] == true
64
+ end
65
+ end
66
+ end
67
+ end
68
+ 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,77 @@
1
+ require 'haml2erb/lexer'
2
+ require 'haml2erb/tokens'
3
+ require 'haml2erb/mixins/comerging'
4
+
5
+ module Haml2Erb
6
+ class HamlParser
7
+
8
+ ParsingError = Class.new(StandardError)
9
+
10
+ def initialize
11
+ @lexer = Haml2Erb::HamlLexer.new
12
+ end
13
+
14
+ def parse(unprocessed, writer)
15
+ @line_number = 0
16
+ # process incoming text one line at a time
17
+ unprocessed.each_line do |line|
18
+ @line_number += 1
19
+ next if line =~ /^\s*$/
20
+ options = { }
21
+ class << options
22
+ include Haml2Erb::Mixins::CoMerging
23
+ end
24
+ @lexer.load_input(line)
25
+
26
+ # handle indent
27
+ if(@lexer.peek(Haml2Erb::Tokens::Indent))
28
+ options.merge!(@lexer.pop(Haml2Erb::Tokens::Indent).options)
29
+ end
30
+ options.merge!(:indent => 0) unless options[:indent]
31
+
32
+ # handle initial tag attributes
33
+ while(@lexer.peek(Haml2Erb::Tokens::InitialAttribute))
34
+ options.comerge!(@lexer.pop(Haml2Erb::Tokens::InitialAttribute).options)
35
+ end
36
+ options[:element_type] = :div if((options[:element_id] || options[:element_class]) && !options[:element_type])
37
+
38
+ # handle interior element attributes
39
+ if(@lexer.peek(Haml2Erb::Tokens::AttributesStart))
40
+ @lexer.pop(Haml2Erb::Tokens::AttributesStart)
41
+ options[:element_attributes] = { }
42
+ while(!@lexer.peek(Haml2Erb::Tokens::AttributesEnd))
43
+ if(@lexer.peek(Haml2Erb::Tokens::InnerAttributeQuoted))
44
+ options[:element_attributes].merge!(@lexer.pop(Haml2Erb::Tokens::InnerAttributeQuoted).options[:element_attribute])
45
+ elsif(@lexer.peek(Haml2Erb::Tokens::InnerAttributeRuby))
46
+ options[:element_attributes].merge!(@lexer.pop(Haml2Erb::Tokens::InnerAttributeRuby).options[:element_attribute])
47
+ elsif(@lexer.peek(Haml2Erb::Tokens::InnerAttributeNumber))
48
+ options[:element_attributes].merge!(@lexer.pop(Haml2Erb::Tokens::InnerAttributeNumber).options[:element_attribute])
49
+ else
50
+ raise 'unrecognized inner attribute'
51
+ end
52
+ end
53
+ @lexer.pop(Haml2Erb::Tokens::AttributesEnd)
54
+ end
55
+
56
+ if(@lexer.peek(Haml2Erb::Tokens::SelfClosingTag))
57
+ @lexer.pop(Haml2Erb::Tokens::SelfClosingTag)
58
+ options[:self_closing_tag] = true
59
+ end
60
+
61
+ # handle element contents
62
+ if(@lexer.peek(Haml2Erb::Tokens::ContentsStart))
63
+ options.merge!(@lexer.pop(Haml2Erb::Tokens::ContentsStart).options)
64
+ end
65
+ options[:content_type] = :text unless options[:content_type]
66
+
67
+ if(@lexer.peek(Haml2Erb::Tokens::Contents))
68
+ options.merge!(:contents => @lexer.pop(Haml2Erb::Tokens::Contents).matched)
69
+ end
70
+
71
+ writer << options
72
+ end
73
+ rescue => error
74
+ raise ParsingError, "Haml2Erb had trouble parsing line #{@line_number} with input #{@lexer.input.inspect} remaining: #{error.to_s}", error.backtrace
75
+ end
76
+ end
77
+ 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,148 @@
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 SelfClosingTag < Token
36
+ @regex = /^\//
37
+ end
38
+
39
+ class ContentsStart < Token
40
+ @regex = /^((\s+)|(==\s*)|(=\s*)|(-\s*))/
41
+
42
+ def self.match(text)
43
+ match_data = @regex.match(text)
44
+ if match_data
45
+ @return_token = case match_data[1][0,1]
46
+ when ' ' then self.new(match_data.to_s, :content_type => :text)
47
+ when '=', '-'
48
+ match_data[1][1,1] == '=' ? self.new(match_data.to_s, :content_type => :mixed) : self.new(match_data.to_s, :content_type => (match_data[1][0,1] == '-' ? :ruby_run : :ruby))
49
+ end
50
+ else
51
+ @return_token = nil
52
+ end
53
+ @return_token
54
+ end
55
+ end
56
+
57
+ class Contents < Token
58
+ @regex = /^.+$/
59
+
60
+ def self.match(text)
61
+ text.gsub!(/\\\-/, "-")
62
+ match_data = @regex.match(text)
63
+ match_data ? self.new(match_data.to_s) : nil
64
+ end
65
+ end
66
+
67
+ class InitialAttribute < Token
68
+ @regex = /^([%#\.])([-\w]+)/
69
+
70
+ def self.match(text)
71
+ match_data = @regex.match(text)
72
+ if match_data
73
+ @return_token = case match_data[1]
74
+ when '%' then self.new(match_data.to_s, :element_type => match_data[2])
75
+ when '#' then self.new(match_data.to_s, :element_id => match_data[2])
76
+ when '.' then self.new(match_data.to_s, :element_class => match_data[2])
77
+ end
78
+ else
79
+ @return_token = nil
80
+ end
81
+ @return_token
82
+ end
83
+ end
84
+
85
+ class InnerAttributeQuoted < Token
86
+ @regex = /^,?\s*:?['"]?([\w-]+)['"]?(:|(\s*=>))\s*['"]([^'"]+)['"]\s*/
87
+ def self.match(text)
88
+ match_data = @regex.match(text)
89
+ if(match_data)
90
+ value = match_data[4].gsub(/#\{([^\}]+?)\}/, '<%= \1 %>') # replace #{ value } with <%= value %>
91
+ self.new(match_data.to_s, :element_attribute => { match_data[1] => value })
92
+ else
93
+ nil
94
+ end
95
+ end
96
+ end
97
+
98
+ class InnerAttributeRuby < Token
99
+ @regex = /^,?\s*:?['"]?([\w-]+)['"]?(:|(\s*=>))\s*([^'"])/
100
+ def self.match(text)
101
+ match_data = @regex.match(text)
102
+ if match_data
103
+ ruby = match_data[4]
104
+ match = match_data.to_s
105
+ remaining = text[match.size..-1]
106
+ stack = []
107
+ remaining.split(//).each do |chr|
108
+ case chr
109
+ when /[\[\{\(]/
110
+ stack.push chr
111
+ ruby << chr
112
+ match << chr
113
+ when /[\]\}\)]/
114
+ if stack.empty?
115
+ break
116
+ else
117
+ stack.pop
118
+ ruby << chr
119
+ match << chr
120
+ end
121
+ when ','
122
+ if stack.empty?
123
+ break
124
+ else
125
+ ruby << chr
126
+ match << chr
127
+ end
128
+ else
129
+ ruby << chr
130
+ match << chr
131
+ end
132
+ end
133
+ self.new(match, :element_attribute => { match_data[1] => "<%= #{ruby} %>" })
134
+ else
135
+ nil
136
+ end
137
+ end
138
+ end
139
+
140
+ class InnerAttributeNumber < Token
141
+ @regex = /^,?\s*:?['"]?([\w-]+)['"]?(:|(\s*=>))\s*(\d+)\s*/
142
+ def self.match(text)
143
+ match_data = @regex.match(text)
144
+ match_data ? self.new(match_data.to_s, :element_attribute => { match_data[1] => match_data[4] }) : nil
145
+ end
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,3 @@
1
+ module Haml2Erb
2
+ VERSION = "0.3"
3
+ end
data/lib/haml2erb.rb ADDED
@@ -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,21 @@
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 = "ouvrages-haml2erb"
9
+ s.version = Haml2Erb::VERSION
10
+ s.platform = Gem::Platform::RUBY
11
+ s.authors = ['Ouvrages', 'Louis Sivillo']
12
+ s.email = ['contact@ouvrages-web.fr']
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
+ 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,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ouvrages-haml2erb
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.3'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ouvrages
9
+ - Louis Sivillo
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2012-08-15 00:00:00.000000000 Z
14
+ dependencies: []
15
+ description: Haml to ERB Converter
16
+ email:
17
+ - contact@ouvrages-web.fr
18
+ executables: []
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - LICENSE
23
+ - README.rdoc
24
+ - lib/haml2erb.rb
25
+ - lib/haml2erb/erb_writer.rb
26
+ - lib/haml2erb/lexer.rb
27
+ - lib/haml2erb/mixins/comerging.rb
28
+ - lib/haml2erb/parser.rb
29
+ - lib/haml2erb/railtie.rb
30
+ - lib/haml2erb/tokens.rb
31
+ - lib/haml2erb/version.rb
32
+ - ouvrages-haml2erb.gemspec
33
+ - tasks/haml2erb.rake
34
+ homepage:
35
+ licenses: []
36
+ post_install_message:
37
+ rdoc_options: []
38
+ require_paths:
39
+ - lib
40
+ required_ruby_version: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ required_rubygems_version: !ruby/object:Gem::Requirement
47
+ none: false
48
+ requirements:
49
+ - - ! '>='
50
+ - !ruby/object:Gem::Version
51
+ version: 1.3.6
52
+ requirements: []
53
+ rubyforge_project:
54
+ rubygems_version: 1.8.11
55
+ signing_key:
56
+ specification_version: 3
57
+ summary: Haml to ERB Converter
58
+ test_files: []
59
+ has_rdoc: