slimi 0.5.1 → 0.7.2

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: 36247783488eef0fc3711f969b37bc5b0cbc06b40086e7c524dfa4f46bba2823
4
- data.tar.gz: 63e12ac1f2d178840b4d956b3c62195ce3601a3c212b1c48e5cc65ce7ca61a24
3
+ metadata.gz: 6c151d108a263b740aa9cf7f7ac6dba84741a722b1fdffcb1b6078c63a55a911
4
+ data.tar.gz: fe127168b410730d5303deff0d50b43d42d805b9fcb16bce17c09fb00549c149
5
5
  SHA512:
6
- metadata.gz: 549fc053c09c2283042f7bad2200d79d07e970d97c3aadacbd38e5fbbff54534bb0918b145580c23f1d4ffb2cba760167f09c6bc2b41de71c0b457c76c981f18
7
- data.tar.gz: af6cc99ec67062a742f8bff4c76ac6da875a97a7afb5c6d193cd6c50b23e9e7e4ddd62b1ac690d3b94f6094ed5da1986cd2705b58a6147941788b13100ee77d2
6
+ metadata.gz: fbffeb9d9bd5dd13b085503bc439a85b4832ae44bd8839d07fd879faf5e158b7f5b41f72f051e3963a73086e302a5f9f3cc2541c6a404b7acbed66dd225824d3
7
+ data.tar.gz: 945f20409900cdd7fb7cff7a2517aae58a334d9528b6092d1a212b4715bc2dbf713650a25201b2bf8ba28f3f181d4e5cc635b1c759f9b0420e3c9dc6b4742ec2
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,48 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.7.2 - 2022-01-24
6
+
7
+ ### Fixed
8
+
9
+ - Fix parser bug at CR+LF empty line.
10
+ - Fix typo at internal const name.
11
+
12
+ ## 0.7.1 - 2022-01-18
13
+
14
+ ### Fixed
15
+
16
+ - Fix error handling on unexpected line ending.
17
+ - Fix missing some metadata in gemspec.
18
+
19
+ ## 0.7.0 - 2022-01-04
20
+
21
+ ### Added
22
+
23
+ - Add `slimi` executable.
24
+
25
+ ### Fixed
26
+
27
+ - Remove preceding white spaces from HTML comment.
28
+ - Fix bug that :generator option was not working.
29
+ - Fix bug that Ruby code in nested line can be problem on compilation.
30
+
31
+ ## 0.6.0 - 2022-01-03
32
+
33
+ ### Added
34
+
35
+ - Support annotate_rendered_view_with_filenames.
36
+
37
+ ### Changed
38
+
39
+ - Rename expression name from slim to slimi.
40
+
41
+ ### Fixed
42
+
43
+ - Fix bug at registering handler to ActionView.
44
+ - Fix Engine options at RailsTemplateHandler.
45
+ - Define missing :generator option at Engine.
46
+
5
47
  ## 0.5.1 - 2022-01-02
6
48
 
7
49
  ### Changed
data/Gemfile CHANGED
@@ -5,6 +5,7 @@ source 'https://rubygems.org'
5
5
  # Specify your gem's dependencies in slimi.gemspec
6
6
  gemspec
7
7
 
8
+ gem 'actionview'
8
9
  gem 'rake', '~> 13.0'
9
10
  gem 'rspec'
10
11
  gem 'rubocop'
data/Gemfile.lock CHANGED
@@ -1,18 +1,48 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- slimi (0.5.1)
4
+ slimi (0.7.2)
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,12 +15,30 @@ It uses Slimi to apply `rubocop --auto-correct` to embedded Ruby codes in Slim t
15
15
 
16
16
  ## Usage
17
17
 
18
- Just replace `gem 'slim'` with `gem 'slimi'` in your application's Gemfile.
18
+ ### Rails
19
+
20
+ Add this line to your application's Gemfile.
19
21
 
20
22
  ```ruby
21
23
  gem 'slimi'
22
24
  ```
23
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
+
24
42
  ## Compatibility
25
43
 
26
44
  - Line indicators
@@ -53,7 +71,11 @@ gem 'slimi'
53
71
  - [ ] Translator/I18n
54
72
  - [ ] Logic-less mode
55
73
  - [ ] Smart text mode
56
- - Etc.
57
- - [ ] CLI tools
74
+ - CLI
75
+ - [x] Convert Slim to Ruby
76
+ - [x] Convert Slim to HTML
77
+ - [x] Convert Slim to ERB
58
78
  - Slimi-only features
59
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
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ $LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
5
+ require 'slimi'
6
+
7
+ Slimi::Cli.start
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 code into Ruby code.
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 :StringBuffer
37
+ use(:Generator) { options[:generator] }
36
38
  end
