haml_to_star 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/lib/haml_to_star.rb +292 -0
- metadata +45 -0
data/lib/haml_to_star.rb
ADDED
@@ -0,0 +1,292 @@
|
|
1
|
+
# HAML-TO-*
|
2
|
+
|
3
|
+
# MIT - Sebastien Drouyer
|
4
|
+
|
5
|
+
# Why an other haml converter (especially for JS) ?
|
6
|
+
# - others are using global variables, except if you prefix all your variables with this.
|
7
|
+
# - they don't support brackets in parameters : try {value: "test}"}
|
8
|
+
# - we are giving line number so that you can debug your code more easily
|
9
|
+
# - class can't be used on prefix and params on others
|
10
|
+
# - this one is intended to be used in various languages : you can easily use it for others languages as Ruby or C
|
11
|
+
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'json'
|
15
|
+
require 'cgi'
|
16
|
+
|
17
|
+
class CodeElement
|
18
|
+
attr_accessor :line
|
19
|
+
attr_accessor :children
|
20
|
+
attr_accessor :line_number
|
21
|
+
|
22
|
+
def initialize
|
23
|
+
@line = ''
|
24
|
+
@line_number = 0
|
25
|
+
@children = []
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class HamlToStar
|
30
|
+
attr_accessor :variable_name
|
31
|
+
attr_accessor :variable_line_name
|
32
|
+
attr_accessor :self_closing
|
33
|
+
attr_accessor :doc_types
|
34
|
+
attr_accessor :line_number
|
35
|
+
|
36
|
+
def initialize
|
37
|
+
@variable_name = '_$output'
|
38
|
+
@variable_line_name = '_$line'
|
39
|
+
@self_closing = [
|
40
|
+
'meta',
|
41
|
+
'img',
|
42
|
+
'link',
|
43
|
+
'br',
|
44
|
+
'hr',
|
45
|
+
'input',
|
46
|
+
'area',
|
47
|
+
'base']
|
48
|
+
|
49
|
+
@doc_types = {
|
50
|
+
'5' => '<!DOCTYPE html>',
|
51
|
+
'xml' => '<?xml version="1.0" encoding="utf-8" ?>',
|
52
|
+
'default' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
|
53
|
+
'strict' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
|
54
|
+
'frameset' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">',
|
55
|
+
'1.1' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">',
|
56
|
+
'basic' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">',
|
57
|
+
'mobile' => '<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">'
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
def convert_from_string(str)
|
63
|
+
nb_char_spacing = get_indentation_spacing_from_string(str)
|
64
|
+
|
65
|
+
@line_number = 0
|
66
|
+
code_tree = CodeElement.new
|
67
|
+
code_tree.children = get_code_children_from_string(str, nb_char_spacing, 0)
|
68
|
+
return convert_from_tree(code_tree)
|
69
|
+
end
|
70
|
+
|
71
|
+
def get_code_children_from_string(str, nb_char_spacing, nb_indentation_objective)
|
72
|
+
temp_str = ''
|
73
|
+
children = []
|
74
|
+
str.each_line do |line|
|
75
|
+
nb_indentations = get_nb_indentation_from_line(line, nb_char_spacing)
|
76
|
+
if (nb_indentations == nb_indentation_objective)
|
77
|
+
code_element = CodeElement.new
|
78
|
+
code_element.line = line[nb_indentation_objective * nb_char_spacing..line.size]
|
79
|
+
if code_element.line[code_element.line.size - 1] == "\n"
|
80
|
+
code_element.line = code_element.line[0..code_element.line.size - 2]
|
81
|
+
end
|
82
|
+
if (temp_str != '')
|
83
|
+
children.last.children = get_code_children_from_string(temp_str, nb_char_spacing, nb_indentation_objective + 1)
|
84
|
+
temp_str = ''
|
85
|
+
end
|
86
|
+
@line_number += 1
|
87
|
+
code_element.line_number = @line_number
|
88
|
+
children << code_element
|
89
|
+
else
|
90
|
+
temp_str += line
|
91
|
+
end
|
92
|
+
end
|
93
|
+
if (temp_str != '')
|
94
|
+
children.last.children = get_code_children_from_string(temp_str, nb_char_spacing, nb_indentation_objective + 1)
|
95
|
+
temp_str = ''
|
96
|
+
end
|
97
|
+
return children
|
98
|
+
end
|
99
|
+
|
100
|
+
def get_nb_indentation_from_line(line, nb_char_spacing)
|
101
|
+
nb_char = 0
|
102
|
+
line.each_char do |char|
|
103
|
+
if is_spacing_character(char)
|
104
|
+
nb_char += 1
|
105
|
+
else
|
106
|
+
break;
|
107
|
+
end
|
108
|
+
end
|
109
|
+
if (nb_char % nb_char_spacing != 0)
|
110
|
+
raise "Bad indentation"
|
111
|
+
end
|
112
|
+
return nb_char / nb_char_spacing
|
113
|
+
end
|
114
|
+
|
115
|
+
def get_indentation_spacing_from_string(str)
|
116
|
+
str.each_line do |line|
|
117
|
+
nb_char = 0
|
118
|
+
line.each_char do |char|
|
119
|
+
if is_spacing_character(char)
|
120
|
+
nb_char += 1
|
121
|
+
else
|
122
|
+
break
|
123
|
+
end
|
124
|
+
end
|
125
|
+
if (nb_char != 0)
|
126
|
+
return nb_char
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
return 1
|
131
|
+
end
|
132
|
+
|
133
|
+
def is_spacing_character(char)
|
134
|
+
return char == ' ' || char == "\t";
|
135
|
+
end
|
136
|
+
|
137
|
+
def convert_from_tree(code_tree, indentation = -1)
|
138
|
+
str = []
|
139
|
+
|
140
|
+
inside = []
|
141
|
+
code_tree.children.each do |child|
|
142
|
+
inside << convert_from_tree(child, indentation + 1)
|
143
|
+
end
|
144
|
+
if (indentation > -1)
|
145
|
+
line = code_tree.line
|
146
|
+
if (line[0] != '-')
|
147
|
+
process_code_number(str, code_tree.line_number)
|
148
|
+
end
|
149
|
+
if (line[0] == '%' || line[0] == '.' || line[0] == '#')
|
150
|
+
dom = convert_dom_element(line)
|
151
|
+
if (dom[:self_closing])
|
152
|
+
add_content(str, dom[:begin])
|
153
|
+
else
|
154
|
+
add_content(str, dom[:begin])
|
155
|
+
if (inside.size > 0)
|
156
|
+
str << inside.join("\n")
|
157
|
+
else
|
158
|
+
if (dom[:inside])
|
159
|
+
add_content(str, dom[:inside])
|
160
|
+
end
|
161
|
+
end
|
162
|
+
add_content(str, dom[:end])
|
163
|
+
end
|
164
|
+
elsif (line[0] == '=' || line[0] == '!')
|
165
|
+
process_inline_code(str, line)
|
166
|
+
elsif (line[0] == '-')
|
167
|
+
add_code(str, line, inside)
|
168
|
+
else
|
169
|
+
add_content(str, line.to_json)
|
170
|
+
end
|
171
|
+
else
|
172
|
+
initialize_content(str, inside)
|
173
|
+
end
|
174
|
+
|
175
|
+
return str.join("\n")
|
176
|
+
end
|
177
|
+
|
178
|
+
def convert_dom_element(line)
|
179
|
+
div_base_informations = line.gsub(%r{[^\{ =]*}).first
|
180
|
+
infos = div_base_informations.gsub(%r{[%.#][\w-]*})
|
181
|
+
params = {:tag => 'div'}
|
182
|
+
infos.each do |info|
|
183
|
+
if (info[0] == '%')
|
184
|
+
params[:tag] = info[1..info.size - 1]
|
185
|
+
elsif (info[0] == '#')
|
186
|
+
params[:id] = info[1..info.size - 1]
|
187
|
+
elsif (info[0] == '.')
|
188
|
+
unless params[:class]
|
189
|
+
params[:class] = ''
|
190
|
+
end
|
191
|
+
params[:class] += ' ' + info[1..info.size - 1]
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
rest_of_line = line[div_base_informations.size..line.size - 1]
|
196
|
+
|
197
|
+
num_brackets = 0
|
198
|
+
char_num = 0
|
199
|
+
start_brackets = 0
|
200
|
+
rest_of_line.each_char do |char|
|
201
|
+
if (char == '{')
|
202
|
+
if (num_brackets == 0)
|
203
|
+
start_brackets = char_num
|
204
|
+
end
|
205
|
+
num_brackets += 1
|
206
|
+
elsif (char == '}')
|
207
|
+
num_brackets -= 1
|
208
|
+
if (num_brackets == 0)
|
209
|
+
params[:additionnals] = process_additionnals(rest_of_line[start_brackets..char_num])
|
210
|
+
end
|
211
|
+
elsif (num_brackets == 0)
|
212
|
+
remaining = rest_of_line[char_num..rest_of_line.size - 1].strip
|
213
|
+
if (remaining.size > 0)
|
214
|
+
if (char == ' ')
|
215
|
+
params[:inside] = remaining
|
216
|
+
break
|
217
|
+
elsif (char == '=' || char == '!')
|
218
|
+
params[:inside_code] = evaluate(remaining)
|
219
|
+
break
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
char_num += 1
|
224
|
+
end
|
225
|
+
|
226
|
+
return construct_dom(params)
|
227
|
+
end
|
228
|
+
|
229
|
+
def construct_dom(params)
|
230
|
+
dom = {}
|
231
|
+
dom[:self_closing] = @self_closing.index(params[:tag])
|
232
|
+
dom[:begin] = '\'<' + params[:tag] + ' '
|
233
|
+
if (params[:additionnals])
|
234
|
+
extend = {}
|
235
|
+
if (params[:id])
|
236
|
+
extend[:id] = params[:id]
|
237
|
+
end
|
238
|
+
if (params[:class])
|
239
|
+
extend[:class] = params[:class]
|
240
|
+
end
|
241
|
+
dom[:begin] += '\' + attrs(' + params[:additionnals] + ', ' + extend.to_json + ') + \''
|
242
|
+
else
|
243
|
+
if (params[:id])
|
244
|
+
dom[:begin] += 'id="' + params[:id] + '" '
|
245
|
+
end
|
246
|
+
if (params[:class])
|
247
|
+
dom[:begin] += 'class="' + params[:class] + '" '
|
248
|
+
end
|
249
|
+
end
|
250
|
+
dom[:begin] += (dom[:self_closing] ? '/' : '') + '>\''
|
251
|
+
if (params[:inside])
|
252
|
+
dom[:inside] = CGI::escapeHTML(params[:inside])
|
253
|
+
elsif (params[:inside_code])
|
254
|
+
dom[:inside] = params[:inside_code]
|
255
|
+
end
|
256
|
+
|
257
|
+
dom[:end] = '\'</' + params[:tag] + '>\''
|
258
|
+
return dom
|
259
|
+
end
|
260
|
+
|
261
|
+
def process_additionnals(additionnals)
|
262
|
+
raise 'To be defined'
|
263
|
+
end
|
264
|
+
|
265
|
+
def process_code_line(line)
|
266
|
+
raise 'To be defined'
|
267
|
+
end
|
268
|
+
|
269
|
+
def initialize_content(str, content)
|
270
|
+
raise 'To be defined'
|
271
|
+
end
|
272
|
+
|
273
|
+
def add_content(str, content)
|
274
|
+
raise 'To be defined'
|
275
|
+
end
|
276
|
+
|
277
|
+
def add_code(str, line, inside)
|
278
|
+
raise 'To be defined'
|
279
|
+
end
|
280
|
+
|
281
|
+
def evaluate(line)
|
282
|
+
raise 'To be defined'
|
283
|
+
end
|
284
|
+
|
285
|
+
def process_code_number(str, code_number)
|
286
|
+
raise 'To be defined'
|
287
|
+
end
|
288
|
+
|
289
|
+
def process_inline_code(str, content)
|
290
|
+
raise 'To be defined'
|
291
|
+
end
|
292
|
+
end
|
metadata
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: haml_to_star
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Sébastien Drouyer
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-12-24 00:00:00.000000000Z
|
13
|
+
dependencies: []
|
14
|
+
description: haml_to_star allows you to convert haml code into any language.
|
15
|
+
email: sdrdis@hotmail.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- lib/haml_to_star.rb
|
21
|
+
homepage: http://rubygems.org/gems/haml_to_star
|
22
|
+
licenses: []
|
23
|
+
post_install_message:
|
24
|
+
rdoc_options: []
|
25
|
+
require_paths:
|
26
|
+
- lib
|
27
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
35
|
+
requirements:
|
36
|
+
- - ! '>='
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
requirements: []
|
40
|
+
rubyforge_project:
|
41
|
+
rubygems_version: 1.8.17
|
42
|
+
signing_key:
|
43
|
+
specification_version: 3
|
44
|
+
summary: convert haml code into an other language
|
45
|
+
test_files: []
|