haml2erb 0.2.1 → 0.3.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/{LICENSE → MIT_LICENSE} +1 -1
- data/README.md +40 -0
- data/Rakefile +1 -0
- data/bin/haml2erb +19 -0
- data/haml2erb.gemspec +21 -16
- data/lib/haml2erb.rb +4 -11
- data/lib/haml2erb/engine.rb +145 -0
- data/lib/haml2erb/version.rb +2 -2
- data/spec/haml2erb_spec.rb +83 -0
- data/spec/spec_helper.rb +3 -0
- metadata +69 -34
- data/README.rdoc +0 -58
- data/lib/haml2erb/erb_writer.rb +0 -51
- data/lib/haml2erb/lexer.rb +0 -28
- data/lib/haml2erb/mixins/comerging.rb +0 -22
- data/lib/haml2erb/parser.rb +0 -69
- data/lib/haml2erb/railtie.rb +0 -7
- data/lib/haml2erb/tokens.rb +0 -110
- data/tasks/haml2erb.rake +0 -7
data/.gitignore
ADDED
data/Gemfile
ADDED
data/{LICENSE → MIT_LICENSE}
RENAMED
data/README.md
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# haml2erb
|
2
|
+
|
3
|
+
haml2erb is a tool for converting [Haml](http://haml-lang.com/) to Erb markup.
|
4
|
+
|
5
|
+
|
6
|
+
## Installing and loading haml2erb
|
7
|
+
|
8
|
+
haml2erb is currently distributed as a Rails plugin.
|
9
|
+
|
10
|
+
Simply move the main haml2erb directory into the vendor/plugins directory of your Rails application.
|
11
|
+
|
12
|
+
|
13
|
+
## Using haml2erb
|
14
|
+
|
15
|
+
Use the `haml2erb` command line or from Ruby call the `Haml2Erb.convert` method to have Haml markup translated into Erb.
|
16
|
+
|
17
|
+
### Example: Simple conversion
|
18
|
+
|
19
|
+
```bash
|
20
|
+
echo '.foo' | haml2erb
|
21
|
+
# <div class='foo'></div>
|
22
|
+
```
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
Haml2Erb.convert('.foo')
|
26
|
+
# => "<div class='foo'></div>\n"
|
27
|
+
```
|
28
|
+
|
29
|
+
|
30
|
+
## License
|
31
|
+
|
32
|
+
[MIT_LICENSE](/elia/haml2erb/blob/master/MIT_LICENSE)
|
33
|
+
|
34
|
+
|
35
|
+
## Credits
|
36
|
+
|
37
|
+
For the [original implementation](https://github.com/c1sgo/haml2erb):
|
38
|
+
|
39
|
+
[Chris Goddard](https://github.com/cgoddard)
|
40
|
+
[Louis Sivillo](https://github.com/BeaconInteractive)
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/haml2erb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
require 'haml2erb'
|
5
|
+
|
6
|
+
if ARGV.any? {|arg| not File.file? arg}
|
7
|
+
puts <<-USAGE
|
8
|
+
Usage:
|
9
|
+
#{$0} <input-file> <output-file> # overwrites <output-file>
|
10
|
+
#{$0} <input-file> # output to stdout
|
11
|
+
#{$0} # input from stdin, output to stdout
|
12
|
+
USAGE
|
13
|
+
end
|
14
|
+
|
15
|
+
haml_file, erb_file = *ARGV
|
16
|
+
input = haml_file ? File.open(haml_file) : $stdin
|
17
|
+
output = erb_file ? File.open(erb_file, 'w') : $stdout
|
18
|
+
|
19
|
+
output.write Haml2Erb.convert(input.read)
|
data/haml2erb.gemspec
CHANGED
@@ -1,23 +1,28 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
$:.unshift lib unless $:.include?(lib)
|
4
|
-
|
1
|
+
# coding: utf-8
|
2
|
+
$:.push File.expand_path('../lib', __FILE__)
|
5
3
|
require 'haml2erb/version'
|
6
4
|
|
7
5
|
Gem::Specification.new do |s|
|
8
|
-
s.name
|
9
|
-
s.version
|
10
|
-
s.
|
11
|
-
s.
|
12
|
-
s.
|
6
|
+
s.name = 'haml2erb'
|
7
|
+
s.version = Haml2Erb::VERSION
|
8
|
+
s.authors = ['Elia Schito']
|
9
|
+
s.email = ['perlelia@gmail.com']
|
10
|
+
s.homepage = ''
|
11
|
+
s.summary = %q{Convert Haml templates to Erb!}
|
12
|
+
s.description = %q{Converts Haml templates to Erb templates using the official Haml::Engine}
|
13
|
+
|
14
|
+
s.rubyforge_project = 'haml2erb'
|
13
15
|
|
14
|
-
s.
|
15
|
-
s.
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ['lib']
|
16
20
|
|
17
|
-
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
# s.add_development_dependency "rspec"
|
23
|
+
# s.add_runtime_dependency "rest-client"
|
18
24
|
|
19
|
-
s.
|
20
|
-
s.
|
21
|
-
|
22
|
-
s.add_dependency 'mixology'
|
25
|
+
s.add_runtime_dependency 'haml', '~> 3.1.3'
|
26
|
+
s.add_development_dependency 'rspec', '~> 2.0'
|
27
|
+
s.add_development_dependency 'rake'
|
23
28
|
end
|
data/lib/haml2erb.rb
CHANGED
@@ -1,15 +1,8 @@
|
|
1
|
-
require 'haml2erb/railtie' if defined?(Rails::Railtie)
|
2
|
-
require 'haml2erb/erb_writer'
|
3
|
-
require 'haml2erb/parser'
|
4
1
|
require 'haml2erb/version'
|
2
|
+
require 'haml2erb/engine'
|
5
3
|
|
6
4
|
module Haml2Erb
|
7
|
-
|
8
|
-
|
9
|
-
parser = Haml2Erb::HamlParser.new
|
10
|
-
writer = Haml2Erb::ErbWriter.new
|
11
|
-
parser.parse(text, writer)
|
12
|
-
writer.output_to_string
|
5
|
+
def self.convert template, options = {}
|
6
|
+
Engine.new(template, {:format => :html5}.merge(options)).to_erb
|
13
7
|
end
|
14
|
-
|
15
|
-
end
|
8
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
require 'haml'
|
2
|
+
|
3
|
+
module Haml2Erb
|
4
|
+
|
5
|
+
# puts RUBY_VERSION
|
6
|
+
|
7
|
+
class Engine < Haml::Engine
|
8
|
+
def push_silent(text, can_suppress = false)
|
9
|
+
flush_merged_text
|
10
|
+
return if can_suppress && options[:suppress_eval]
|
11
|
+
# WAS:
|
12
|
+
# @precompiled << "#{resolve_newlines}#{text}\n"
|
13
|
+
# @output_line += text.count("\n") + 1
|
14
|
+
|
15
|
+
push_script(text,
|
16
|
+
:preserve_script => @node.value[:preserve],
|
17
|
+
:escape_html => @node.value[:escape_html],
|
18
|
+
:silent => true)
|
19
|
+
end
|
20
|
+
|
21
|
+
def compile_haml_comment
|
22
|
+
text = @node.value[:text]
|
23
|
+
return if text.empty?
|
24
|
+
|
25
|
+
push_script(text,
|
26
|
+
:preserve_script => @node.value[:preserve],
|
27
|
+
:escape_html => @node.value[:escape_html],
|
28
|
+
:silent => true, :comment => true)
|
29
|
+
end
|
30
|
+
|
31
|
+
def compile_silent_script
|
32
|
+
return if @options[:suppress_eval]
|
33
|
+
keyword = @node.value[:keyword]
|
34
|
+
@output_tabs -= 1 if Haml::Parser::MID_BLOCK_KEYWORDS.include?(keyword)
|
35
|
+
|
36
|
+
push_silent(@node.value[:text])
|
37
|
+
ruby_block = block_given? && !keyword
|
38
|
+
|
39
|
+
|
40
|
+
if block_given?
|
41
|
+
# Store these values because for conditional statements,
|
42
|
+
# we want to restore them for each branch
|
43
|
+
@node.value[:dont_indent_next_line] = @dont_indent_next_line
|
44
|
+
@node.value[:dont_tab_up_next_text] = @dont_tab_up_next_text
|
45
|
+
|
46
|
+
@output_tabs += 1
|
47
|
+
yield
|
48
|
+
@output_tabs -= 1
|
49
|
+
|
50
|
+
push_silent("end", :can_suppress) unless @node.value[:dont_push_end]
|
51
|
+
elsif keyword == "end"
|
52
|
+
if @node.parent.children.last.equal?(@node)
|
53
|
+
# Since this "end" is ending the block,
|
54
|
+
# we don't need to generate an additional one
|
55
|
+
@node.parent.value[:dont_push_end] = true
|
56
|
+
end
|
57
|
+
# Don't restore dont_* for end because it isn't a conditional branch.
|
58
|
+
elsif Haml::Parser::MID_BLOCK_KEYWORDS.include?(keyword)
|
59
|
+
@output_tabs += 1
|
60
|
+
|
61
|
+
# Restore dont_* for this conditional branch
|
62
|
+
@dont_indent_next_line = @node.parent.value[:dont_indent_next_line]
|
63
|
+
@dont_tab_up_next_text = @node.parent.value[:dont_tab_up_next_text]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def push_script text, opts={}
|
68
|
+
tag_lead = opts[:silent] ? '' : '='
|
69
|
+
tag_lead << '#' if opts[:comment]
|
70
|
+
erb_tag = "<%#{tag_lead} #{text.strip} %>"
|
71
|
+
|
72
|
+
# USED TO START HERE:
|
73
|
+
return if options[:suppress_eval]
|
74
|
+
|
75
|
+
args = %w[preserve_script in_tag preserve_tag escape_html nuke_inner_whitespace]
|
76
|
+
args.map! {|name| opts[name.to_sym]}
|
77
|
+
args << !block_given? << @options[:ugly]
|
78
|
+
|
79
|
+
no_format = @options[:ugly] &&
|
80
|
+
!(opts[:preserve_script] || opts[:preserve_tag] || opts[:escape_html])
|
81
|
+
output_expr = "(#{text}\n)"
|
82
|
+
static_method = "_hamlout.#{static_method_name(:format_script, *args)}"
|
83
|
+
|
84
|
+
# Prerender tabulation unless we're in a tag
|
85
|
+
push_merged_text '' unless opts[:in_tag]
|
86
|
+
|
87
|
+
unless block_given?
|
88
|
+
# WAS: push_generated_script(no_format ? "#{text}\n" : "#{static_method}(#{output_expr});")
|
89
|
+
push_generated_script(erb_tag.inspect)
|
90
|
+
|
91
|
+
concat_merged_text("\n") unless opts[:in_tag] || opts[:nuke_inner_whitespace]
|
92
|
+
|
93
|
+
# push_generated_script(erb_tag.inspect)
|
94
|
+
#
|
95
|
+
# concat_merged_text("\n") unless opts[:in_tag] || opts[:nuke_inner_whitespace]
|
96
|
+
|
97
|
+
# @output_tabs += 1
|
98
|
+
return
|
99
|
+
end
|
100
|
+
|
101
|
+
flush_merged_text
|
102
|
+
push_generated_script erb_tag.inspect
|
103
|
+
concat_merged_text("\n") unless opts[:in_tag] || opts[:nuke_inner_whitespace]
|
104
|
+
|
105
|
+
# push_silent text
|
106
|
+
|
107
|
+
@output_tabs += 1 unless opts[:nuke_inner_whitespace]
|
108
|
+
yield
|
109
|
+
@output_tabs -= 1 unless opts[:nuke_inner_whitespace]
|
110
|
+
|
111
|
+
push_silent('end', :can_suppress) unless @node.value[:dont_push_end]
|
112
|
+
# COMMENTED: @precompiled << "_hamlout.buffer << #{no_format ? "haml_temp.to_s;" : "#{static_method}(haml_temp);"}"
|
113
|
+
concat_merged_text("\n") unless opts[:in_tag] || opts[:nuke_inner_whitespace] || @options[:ugly]
|
114
|
+
end
|
115
|
+
|
116
|
+
def to_erb(scope = Object.new, locals = {}, &block)
|
117
|
+
buffer = Haml::Buffer.new(scope.instance_variable_get('@haml_buffer'), options_for_buffer)
|
118
|
+
|
119
|
+
if scope.is_a?(Binding) || scope.is_a?(Proc)
|
120
|
+
scope_object = eval("self", scope)
|
121
|
+
scope = scope_object.instance_eval{binding} if block_given?
|
122
|
+
else
|
123
|
+
scope_object = scope
|
124
|
+
scope = scope_object.instance_eval{binding}
|
125
|
+
end
|
126
|
+
|
127
|
+
set_locals(locals.merge(:_hamlout => buffer, :_erbout => buffer.buffer), scope, scope_object)
|
128
|
+
|
129
|
+
scope_object.instance_eval do
|
130
|
+
extend Haml::Helpers
|
131
|
+
@haml_buffer = buffer
|
132
|
+
end
|
133
|
+
|
134
|
+
eval(precompiled + ";" + precompiled_method_return_value,
|
135
|
+
scope, @options[:filename], @options[:line])
|
136
|
+
ensure
|
137
|
+
# Get rid of the current buffer
|
138
|
+
scope_object.instance_eval do
|
139
|
+
@haml_buffer = buffer.upper if buffer
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
data/lib/haml2erb/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
module Haml2Erb
|
2
|
-
VERSION =
|
3
|
-
end
|
2
|
+
VERSION = '0.3.0.pre'
|
3
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
haml = %{
|
4
|
+
!!!
|
5
|
+
%html(lang="en")
|
6
|
+
%head
|
7
|
+
- ciao
|
8
|
+
- if 3
|
9
|
+
= pippo
|
10
|
+
- else
|
11
|
+
= caio
|
12
|
+
|
13
|
+
%meta(charset="utf-8")
|
14
|
+
%meta(content="IE=edge,chrome=1" http-equiv="X-UA-Compatible")
|
15
|
+
= csrf_meta_tags
|
16
|
+
|
17
|
+
%title Doomboard!
|
18
|
+
|
19
|
+
/ Mobile viewport optimized: j.mp/bplateviewport
|
20
|
+
%meta(content="width=device-width,initial-scale=1" name="viewport")
|
21
|
+
|
22
|
+
= javascript_include_tag 'http://js.pusherapp.com/1.9/pusher.min.js'
|
23
|
+
= stylesheet_link_tag 'application'
|
24
|
+
= javascript_include_tag 'application'
|
25
|
+
|
26
|
+
%body
|
27
|
+
%aside.left
|
28
|
+
%section#leaderboard(data-widget="leaderboard")
|
29
|
+
%section#dr_doomboard(data-widget="dr_doomboard")
|
30
|
+
|
31
|
+
%section#projects
|
32
|
+
- [1,2,3].each do |n|
|
33
|
+
= n
|
34
|
+
- 1234
|
35
|
+
%aside.right
|
36
|
+
%section#tweets(data-widget="twitter")
|
37
|
+
%section#hammurabi
|
38
|
+
}
|
39
|
+
|
40
|
+
erb = %{<!DOCTYPE html>
|
41
|
+
<html lang='en'>
|
42
|
+
<head>
|
43
|
+
<% ciao %>
|
44
|
+
<% if 3 %>
|
45
|
+
<%= pippo %>
|
46
|
+
<% else %>
|
47
|
+
<%= caio %>
|
48
|
+
<% end %>
|
49
|
+
<meta charset='utf-8'>
|
50
|
+
<meta content='IE=edge,chrome=1' http-equiv='X-UA-Compatible'>
|
51
|
+
<%= csrf_meta_tags %>
|
52
|
+
<title>Doomboard!</title>
|
53
|
+
<!-- Mobile viewport optimized: j.mp/bplateviewport -->
|
54
|
+
<meta content='width=device-width,initial-scale=1' name='viewport'>
|
55
|
+
<%= javascript_include_tag 'http://js.pusherapp.com/1.9/pusher.min.js' %>
|
56
|
+
<%= stylesheet_link_tag 'application' %>
|
57
|
+
<%= javascript_include_tag 'application' %>
|
58
|
+
</head>
|
59
|
+
<body>
|
60
|
+
<aside class='left'>
|
61
|
+
<section data-widget='leaderboard' id='leaderboard'></section>
|
62
|
+
<section data-widget='dr_doomboard' id='dr_doomboard'></section>
|
63
|
+
</aside>
|
64
|
+
<section id='projects'>
|
65
|
+
<% [1,2,3].each do |n| %>
|
66
|
+
<%= n %>
|
67
|
+
<% end %>
|
68
|
+
<% 1234 %>
|
69
|
+
</section>
|
70
|
+
<aside class='right'>
|
71
|
+
<section data-widget='twitter' id='tweets'></section>
|
72
|
+
<section id='hammurabi'></section>
|
73
|
+
</aside>
|
74
|
+
</body>
|
75
|
+
</html>
|
76
|
+
}
|
77
|
+
|
78
|
+
|
79
|
+
describe 'haml2erb' do
|
80
|
+
it 'converts to ERB' do
|
81
|
+
Haml2Erb.convert(haml).should eq(erb)
|
82
|
+
end
|
83
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
CHANGED
@@ -1,59 +1,91 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: haml2erb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 961915996
|
5
|
+
prerelease: 6
|
5
6
|
segments:
|
6
7
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
|
8
|
+
- 3
|
9
|
+
- 0
|
10
|
+
- pre
|
11
|
+
version: 0.3.0.pre
|
10
12
|
platform: ruby
|
11
13
|
authors:
|
12
|
-
-
|
14
|
+
- Elia Schito
|
13
15
|
autorequire:
|
14
16
|
bindir: bin
|
15
17
|
cert_chain: []
|
16
18
|
|
17
|
-
date: 2011-
|
18
|
-
default_executable:
|
19
|
+
date: 2011-11-09 00:00:00 Z
|
19
20
|
dependencies:
|
20
21
|
- !ruby/object:Gem::Dependency
|
21
|
-
|
22
|
-
prerelease: false
|
22
|
+
type: :runtime
|
23
23
|
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ~>
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 5
|
29
|
+
segments:
|
30
|
+
- 3
|
31
|
+
- 1
|
32
|
+
- 3
|
33
|
+
version: 3.1.3
|
34
|
+
prerelease: false
|
35
|
+
name: haml
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
type: :development
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ~>
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 3
|
45
|
+
segments:
|
46
|
+
- 2
|
47
|
+
- 0
|
48
|
+
version: "2.0"
|
49
|
+
prerelease: false
|
50
|
+
name: rspec
|
51
|
+
version_requirements: *id002
|
52
|
+
- !ruby/object:Gem::Dependency
|
53
|
+
type: :development
|
54
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
24
55
|
none: false
|
25
56
|
requirements:
|
26
57
|
- - ">="
|
27
58
|
- !ruby/object:Gem::Version
|
59
|
+
hash: 3
|
28
60
|
segments:
|
29
61
|
- 0
|
30
62
|
version: "0"
|
31
|
-
|
32
|
-
|
33
|
-
|
63
|
+
prerelease: false
|
64
|
+
name: rake
|
65
|
+
version_requirements: *id003
|
66
|
+
description: Converts Haml templates to Erb templates using the official Haml::Engine
|
34
67
|
email:
|
35
|
-
-
|
36
|
-
executables:
|
37
|
-
|
68
|
+
- perlelia@gmail.com
|
69
|
+
executables:
|
70
|
+
- haml2erb
|
38
71
|
extensions: []
|
39
72
|
|
40
73
|
extra_rdoc_files: []
|
41
74
|
|
42
75
|
files:
|
43
|
-
-
|
44
|
-
-
|
76
|
+
- .gitignore
|
77
|
+
- Gemfile
|
78
|
+
- MIT_LICENSE
|
79
|
+
- README.md
|
80
|
+
- Rakefile
|
81
|
+
- bin/haml2erb
|
45
82
|
- haml2erb.gemspec
|
46
83
|
- lib/haml2erb.rb
|
47
|
-
- lib/haml2erb/
|
48
|
-
- lib/haml2erb/lexer.rb
|
49
|
-
- lib/haml2erb/mixins/comerging.rb
|
50
|
-
- lib/haml2erb/parser.rb
|
51
|
-
- lib/haml2erb/railtie.rb
|
52
|
-
- lib/haml2erb/tokens.rb
|
84
|
+
- lib/haml2erb/engine.rb
|
53
85
|
- lib/haml2erb/version.rb
|
54
|
-
-
|
55
|
-
|
56
|
-
homepage:
|
86
|
+
- spec/haml2erb_spec.rb
|
87
|
+
- spec/spec_helper.rb
|
88
|
+
homepage: ""
|
57
89
|
licenses: []
|
58
90
|
|
59
91
|
post_install_message:
|
@@ -66,25 +98,28 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
66
98
|
requirements:
|
67
99
|
- - ">="
|
68
100
|
- !ruby/object:Gem::Version
|
101
|
+
hash: 3
|
69
102
|
segments:
|
70
103
|
- 0
|
71
104
|
version: "0"
|
72
105
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
106
|
none: false
|
74
107
|
requirements:
|
75
|
-
- - "
|
108
|
+
- - ">"
|
76
109
|
- !ruby/object:Gem::Version
|
110
|
+
hash: 25
|
77
111
|
segments:
|
78
112
|
- 1
|
79
113
|
- 3
|
80
|
-
-
|
81
|
-
version: 1.3.
|
114
|
+
- 1
|
115
|
+
version: 1.3.1
|
82
116
|
requirements: []
|
83
117
|
|
84
|
-
rubyforge_project:
|
85
|
-
rubygems_version: 1.
|
118
|
+
rubyforge_project: haml2erb
|
119
|
+
rubygems_version: 1.8.10
|
86
120
|
signing_key:
|
87
121
|
specification_version: 3
|
88
|
-
summary: Haml to
|
89
|
-
test_files:
|
90
|
-
|
122
|
+
summary: Convert Haml templates to Erb!
|
123
|
+
test_files:
|
124
|
+
- spec/haml2erb_spec.rb
|
125
|
+
- spec/spec_helper.rb
|
data/README.rdoc
DELETED
@@ -1,58 +0,0 @@
|
|
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.
|
data/lib/haml2erb/erb_writer.rb
DELETED
@@ -1,51 +0,0 @@
|
|
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
|
data/lib/haml2erb/lexer.rb
DELETED
@@ -1,28 +0,0 @@
|
|
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
|
@@ -1,22 +0,0 @@
|
|
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
|
data/lib/haml2erb/parser.rb
DELETED
@@ -1,69 +0,0 @@
|
|
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
|
data/lib/haml2erb/railtie.rb
DELETED
data/lib/haml2erb/tokens.rb
DELETED
@@ -1,110 +0,0 @@
|
|
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
|
data/tasks/haml2erb.rake
DELETED
@@ -1,7 +0,0 @@
|
|
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
|