slimi 0.1.1 → 0.2.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 +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
|