slimi 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/Gemfile.lock +1 -1
- data/README.md +1 -19
- data/lib/slimi/errors.rb +35 -7
- data/lib/slimi/parser.rb +48 -4
- data/lib/slimi/range.rb +39 -0
- data/lib/slimi/version.rb +1 -1
- data/lib/slimi.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ce4329befc9d19fb756c5609a28a3169c4f5a5aa2698771df14541b88b792da1
|
4
|
+
data.tar.gz: d99512e7191942f2fabb8667cb4de369dcad5d773c1e162cc039f2911b4b1dc9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6c1b46a4afdfc4ce2a8ce816898a17e6bd448e0e76a001efbebfe7fc498375a2c1c71aaa5f40cce11012f28e7e87f5c7eef06b70b6dbcd560a6343d5494ee71c
|
7
|
+
data.tar.gz: 7554a443efa9d30952d3446b92c494dd6ecf1caeb78d77aea347eef1ab862e64c35e93d4ef76c1423728734eb3b23913e75497c3358b0df2543229e05b177c07
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Yet another implementation for [Slim](https://github.com/slim-template/slim) template language.
|
7
7
|
|
8
|
-
|
8
|
+
Slimi is used by [Slimcop](https://github.com/r7kamura/slimcop).
|
9
9
|
|
10
10
|
## Installation
|
11
11
|
|
@@ -30,21 +30,3 @@ gem install slimi
|
|
30
30
|
## Usage
|
31
31
|
|
32
32
|
TBD.
|
33
|
-
|
34
|
-
## Development
|
35
|
-
|
36
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
37
|
-
|
38
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
39
|
-
|
40
|
-
## Contributing
|
41
|
-
|
42
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/r7kamura/slimi. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/r7kamura/slimi/blob/main/CODE_OF_CONDUCT.md).
|
43
|
-
|
44
|
-
## License
|
45
|
-
|
46
|
-
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
47
|
-
|
48
|
-
## Code of Conduct
|
49
|
-
|
50
|
-
Everyone interacting in the Slimi project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/r7kamura/slimi/blob/main/CODE_OF_CONDUCT.md).
|
data/lib/slimi/errors.rb
CHANGED
@@ -5,25 +5,53 @@ module Slimi
|
|
5
5
|
class BaseError < StandardError
|
6
6
|
end
|
7
7
|
|
8
|
-
class
|
8
|
+
class SlimSyntaxError < BaseError
|
9
|
+
# @param [Integer] column
|
10
|
+
# @param [String] file_path
|
11
|
+
# @param [String] line
|
12
|
+
# @param [Integer] line_number
|
13
|
+
def initialize(column:, file_path:, line:, line_number:)
|
14
|
+
super()
|
15
|
+
@column = column
|
16
|
+
@file_path = file_path
|
17
|
+
@line = line
|
18
|
+
@line_number = line_number
|
19
|
+
end
|
20
|
+
|
21
|
+
# @note Override.
|
22
|
+
# @return [String]
|
23
|
+
def to_s
|
24
|
+
<<~TEXT
|
25
|
+
#{error_type} at #{@file_path}:#{@line_number}:#{@column}
|
26
|
+
#{@line}
|
27
|
+
#{' ' * (@column - 1)}^
|
28
|
+
TEXT
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
# @return [String]
|
34
|
+
def error_type
|
35
|
+
self.class.to_s.split('::').last
|
36
|
+
end
|
9
37
|
end
|
10
38
|
|
11
|
-
class LineEndingNotFoundError <
|
39
|
+
class LineEndingNotFoundError < SlimSyntaxError
|
12
40
|
end
|
13
41
|
|
14
|
-
class MalformedIndentationError <
|
42
|
+
class MalformedIndentationError < SlimSyntaxError
|
15
43
|
end
|
16
44
|
|
17
|
-
class UnexpectedEosError <
|
45
|
+
class UnexpectedEosError < SlimSyntaxError
|
18
46
|
end
|
19
47
|
|
20
|
-
class UnexpectedIndentationError <
|
48
|
+
class UnexpectedIndentationError < SlimSyntaxError
|
21
49
|
end
|
22
50
|
|
23
|
-
class UnexpectedTextAfterClosedTagError <
|
51
|
+
class UnexpectedTextAfterClosedTagError < SlimSyntaxError
|
24
52
|
end
|
25
53
|
|
26
|
-
class UnknownLineIndicator <
|
54
|
+
class UnknownLineIndicator < SlimSyntaxError
|
27
55
|
end
|
28
56
|
end
|
29
57
|
end
|
data/lib/slimi/parser.rb
CHANGED
@@ -32,6 +32,7 @@ module Slimi
|
|
32
32
|
@quoted_attribute_regexp = factory.quoted_attribute_regexp
|
33
33
|
@tag_name_regexp = factory.tag_name_regexp
|
34
34
|
@attribute_name_regexp = factory.attribute_name_regexp
|
35
|
+
@embedded_template_regexp = factory.embedded_template_regexp
|
35
36
|
end
|
36
37
|
|
37
38
|
def call(source)
|
@@ -55,6 +56,7 @@ module Slimi
|
|
55
56
|
parse_inline_html ||
|
56
57
|
parse_code_block ||
|
57
58
|
parse_output_block ||
|
59
|
+
parse_embedded_template ||
|
58
60
|
parse_doctype ||
|
59
61
|
parse_tag ||
|
60
62
|
raise(Errors::UnknownLineIndicatorError)
|
@@ -66,7 +68,7 @@ module Slimi
|
|
66
68
|
@indents << indent if @indents.empty?
|
67
69
|
|
68
70
|
if indent > @indents.last
|
69
|
-
|
71
|
+
syntax_error!(Errors::UnexpectedIndentationError) unless expecting_indentation?
|
70
72
|
|
71
73
|
@indents << indent
|
72
74
|
else
|
@@ -77,10 +79,22 @@ module Slimi
|
|
77
79
|
@stacks.pop
|
78
80
|
end
|
79
81
|
|
80
|
-
|
82
|
+
syntax_error!(Errors::MalformedIndentationError) if indent != @indents.last
|
81
83
|
end
|
82
84
|
end
|
83
85
|
|
86
|
+
# Parse embedded template lines.
|
87
|
+
# e.g.
|
88
|
+
# ruby:
|
89
|
+
# a = b + c
|
90
|
+
def parse_embedded_template
|
91
|
+
return unless @scanner.skip(@embedded_template_regexp)
|
92
|
+
|
93
|
+
embedded_template_engine_name = @scanner[1]
|
94
|
+
attributes = parse_attributes
|
95
|
+
@stacks.last << [:slim, :embedded, embedded_template_engine_name, parse_text_block, attributes]
|
96
|
+
end
|
97
|
+
|
84
98
|
# @return [Boolean]
|
85
99
|
def parse_tag
|
86
100
|
parse_tag_inner && expect_line_ending
|
@@ -117,7 +131,7 @@ module Slimi
|
|
117
131
|
@stacks.last << [:static, ' '] if with_trailing_white_space2
|
118
132
|
@stacks << block
|
119
133
|
elsif @scanner.skip(%r{[ \t]*/[ \t]*})
|
120
|
-
|
134
|
+
syntax_error!(Errors::UnexpectedTextAfterClosedTagError) unless @scanner.match?(/\r?\n/)
|
121
135
|
else
|
122
136
|
@scanner.skip(/[ \t]+/)
|
123
137
|
tag << [:slim, :text, :inline, parse_text_block]
|
@@ -452,7 +466,7 @@ module Slimi
|
|
452
466
|
result = +''
|
453
467
|
result << @scanner.scan(/.*/)
|
454
468
|
while result.end_with?(',') || result.end_with?('\\')
|
455
|
-
|
469
|
+
syntax_error!(Errors::UnexpectedEosError) unless @scanner.scan(/\r?\n/)
|
456
470
|
|
457
471
|
result << "\n"
|
458
472
|
result << @scanner.scan(/.*/)
|
@@ -468,8 +482,33 @@ module Slimi
|
|
468
482
|
[:slimi, :position, begin_, end_, inner]
|
469
483
|
end
|
470
484
|
|
485
|
+
# @param [Class] syntax_error_class A child class of Slimi::Errors::SlimSyntaxError.
|
486
|
+
# @raise [Slimi::Errors::SlimSyntaxError]
|
487
|
+
def syntax_error!(syntax_error_class)
|
488
|
+
range = Range.new(index: @scanner.charpos, source: @scanner.string)
|
489
|
+
raise syntax_error_class.new(
|
490
|
+
column: range.column,
|
491
|
+
file_path: '(__TEMPLATE__)',
|
492
|
+
line: range.line,
|
493
|
+
line_number: range.line_number
|
494
|
+
)
|
495
|
+
end
|
496
|
+
|
471
497
|
# Convert human-friendly options into machine-friendly objects.
|
472
498
|
class Factory
|
499
|
+
EMBEDDED_TEMPLAE_ENGINE_NAMES = %w[
|
500
|
+
coffee
|
501
|
+
css
|
502
|
+
javascript
|
503
|
+
less
|
504
|
+
markdown
|
505
|
+
rdoc
|
506
|
+
ruby
|
507
|
+
sass
|
508
|
+
scss
|
509
|
+
textile
|
510
|
+
].freeze
|
511
|
+
|
473
512
|
# @return [Hash]
|
474
513
|
attr_reader :attribute_delimiters
|
475
514
|
|
@@ -534,6 +573,11 @@ module Slimi
|
|
534
573
|
%r{(#{markers_regexp}+)((?:\p{Word}|-|/\d+|:(\w|-)+)*)}
|
535
574
|
end
|
536
575
|
|
576
|
+
# @return [Regexp]
|
577
|
+
def embedded_template_regexp
|
578
|
+
/(#{::Regexp.union(EMBEDDED_TEMPLAE_ENGINE_NAMES)})(?:[ \t]*(?:(.*)))?:([ \t]*)/
|
579
|
+
end
|
580
|
+
|
537
581
|
# @return [Regexp]
|
538
582
|
def quoted_attribute_regexp
|
539
583
|
/#{attribute_name_regexp}[ \t]*=(=?)[ \t]*("|')/
|
data/lib/slimi/range.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Slimi
|
4
|
+
# Get line-based information from source code and its index.
|
5
|
+
class Range
|
6
|
+
# @param [Integer] index 0-indexed per-character index.
|
7
|
+
# @param [String] source
|
8
|
+
def initialize(index:, source:)
|
9
|
+
@index = index
|
10
|
+
@source = source
|
11
|
+
end
|
12
|
+
|
13
|
+
# @return [Integer] 1-indexed column index.
|
14
|
+
def column
|
15
|
+
(@index - line_beginning_index) + 1
|
16
|
+
end
|
17
|
+
|
18
|
+
def line
|
19
|
+
@source[line_beginning_index...line_ending_index]
|
20
|
+
end
|
21
|
+
|
22
|
+
# @return [Integer] 1-indexed line index.
|
23
|
+
def line_number
|
24
|
+
@source[0..@index].scan(/^/).length
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
# @return [Integer]
|
30
|
+
def line_beginning_index
|
31
|
+
@source.rindex(/^/, @index) || 0
|
32
|
+
end
|
33
|
+
|
34
|
+
# @return [Integer]
|
35
|
+
def line_ending_index
|
36
|
+
@source.index(/$/, @index)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/slimi/version.rb
CHANGED
data/lib/slimi.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.2.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-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: temple
|
@@ -48,6 +48,7 @@ files:
|
|
48
48
|
- lib/slimi/filters/interpolation.rb
|
49
49
|
- lib/slimi/filters/unposition.rb
|
50
50
|
- lib/slimi/parser.rb
|
51
|
+
- lib/slimi/range.rb
|
51
52
|
- lib/slimi/version.rb
|
52
53
|
- slimi.gemspec
|
53
54
|
homepage: https://github.com/r7kamura/slimi
|