37
39
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Slimi
4
+ # Convert Slim into ERB.
5
+ class ErbConverter < Engine
6
+ replace :StaticMerger, ::Temple::Filters::CodeMerger
7
+ replace :Generator, Temple::Generators::ERB
8
+ end
9
+ 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 < ::Temple::HTML::Filter
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] == :slim && value[1] == :attrvalue && !options[:merge_attrs][name]
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 on_slim_attrvalue(escape, code)
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 `[:slim, :control, code, multi]`.
6
- class Control < ::Temple::HTML::Filter
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 on_slim_control(code, multi)
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 < ::Temple::HTML::Filter
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 on_slim_control(code, expression)
12
+ def on_slimi_control(code, expression)
13
13
  code += ' do' unless code.match?(VALID_RUBY_LINE_REGEXP) || empty_exp?(expression)
14
- [:slim, :control, code, compile(expression)]
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 on_slim_output(escape, code, expression)
21
+ def on_slimi_output(escape, code, expression)
22
22
  code += ' do' unless code.match?(VALID_RUBY_LINE_REGEXP) || empty_exp?(expression)
23
- [:slim, :output, escape, code, compile(expression)]
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 < ::Temple::HTML::Filter
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 on_slim_interpolate(text)
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 < ::Temple::HTML::Filter
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 < ::Temple::HTML::Filter
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 on_slim_output(escape, text, content)
50
+ def on_slimi_output(escape, text, content)
49
51
  @collected << @tag
50
- @protect << [:slim, :output, escape, text, content]
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 < ::Temple::HTML::Filter
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 on_slim_embedded(name, body, attrs)
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].on_slim_embedded(name, body, attrs)
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 < ::Temple::HTML::Filter
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 on_slim_embedded(engine, body, _attrs)
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 on_slim_embedded(engine, body, attrs)
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.on_slim_embedded(engine, body, attrs)
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 on_slim_embedded(engine, body, attrs)
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 on_slim_embedded(_engine, body, _attrs)
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 < ::Temple::HTML::Filter
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] == :slim && @expression[1] == :control
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, [:slim, :output, escape, code, [:multi]]]
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
@@ -2,8 +2,8 @@
2
2
 
3
3
  module Slimi
4
4
  module Filters
5
- # Handle `[:slim, :output, escape, code, multi]`.
6
- class Output < ::Temple::HTML::Filter
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 on_slim_output(escape, code, multi)
15
+ def on_slimi_output(escape, code, multi)
16
16
  if code.match?(IF_REGEXP)
17
17
  tmp = unique_name
18
18
  [
@@ -2,12 +2,12 @@
2
2
 
3
3
  module Slimi
4
4
  module Filters
5
- # Handle `[:slim, :text, multi]`.
6
- class Text < ::Temple::HTML::Filter
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 on_slim_text(_type, multi)
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
- def initialize(*); end
7
-
8
- # @param [Array] node S-expression.
9
- # @return [Array] S-expression.
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] == :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
@@ -77,7 +77,7 @@ module Slimi
77
77
  # Parse blank line.
78
78
  # @return [Boolean] True if it could parse a blank line.
79
79
  def parse_blank_line
80
- if @scanner.skip(/[ \t]*$/)
80
+ if @scanner.skip(/[ \t]*(?=\R|$)/)
81
81
  parse_line_ending
82
82
  true
83
83
  else
@@ -115,7 +115,7 @@ module Slimi
115
115
 
116
116
  embedded_template_engine_name = @scanner[1]
117
117
  attributes = parse_attributes
118
- @stacks.last << [:slim, :embedded, embedded_template_engine_name, parse_text_block, attributes]
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 { [:slim, :output, escape, parse_broken_lines, block] }
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 << [:slim, :text, :inline, parse_text_block]
160
+ tag << [:slimi, :text, :inline, parse_text_block]
161
161
  end
162
162
  true
163
163
  else
@@ -272,7 +272,7 @@ module Slimi
272
272
  charpos = @scanner.charpos
273
273
  attribute_value = parse_ruby_attribute_value(attribute_delimiter_closing)
274
274
  syntax_error!(Errors::InvalidEmptyAttributeError) if attribute_value.empty?
275
- attributes << [:html, :attr, attribute_name, [:slimi, :position, charpos, charpos + attribute_value.length, [:slim, :attrvalue, escape, attribute_value]]]
275
+ attributes << [:html, :attr, attribute_name, [:slimi, :position, charpos, charpos + attribute_value.length, [:slimi, :attrvalue, escape, attribute_value]]]
276
276
  elsif !attribute_delimiter_closing_part_regexp
277
277
  break
278
278
  elsif @scanner.skip(boolean_attribute_regexp)
@@ -332,9 +332,9 @@ module Slimi
332
332
 
333
333
  # @return [Boolean]
334
334
  def parse_html_comment
335
- if @scanner.skip(%r{/!})
335
+ if @scanner.skip(%r{/![ \t]*})
336
336
  text_block = parse_text_block
337
- text = [:slim, :text, :verbatim, text_block]
337
+ text = [:slimi, :text, :verbatim, text_block]
338
338
  @stacks.last << [:html, :comment, text]
