haml2handlebars 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 +4 -0
- data/Gemfile +4 -0
- data/MIT_LICENSE +20 -0
- data/README.md +57 -0
- data/Rakefile +1 -0
- data/bin/haml2handlebars +19 -0
- data/haml2handlebars.gemspec +28 -0
- data/lib/haml2handlebars.rb +8 -0
- data/lib/haml2handlebars/attributes_parser.rb +86 -0
- data/lib/haml2handlebars/engine.rb +251 -0
- data/lib/haml2handlebars/version.rb +3 -0
- data/spec/haml2handlebars_spec.rb +85 -0
- data/spec/spec_helper.rb +3 -0
- metadata +109 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/MIT_LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2006-2011 Elia Schito
|
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.md
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
# haml2handlebars
|
2
|
+
|
3
|
+
haml2handlebars is a tool for converting [Haml](http://haml-lang.com/) to Handlebars markup.
|
4
|
+
|
5
|
+
|
6
|
+
## Installing and loading haml2handlebars
|
7
|
+
|
8
|
+
haml2handlebars is currently distributed as a ruby gem.
|
9
|
+
|
10
|
+
`gem install haml2handlebars`
|
11
|
+
|
12
|
+
|
13
|
+
## Using haml2handlebars
|
14
|
+
|
15
|
+
Use the `haml2handlebars` command line or from Ruby call the `Haml2Handlebars.convert` method to have Haml markup translated into Handlebars.
|
16
|
+
|
17
|
+
### Example: Simple conversion
|
18
|
+
|
19
|
+
```bash
|
20
|
+
echo '.foo= bar' | haml2handlebars
|
21
|
+
# <div class='foo'>{{bar}}</div>
|
22
|
+
```
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
haml = """
|
26
|
+
- if foo
|
27
|
+
.bar= baz
|
28
|
+
- else
|
29
|
+
= qux
|
30
|
+
"""
|
31
|
+
Haml2Handlebars.convert(haml)
|
32
|
+
# =>
|
33
|
+
# {{#if foo}}
|
34
|
+
# <div class='bar'>{{baz}}</div>
|
35
|
+
# {{else}}
|
36
|
+
# {{qux}}
|
37
|
+
# {{/if}}
|
38
|
+
```
|
39
|
+
|
40
|
+
|
41
|
+
## TODO
|
42
|
+
|
43
|
+
* Integrate with Rails Asset Pipeline for use in rails-ember projects, probably in a separate gem that depends on this?
|
44
|
+
|
45
|
+
## License
|
46
|
+
|
47
|
+
[MIT_LICENSE](/botandrose/haml2handlebars/blob/master/MIT_LICENSE)
|
48
|
+
|
49
|
+
|
50
|
+
## Credits
|
51
|
+
|
52
|
+
Based on [elia/haml2erb](https://github.com/elia/haml2erb):
|
53
|
+
[Elia Schito](https://github.com/elia)
|
54
|
+
|
55
|
+
Which is based on [c1sgo/haml2erb](https://github.com/c1sgo/haml2erb):
|
56
|
+
[Chris Goddard](https://github.com/cgoddard)
|
57
|
+
[Louis Sivillo](https://github.com/BeaconInteractive)
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/haml2handlebars
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
require 'haml2handlebars'
|
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, handlebars_file = *ARGV
|
16
|
+
input = haml_file ? File.open(haml_file) : $stdin
|
17
|
+
output = handlebars_file ? File.open(handlebars_file, 'w') : $stdout
|
18
|
+
|
19
|
+
output.write Haml2Handlebars.convert(input.read)
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
$:.push File.expand_path('../lib', __FILE__)
|
3
|
+
require 'haml2handlebars/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'haml2handlebars'
|
7
|
+
s.version = Haml2Handlebars::VERSION
|
8
|
+
s.authors = ['Elia Schito', 'Micah Geisel']
|
9
|
+
s.email = ['perlelia@gmail.com', 'micah@botandrose.com']
|
10
|
+
s.homepage = ''
|
11
|
+
s.summary = %q{Convert Haml templates to Handlebars!}
|
12
|
+
s.description = %q{Converts Haml templates to Handlebars templates using the official Haml::Engine}
|
13
|
+
|
14
|
+
s.rubyforge_project = 'haml2handlebars'
|
15
|
+
|
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']
|
20
|
+
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
# s.add_development_dependency "rspec"
|
23
|
+
# s.add_runtime_dependency "rest-client"
|
24
|
+
|
25
|
+
s.add_runtime_dependency 'haml', '~> 3.1.3'
|
26
|
+
s.add_development_dependency 'rspec', '~> 2.0'
|
27
|
+
s.add_development_dependency 'rake'
|
28
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Haml2Handlebars
|
2
|
+
class AttributesParser
|
3
|
+
class DynamicAttributes < StandardError
|
4
|
+
end
|
5
|
+
|
6
|
+
def initialize attributes
|
7
|
+
@attributes = attributes
|
8
|
+
@pairs = []
|
9
|
+
end
|
10
|
+
attr_reader :pairs, :attributes
|
11
|
+
|
12
|
+
CONTENTS = /^, \{(.*)\}$/
|
13
|
+
ROCKET = '\=\>'
|
14
|
+
|
15
|
+
SYMBOL_TEXT = '[\w_]+'
|
16
|
+
STRING_TEXT = '[\w_-]+'
|
17
|
+
|
18
|
+
SYMBOL_KEY = /^(?:\:(#{SYMBOL_TEXT})\s*#{ROCKET}|(#{SYMBOL_TEXT}):)\s*/
|
19
|
+
STRING_KEY = /^(?:'(#{STRING_TEXT})'|"(#{STRING_TEXT})")\s*#{ROCKET}\s*/
|
20
|
+
|
21
|
+
SYMBOL_VALUE = /^:(#{SYMBOL_TEXT})\s*/
|
22
|
+
STRING_VALUE = /^(?:"([^"]+)"|'([^']+)')\s*/
|
23
|
+
STRING_INTERPOLATION = /^("[^\\]*)#\{/
|
24
|
+
|
25
|
+
def parse!
|
26
|
+
rest = attributes.strip.scan(CONTENTS).flatten.first
|
27
|
+
begin
|
28
|
+
while rest and not(rest.empty?)
|
29
|
+
if rest =~ SYMBOL_KEY
|
30
|
+
key = $1 || $2
|
31
|
+
rest.gsub! SYMBOL_KEY, ''
|
32
|
+
elsif rest =~ STRING_KEY
|
33
|
+
key = $1 || $2
|
34
|
+
rest.gsub! STRING_KEY, ''
|
35
|
+
else
|
36
|
+
raise DynamicAttributes
|
37
|
+
end
|
38
|
+
|
39
|
+
if rest =~ STRING_VALUE
|
40
|
+
value = $1
|
41
|
+
raise DynamicAttributes if rest =~ STRING_INTERPOLATION
|
42
|
+
elsif rest =~ SYMBOL_VALUE
|
43
|
+
value = $1 || $2
|
44
|
+
else
|
45
|
+
raise DynamicAttributes
|
46
|
+
end
|
47
|
+
|
48
|
+
pairs << [key, value]
|
49
|
+
end
|
50
|
+
rescue DynamicAttributes
|
51
|
+
@dynamic = true
|
52
|
+
return
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def dynamic?
|
57
|
+
@dynamic
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.hash_to_html hash
|
61
|
+
hash.each_pair.map do |key, value|
|
62
|
+
" #{key}='#{value.gsub("'", ''')}'"
|
63
|
+
end.join('')
|
64
|
+
end
|
65
|
+
|
66
|
+
def to_html
|
67
|
+
if attributes.strip.empty?
|
68
|
+
return ''
|
69
|
+
else
|
70
|
+
parse!
|
71
|
+
if dynamic?
|
72
|
+
hash = attributes.scan(CONTENTS).flatten.first
|
73
|
+
hash.strip!
|
74
|
+
hash.gsub! /\s*,$/, ''
|
75
|
+
hash.gsub! /\#{(\w+)}/, "{{\\1}}"
|
76
|
+
hash = eval "{#{hash}}"
|
77
|
+
" #{hash.keys.first}=\"#{hash.values.first}\""
|
78
|
+
else
|
79
|
+
pairs.map do |(key, value)|
|
80
|
+
"#{key}='#{value.gsub("'", ''')}'"
|
81
|
+
end.join('')
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,251 @@
|
|
1
|
+
require 'haml'
|
2
|
+
require 'haml2handlebars/attributes_parser'
|
3
|
+
|
4
|
+
module Haml::Parser
|
5
|
+
START_BLOCK_KEYWORDS << "each"
|
6
|
+
START_BLOCK_KEYWORD_REGEX = /(?:\w+(?:,\s*\w+)*\s*=\s*)?(#{START_BLOCK_KEYWORDS.join('|')})/
|
7
|
+
BLOCK_KEYWORD_REGEX = /^-\s*(?:(#{MID_BLOCK_KEYWORDS.join('|')})|#{START_BLOCK_KEYWORD_REGEX.source})\b/
|
8
|
+
end
|
9
|
+
|
10
|
+
module Haml2Handlebars
|
11
|
+
class Engine < Haml::Engine
|
12
|
+
|
13
|
+
|
14
|
+
def push_silent(text, can_suppress = false, opts = {})
|
15
|
+
flush_merged_text
|
16
|
+
return if can_suppress && options[:suppress_eval]
|
17
|
+
# WAS:
|
18
|
+
# @precompiled << "#{resolve_newlines}#{text}\n"
|
19
|
+
# @output_line += text.count("\n") + 1
|
20
|
+
|
21
|
+
push_script(text,
|
22
|
+
opts.merge(:preserve_script => @node.value[:preserve],
|
23
|
+
:escape_html => @node.value[:escape_html],
|
24
|
+
:silent => true))
|
25
|
+
end
|
26
|
+
|
27
|
+
def compile_haml_comment
|
28
|
+
text = @node.value[:text]
|
29
|
+
return if text.empty?
|
30
|
+
|
31
|
+
push_script(text,
|
32
|
+
:preserve_script => @node.value[:preserve],
|
33
|
+
:escape_html => @node.value[:escape_html],
|
34
|
+
:silent => true, :comment => true)
|
35
|
+
end
|
36
|
+
|
37
|
+
def compile_silent_script
|
38
|
+
return if @options[:suppress_eval]
|
39
|
+
keyword = @node.value[:keyword]
|
40
|
+
@output_tabs -= 1 if Haml::Parser::MID_BLOCK_KEYWORDS.include?(keyword)
|
41
|
+
|
42
|
+
push_silent(@node.value[:text], false, :block_given => block_given?)
|
43
|
+
ruby_block = block_given? && !keyword
|
44
|
+
|
45
|
+
|
46
|
+
if block_given?
|
47
|
+
# Store these values because for conditional statements,
|
48
|
+
# we want to restore them for each branch
|
49
|
+
@node.value[:dont_indent_next_line] = @dont_indent_next_line
|
50
|
+
@node.value[:dont_tab_up_next_text] = @dont_tab_up_next_text
|
51
|
+
|
52
|
+
@output_tabs += 1
|
53
|
+
yield
|
54
|
+
@output_tabs -= 1
|
55
|
+
|
56
|
+
push_silent("/#{@node.value[:keyword]}", :can_suppress) unless @node.value[:dont_push_end]
|
57
|
+
elsif keyword == "end"
|
58
|
+
if @node.parent.children.last.equal?(@node)
|
59
|
+
# Since this "end" is ending the block,
|
60
|
+
# we don't need to generate an additional one
|
61
|
+
@node.parent.value[:dont_push_end] = true
|
62
|
+
end
|
63
|
+
# Don't restore dont_* for end because it isn't a conditional branch.
|
64
|
+
elsif Haml::Parser::MID_BLOCK_KEYWORDS.include?(keyword)
|
65
|
+
@output_tabs += 1
|
66
|
+
|
67
|
+
# Restore dont_* for this conditional branch
|
68
|
+
@dont_indent_next_line = @node.parent.value[:dont_indent_next_line]
|
69
|
+
@dont_tab_up_next_text = @node.parent.value[:dont_tab_up_next_text]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def push_script text, opts={}
|
74
|
+
tag_lead = opts[:block_given] ? "#" : ""
|
75
|
+
handlebars_tag = "{{#{tag_lead}#{text.strip}}}"
|
76
|
+
|
77
|
+
# USED TO START HERE:
|
78
|
+
return if options[:suppress_eval]
|
79
|
+
|
80
|
+
args = %w[preserve_script in_tag preserve_tag escape_html nuke_inner_whitespace]
|
81
|
+
args.map! {|name| opts[name.to_sym]}
|
82
|
+
args << !block_given? << @options[:ugly]
|
83
|
+
|
84
|
+
no_format = @options[:ugly] &&
|
85
|
+
!(opts[:preserve_script] || opts[:preserve_tag] || opts[:escape_html])
|
86
|
+
output_expr = "(#{text}\n)"
|
87
|
+
static_method = "_hamlout.#{static_method_name(:format_script, *args)}"
|
88
|
+
|
89
|
+
# Prerender tabulation unless we're in a tag
|
90
|
+
push_merged_text '' unless opts[:in_tag]
|
91
|
+
|
92
|
+
unless block_given?
|
93
|
+
# WAS: push_generated_script(no_format ? "#{text}\n" : "#{static_method}(#{output_expr});")
|
94
|
+
push_generated_script(handlebars_tag.inspect)
|
95
|
+
|
96
|
+
concat_merged_text("\n") unless opts[:in_tag] || opts[:nuke_inner_whitespace]
|
97
|
+
|
98
|
+
# push_generated_script(handlebars_tag.inspect)
|
99
|
+
#
|
100
|
+
# concat_merged_text("\n") unless opts[:in_tag] || opts[:nuke_inner_whitespace]
|
101
|
+
|
102
|
+
# @output_tabs += 1
|
103
|
+
return
|
104
|
+
end
|
105
|
+
|
106
|
+
flush_merged_text
|
107
|
+
push_generated_script handlebars_tag.inspect
|
108
|
+
concat_merged_text("\n") unless opts[:in_tag] || opts[:nuke_inner_whitespace]
|
109
|
+
|
110
|
+
# push_silent text
|
111
|
+
|
112
|
+
@output_tabs += 1 unless opts[:nuke_inner_whitespace]
|
113
|
+
yield
|
114
|
+
@output_tabs -= 1 unless opts[:nuke_inner_whitespace]
|
115
|
+
|
116
|
+
push_silent('end', :can_suppress) unless @node.value[:dont_push_end]
|
117
|
+
# COMMENTED: @precompiled << "_hamlout.buffer << #{no_format ? "haml_temp.to_s;" : "#{static_method}(haml_temp);"}"
|
118
|
+
concat_merged_text("\n") unless opts[:in_tag] || opts[:nuke_inner_whitespace] || @options[:ugly]
|
119
|
+
end
|
120
|
+
|
121
|
+
def to_handlebars(scope = Object.new, locals = {}, &block)
|
122
|
+
buffer = Haml::Buffer.new(scope.instance_variable_get('@haml_buffer'), options_for_buffer)
|
123
|
+
|
124
|
+
if scope.is_a?(Binding) || scope.is_a?(Proc)
|
125
|
+
scope_object = eval("self", scope)
|
126
|
+
scope = scope_object.instance_eval{binding} if block_given?
|
127
|
+
else
|
128
|
+
scope_object = scope
|
129
|
+
scope = scope_object.instance_eval{binding}
|
130
|
+
end
|
131
|
+
|
132
|
+
set_locals(locals.merge(:_hamlout => buffer, :_erbout => buffer.buffer), scope, scope_object)
|
133
|
+
|
134
|
+
scope_object.instance_eval do
|
135
|
+
extend Haml::Helpers
|
136
|
+
@haml_buffer = buffer
|
137
|
+
end
|
138
|
+
|
139
|
+
eval(precompiled + ";" + precompiled_method_return_value,
|
140
|
+
scope, @options[:filename], @options[:line])
|
141
|
+
ensure
|
142
|
+
# Get rid of the current buffer
|
143
|
+
scope_object.instance_eval do
|
144
|
+
@haml_buffer = buffer.upper if buffer
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
|
149
|
+
def compile_tag
|
150
|
+
t = @node.value
|
151
|
+
|
152
|
+
# Get rid of whitespace outside of the tag if we need to
|
153
|
+
rstrip_buffer! if t[:nuke_outer_whitespace]
|
154
|
+
|
155
|
+
dont_indent_next_line =
|
156
|
+
(t[:nuke_outer_whitespace] && !block_given?) ||
|
157
|
+
(t[:nuke_inner_whitespace] && block_given?)
|
158
|
+
|
159
|
+
if @options[:suppress_eval]
|
160
|
+
object_ref = "nil"
|
161
|
+
parse = false
|
162
|
+
value = t[:parse] ? nil : t[:value]
|
163
|
+
attributes_hashes = {}
|
164
|
+
preserve_script = false
|
165
|
+
else
|
166
|
+
object_ref = t[:object_ref]
|
167
|
+
parse = t[:parse]
|
168
|
+
value = t[:value]
|
169
|
+
attributes_hashes = t[:attributes_hashes]
|
170
|
+
preserve_script = t[:preserve_script]
|
171
|
+
end
|
172
|
+
|
173
|
+
# Check if we can render the tag directly to text and not process it in the buffer
|
174
|
+
if object_ref == "nil" && attributes_hashes.empty? && !preserve_script
|
175
|
+
tag_closed = !block_given? && !t[:self_closing] && !parse
|
176
|
+
|
177
|
+
open_tag = prerender_tag(t[:name], t[:self_closing], t[:attributes])
|
178
|
+
if tag_closed
|
179
|
+
open_tag << "#{value}</#{t[:name]}>"
|
180
|
+
open_tag << "\n" unless t[:nuke_outer_whitespace]
|
181
|
+
elsif !(parse || t[:nuke_inner_whitespace] ||
|
182
|
+
(t[:self_closing] && t[:nuke_outer_whitespace]))
|
183
|
+
open_tag << "\n"
|
184
|
+
end
|
185
|
+
|
186
|
+
push_merged_text(open_tag,
|
187
|
+
tag_closed || t[:self_closing] || t[:nuke_inner_whitespace] ? 0 : 1,
|
188
|
+
!t[:nuke_outer_whitespace])
|
189
|
+
|
190
|
+
@dont_indent_next_line = dont_indent_next_line
|
191
|
+
return if tag_closed
|
192
|
+
else
|
193
|
+
if attributes_hashes.empty?
|
194
|
+
attributes_hashes = ''
|
195
|
+
elsif attributes_hashes.size == 1
|
196
|
+
attributes_hashes = ", #{attributes_hashes.first}"
|
197
|
+
else
|
198
|
+
attributes_hashes = ", (#{attributes_hashes.join(").merge(")})"
|
199
|
+
end
|
200
|
+
attributes_hashes.gsub! ",}", "}"
|
201
|
+
|
202
|
+
push_merged_text "<#{t[:name]}", 0, !t[:nuke_outer_whitespace]
|
203
|
+
|
204
|
+
# WAS:
|
205
|
+
# push_generated_script(
|
206
|
+
# "_hamlout.attributes(#{inspect_obj(t[:attributes])}, #{object_ref}#{attributes_hashes})")
|
207
|
+
# NOW: attempt a simplistic parse of the attributes
|
208
|
+
concat_merged_text AttributesParser.hash_to_html(t[:attributes])+
|
209
|
+
AttributesParser.new(attributes_hashes).to_html
|
210
|
+
|
211
|
+
concat_merged_text(
|
212
|
+
if t[:self_closing] && xhtml?
|
213
|
+
" />" + (t[:nuke_outer_whitespace] ? "" : "\n")
|
214
|
+
else
|
215
|
+
">" + ((if t[:self_closing] && html?
|
216
|
+
t[:nuke_outer_whitespace]
|
217
|
+
else
|
218
|
+
!block_given? || t[:preserve_tag] || t[:nuke_inner_whitespace]
|
219
|
+
end) ? "" : "\n")
|
220
|
+
end)
|
221
|
+
|
222
|
+
if value && !parse
|
223
|
+
concat_merged_text("#{value}</#{t[:name]}>#{t[:nuke_outer_whitespace] ? "" : "\n"}")
|
224
|
+
else
|
225
|
+
@to_merge << [:text, '', 1] unless t[:nuke_inner_whitespace]
|
226
|
+
end
|
227
|
+
|
228
|
+
@dont_indent_next_line = dont_indent_next_line
|
229
|
+
end
|
230
|
+
|
231
|
+
return if t[:self_closing]
|
232
|
+
|
233
|
+
if value.nil?
|
234
|
+
@output_tabs += 1 unless t[:nuke_inner_whitespace]
|
235
|
+
yield if block_given?
|
236
|
+
@output_tabs -= 1 unless t[:nuke_inner_whitespace]
|
237
|
+
rstrip_buffer! if t[:nuke_inner_whitespace]
|
238
|
+
push_merged_text("</#{t[:name]}>" + (t[:nuke_outer_whitespace] ? "" : "\n"),
|
239
|
+
t[:nuke_inner_whitespace] ? 0 : -1, !t[:nuke_inner_whitespace])
|
240
|
+
@dont_indent_next_line = t[:nuke_outer_whitespace]
|
241
|
+
return
|
242
|
+
end
|
243
|
+
|
244
|
+
if parse
|
245
|
+
push_script(value, t.merge(:in_tag => true))
|
246
|
+
concat_merged_text("</#{t[:name]}>" + (t[:nuke_outer_whitespace] ? "" : "\n"))
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
end
|
251
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
haml = %q{
|
4
|
+
!!!
|
5
|
+
%html(lang="en")
|
6
|
+
%head(dynamic="#{attribute}")
|
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
|
+
- each numbers
|
33
|
+
= n
|
34
|
+
= 1234
|
35
|
+
%aside.right
|
36
|
+
%section#tweets(data-widget="twitter")
|
37
|
+
%section#hammurabi
|
38
|
+
}
|
39
|
+
|
40
|
+
handlebars = %q{<!DOCTYPE html>
|
41
|
+
<html lang='en'>
|
42
|
+
<head dynamic="{{attribute}}">
|
43
|
+
{{ciao}}
|
44
|
+
{{#if 3}}
|
45
|
+
{{pippo}}
|
46
|
+
{{else}}
|
47
|
+
{{caio}}
|
48
|
+
{{/if}}
|
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
|
+
{{#each numbers}}
|
66
|
+
{{n}}
|
67
|
+
{{/each}}
|
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 Haml2Handlebars do
|
80
|
+
describe ".convert" do
|
81
|
+
it 'converts haml to handlebars' do
|
82
|
+
Haml2Handlebars.convert(haml).should eq(handlebars)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: haml2handlebars
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Elia Schito
|
9
|
+
- Micah Geisel
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2012-04-26 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: haml
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ~>
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 3.1.3
|
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: 3.1.3
|
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: '2.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: '2.0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rake
|
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: Converts Haml templates to Handlebars templates using the official Haml::Engine
|
64
|
+
email:
|
65
|
+
- perlelia@gmail.com
|
66
|
+
- micah@botandrose.com
|
67
|
+
executables:
|
68
|
+
- haml2handlebars
|
69
|
+
extensions: []
|
70
|
+
extra_rdoc_files: []
|
71
|
+
files:
|
72
|
+
- .gitignore
|
73
|
+
- Gemfile
|
74
|
+
- MIT_LICENSE
|
75
|
+
- README.md
|
76
|
+
- Rakefile
|
77
|
+
- bin/haml2handlebars
|
78
|
+
- haml2handlebars.gemspec
|
79
|
+
- lib/haml2handlebars.rb
|
80
|
+
- lib/haml2handlebars/attributes_parser.rb
|
81
|
+
- lib/haml2handlebars/engine.rb
|
82
|
+
- lib/haml2handlebars/version.rb
|
83
|
+
- spec/haml2handlebars_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: haml2handlebars
|
105
|
+
rubygems_version: 1.8.22
|
106
|
+
signing_key:
|
107
|
+
specification_version: 3
|
108
|
+
summary: Convert Haml templates to Handlebars!
|
109
|
+
test_files: []
|