hamlet 0.1 → 0.2
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/hamlet.gemspec +2 -2
- data/lib/hamlet/forked_slim_parser.rb +448 -0
- data/lib/hamlet/parser.rb +2 -2
- data/lib/hamlet.rb +0 -2
- metadata +23 -22
data/hamlet.gemspec
CHANGED
@@ -4,7 +4,7 @@ require 'date'
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |s|
|
6
6
|
s.name = 'hamlet'
|
7
|
-
s.version = 0.
|
7
|
+
s.version = 0.2
|
8
8
|
s.date = Date.today.to_s
|
9
9
|
s.authors = ['Greg Weber']
|
10
10
|
s.email = ['greg@gregweber.info']
|
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
20
|
s.require_paths = %w(lib)
|
21
21
|
|
22
|
-
s.add_dependency('slim', ['~> 1.0'])
|
22
|
+
s.add_dependency('slim', ['~> 1.0.0'])
|
23
23
|
|
24
24
|
s.add_development_dependency('rake', ['>= 0.8.7'])
|
25
25
|
s.add_development_dependency('sass', ['>= 3.1.0'])
|
@@ -0,0 +1,448 @@
|
|
1
|
+
module ForkedSlim
|
2
|
+
# Parses Slim code and transforms it to a Temple expression
|
3
|
+
# @api private
|
4
|
+
class Parser
|
5
|
+
include Temple::Mixins::Options
|
6
|
+
|
7
|
+
set_default_options :tabsize => 4,
|
8
|
+
:encoding => 'utf-8',
|
9
|
+
:default_tag => 'div'
|
10
|
+
|
11
|
+
class SyntaxError < StandardError
|
12
|
+
attr_reader :error, :file, :line, :lineno, :column
|
13
|
+
|
14
|
+
def initialize(error, file, line, lineno, column)
|
15
|
+
@error = error
|
16
|
+
@file = file || '(__TEMPLATE__)'
|
17
|
+
@line = line.to_s
|
18
|
+
@lineno = lineno
|
19
|
+
@column = column
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_s
|
23
|
+
line = @line.strip
|
24
|
+
column = @column + line.size - @line.size
|
25
|
+
%{#{error}
|
26
|
+
#{file}, Line #{lineno}
|
27
|
+
#{line}
|
28
|
+
#{' ' * column}^
|
29
|
+
}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize(options = {})
|
34
|
+
super
|
35
|
+
@tab = ' ' * @options[:tabsize]
|
36
|
+
end
|
37
|
+
|
38
|
+
# Compile string to Temple expression
|
39
|
+
#
|
40
|
+
# @param [String] str Slim code
|
41
|
+
# @return [Array] Temple expression representing the code]]
|
42
|
+
def call(str)
|
43
|
+
# Set string encoding if option is set
|
44
|
+
if options[:encoding] && str.respond_to?(:encoding)
|
45
|
+
old = str.encoding
|
46
|
+
str = str.dup if str.frozen?
|
47
|
+
str.force_encoding(options[:encoding])
|
48
|
+
# Fall back to old encoding if new encoding is invalid
|
49
|
+
str.force_encoding(old_enc) unless str.valid_encoding?
|
50
|
+
end
|
51
|
+
|
52
|
+
result = [:multi]
|
53
|
+
reset(str.split($/), [result])
|
54
|
+
|
55
|
+
parse_line while next_line
|
56
|
+
|
57
|
+
reset
|
58
|
+
result
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
DELIMITERS = {
|
64
|
+
'(' => ')',
|
65
|
+
'[' => ']',
|
66
|
+
'{' => '}',
|
67
|
+
}.freeze
|
68
|
+
|
69
|
+
ATTR_SHORTCUT = {
|
70
|
+
'#' => 'id',
|
71
|
+
'.' => 'class',
|
72
|
+
}.freeze
|
73
|
+
|
74
|
+
DELIMITER_REGEX = /\A[\(\[\{]/
|
75
|
+
ATTR_NAME_REGEX = '\A\s*(\w[:\w-]*)'
|
76
|
+
|
77
|
+
if RUBY_VERSION > '1.9'
|
78
|
+
CLASS_ID_REGEX = /\A(#|\.)([\w\u00c0-\uFFFF][\w:\u00c0-\uFFFF-]*)/
|
79
|
+
else
|
80
|
+
CLASS_ID_REGEX = /\A(#|\.)(\w[\w:-]*)/
|
81
|
+
end
|
82
|
+
|
83
|
+
def reset(lines = nil, stacks = nil)
|
84
|
+
# Since you can indent however you like in Slim, we need to keep a list
|
85
|
+
# of how deeply indented you are. For instance, in a template like this:
|
86
|
+
#
|
87
|
+
# doctype # 0 spaces
|
88
|
+
# html # 0 spaces
|
89
|
+
# head # 1 space
|
90
|
+
# title # 4 spaces
|
91
|
+
#
|
92
|
+
# indents will then contain [0, 1, 4] (when it's processing the last line.)
|
93
|
+
#
|
94
|
+
# We uses this information to figure out how many steps we must "jump"
|
95
|
+
# out when we see an de-indented line.
|
96
|
+
@indents = [0]
|
97
|
+
|
98
|
+
# Whenever we want to output something, we'll *always* output it to the
|
99
|
+
# last stack in this array. So when there's a line that expects
|
100
|
+
# indentation, we simply push a new stack onto this array. When it
|
101
|
+
# processes the next line, the content will then be outputted into that
|
102
|
+
# stack.
|
103
|
+
@stacks = stacks
|
104
|
+
|
105
|
+
@lineno = 0
|
106
|
+
@lines = lines
|
107
|
+
@line = @orig_line = nil
|
108
|
+
end
|
109
|
+
|
110
|
+
def next_line
|
111
|
+
if @lines.empty?
|
112
|
+
@orig_line = @line = nil
|
113
|
+
else
|
114
|
+
@orig_line = @lines.shift
|
115
|
+
@lineno += 1
|
116
|
+
@line = @orig_line.dup
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def get_indent(line)
|
121
|
+
# Figure out the indentation. Kinda ugly/slow way to support tabs,
|
122
|
+
# but remember that this is only done at parsing time.
|
123
|
+
line[/\A[ \t]*/].gsub("\t", @tab).size
|
124
|
+
end
|
125
|
+
|
126
|
+
def parse_line
|
127
|
+
if @line =~ /\A\s*\Z/
|
128
|
+
@stacks.last << [:newline]
|
129
|
+
return
|
130
|
+
end
|
131
|
+
|
132
|
+
indent = get_indent(@line)
|
133
|
+
|
134
|
+
# Remove the indentation
|
135
|
+
@line.lstrip!
|
136
|
+
|
137
|
+
# If there's more stacks than indents, it means that the previous
|
138
|
+
# line is expecting this line to be indented.
|
139
|
+
expecting_indentation = @stacks.size > @indents.size
|
140
|
+
|
141
|
+
if indent > @indents.last
|
142
|
+
# This line was actually indented, so we'll have to check if it was
|
143
|
+
# supposed to be indented or not.
|
144
|
+
syntax_error!('Unexpected indentation') unless expecting_indentation
|
145
|
+
|
146
|
+
@indents << indent
|
147
|
+
else
|
148
|
+
# This line was *not* indented more than the line before,
|
149
|
+
# so we'll just forget about the stack that the previous line pushed.
|
150
|
+
@stacks.pop if expecting_indentation
|
151
|
+
|
152
|
+
# This line was deindented.
|
153
|
+
# Now we're have to go through the all the indents and figure out
|
154
|
+
# how many levels we've deindented.
|
155
|
+
while indent < @indents.last
|
156
|
+
@indents.pop
|
157
|
+
@stacks.pop
|
158
|
+
end
|
159
|
+
|
160
|
+
# This line's indentation happens lie "between" two other line's
|
161
|
+
# indentation:
|
162
|
+
#
|
163
|
+
# hello
|
164
|
+
# world
|
165
|
+
# this # <- This should not be possible!
|
166
|
+
syntax_error!('Malformed indentation') if indent != @indents.last
|
167
|
+
end
|
168
|
+
|
169
|
+
parse_line_indicators
|
170
|
+
end
|
171
|
+
|
172
|
+
def parse_line_indicators
|
173
|
+
case @line
|
174
|
+
when /\A\//
|
175
|
+
# Found a comment block.
|
176
|
+
if @line =~ %r{\A/!( ?)(.*)\Z}
|
177
|
+
# HTML comment
|
178
|
+
block = [:multi]
|
179
|
+
@stacks.last << [:html, :comment, block]
|
180
|
+
@stacks << block
|
181
|
+
@stacks.last << [:slim, :interpolate, $2] unless $2.empty?
|
182
|
+
parse_text_block($2.empty? ? nil : @indents.last + $1.size + 2)
|
183
|
+
elsif @line =~ %r{\A/\[\s*(.*?)\s*\]\s*\Z}
|
184
|
+
# HTML conditional comment
|
185
|
+
block = [:multi]
|
186
|
+
@stacks.last << [:slim, :condcomment, $1, block]
|
187
|
+
@stacks << block
|
188
|
+
else
|
189
|
+
# Slim comment
|
190
|
+
parse_comment_block
|
191
|
+
end
|
192
|
+
when /\A-/
|
193
|
+
# Found a code block.
|
194
|
+
# We expect the line to be broken or the next line to be indented.
|
195
|
+
block = [:multi]
|
196
|
+
@line.slice!(0)
|
197
|
+
@stacks.last << [:slim, :control, parse_broken_line, block]
|
198
|
+
@stacks << block
|
199
|
+
when /\A=/
|
200
|
+
# Found an output block.
|
201
|
+
# We expect the line to be broken or the next line to be indented.
|
202
|
+
@line =~ /\A=(=?)('?)/
|
203
|
+
@line = $'
|
204
|
+
block = [:multi]
|
205
|
+
@stacks.last << [:slim, :output, $1.empty?, parse_broken_line, block]
|
206
|
+
@stacks.last << [:static, ' '] unless $2.empty?
|
207
|
+
@stacks << block
|
208
|
+
when /\A<(\w+):\s*\Z/
|
209
|
+
# Embedded template detected. It is treated as block.
|
210
|
+
block = [:multi]
|
211
|
+
@stacks.last << [:newline] << [:slim, :embedded, $1, block]
|
212
|
+
@stacks << block
|
213
|
+
parse_text_block
|
214
|
+
return # Don't append newline, this has already been done before
|
215
|
+
when /\Adoctype\s+/i
|
216
|
+
# Found doctype declaration
|
217
|
+
@stacks.last << [:html, :doctype, $'.strip]
|
218
|
+
when /\A<([#\.]|\w[:\w-]*)/
|
219
|
+
# Found a HTML tag.
|
220
|
+
parse_tag($1)
|
221
|
+
when /\A(> *)?(.*)?\Z/
|
222
|
+
# Found a text block.
|
223
|
+
trailing_ws = !$1
|
224
|
+
@stacks.last << [:slim, :interpolate, $2] unless $2.empty?
|
225
|
+
parse_text_block($2.empty? ? nil : @indents.last + $1.to_s.size)
|
226
|
+
@stacks.last << [:static, ' '] if trailing_ws
|
227
|
+
else
|
228
|
+
syntax_error! 'Unknown line indicator'
|
229
|
+
end
|
230
|
+
@stacks.last << [:newline]
|
231
|
+
end
|
232
|
+
|
233
|
+
def parse_comment_block
|
234
|
+
while !@lines.empty? && (@lines.first =~ /\A\s*\Z/ || get_indent(@lines.first) > @indents.last)
|
235
|
+
next_line
|
236
|
+
@stacks.last << [:newline]
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
def parse_text_block(text_indent = nil)
|
241
|
+
empty_lines = 0
|
242
|
+
until @lines.empty?
|
243
|
+
if @lines.first =~ /\A\s*\Z/
|
244
|
+
next_line
|
245
|
+
@stacks.last << [:newline]
|
246
|
+
empty_lines += 1 if text_indent
|
247
|
+
else
|
248
|
+
indent = get_indent(@lines.first)
|
249
|
+
break if indent <= @indents.last
|
250
|
+
|
251
|
+
if empty_lines > 0
|
252
|
+
@stacks.last << [:slim, :interpolate, "\n" * empty_lines]
|
253
|
+
empty_lines = 0
|
254
|
+
end
|
255
|
+
|
256
|
+
next_line
|
257
|
+
|
258
|
+
# The text block lines must be at least indented
|
259
|
+
# as deep as the first line.
|
260
|
+
if text_indent && indent < text_indent
|
261
|
+
@line.lstrip!
|
262
|
+
syntax_error!('Unexpected text indentation')
|
263
|
+
end
|
264
|
+
|
265
|
+
@line.slice!(0, text_indent || indent)
|
266
|
+
@stacks.last << [:slim, :interpolate, (text_indent ? "\n" : '') + @line] << [:newline]
|
267
|
+
|
268
|
+
# The indentation of first line of the text block
|
269
|
+
# determines the text base indentation.
|
270
|
+
text_indent ||= indent
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
def parse_broken_line
|
276
|
+
broken_line = @line.strip
|
277
|
+
while broken_line[-1] == ?\\
|
278
|
+
next_line || syntax_error!('Unexpected end of file')
|
279
|
+
broken_line << "\n" << @line.strip
|
280
|
+
end
|
281
|
+
broken_line
|
282
|
+
end
|
283
|
+
|
284
|
+
def parse_tag(tag)
|
285
|
+
@line.slice!(0,1) # get rid of leading '<'
|
286
|
+
if tag == '#' || tag == '.'
|
287
|
+
tag = options[:default_tag]
|
288
|
+
else
|
289
|
+
@line.slice!(0, tag.size)
|
290
|
+
end
|
291
|
+
|
292
|
+
tag = [:html, :tag, tag, parse_attributes]
|
293
|
+
@stacks.last << tag
|
294
|
+
|
295
|
+
case @line
|
296
|
+
when /\A\s*>?=(=?)('?)/
|
297
|
+
# Handle output code
|
298
|
+
block = [:multi]
|
299
|
+
@line = $'
|
300
|
+
content = [:slim, :output, $1 != '=', parse_broken_line, block]
|
301
|
+
tag << content
|
302
|
+
@stacks.last << [:static, ' '] unless $2.empty?
|
303
|
+
@stacks << block
|
304
|
+
when /\A\s*\//
|
305
|
+
# Closed tag. Do nothing
|
306
|
+
when /\A\s*>?\s*\Z/
|
307
|
+
# Empty content
|
308
|
+
content = [:multi]
|
309
|
+
tag << content
|
310
|
+
@stacks << content
|
311
|
+
when /\A( ?)>?(.*)\Z/
|
312
|
+
# Text content
|
313
|
+
content = [:multi, [:slim, :interpolate, $2]]
|
314
|
+
tag << content
|
315
|
+
@stacks << content
|
316
|
+
parse_text_block(@orig_line.size - @line.size + $1.size)
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
def parse_attributes
|
321
|
+
attributes = [:html, :attrs]
|
322
|
+
|
323
|
+
# Find any literal class/id attributes
|
324
|
+
while @line =~ CLASS_ID_REGEX
|
325
|
+
# The class/id attribute is :static instead of :slim :text,
|
326
|
+
# because we don't want text interpolation in .class or #id shortcut
|
327
|
+
attributes << [:html, :attr, ATTR_SHORTCUT[$1], [:static, $2]]
|
328
|
+
@line = $'
|
329
|
+
end
|
330
|
+
|
331
|
+
# Check to see if there is a delimiter right after the tag name
|
332
|
+
delimiter = nil
|
333
|
+
if @line =~ DELIMITER_REGEX
|
334
|
+
delimiter = DELIMITERS[$&]
|
335
|
+
@line.slice!(0)
|
336
|
+
end
|
337
|
+
|
338
|
+
orig_line = @orig_line
|
339
|
+
lineno = @lineno
|
340
|
+
while true
|
341
|
+
# Parse attributes
|
342
|
+
attr_regex = delimiter ? /#{ATTR_NAME_REGEX}(=|\s|(?=#{Regexp.escape delimiter}))/ : /#{ATTR_NAME_REGEX}=/
|
343
|
+
while @line =~ attr_regex
|
344
|
+
@line = $'
|
345
|
+
name = $1
|
346
|
+
if delimiter && $2 != '='
|
347
|
+
attributes << [:slim, :attr, name, false, 'true']
|
348
|
+
elsif @line =~ /\A["']/
|
349
|
+
# Value is quoted (static)
|
350
|
+
@line = $'
|
351
|
+
attributes << [:html, :attr, name, [:slim, :interpolate, parse_quoted_attribute($&)]]
|
352
|
+
else
|
353
|
+
# Value is ruby code
|
354
|
+
escape = @line[0] != ?=
|
355
|
+
@line.slice!(0) unless escape
|
356
|
+
attributes << [:slim, :attr, name, escape, parse_ruby_attribute(delimiter)]
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
# No ending delimiter, attribute end
|
361
|
+
break unless delimiter
|
362
|
+
|
363
|
+
# Find ending delimiter
|
364
|
+
if @line =~ /\A\s*#{Regexp.escape delimiter}/
|
365
|
+
@line = $'
|
366
|
+
break
|
367
|
+
end
|
368
|
+
|
369
|
+
# Found something where an attribute should be
|
370
|
+
@line.lstrip!
|
371
|
+
syntax_error!('Expected attribute') unless @line.empty?
|
372
|
+
|
373
|
+
# Attributes span multiple lines
|
374
|
+
@stacks.last << [:newline]
|
375
|
+
next_line || syntax_error!("Expected closing delimiter #{delimiter}",
|
376
|
+
:orig_line => orig_line,
|
377
|
+
:lineno => lineno,
|
378
|
+
:column => orig_line.size)
|
379
|
+
end
|
380
|
+
|
381
|
+
attributes
|
382
|
+
end
|
383
|
+
|
384
|
+
def parse_ruby_attribute(outer_delimiter)
|
385
|
+
value, count, delimiter, close_delimiter = '', 0, nil, nil
|
386
|
+
|
387
|
+
# Attribute ends with space or attribute delimiter
|
388
|
+
end_regex = /\A[\s#{Regexp.escape outer_delimiter.to_s}]/
|
389
|
+
|
390
|
+
until @line.empty? || (count == 0 && @line =~ end_regex)
|
391
|
+
if count > 0
|
392
|
+
if @line[0] == delimiter[0]
|
393
|
+
count += 1
|
394
|
+
elsif @line[0] == close_delimiter[0]
|
395
|
+
count -= 1
|
396
|
+
end
|
397
|
+
elsif @line =~ DELIMITER_REGEX
|
398
|
+
count = 1
|
399
|
+
delimiter, close_delimiter = $&, DELIMITERS[$&]
|
400
|
+
end
|
401
|
+
value << @line.slice!(0)
|
402
|
+
end
|
403
|
+
|
404
|
+
syntax_error!("Expected closing attribute delimiter #{close_delimiter}") if count != 0
|
405
|
+
syntax_error!('Invalid empty attribute') if value.empty?
|
406
|
+
|
407
|
+
# Remove attribute wrapper which doesn't belong to the ruby code
|
408
|
+
# e.g id=[hash[:a] + hash[:b]]
|
409
|
+
value = value[1..-2] if value =~ DELIMITER_REGEX &&
|
410
|
+
DELIMITERS[$&] == value[-1, 1]
|
411
|
+
|
412
|
+
value
|
413
|
+
end
|
414
|
+
|
415
|
+
def parse_quoted_attribute(quote)
|
416
|
+
value, count = '', 0
|
417
|
+
|
418
|
+
until @line.empty? || (count == 0 && @line[0] == quote[0])
|
419
|
+
if count > 0
|
420
|
+
if @line[0] == ?{
|
421
|
+
count += 1
|
422
|
+
elsif @line[0] == ?}
|
423
|
+
count -= 1
|
424
|
+
end
|
425
|
+
elsif @line =~ /\A#\{/
|
426
|
+
value << @line.slice!(0)
|
427
|
+
count = 1
|
428
|
+
end
|
429
|
+
value << @line.slice!(0)
|
430
|
+
end
|
431
|
+
|
432
|
+
syntax_error!("Expected closing brace }") if count != 0
|
433
|
+
@line.slice!(0)
|
434
|
+
value
|
435
|
+
end
|
436
|
+
|
437
|
+
# Helper for raising exceptions
|
438
|
+
def syntax_error!(message, args = {})
|
439
|
+
args[:orig_line] ||= @orig_line
|
440
|
+
args[:line] ||= @line
|
441
|
+
args[:lineno] ||= @lineno
|
442
|
+
args[:column] ||= args[:orig_line] && args[:line] ?
|
443
|
+
args[:orig_line].size - args[:line].size : 0
|
444
|
+
raise SyntaxError.new(message, options[:file],
|
445
|
+
args[:orig_line], args[:lineno], args[:column])
|
446
|
+
end
|
447
|
+
end
|
448
|
+
end
|
data/lib/hamlet/parser.rb
CHANGED
data/lib/hamlet.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hamlet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.2'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,18 +13,18 @@ date: 2011-10-28 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: slim
|
16
|
-
requirement: &
|
16
|
+
requirement: &3486700 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
21
|
+
version: 1.0.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *3486700
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rake
|
27
|
-
requirement: &
|
27
|
+
requirement: &3485880 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 0.8.7
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *3485880
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: sass
|
38
|
-
requirement: &
|
38
|
+
requirement: &3484300 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 3.1.0
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *3484300
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: minitest
|
49
|
-
requirement: &
|
49
|
+
requirement: &3482000 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *3482000
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: kramdown
|
60
|
-
requirement: &
|
60
|
+
requirement: &3481000 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *3481000
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: yard
|
71
|
-
requirement: &
|
71
|
+
requirement: &3442840 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ! '>='
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: '0'
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *3442840
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: creole
|
82
|
-
requirement: &
|
82
|
+
requirement: &3441240 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ! '>='
|
@@ -87,10 +87,10 @@ dependencies:
|
|
87
87
|
version: '0'
|
88
88
|
type: :development
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *3441240
|
91
91
|
- !ruby/object:Gem::Dependency
|
92
92
|
name: builder
|
93
|
-
requirement: &
|
93
|
+
requirement: &3440020 !ruby/object:Gem::Requirement
|
94
94
|
none: false
|
95
95
|
requirements:
|
96
96
|
- - ! '>='
|
@@ -98,10 +98,10 @@ dependencies:
|
|
98
98
|
version: '0'
|
99
99
|
type: :development
|
100
100
|
prerelease: false
|
101
|
-
version_requirements: *
|
101
|
+
version_requirements: *3440020
|
102
102
|
- !ruby/object:Gem::Dependency
|
103
103
|
name: pry
|
104
|
-
requirement: &
|
104
|
+
requirement: &3438600 !ruby/object:Gem::Requirement
|
105
105
|
none: false
|
106
106
|
requirements:
|
107
107
|
- - ! '>='
|
@@ -109,10 +109,10 @@ dependencies:
|
|
109
109
|
version: '0'
|
110
110
|
type: :development
|
111
111
|
prerelease: false
|
112
|
-
version_requirements: *
|
112
|
+
version_requirements: *3438600
|
113
113
|
- !ruby/object:Gem::Dependency
|
114
114
|
name: rcov
|
115
|
-
requirement: &
|
115
|
+
requirement: &3435800 !ruby/object:Gem::Requirement
|
116
116
|
none: false
|
117
117
|
requirements:
|
118
118
|
- - ! '>='
|
@@ -120,7 +120,7 @@ dependencies:
|
|
120
120
|
version: '0'
|
121
121
|
type: :development
|
122
122
|
prerelease: false
|
123
|
-
version_requirements: *
|
123
|
+
version_requirements: *3435800
|
124
124
|
description: Hamlet is a template language whose goal is reduce HTML syntax to the
|
125
125
|
essential parts.
|
126
126
|
email:
|
@@ -142,6 +142,7 @@ files:
|
|
142
142
|
- hamlet.gemspec
|
143
143
|
- lib/hamlet.rb
|
144
144
|
- lib/hamlet/engine.rb
|
145
|
+
- lib/hamlet/forked_slim_parser.rb
|
145
146
|
- lib/hamlet/parser.rb
|
146
147
|
- lib/hamlet/template.rb
|
147
148
|
- test/rails/Rakefile
|