339
339
  true
340
340
  else
@@ -381,7 +381,7 @@ module Slimi
381
381
  def parse_verbatim_text_block_inner
382
382
  if @scanner.skip(/([|']) ?/)
383
383
  with_trailing_white_space = @scanner[1] == "'"
384
- @stacks.last << [:slim, :text, :verbatim, parse_text_block]
384
+ @stacks.last << [:slimi, :text, :verbatim, parse_text_block]
385
385
  @stacks.last << [:static, ' '] if with_trailing_white_space
386
386
  true
387
387
  else
@@ -420,7 +420,7 @@ module Slimi
420
420
  if @scanner.skip(/-/)
421
421
  block = [:multi]
422
422
  @scanner.skip(/[ \t]+/)
423
- @stacks.last << with_position { [:slim, :control, parse_broken_lines, block] }
423
+ @stacks.last << with_position { [:slimi, :control, parse_broken_lines, block] }
424
424
  @stacks << block
425
425
  true
426
426
  else
@@ -443,7 +443,7 @@ module Slimi
443
443
  block = [:multi]
444
444
  @stacks.last << [:static, ' '] if with_trailing_white_space
445
445
  @scanner.skip(/[ \t]+/)
446
- @stacks.last << with_position { [:slim, :output, escape, parse_broken_lines, block] }
446
+ @stacks.last << with_position { [:slimi, :output, escape, parse_broken_lines, block] }
447
447
  @stacks.last << [:static, ' '] if with_leading_white_space
448
448
  @stacks << block
449
449
  else
@@ -473,7 +473,7 @@ module Slimi
473
473
 
474
474
  # @raise
475
475
  def expect_line_ending
476
- parse_line_ending || @scanner.eos? || raise(LineEndingNotFoundError)
476
+ parse_line_ending || @scanner.eos? || syntax_error!(Errors::LineEndingNotFoundError)
477
477
  end
478
478
 
479
479
  # @return [Integer] Indent level.
@@ -578,7 +578,7 @@ module Slimi
578
578
 
579
579
  # Convert human-friendly options into machine-friendly objects.
580
580
  class Factory
581
- EMBEDDED_TEMPLAE_ENGINE_NAMES = %w[
581
+ EMBEDDED_TEMPLATE_ENGINE_NAMES = %w[
582
582
  coffee
583
583
  css
584
584
  javascript
@@ -667,7 +667,7 @@ module Slimi
667
667
 
668
668
  # @return [Regexp]
669
669
  def embedded_template_regexp
670
- /(#{::Regexp.union(EMBEDDED_TEMPLAE_ENGINE_NAMES)})(?:[ \t]*(?:(.*)))?:([ \t]*)/
670
+ /(#{::Regexp.union(EMBEDDED_TEMPLATE_ENGINE_NAMES)})(?:[ \t]*(?:(.*)))?:([ \t]*)/
671
671
  end
672
672
 
673
673
  # @return [Regexp]
@@ -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
- def initialize
6
- @engine = Engine.new
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
- def call(template, source = nil)
10
- source ||= template.source
11
- @engine.call(source)
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
@@ -5,6 +5,7 @@ module Slimi
5
5
  initializer 'Register Slimi template handler' do
6
6
  ::ActiveSupport.on_load(:action_view) do
7
7
  ::ActionView::Template.register_template_handler(
8
+ :slim,
8
9
  RailsTemplateHandler.new
9
10
  )
10
11
  end
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.5.1'
4
+ VERSION = '0.7.2'
5
5
  end
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
@@ -16,6 +16,7 @@ Gem::Specification.new do |spec|
16
16
  spec.metadata['homepage_uri'] = spec.homepage
17
17
  spec.metadata['source_code_uri'] = spec.homepage
18
18
  spec.metadata['changelog_uri'] = "#{spec.homepage}/blob/main/CHANGELOG.md"
19
+ spec.metadata['rubygems_mfa_required'] = 'true'
19
20
 
20
21
  # Specify which files should be added to the gem when it is released.
21
22
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
@@ -27,10 +28,8 @@ Gem::Specification.new do |spec|
27
28
  spec.bindir = 'exe'
28
29
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
29
30
  spec.require_paths = ['lib']
30
- spec.metadata = {
31
- 'rubygems_mfa_required' => 'true'
32
- }
33
31
 
34
32
  spec.add_dependency 'temple'
33
+ spec.add_dependency 'thor'
35
34
  spec.add_dependency 'tilt'
36
35
  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.5.1
4
+ version: 0.7.2
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-02 00:00:00.000000000 Z
11
+ date: 2022-01-24 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,6 +99,9 @@ homepage: https://github.com/r7kamura/slimi
79
99
  licenses:
80
100
  - MIT
81
101
  metadata:
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
82
105
  rubygems_mfa_required: 'true'
83
106
  post_install_message:
84
107
  rdoc_options: []