slimi 0.5.0 → 0.7.1
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/.rubocop.yml +6 -0
- data/CHANGELOG.md +41 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +35 -1
- data/README.md +60 -1
- data/exe/slimi +7 -0
- data/lib/slimi/cli.rb +37 -0
- data/lib/slimi/engine.rb +5 -3
- data/lib/slimi/erb_converter.rb +9 -0
- data/lib/slimi/filters/amble.rb +23 -0
- data/lib/slimi/filters/attribute.rb +3 -3
- data/lib/slimi/filters/base.rb +49 -0
- data/lib/slimi/filters/control.rb +3 -3
- data/lib/slimi/filters/do_inserter.rb +5 -5
- data/lib/slimi/filters/embedded.rb +17 -15
- data/lib/slimi/filters/end_inserter.rb +2 -2
- data/lib/slimi/filters/interpolation.rb +2 -24
- data/lib/slimi/filters/output.rb +3 -3
- data/lib/slimi/filters/text.rb +3 -3
- data/lib/slimi/filters/unposition.rb +7 -23
- data/lib/slimi/filters.rb +2 -0
- data/lib/slimi/parser.rb +11 -10
- data/lib/slimi/rails_template_handler.rb +68 -5
- data/lib/slimi/railtie.rb +1 -0
- data/lib/slimi/version.rb +1 -1
- data/lib/slimi.rb +2 -0
- data/slimi.gemspec +1 -3
- metadata +26 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b6e85f64f0d3aeb959f34ab6c7779a1e355fcf03d660f1b91aea2ef77cbf3c34
|
4
|
+
data.tar.gz: a61600677c85e6eebd57d5d58b8c47fe6669487a88f1398e9f641972ad6dd603
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eee6c48c7c8ae0270ce25c24ed8f0061c4656b4f0df3802f8536700f566a795f91f233a9a0eeda856829fb7143d35c426d31b02f77118d658950024dd4458949
|
7
|
+
data.tar.gz: 779ac85207a4ebd2511d868322281e30fe8f2364d49b77eff380dc7f93513905bfd5a8bd6253c2d6062525d8bacabf455f9a1164281e253df7098c0b54bfb23e
|
data/.rubocop.yml
CHANGED
@@ -24,8 +24,14 @@ RSpec/ImplicitSubject:
|
|
24
24
|
RSpec/MultipleExpectations:
|
25
25
|
Enabled: false
|
26
26
|
|
27
|
+
RSpec/MultipleMemoizedHelpers:
|
28
|
+
Enabled: false
|
29
|
+
|
27
30
|
RSpec/NamedSubject:
|
28
31
|
Enabled: false
|
29
32
|
|
33
|
+
Security/Eval:
|
34
|
+
Enabled: false
|
35
|
+
|
30
36
|
Style/Documentation:
|
31
37
|
Enabled: false
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,47 @@
|
|
2
2
|
|
3
3
|
## Unreleased
|
4
4
|
|
5
|
+
## 0.7.1 - 2022-01-18
|
6
|
+
|
7
|
+
### Fixed
|
8
|
+
|
9
|
+
- Fix error handling on unexpected line ending.
|
10
|
+
- Fix missing some metadata in gemspec.
|
11
|
+
|
12
|
+
## 0.7.0 - 2022-01-04
|
13
|
+
|
14
|
+
### Added
|
15
|
+
|
16
|
+
- Add `slimi` executable.
|
17
|
+
|
18
|
+
### Fixed
|
19
|
+
|
20
|
+
- Remove preceding white spaces from HTML comment.
|
21
|
+
- Fix bug that :generator option was not working.
|
22
|
+
- Fix bug that Ruby code in nested line can be problem on compilation.
|
23
|
+
|
24
|
+
## 0.6.0 - 2022-01-03
|
25
|
+
|
26
|
+
### Added
|
27
|
+
|
28
|
+
- Support annotate_rendered_view_with_filenames.
|
29
|
+
|
30
|
+
### Changed
|
31
|
+
|
32
|
+
- Rename expression name from slim to slimi.
|
33
|
+
|
34
|
+
### Fixed
|
35
|
+
|
36
|
+
- Fix bug at registering handler to ActionView.
|
37
|
+
- Fix Engine options at RailsTemplateHandler.
|
38
|
+
- Define missing :generator option at Engine.
|
39
|
+
|
40
|
+
## 0.5.1 - 2022-01-02
|
41
|
+
|
42
|
+
### Changed
|
43
|
+
|
44
|
+
- Wrap slim attrvalue by slimi position expression.
|
45
|
+
|
5
46
|
## 0.5.0 - 2022-01-02
|
6
47
|
|
7
48
|
### Added
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,18 +1,48 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
slimi (0.
|
4
|
+
slimi (0.7.1)
|
5
5
|
temple
|
6
|
+
thor
|
6
7
|
tilt
|
7
8
|
|
8
9
|
GEM
|
9
10
|
remote: https://rubygems.org/
|
10
11
|
specs:
|
12
|
+
actionview (7.0.0)
|
13
|
+
activesupport (= 7.0.0)
|
14
|
+
builder (~> 3.1)
|
15
|
+
erubi (~> 1.4)
|
16
|
+
rails-dom-testing (~> 2.0)
|
17
|
+
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
18
|
+
activesupport (7.0.0)
|
19
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
20
|
+
i18n (>= 1.6, < 2)
|
21
|
+
minitest (>= 5.1)
|
22
|
+
tzinfo (~> 2.0)
|
11
23
|
ast (2.4.2)
|
24
|
+
builder (3.2.4)
|
25
|
+
concurrent-ruby (1.1.9)
|
26
|
+
crass (1.0.6)
|
12
27
|
diff-lcs (1.4.4)
|
28
|
+
erubi (1.10.0)
|
29
|
+
i18n (1.8.11)
|
30
|
+
concurrent-ruby (~> 1.0)
|
31
|
+
loofah (2.13.0)
|
32
|
+
crass (~> 1.0.2)
|
33
|
+
nokogiri (>= 1.5.9)
|
34
|
+
minitest (5.15.0)
|
35
|
+
nokogiri (1.12.5-x86_64-linux)
|
36
|
+
racc (~> 1.4)
|
13
37
|
parallel (1.21.0)
|
14
38
|
parser (3.0.3.2)
|
15
39
|
ast (~> 2.4.1)
|
40
|
+
racc (1.6.0)
|
41
|
+
rails-dom-testing (2.0.3)
|
42
|
+
activesupport (>= 4.2.0)
|
43
|
+
nokogiri (>= 1.6)
|
44
|
+
rails-html-sanitizer (1.4.2)
|
45
|
+
loofah (~> 2.3)
|
16
46
|
rainbow (3.0.0)
|
17
47
|
rake (13.0.6)
|
18
48
|
regexp_parser (2.2.0)
|
@@ -45,13 +75,17 @@ GEM
|
|
45
75
|
rubocop (~> 1.19)
|
46
76
|
ruby-progressbar (1.11.0)
|
47
77
|
temple (0.8.2)
|
78
|
+
thor (1.2.1)
|
48
79
|
tilt (2.0.10)
|
80
|
+
tzinfo (2.0.4)
|
81
|
+
concurrent-ruby (~> 1.0)
|
49
82
|
unicode-display_width (2.1.0)
|
50
83
|
|
51
84
|
PLATFORMS
|
52
85
|
x86_64-linux
|
53
86
|
|
54
87
|
DEPENDENCIES
|
88
|
+
actionview
|
55
89
|
rake (~> 13.0)
|
56
90
|
rspec
|
57
91
|
rubocop
|
data/README.md
CHANGED
@@ -15,8 +15,67 @@ It uses Slimi to apply `rubocop --auto-correct` to embedded Ruby codes in Slim t
|
|
15
15
|
|
16
16
|
## Usage
|
17
17
|
|
18
|
-
|
18
|
+
### Rails
|
19
|
+
|
20
|
+
Add this line to your application's Gemfile.
|
19
21
|
|
20
22
|
```ruby
|
21
23
|
gem 'slimi'
|
22
24
|
```
|
25
|
+
|
26
|
+
This will cause `app/views/**/*.slim` files to be rendered by Slimi.
|
27
|
+
|
28
|
+
### CLI
|
29
|
+
|
30
|
+
Slimi can be tested from command line by `slimi` executable. This takes Slim code from STDIN and converts it into another form.
|
31
|
+
|
32
|
+
```console
|
33
|
+
$ slimi --help
|
34
|
+
Commands:
|
35
|
+
slimi compile # Convert Slim into Ruby
|
36
|
+
slimi erb # Convert Slim into ERB
|
37
|
+
slimi help [COMMAND] # Describe available commands or one specific command
|
38
|
+
slimi parse # Convert Slim into Temple expression
|
39
|
+
slimi render # Convert Slim into HTML
|
40
|
+
```
|
41
|
+
|
42
|
+
## Compatibility
|
43
|
+
|
44
|
+
- Line indicators
|
45
|
+
- [x] Vebatim text
|
46
|
+
- [x] Inline HTML
|
47
|
+
- [x] Control
|
48
|
+
- [x] Output
|
49
|
+
- [x] HTML comment
|
50
|
+
- [x] Code comment
|
51
|
+
- [x] IE conditional comment
|
52
|
+
- Tags
|
53
|
+
- [x] Doctype declaration
|
54
|
+
- [x] Closed tags
|
55
|
+
- [x] Trailing and leading white space
|
56
|
+
- [x] Inline tags
|
57
|
+
- [x] Text content
|
58
|
+
- [x] Dynamic content
|
59
|
+
- [x] Tag shortcuts
|
60
|
+
- [ ] Dynamic tags
|
61
|
+
- Attributes
|
62
|
+
- [x] Attributes wrapper
|
63
|
+
- [x] Quoted attributes
|
64
|
+
- [x] Ruby attributes
|
65
|
+
- [x] Boolean attributes
|
66
|
+
- [x] Attribute merging
|
67
|
+
- [x] Attribute shortcuts
|
68
|
+
- [ ] Splat attributes
|
69
|
+
- Plugins
|
70
|
+
- [ ] Include partials
|
71
|
+
- [ ] Translator/I18n
|
72
|
+
- [ ] Logic-less mode
|
73
|
+
- [ ] Smart text mode
|
74
|
+
- CLI
|
75
|
+
- [x] Convert Slim to Ruby
|
76
|
+
- [x] Convert Slim to HTML
|
77
|
+
- [x] Convert Slim to ERB
|
78
|
+
- Slimi-only features
|
79
|
+
- [x] Embedded Ruby code location
|
80
|
+
- [x] Support for annotate_rendered_view_with_filenames
|
81
|
+
- [x] Convert Slim to Temple expression by CLI
|
data/exe/slimi
ADDED
data/lib/slimi/cli.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'thor'
|
4
|
+
|
5
|
+
module Slimi
|
6
|
+
# Provide CLI features.
|
7
|
+
class Cli < ::Thor
|
8
|
+
desc 'compile', 'Convert Slim into Ruby'
|
9
|
+
def compile
|
10
|
+
slim = $stdin.read
|
11
|
+
ruby = Engine.new.call(slim)
|
12
|
+
puts ruby
|
13
|
+
end
|
14
|
+
|
15
|
+
desc 'erb', 'Convert Slim into ERB'
|
16
|
+
def erb
|
17
|
+
slim = $stdin.read
|
18
|
+
expression = ErbConverter.new.call(slim)
|
19
|
+
puts expression
|
20
|
+
end
|
21
|
+
|
22
|
+
desc 'parse', 'Convert Slim into Temple expression'
|
23
|
+
def parse
|
24
|
+
slim = $stdin.read
|
25
|
+
expression = Parser.new.call(slim)
|
26
|
+
pp expression
|
27
|
+
end
|
28
|
+
|
29
|
+
desc 'render', 'Convert Slim into HTML'
|
30
|
+
def render
|
31
|
+
slim = $stdin.read
|
32
|
+
ruby = Engine.new.call(slim)
|
33
|
+
result = eval(ruby)
|
34
|
+
puts result
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/slimi/engine.rb
CHANGED
@@ -3,21 +3,22 @@
|
|
3
3
|
require 'temple'
|
4
4
|
|
5
5
|
module Slimi
|
6
|
-
# Convert Slim
|
6
|
+
# Convert Slim into Ruby.
|
7
7
|
class Engine < ::Temple::Engine
|
8
8
|
define_options(
|
9
9
|
attr_quote: '"',
|
10
10
|
default_tag: 'div',
|
11
11
|
format: :xhtml,
|
12
|
+
generator: ::Temple::Generators::StringBuffer,
|
12
13
|
merge_attrs: { 'class' => ' ' },
|
13
14
|
pretty: false,
|
14
15
|
sort_attrs: true
|
15
16
|
)
|
16
17
|
|
17
18
|
use Parser
|
18
|
-
use Filters::Unposition
|
19
19
|
use Filters::Embedded
|
20
20
|
use Filters::Interpolation
|
21
|
+
use Filters::Unposition
|
21
22
|
use Filters::DoInserter
|
22
23
|
use Filters::EndInserter
|
23
24
|
use Filters::Control
|
@@ -28,10 +29,11 @@ module Slimi
|
|
28
29
|
use Filters::Attribute
|
29
30
|
use(:AttributeRemover) { ::Temple::HTML::AttributeRemover.new(remove_empty_attrs: options[:merge_attrs].keys) }
|
30
31
|
html :Pretty
|
32
|
+
use Filters::Amble
|
31
33
|
filter :Escapable
|
32
34
|
filter :ControlFlow
|
33
35
|
filter :MultiFlattener
|
34
36
|
filter :StaticMerger
|
35
|
-
generator
|
37
|
+
use(:Generator) { options[:generator] }
|
36
38
|
end
|
37
39
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Slimi
|
4
|
+
module Filters
|
5
|
+
# Support Rails annotate_rendered_view_with_filenames feature.
|
6
|
+
class Amble < Base
|
7
|
+
define_options(
|
8
|
+
:postamble,
|
9
|
+
:preamble
|
10
|
+
)
|
11
|
+
|
12
|
+
# @param [Array] expression
|
13
|
+
# @return [Array]
|
14
|
+
def call(expression)
|
15
|
+
result = %i[multi]
|
16
|
+
result << [:static, options[:preamble]] if options[:preamble]
|
17
|
+
result << expression
|
18
|
+
result << [:static, options[:postamble]] if options[:postamble]
|
19
|
+
result
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module Slimi
|
4
4
|
module Filters
|
5
5
|
# Handle `[:slimi, :attributes, ...]`.
|
6
|
-
class Attribute <
|
6
|
+
class Attribute < Base
|
7
7
|
define_options :merge_attrs
|
8
8
|
|
9
9
|
# @param [Array<Array>] expressions
|
@@ -16,7 +16,7 @@ module Slimi
|
|
16
16
|
# @param [Array] value
|
17
17
|
# @return [Array]
|
18
18
|
def on_html_attr(name, value)
|
19
|
-
if value[0] == :
|
19
|
+
if value[0] == :slimi && value[1] == :attrvalue && !options[:merge_attrs][name]
|
20
20
|
escape = value[2]
|
21
21
|
code = value[3]
|
22
22
|
case code
|
@@ -42,7 +42,7 @@ module Slimi
|
|
42
42
|
# @param [Boolean] escape
|
43
43
|
# @param [String] code\
|
44
44
|
# @return [Array]\
|
45
|
-
def
|
45
|
+
def on_slimi_attrvalue(escape, code)
|
46
46
|
if (delimiter = options[:merge_attrs][@attr])
|
47
47
|
tmp = unique_name
|
48
48
|
[:multi,
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'temple'
|
4
|
+
|
5
|
+
module Slimi
|
6
|
+
module Filters
|
7
|
+
# Pass-through some expressions which are unknown for Temple.
|
8
|
+
class Base < ::Temple::HTML::Filter
|
9
|
+
# @param [String] code
|
10
|
+
# @param [Array] expression
|
11
|
+
# @return [Array]
|
12
|
+
def on_slimi_control(code, expression)
|
13
|
+
[:slimi, :control, code, compile(expression)]
|
14
|
+
end
|
15
|
+
|
16
|
+
# @param [String] type
|
17
|
+
# @param [String] code
|
18
|
+
# @param [Array] expression
|
19
|
+
# @param [Array] attributes
|
20
|
+
# @return [Array]
|
21
|
+
def on_slimi_embedded(type, expression, attributes)
|
22
|
+
[:slimi, :embedded, type, compile(expression), attributes]
|
23
|
+
end
|
24
|
+
|
25
|
+
# @param [Boolean] escape
|
26
|
+
# @param [String] code
|
27
|
+
# @param [Array] expression
|
28
|
+
# @return [Array]
|
29
|
+
def on_slimi_output(escape, code, expression)
|
30
|
+
[:slimi, :output, escape, code, compile(expression)]
|
31
|
+
end
|
32
|
+
|
33
|
+
# @param [Integer] begin_
|
34
|
+
# @param [Integer] end_
|
35
|
+
# @param [Array] expression
|
36
|
+
# @return [Array]
|
37
|
+
def on_slimi_position(begin_, end_, expression)
|
38
|
+
[:slimi, :position, begin_, end_, compile(expression)]
|
39
|
+
end
|
40
|
+
|
41
|
+
# @param [String] type
|
42
|
+
# @param [Array] expression
|
43
|
+
# @return [Array]
|
44
|
+
def on_slimi_text(type, expression)
|
45
|
+
[:slimi, :text, type, compile(expression)]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -2,12 +2,12 @@
|
|
2
2
|
|
3
3
|
module Slimi
|
4
4
|
module Filters
|
5
|
-
# Handle `[:
|
6
|
-
class Control <
|
5
|
+
# Handle `[:slimi, :control, code, multi]`.
|
6
|
+
class Control < Base
|
7
7
|
# @param [String] code
|
8
8
|
# @param [Array] multi
|
9
9
|
# @return [Array]
|
10
|
-
def
|
10
|
+
def on_slimi_control(code, multi)
|
11
11
|
[
|
12
12
|
:multi,
|
13
13
|
[:code, code],
|
@@ -3,24 +3,24 @@
|
|
3
3
|
module Slimi
|
4
4
|
module Filters
|
5
5
|
# Append missing `do` to embedded Ruby code.
|
6
|
-
class DoInserter <
|
6
|
+
class DoInserter < Base
|
7
7
|
VALID_RUBY_LINE_REGEXP = /(\A(if|unless|else|elsif|when|begin|rescue|ensure|case)\b)|\bdo\s*(\|[^|]*\|\s*)?\Z/.freeze
|
8
8
|
|
9
9
|
# @param [String] code
|
10
10
|
# @param [Array] expressio
|
11
11
|
# @return [Array]
|
12
|
-
def
|
12
|
+
def on_slimi_control(code, expression)
|
13
13
|
code += ' do' unless code.match?(VALID_RUBY_LINE_REGEXP) || empty_exp?(expression)
|
14
|
-
[:
|
14
|
+
[:slimi, :control, code, compile(expression)]
|
15
15
|
end
|
16
16
|
|
17
17
|
# @param [Boolean] escape
|
18
18
|
# @param [String] code
|
19
19
|
# @param [Array] expression
|
20
20
|
# @return [Array]
|
21
|
-
def
|
21
|
+
def on_slimi_output(escape, code, expression)
|
22
22
|
code += ' do' unless code.match?(VALID_RUBY_LINE_REGEXP) || empty_exp?(expression)
|
23
|
-
[:
|
23
|
+
[:slimi, :output, escape, code, compile(expression)]
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
@@ -1,23 +1,25 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'tilt'
|
4
|
+
|
3
5
|
module Slimi
|
4
6
|
module Filters
|
5
7
|
# @api private
|
6
|
-
class TextCollector <
|
8
|
+
class TextCollector < Base
|
7
9
|
def call(exp)
|
8
10
|
@collected = ''
|
9
11
|
super(exp)
|
10
12
|
@collected
|
11
13
|
end
|
12
14
|
|
13
|
-
def
|
15
|
+
def on_slimi_interpolate(text)
|
14
16
|
@collected << text
|
15
17
|
nil
|
16
18
|
end
|
17
19
|
end
|
18
20
|
|
19
21
|
# @api private
|
20
|
-
class NewlineCollector <
|
22
|
+
class NewlineCollector < Base
|
21
23
|
def call(exp)
|
22
24
|
@collected = [:multi]
|
23
25
|
super(exp)
|
@@ -31,7 +33,7 @@ module Slimi
|
|
31
33
|
end
|
32
34
|
|
33
35
|
# @api private
|
34
|
-
class OutputProtector <
|
36
|
+
class OutputProtector < Base
|
35
37
|
def call(exp)
|
36
38
|
@protect = []
|
37
39
|
@collected = ''
|
@@ -45,9 +47,9 @@ module Slimi
|
|
45
47
|
nil
|
46
48
|
end
|
47
49
|
|
48
|
-
def
|
50
|
+
def on_slimi_output(escape, text, content)
|
49
51
|
@collected << @tag
|
50
|
-
@protect << [:
|
52
|
+
@protect << [:slimi, :output, escape, text, content]
|
51
53
|
nil
|
52
54
|
end
|
53
55
|
|
@@ -64,7 +66,7 @@ module Slimi
|
|
64
66
|
|
65
67
|
# Temple filter which processes embedded engines
|
66
68
|
# @api private
|
67
|
-
class Embedded <
|
69
|
+
class Embedded < Base
|
68
70
|
@engines = {}
|
69
71
|
|
70
72
|
class << self
|
@@ -101,12 +103,12 @@ module Slimi
|
|
101
103
|
@disabled = normalize_engine_list(options[:disable_engines])
|
102
104
|
end
|
103
105
|
|
104
|
-
def
|
106
|
+
def on_slimi_embedded(name, body, attrs)
|
105
107
|
name = name.to_sym
|
106
108
|
raise(Temple::FilterError, "Embedded engine #{name} is disabled") unless enabled?(name)
|
107
109
|
|
108
110
|
@engines[name] ||= self.class.create(name, options)
|
109
|
-
@engines[name].
|
111
|
+
@engines[name].on_slimi_embedded(name, body, attrs)
|
110
112
|
end
|
111
113
|
|
112
114
|
def enabled?(name)
|
@@ -122,7 +124,7 @@ module Slimi
|
|
122
124
|
list&.map(&:to_sym)
|
123
125
|
end
|
124
126
|
|
125
|
-
class Engine <
|
127
|
+
class Engine < Base
|
126
128
|
protected
|
127
129
|
|
128
130
|
def collect_text(body)
|
@@ -138,7 +140,7 @@ module Slimi
|
|
138
140
|
|
139
141
|
# Basic tilt engine
|
140
142
|
class TiltEngine < Engine
|
141
|
-
def
|
143
|
+
def on_slimi_embedded(engine, body, _attrs)
|
142
144
|
tilt_engine = Tilt[engine] || raise(Temple::FilterError, "Tilt engine #{engine} is not available.")
|
143
145
|
tilt_options = options[engine.to_sym] || {}
|
144
146
|
tilt_options[:default_encoding] ||= 'utf-8'
|
@@ -194,7 +196,7 @@ module Slimi
|
|
194
196
|
class TagEngine < Engine
|
195
197
|
disable_option_validator!
|
196
198
|
|
197
|
-
def
|
199
|
+
def on_slimi_embedded(engine, body, attrs)
|
198
200
|
unless options[:attributes].empty?
|
199
201
|
options[:attributes].map do |k, v|
|
200
202
|
attrs << [:html, :attr, k, [:static, v]]
|
@@ -207,7 +209,7 @@ module Slimi
|
|
207
209
|
opts.delete(:tag)
|
208
210
|
opts.delete(:attributes)
|
209
211
|
@engine ||= options[:engine].new(opts)
|
210
|
-
body = @engine.
|
212
|
+
body = @engine.on_slimi_embedded(engine, body, attrs)
|
211
213
|
end
|
212
214
|
|
213
215
|
[:html, :tag, options[:tag], attrs, body]
|
@@ -221,14 +223,14 @@ module Slimi
|
|
221
223
|
|
222
224
|
set_options tag: :script, attributes: {}
|
223
225
|
|
224
|
-
def
|
226
|
+
def on_slimi_embedded(engine, body, attrs)
|
225
227
|
super(engine, [:html, :js, body], attrs)
|
226
228
|
end
|
227
229
|
end
|
228
230
|
|
229
231
|
# Embeds ruby code
|
230
232
|
class RubyEngine < Engine
|
231
|
-
def
|
233
|
+
def on_slimi_embedded(_engine, body, _attrs)
|
232
234
|
[:multi, [:newline], [:code, "#{collect_text(body)}\n"]]
|
233
235
|
end
|
234
236
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module Slimi
|
4
4
|
module Filters
|
5
5
|
# Append missing `end` line to embedded Ruby code in control block.
|
6
|
-
class EndInserter <
|
6
|
+
class EndInserter < Base
|
7
7
|
# @param [Array<Array>] expressions
|
8
8
|
def on_multi(*expressions)
|
9
9
|
result = [:multi]
|
@@ -49,7 +49,7 @@ module Slimi
|
|
49
49
|
|
50
50
|
# @return [Boolean]
|
51
51
|
def control?
|
52
|
-
@expression[0] == :
|
52
|
+
@expression[0] == :slimi && @expression[1] == :control
|
53
53
|
end
|
54
54
|
|
55
55
|
# @return [Boolean]
|
@@ -4,29 +4,7 @@ require 'strscan'
|
|
4
4
|
|
5
5
|
module Slimi
|
6
6
|
module Filters
|
7
|
-
class Interpolation
|
8
|
-
def initialize(*); end
|
9
|
-
|
10
|
-
def call(node)
|
11
|
-
convert(node)
|
12
|
-
end
|
13
|
-
|
14
|
-
private
|
15
|
-
|
16
|
-
def convert(value)
|
17
|
-
if value.instance_of?(::Array)
|
18
|
-
if value[0] == :slimi && value[1] == :interpolate
|
19
|
-
on_slimi_interpolate(value[2], value[3], value[4])
|
20
|
-
else
|
21
|
-
value.map do |element|
|
22
|
-
call(element)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
else
|
26
|
-
value
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
7
|
+
class Interpolation < Base
|
30
8
|
# @param [Integer] begin_
|
31
9
|
# @param [Integer] end_
|
32
10
|
# @return [Array] S-expression.
|
@@ -47,7 +25,7 @@ module Slimi
|
|
47
25
|
else
|
48
26
|
escape = false
|
49
27
|
end
|
50
|
-
block << [:slimi, :position, begin2, begin2 + code.length, [:
|
28
|
+
block << [:slimi, :position, begin2, begin2 + code.length, [:slimi, :output, escape, code, [:multi]]]
|
51
29
|
elsif (value = scanner.scan(/([#\\]?[^#\\]*([#\\][^\\\#{][^#\\]*)*)/)) # rubocop:disable Lint/DuplicateBranch
|
52
30
|
block << [:static, value]
|
53
31
|
end
|
data/lib/slimi/filters/output.rb
CHANGED
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
module Slimi
|
4
4
|
module Filters
|
5
|
-
# Handle `[:
|
6
|
-
class Output <
|
5
|
+
# Handle `[:slimi, :output, escape, code, multi]`.
|
6
|
+
class Output < Base
|
7
7
|
define_options :disable_capture
|
8
8
|
|
9
9
|
IF_REGEXP = /\A(if|unless)\b|\bdo\s*(\|[^|]*\|)?\s*$/.freeze
|
@@ -12,7 +12,7 @@ module Slimi
|
|
12
12
|
# @param [String] code
|
13
13
|
# @param [Array] multi
|
14
14
|
# @return [Array]
|
15
|
-
def
|
15
|
+
def on_slimi_output(escape, code, multi)
|
16
16
|
if code.match?(IF_REGEXP)
|
17
17
|
tmp = unique_name
|
18
18
|
[
|
data/lib/slimi/filters/text.rb
CHANGED
@@ -2,12 +2,12 @@
|
|
2
2
|
|
3
3
|
module Slimi
|
4
4
|
module Filters
|
5
|
-
# Handle `[:
|
6
|
-
class Text <
|
5
|
+
# Handle `[:slimi, :text, multi]`.
|
6
|
+
class Text < Base
|
7
7
|
# @param [Symbol] _type
|
8
8
|
# @param [Array] multi
|
9
9
|
# @return [Array]
|
10
|
-
def
|
10
|
+
def on_slimi_text(_type, multi)
|
11
11
|
compile(multi)
|
12
12
|
end
|
13
13
|
end
|
@@ -2,29 +2,13 @@
|
|
2
2
|
|
3
3
|
module Slimi
|
4
4
|
module Filters
|
5
|
-
class Unposition
|
6
|
-
|
7
|
-
|
8
|
-
# @param [Array]
|
9
|
-
# @return [Array]
|
10
|
-
def
|
11
|
-
|
12
|
-
end
|
13
|
-
|
14
|
-
private
|
15
|
-
|
16
|
-
def convert(value)
|
17
|
-
if value.instance_of?(::Array)
|
18
|
-
if value[0] == :slimi && value[1] == :position
|
19
|
-
call(value[4])
|
20
|
-
else
|
21
|
-
value.map do |element|
|
22
|
-
call(element)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
else
|
26
|
-
value
|
27
|
-
end
|
5
|
+
class Unposition < Base
|
6
|
+
# @param [Integer] _begin
|
7
|
+
# @param [Integer] _end
|
8
|
+
# @param [Array] expression
|
9
|
+
# @return [Array]
|
10
|
+
def on_slimi_position(_begin, _end, expression)
|
11
|
+
compile(expression)
|
28
12
|
end
|
29
13
|
end
|
30
14
|
end
|
data/lib/slimi/filters.rb
CHANGED
@@ -2,7 +2,9 @@
|
|
2
2
|
|
3
3
|
module Slimi
|
4
4
|
module Filters
|
5
|
+
autoload :Amble, 'slimi/filters/amble'
|
5
6
|
autoload :Attribute, 'slimi/filters/attribute'
|
7
|
+
autoload :Base, 'slimi/filters/base'
|
6
8
|
autoload :Control, 'slimi/filters/control'
|
7
9
|
autoload :DoInserter, 'slimi/filters/do_inserter'
|
8
10
|
autoload :Embedded, 'slimi/filters/embedded'
|
data/lib/slimi/parser.rb
CHANGED
@@ -115,7 +115,7 @@ module Slimi
|
|
115
115
|
|
116
116
|
embedded_template_engine_name = @scanner[1]
|
117
117
|
attributes = parse_attributes
|
118
|
-
@stacks.last << [:
|
118
|
+
@stacks.last << [:slimi, :embedded, embedded_template_engine_name, parse_text_block, attributes]
|
119
119
|
end
|
120
120
|
|
121
121
|
# @return [Boolean]
|
@@ -150,14 +150,14 @@ module Slimi
|
|
150
150
|
block = [:multi]
|
151
151
|
@stacks.last.insert(-2, [:static, ' ']) if with_leading_white_space2
|
152
152
|
@scanner.skip(/[ \t]+/)
|
153
|
-
tag << with_position { [:
|
153
|
+
tag << with_position { [:slimi, :output, escape, parse_broken_lines, block] }
|
154
154
|
@stacks.last << [:static, ' '] if with_trailing_white_space2
|
155
155
|
@stacks << block
|
156
156
|
elsif @scanner.skip(%r{[ \t]*/[ \t]*})
|
157
157
|
syntax_error!(Errors::UnexpectedTextAfterClosedTagError) unless @scanner.match?(/\r?\n/)
|
158
158
|
else
|
159
159
|
@scanner.skip(/[ \t]+/)
|
160
|
-
tag << [:
|
160
|
+
tag << [:slimi, :text, :inline, parse_text_block]
|
161
161
|
end
|
162
162
|
true
|
163
163
|
else
|
@@ -269,9 +269,10 @@ module Slimi
|
|
269
269
|
elsif @scanner.skip(@ruby_attribute_regexp)
|
270
270
|
attribute_name = @scanner[1]
|
271
271
|
escape = @scanner[2].empty?
|
272
|
+
charpos = @scanner.charpos
|
272
273
|
attribute_value = parse_ruby_attribute_value(attribute_delimiter_closing)
|
273
274
|
syntax_error!(Errors::InvalidEmptyAttributeError) if attribute_value.empty?
|
274
|
-
attributes << [:html, :attr, attribute_name, [:
|
275
|
+
attributes << [:html, :attr, attribute_name, [:slimi, :position, charpos, charpos + attribute_value.length, [:slimi, :attrvalue, escape, attribute_value]]]
|
275
276
|
elsif !attribute_delimiter_closing_part_regexp
|
276
277
|
break
|
277
278
|
elsif @scanner.skip(boolean_attribute_regexp)
|
@@ -331,9 +332,9 @@ module Slimi
|
|
331
332
|
|
332
333
|
# @return [Boolean]
|
333
334
|
def parse_html_comment
|
334
|
-
if @scanner.skip(%r{/!})
|
335
|
+
if @scanner.skip(%r{/![ \t]*})
|
335
336
|
text_block = parse_text_block
|
336
|
-
text = [:
|
337
|
+
text = [:slimi, :text, :verbatim, text_block]
|
337
338
|
@stacks.last << [:html, :comment, text]
|
338
339
|
true
|
339
340
|
else
|
@@ -380,7 +381,7 @@ module Slimi
|
|
380
381
|
def parse_verbatim_text_block_inner
|
381
382
|
if @scanner.skip(/([|']) ?/)
|
382
383
|
with_trailing_white_space = @scanner[1] == "'"
|
383
|
-
@stacks.last << [:
|
384
|
+
@stacks.last << [:slimi, :text, :verbatim, parse_text_block]
|
384
385
|
@stacks.last << [:static, ' '] if with_trailing_white_space
|
385
386
|
true
|
386
387
|
else
|
@@ -419,7 +420,7 @@ module Slimi
|
|
419
420
|
if @scanner.skip(/-/)
|
420
421
|
block = [:multi]
|
421
422
|
@scanner.skip(/[ \t]+/)
|
422
|
-
@stacks.last << with_position { [:
|
423
|
+
@stacks.last << with_position { [:slimi, :control, parse_broken_lines, block] }
|
423
424
|
@stacks << block
|
424
425
|
true
|
425
426
|
else
|
@@ -442,7 +443,7 @@ module Slimi
|
|
442
443
|
block = [:multi]
|
443
444
|
@stacks.last << [:static, ' '] if with_trailing_white_space
|
444
445
|
@scanner.skip(/[ \t]+/)
|
445
|
-
@stacks.last << with_position { [:
|
446
|
+
@stacks.last << with_position { [:slimi, :output, escape, parse_broken_lines, block] }
|
446
447
|
@stacks.last << [:static, ' '] if with_leading_white_space
|
447
448
|
@stacks << block
|
448
449
|
else
|
@@ -472,7 +473,7 @@ module Slimi
|
|
472
473
|
|
473
474
|
# @raise
|
474
475
|
def expect_line_ending
|
475
|
-
parse_line_ending || @scanner.eos? ||
|
476
|
+
parse_line_ending || @scanner.eos? || syntax_error!(Errors::LineEndingNotFoundError)
|
476
477
|
end
|
477
478
|
|
478
479
|
# @return [Integer] Indent level.
|
@@ -1,14 +1,77 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Slimi
|
4
|
+
# Render Slim template in response to requests from Rails.
|
4
5
|
class RailsTemplateHandler
|
5
|
-
|
6
|
-
|
6
|
+
# @param [ActionView::Template] template
|
7
|
+
# @param [String, nil] source
|
8
|
+
# @return [String]
|
9
|
+
def call(template, source = nil)
|
10
|
+
Renderer.new(
|
11
|
+
source: source,
|
12
|
+
template: template
|
13
|
+
).call
|
7
14
|
end
|
8
15
|
|
9
|
-
|
10
|
-
|
11
|
-
@
|
16
|
+
# Render HTML from given source and options.
|
17
|
+
class Renderer
|
18
|
+
# @param [String] source
|
19
|
+
# @param [ActionView::Template] template
|
20
|
+
def initialize(
|
21
|
+
source:,
|
22
|
+
template:
|
23
|
+
)
|
24
|
+
@source = source
|
25
|
+
@template = template
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [String]
|
29
|
+
def call
|
30
|
+
engine.call(source)
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
# @return [Slimi::Engine]
|
36
|
+
def engine
|
37
|
+
Engine.new(engine_options)
|
38
|
+
end
|
39
|
+
|
40
|
+
# @return [Hash{Symbol => Object}]
|
41
|
+
def engine_options
|
42
|
+
engine_default_options.merge(engine_amble_options)
|
43
|
+
end
|
44
|
+
|
45
|
+
# @return [Hash{Symbol => Object}]
|
46
|
+
def engine_default_options
|
47
|
+
{
|
48
|
+
generator: ::Temple::Generators::RailsOutputBuffer,
|
49
|
+
streaming: true,
|
50
|
+
use_html_safe: true
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
# @return [Hash{Symbol => Object}]
|
55
|
+
def engine_amble_options
|
56
|
+
if with_annotate_rendered_view_with_filenames?
|
57
|
+
{
|
58
|
+
postamble: "<!-- END #{@template.short_identifier} -->\n",
|
59
|
+
preamble: "<!-- BEGIN #{@template.short_identifier} -->\n"
|
60
|
+
}
|
61
|
+
else
|
62
|
+
{}
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# @return [String]
|
67
|
+
def source
|
68
|
+
@source || @template.source
|
69
|
+
end
|
70
|
+
|
71
|
+
# @return [Boolean]
|
72
|
+
def with_annotate_rendered_view_with_filenames?
|
73
|
+
::ActionView::Base.try(:annotate_rendered_view_with_filenames) && @template.format == :html
|
74
|
+
end
|
12
75
|
end
|
13
76
|
end
|
14
77
|
end
|
data/lib/slimi/railtie.rb
CHANGED
data/lib/slimi/version.rb
CHANGED
data/lib/slimi.rb
CHANGED
@@ -3,7 +3,9 @@
|
|
3
3
|
require_relative 'slimi/version'
|
4
4
|
|
5
5
|
module Slimi
|
6
|
+
autoload :Cli, 'slimi/cli'
|
6
7
|
autoload :Engine, 'slimi/engine'
|
8
|
+
autoload :ErbConverter, 'slimi/erb_converter'
|
7
9
|
autoload :Errors, 'slimi/errors'
|
8
10
|
autoload :Filters, 'slimi/filters'
|
9
11
|
autoload :Parser, 'slimi/parser'
|
data/slimi.gemspec
CHANGED
@@ -27,10 +27,8 @@ Gem::Specification.new do |spec|
|
|
27
27
|
spec.bindir = 'exe'
|
28
28
|
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
29
29
|
spec.require_paths = ['lib']
|
30
|
-
spec.metadata = {
|
31
|
-
'rubygems_mfa_required' => 'true'
|
32
|
-
}
|
33
30
|
|
34
31
|
spec.add_dependency 'temple'
|
32
|
+
spec.add_dependency 'thor'
|
35
33
|
spec.add_dependency 'tilt'
|
36
34
|
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.
|
4
|
+
version: 0.7.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryo Nakamura
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-01-
|
11
|
+
date: 2022-01-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: temple
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: thor
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: tilt
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -41,7 +55,8 @@ dependencies:
|
|
41
55
|
description:
|
42
56
|
email:
|
43
57
|
- r7kamura@gmail.com
|
44
|
-
executables:
|
58
|
+
executables:
|
59
|
+
- slimi
|
45
60
|
extensions: []
|
46
61
|
extra_rdoc_files: []
|
47
62
|
files:
|
@@ -56,11 +71,16 @@ files:
|
|
56
71
|
- Rakefile
|
57
72
|
- bin/console
|
58
73
|
- bin/setup
|
74
|
+
- exe/slimi
|
59
75
|
- lib/slimi.rb
|
76
|
+
- lib/slimi/cli.rb
|
60
77
|
- lib/slimi/engine.rb
|
78
|
+
- lib/slimi/erb_converter.rb
|
61
79
|
- lib/slimi/errors.rb
|
62
80
|
- lib/slimi/filters.rb
|
81
|
+
- lib/slimi/filters/amble.rb
|
63
82
|
- lib/slimi/filters/attribute.rb
|
83
|
+
- lib/slimi/filters/base.rb
|
64
84
|
- lib/slimi/filters/control.rb
|
65
85
|
- lib/slimi/filters/do_inserter.rb
|
66
86
|
- lib/slimi/filters/embedded.rb
|
@@ -79,7 +99,9 @@ homepage: https://github.com/r7kamura/slimi
|
|
79
99
|
licenses:
|
80
100
|
- MIT
|
81
101
|
metadata:
|
82
|
-
|
102
|
+
homepage_uri: https://github.com/r7kamura/slimi
|
103
|
+
source_code_uri: https://github.com/r7kamura/slimi
|
104
|
+
changelog_uri: https://github.com/r7kamura/slimi/blob/main/CHANGELOG.md
|
83
105
|
post_install_message:
|
84
106
|
rdoc_options: []
|
85
107
|
require_paths:
|