slimi 0.2.0 → 0.3.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/Gemfile.lock +1 -1
- data/lib/slimi/errors.rb +6 -0
- data/lib/slimi/parser.rb +86 -3
- data/lib/slimi/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 69032d72b1695bfe2afc7a11dbb965e4abf252a7c42caab252e972bcb45c13f8
|
4
|
+
data.tar.gz: af3822a5d2375300d4b07f0114c30c933eb215c88bfcee1bd6cc4938d769d76e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b59318e78f3c7c83e67334326992babdc60d3d299ed8973778f7c3c463b1eaaaacbefafe20ee8f7072eff13db72c3a88c5a0cae7f4ecd18629bc9e8a35645599
|
7
|
+
data.tar.gz: 173fdc474e985a89ead0c473d25bcb2bb4deb586679d17bee18d5384b29e21900e79e03567ed302bce9ac37b81dc4ad29ed3b837eeeac5027d7db57ed3879c4b
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
data/lib/slimi/errors.rb
CHANGED
@@ -36,12 +36,18 @@ module Slimi
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
+
class InvalidEmptyAttributeError < SlimSyntaxError
|
40
|
+
end
|
41
|
+
|
39
42
|
class LineEndingNotFoundError < SlimSyntaxError
|
40
43
|
end
|
41
44
|
|
42
45
|
class MalformedIndentationError < SlimSyntaxError
|
43
46
|
end
|
44
47
|
|
48
|
+
class RubyAttributeClosingDelimiterNotFoundError < SlimSyntaxError
|
49
|
+
end
|
50
|
+
|
45
51
|
class UnexpectedEosError < SlimSyntaxError
|
46
52
|
end
|
47
53
|
|
data/lib/slimi/parser.rb
CHANGED
@@ -11,6 +11,11 @@ module Slimi
|
|
11
11
|
'[' => ']',
|
12
12
|
'{' => '}'
|
13
13
|
},
|
14
|
+
code_attr_delims: {
|
15
|
+
'(' => ')',
|
16
|
+
'[' => ']',
|
17
|
+
'{' => '}'
|
18
|
+
},
|
14
19
|
shortcut: {
|
15
20
|
'#' => { attr: 'id' },
|
16
21
|
'.' => { attr: 'class' }
|
@@ -22,6 +27,7 @@ module Slimi
|
|
22
27
|
factory = Factory.new(
|
23
28
|
attribute_delimiters: options[:attr_list_delims] || {},
|
24
29
|
default_tag: options[:default_tag] || 'div',
|
30
|
+
ruby_attribute_delimiters: options[:code_attr_delims] || {},
|
25
31
|
shortcut: options[:shortcut] || {}
|
26
32
|
)
|
27
33
|
@attribute_delimiters = factory.attribute_delimiters
|
@@ -32,6 +38,9 @@ module Slimi
|
|
32
38
|
@quoted_attribute_regexp = factory.quoted_attribute_regexp
|
33
39
|
@tag_name_regexp = factory.tag_name_regexp
|
34
40
|
@attribute_name_regexp = factory.attribute_name_regexp
|
41
|
+
@ruby_attribute_regexp = factory.ruby_attribute_regexp
|
42
|
+
@ruby_attribute_delimiter_regexp = factory.ruby_attribute_delimiter_regexp
|
43
|
+
@ruby_attribute_delimiters = factory.ruby_attribute_delimiters
|
35
44
|
@embedded_template_regexp = factory.embedded_template_regexp
|
36
45
|
end
|
37
46
|
|
@@ -46,10 +55,11 @@ module Slimi
|
|
46
55
|
private
|
47
56
|
|
48
57
|
def parse_block
|
58
|
+
return if parse_blank_line
|
59
|
+
|
49
60
|
parse_indent
|
50
61
|
|
51
|
-
|
52
|
-
parse_html_comment ||
|
62
|
+
parse_html_comment ||
|
53
63
|
parse_html_conditional_comment ||
|
54
64
|
parse_slim_comment_block ||
|
55
65
|
parse_verbatim_text_block ||
|
@@ -62,6 +72,17 @@ module Slimi
|
|
62
72
|
raise(Errors::UnknownLineIndicatorError)
|
63
73
|
end
|
64
74
|
|
75
|
+
# Parse blank line.
|
76
|
+
# @return [Boolean] True if it could parse a blank line.
|
77
|
+
def parse_blank_line
|
78
|
+
if @scanner.skip(/[ \t]*$/)
|
79
|
+
parse_line_ending
|
80
|
+
true
|
81
|
+
else
|
82
|
+
false
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
65
86
|
def parse_indent
|
66
87
|
@scanner.skip(/[ \t]*/)
|
67
88
|
indent = indent_from_last_match
|
@@ -232,12 +253,19 @@ module Slimi
|
|
232
253
|
attribute_delimiter_closing_part_regexp = /[ \t]*#{attribute_delimiter_closing_regexp}/
|
233
254
|
end
|
234
255
|
|
256
|
+
# TODO: Support splat attributes.
|
235
257
|
loop do
|
236
258
|
if @scanner.skip(@quoted_attribute_regexp)
|
237
259
|
attribute_name = @scanner[1]
|
238
260
|
escape = @scanner[2].empty?
|
239
261
|
quote = @scanner[3]
|
240
262
|
attributes << [:html, :attr, attribute_name, [:escape, escape, parse_quoted_attribute_value(quote)]]
|
263
|
+
elsif @scanner.skip(@ruby_attribute_regexp)
|
264
|
+
attribute_name = @scanner[1]
|
265
|
+
escape = @scanner[2].empty?
|
266
|
+
attribute_value = parse_ruby_attribute_value(attribute_delimiter_closing)
|
267
|
+
syntax_error!(Errors::InvalidEmptyAttributeError) if attribute_value.empty?
|
268
|
+
attributes << [:html, :attr, attribute_name, [:slim, :attrvalue, escape, attribute_value]]
|
241
269
|
elsif !attribute_delimiter_closing_part_regexp
|
242
270
|
break
|
243
271
|
elsif @scanner.skip(boolean_attribute_regexp)
|
@@ -252,6 +280,46 @@ module Slimi
|
|
252
280
|
attributes
|
253
281
|
end
|
254
282
|
|
283
|
+
# Parse Ruby attribute value part.
|
284
|
+
# e.g. div class=foo
|
285
|
+
# ^^^
|
286
|
+
# `- Ruby attribute value
|
287
|
+
# @param [String] attribute_delimiter_closing
|
288
|
+
# @return [String]
|
289
|
+
def parse_ruby_attribute_value(attribute_delimiter_closing)
|
290
|
+
ending_regexp = /\s/
|
291
|
+
ending_regexp = ::Regexp.union(ending_regexp, attribute_delimiter_closing) if attribute_delimiter_closing
|
292
|
+
count = 0
|
293
|
+
attribute_value = +''
|
294
|
+
opening_delimiter = nil
|
295
|
+
closing_delimiter = nil
|
296
|
+
loop do
|
297
|
+
break if count.zero? && @scanner.match?(ending_regexp)
|
298
|
+
|
299
|
+
if @scanner.skip(/([,\\])\r?\n/)
|
300
|
+
attribute_value << @scanner[1] << "\n"
|
301
|
+
else
|
302
|
+
if count.positive?
|
303
|
+
if opening_delimiter && @scanner.skip(::Regexp.escape(opening_delimiter))
|
304
|
+
count += 1
|
305
|
+
elsif closing_delimiter && @scanner.skip(::Regexp.escape(closing_delimiter))
|
306
|
+
count -= 1
|
307
|
+
end
|
308
|
+
elsif @scanner.skip(@ruby_attribute_delimiter_regexp)
|
309
|
+
count = 1
|
310
|
+
opening_delimiter = @scanner.matched
|
311
|
+
closing_delimiter = @ruby_attribute_delimiters[opening_delimiter]
|
312
|
+
end
|
313
|
+
if (character = @scanner.scan(/./))
|
314
|
+
attribute_value << character
|
315
|
+
end
|
316
|
+
end
|
317
|
+
end
|
318
|
+
syntax_error!(Errors::RubyAttributeClosingDelimiterNotFoundError) if count != 0
|
319
|
+
|
320
|
+
attribute_value
|
321
|
+
end
|
322
|
+
|
255
323
|
# @return [Boolean]
|
256
324
|
def parse_html_comment
|
257
325
|
if @scanner.skip(%r{/!})
|
@@ -512,12 +580,17 @@ module Slimi
|
|
512
580
|
# @return [Hash]
|
513
581
|
attr_reader :attribute_delimiters
|
514
582
|
|
583
|
+
# @return [Hash]
|
584
|
+
attr_reader :ruby_attribute_delimiters
|
585
|
+
|
515
586
|
# @param [Hash] attribute_delimiters
|
516
587
|
# @param [String] default_tag
|
588
|
+
# @param [Hash] ruby_attribute_delimiters
|
517
589
|
# @param [Hash] shortcut
|
518
|
-
def initialize(attribute_delimiters:, default_tag:, shortcut:)
|
590
|
+
def initialize(attribute_delimiters:, default_tag:, ruby_attribute_delimiters:, shortcut:)
|
519
591
|
@attribute_delimiters = attribute_delimiters
|
520
592
|
@default_tag = default_tag
|
593
|
+
@ruby_attribute_delimiters = ruby_attribute_delimiters
|
521
594
|
@shortcut = shortcut
|
522
595
|
end
|
523
596
|
|
@@ -573,6 +646,11 @@ module Slimi
|
|
573
646
|
%r{(#{markers_regexp}+)((?:\p{Word}|-|/\d+|:(\w|-)+)*)}
|
574
647
|
end
|
575
648
|
|
649
|
+
# @return [Regexp]
|
650
|
+
def ruby_attribute_regexp
|
651
|
+
/#{attribute_name_regexp}[ \t]*=(=?)[ \t]*/
|
652
|
+
end
|
653
|
+
|
576
654
|
# @return [Regexp]
|
577
655
|
def embedded_template_regexp
|
578
656
|
/(#{::Regexp.union(EMBEDDED_TEMPLAE_ENGINE_NAMES)})(?:[ \t]*(?:(.*)))?:([ \t]*)/
|
@@ -583,6 +661,11 @@ module Slimi
|
|
583
661
|
/#{attribute_name_regexp}[ \t]*=(=?)[ \t]*("|')/
|
584
662
|
end
|
585
663
|
|
664
|
+
# @return [Regexp]
|
665
|
+
def ruby_attribute_delimiter_regexp
|
666
|
+
::Regexp.union(@ruby_attribute_delimiters.keys)
|
667
|
+
end
|
668
|
+
|
586
669
|
# @return [Regexp] Pattern that matches to tag header part.
|
587
670
|
def tag_name_regexp
|
588
671
|
markers = tag_shortcuts.keys.sort_by { |marker| -marker.size }
|
data/lib/slimi/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: slimi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryo Nakamura
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-12-
|
11
|
+
date: 2021-12-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: temple
|