slimi 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ce4329befc9d19fb756c5609a28a3169c4f5a5aa2698771df14541b88b792da1
4
- data.tar.gz: d99512e7191942f2fabb8667cb4de369dcad5d773c1e162cc039f2911b4b1dc9
3
+ metadata.gz: 69032d72b1695bfe2afc7a11dbb965e4abf252a7c42caab252e972bcb45c13f8
4
+ data.tar.gz: af3822a5d2375300d4b07f0114c30c933eb215c88bfcee1bd6cc4938d769d76e
5
5
  SHA512:
6
- metadata.gz: 6c1b46a4afdfc4ce2a8ce816898a17e6bd448e0e76a001efbebfe7fc498375a2c1c71aaa5f40cce11012f28e7e87f5c7eef06b70b6dbcd560a6343d5494ee71c
7
- data.tar.gz: 7554a443efa9d30952d3446b92c494dd6ecf1caeb78d77aea347eef1ab862e64c35e93d4ef76c1423728734eb3b23913e75497c3358b0df2543229e05b177c07
6
+ metadata.gz: b59318e78f3c7c83e67334326992babdc60d3d299ed8973778f7c3c463b1eaaaacbefafe20ee8f7072eff13db72c3a88c5a0cae7f4ecd18629bc9e8a35645599
7
+ data.tar.gz: 173fdc474e985a89ead0c473d25bcb2bb4deb586679d17bee18d5384b29e21900e79e03567ed302bce9ac37b81dc4ad29ed3b837eeeac5027d7db57ed3879c4b
data/CHANGELOG.md CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.3.0 - 2021-12-24
6
+
7
+ ### Added
8
+
9
+ - Support unquoted attributes.
10
+
11
+ ### Fixed
12
+
13
+ - Fix bug about blank line handling.
14
+
5
15
  ## 0.2.0 - 2021-12-23
6
16
 
7
17
  ### Added
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- slimi (0.2.0)
4
+ slimi (0.3.0)
5
5
  temple
6
6
 
7
7
  GEM
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
- parse_line_ending ||
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Slimi
4
- VERSION = '0.2.0'
4
+ VERSION = '0.3.0'
5
5
  end
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.2.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-22 00:00:00.000000000 Z
11
+ date: 2021-12-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: temple