slim 5.1.0 → 5.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/.github/workflows/test.yml +28 -5
- data/CHANGES +12 -1
- data/Gemfile +6 -7
- data/README.jp.md +19 -29
- data/README.md +43 -28
- data/Rakefile +1 -1
- data/lib/slim/code_attributes.rb +2 -1
- data/lib/slim/command.rb +2 -8
- data/lib/slim/controls.rb +1 -0
- data/lib/slim/do_inserter.rb +3 -2
- data/lib/slim/embedded.rb +6 -7
- data/lib/slim/end_inserter.rb +1 -0
- data/lib/slim/engine.rb +1 -0
- data/lib/slim/erb_converter.rb +1 -0
- data/lib/slim/filter.rb +1 -0
- data/lib/slim/grammar.rb +1 -0
- data/lib/slim/include.rb +1 -0
- data/lib/slim/interpolation.rb +1 -0
- data/lib/slim/logic_less/context.rb +6 -7
- data/lib/slim/logic_less/filter.rb +1 -0
- data/lib/slim/logic_less.rb +1 -0
- data/lib/slim/parser.rb +17 -10
- data/lib/slim/railtie.rb +3 -1
- data/lib/slim/smart/escaper.rb +1 -1
- data/lib/slim/smart/filter.rb +3 -2
- data/lib/slim/smart/parser.rb +4 -3
- data/lib/slim/smart.rb +1 -0
- data/lib/slim/splat/builder.rb +10 -8
- data/lib/slim/splat/filter.rb +4 -3
- data/lib/slim/template.rb +1 -0
- data/lib/slim/translator.rb +4 -3
- data/lib/slim/version.rb +2 -1
- data/lib/slim.rb +1 -0
- data/slim.gemspec +1 -1
- data/test/core/helper.rb +3 -11
- data/test/core/test_commands.rb +11 -15
- data/test/core/test_encoding.rb +2 -2
- data/test/core/test_html_structure.rb +48 -0
- data/test/core/test_ruby_errors.rb +19 -0
- data/test/literate/helper.rb +1 -1
- data/test/literate/run.rb +1 -1
- data/test/logic_less/test_logic_less.rb +15 -0
- data/test/rails/app/controllers/slim_controller.rb +7 -1
- data/test/rails/app/views/layouts/application.html+testvariant.slim +10 -0
- data/test/rails/app/views/slim/attributes.html.slim +3 -0
- data/test/rails/app/views/slim/splat_with_delimiter.slim +1 -0
- data/test/rails/config/application.rb +1 -1
- data/test/rails/test/test_slim.rb +18 -0
- metadata +11 -14
data/lib/slim/filter.rb
CHANGED
data/lib/slim/grammar.rb
CHANGED
data/lib/slim/include.rb
CHANGED
data/lib/slim/interpolation.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Slim
|
2
3
|
class LogicLess
|
3
4
|
# @api private
|
@@ -16,7 +17,7 @@ module Slim
|
|
16
17
|
yield
|
17
18
|
else
|
18
19
|
new_scope do
|
19
|
-
dict.inject('') do |result, d|
|
20
|
+
dict.inject(''.dup) do |result, d|
|
20
21
|
scope.dict = d
|
21
22
|
result << yield
|
22
23
|
end
|
@@ -73,7 +74,7 @@ module Slim
|
|
73
74
|
return @dict.instance_variable_get(var_name).call(&block) if instance_variable?(var_name)
|
74
75
|
end
|
75
76
|
end
|
76
|
-
@parent.lambda(name) if @parent
|
77
|
+
@parent.lambda(name, &block) if @parent
|
77
78
|
end
|
78
79
|
|
79
80
|
def [](name)
|
@@ -104,11 +105,9 @@ module Slim
|
|
104
105
|
end
|
105
106
|
|
106
107
|
def instance_variable?(name)
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
false
|
111
|
-
end
|
108
|
+
@dict.instance_variable_defined?(name)
|
109
|
+
rescue NameError
|
110
|
+
false
|
112
111
|
end
|
113
112
|
end
|
114
113
|
|
data/lib/slim/logic_less.rb
CHANGED
data/lib/slim/parser.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Slim
|
2
3
|
# Parses Slim code and transforms it to a Temple expression
|
3
4
|
# @api private
|
@@ -49,7 +50,7 @@ module Slim
|
|
49
50
|
@code_attr_delims = options[:code_attr_delims]
|
50
51
|
tabsize = options[:tabsize]
|
51
52
|
if tabsize > 1
|
52
|
-
@tab_re = /\G((?: {#{tabsize}})*) {0,#{tabsize-1}}\t/
|
53
|
+
@tab_re = /\G((?: {#{tabsize}})*) {0,#{tabsize - 1}}\t/
|
53
54
|
@tab = '\1' + ' ' * tabsize
|
54
55
|
else
|
55
56
|
@tab_re = "\t"
|
@@ -63,15 +64,15 @@ module Slim
|
|
63
64
|
raise ArgumentError, 'You can only use special characters for attribute shortcuts' if k =~ /(\p{Word}|-)/
|
64
65
|
end
|
65
66
|
if v.include?(:attr)
|
66
|
-
@attr_shortcut[k] = [v[:attr]].flatten
|
67
|
+
@attr_shortcut[k] = v[:attr].is_a?(Proc) ? v[:attr] : [v[:attr]].flatten
|
67
68
|
end
|
68
69
|
if v.include?(:additional_attrs)
|
69
70
|
@additional_attrs[k] = v[:additional_attrs]
|
70
71
|
end
|
71
72
|
end
|
72
|
-
keys = Regexp.union @attr_shortcut.keys.sort_by {|k| -k.size }
|
73
|
+
keys = Regexp.union @attr_shortcut.keys.sort_by { |k| -k.size }
|
73
74
|
@attr_shortcut_re = /\A(#{keys}+)((?:\p{Word}|-|\/\d+|:(\w|-)+)*)/
|
74
|
-
keys = Regexp.union @tag_shortcut.keys.sort_by {|k| -k.size }
|
75
|
+
keys = Regexp.union @tag_shortcut.keys.sort_by { |k| -k.size }
|
75
76
|
@tag_re = /\A(?:#{keys}|\*(?=[^\s]+)|(\p{Word}(?:\p{Word}|:|-)*\p{Word}|\p{Word}+))/
|
76
77
|
keys = Regexp.escape @code_attr_delims.keys.join
|
77
78
|
@code_attr_delims_re = /\A[#{keys}]/
|
@@ -84,7 +85,7 @@ module Slim
|
|
84
85
|
@code_attr_re = /#{@attr_name}\s*=(=?)\s*/
|
85
86
|
|
86
87
|
splat_prefix = Regexp.escape(options[:splat_prefix])
|
87
|
-
splat_regexp_source = '\A\s*'
|
88
|
+
splat_regexp_source = '\A\s*' + splat_prefix + '(?=[^\s]+)'
|
88
89
|
@splat_attrs_regexp = Regexp.new(splat_regexp_source)
|
89
90
|
end
|
90
91
|
|
@@ -335,7 +336,13 @@ module Slim
|
|
335
336
|
# The class/id attribute is :static instead of :slim :interpolate,
|
336
337
|
# because we don't want text interpolation in .class or #id shortcut
|
337
338
|
syntax_error!('Illegal shortcut') unless shortcut = @attr_shortcut[$1]
|
338
|
-
|
339
|
+
|
340
|
+
if shortcut.is_a?(Proc)
|
341
|
+
shortcut.call($2).each { |a, v| attributes << [:html, :attr, a, [:static, v]] }
|
342
|
+
else
|
343
|
+
shortcut.each {|a| attributes << [:html, :attr, a, [:static, $2]] }
|
344
|
+
end
|
345
|
+
|
339
346
|
if additional_attr_pairs = @additional_attrs[$1]
|
340
347
|
additional_attr_pairs.each do |k,v|
|
341
348
|
attributes << [:html, :attr, k.to_s, [:static, v]]
|
@@ -461,7 +468,7 @@ module Slim
|
|
461
468
|
end
|
462
469
|
|
463
470
|
def parse_ruby_code(outer_delimiter)
|
464
|
-
code, count, delimiter, close_delimiter = '', 0, nil, nil
|
471
|
+
code, count, delimiter, close_delimiter = ''.dup, 0, nil, nil
|
465
472
|
|
466
473
|
# Attribute ends with space or attribute delimiter
|
467
474
|
end_re = /\A[\s#{Regexp.escape outer_delimiter.to_s}]/
|
@@ -489,16 +496,16 @@ module Slim
|
|
489
496
|
end
|
490
497
|
|
491
498
|
def parse_quoted_attribute(quote)
|
492
|
-
value, count = '', 0
|
499
|
+
value, count = ''.dup, 0
|
493
500
|
|
494
501
|
until count == 0 && @line[0] == quote[0]
|
495
502
|
if @line =~ /\A(\\)?\Z/
|
496
503
|
value << ($1 ? ' ' : "\n")
|
497
504
|
expect_next_line
|
498
505
|
else
|
499
|
-
if @line[0] ==
|
506
|
+
if @line[0] == '{'
|
500
507
|
count += 1
|
501
|
-
elsif @line[0] ==
|
508
|
+
elsif @line[0] == '}'
|
502
509
|
count -= 1
|
503
510
|
end
|
504
511
|
value << @line.slice!(0)
|
data/lib/slim/railtie.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Slim
|
2
4
|
class Railtie < ::Rails::Railtie
|
3
|
-
initializer
|
5
|
+
initializer 'initialize slim template handler' do
|
4
6
|
ActiveSupport.on_load(:action_view) do
|
5
7
|
Slim::RailsTemplate = Temple::Templates::Rails(Slim::Engine,
|
6
8
|
register_as: :slim,
|
data/lib/slim/smart/escaper.rb
CHANGED
data/lib/slim/smart/filter.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Slim
|
2
3
|
module Smart
|
3
4
|
# Perform newline processing in the
|
@@ -50,13 +51,13 @@ module Slim
|
|
50
51
|
# so we don't have to worry about that at all.
|
51
52
|
block = [:multi]
|
52
53
|
prev = nil
|
53
|
-
last_exp = exps.reject{ |exp| exp.first == :newline }.last unless @active && @append
|
54
|
+
last_exp = exps.reject { |exp| exp.first == :newline }.last unless @active && @append
|
54
55
|
exps.each do |exp|
|
55
56
|
@append = exp.equal?(last_exp)
|
56
57
|
if @active
|
57
58
|
@prepend = false if prev
|
58
59
|
else
|
59
|
-
@prepend = prev && (
|
60
|
+
@prepend = prev && (prev.first != :slim || prev[1] != :text)
|
60
61
|
end
|
61
62
|
block << compile(exp)
|
62
63
|
prev = exp unless exp.first == :newline
|
data/lib/slim/smart/parser.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Slim
|
2
3
|
module Smart
|
3
4
|
# @api private
|
@@ -7,9 +8,9 @@ module Slim
|
|
7
8
|
def initialize(opts = {})
|
8
9
|
super
|
9
10
|
word_re = options[:implicit_text] ? '[_a-z0-9]' : '\p{Word}'
|
10
|
-
attr_keys = Regexp.union(@attr_shortcut.keys.sort_by {|k| -k.size }
|
11
|
+
attr_keys = Regexp.union(@attr_shortcut.keys.sort_by { |k| -k.size })
|
11
12
|
@attr_shortcut_re = /\A(#{attr_keys}+)((?:\p{Word}|-)*)/
|
12
|
-
tag_keys = Regexp.union((@tag_shortcut.keys - @attr_shortcut.keys).sort_by {|k| -k.size }
|
13
|
+
tag_keys = Regexp.union((@tag_shortcut.keys - @attr_shortcut.keys).sort_by { |k| -k.size })
|
13
14
|
@tag_re = /\A(?:#{attr_keys}(?=-*\p{Word})|#{tag_keys}|\*(?=[^\s]+)|(#{word_re}(?:#{word_re}|:|-)*#{word_re}|#{word_re}+))/
|
14
15
|
end
|
15
16
|
|
@@ -24,7 +25,7 @@ module Slim
|
|
24
25
|
end
|
25
26
|
# Found implicit smart text block.
|
26
27
|
if line = @lines.first
|
27
|
-
indent = (
|
28
|
+
indent = (line =~ /\A\s*\Z/ ? @indents.last + 1 : get_indent(line))
|
28
29
|
end
|
29
30
|
@stacks.last << [:slim, :text, :implicit, parse_text_block(@line, indent)]
|
30
31
|
end
|
data/lib/slim/smart.rb
CHANGED
data/lib/slim/splat/builder.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Slim
|
2
3
|
class InvalidAttributeNameError < StandardError; end
|
3
4
|
module Splat
|
4
5
|
# @api private
|
5
6
|
class Builder
|
6
|
-
|
7
|
-
|
7
|
+
# https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
|
8
|
+
INVALID_ATTRIBUTE_NAME_REGEX = /[ \0"'>\/=]/
|
9
|
+
|
8
10
|
def initialize(options)
|
9
11
|
@options = options
|
10
12
|
@attrs = {}
|
@@ -17,7 +19,7 @@ module Slim
|
|
17
19
|
elsif @options[:hyphen_attrs].include?(name) && Hash === value
|
18
20
|
hyphen_attr(name, escape, value)
|
19
21
|
elsif value != false && value != nil
|
20
|
-
attr(name, escape_html(
|
22
|
+
attr(name, escape_html(escape, value))
|
21
23
|
end
|
22
24
|
end
|
23
25
|
|
@@ -33,7 +35,7 @@ module Slim
|
|
33
35
|
end
|
34
36
|
if @attrs[name]
|
35
37
|
if delim = @options[:merge_attrs][name]
|
36
|
-
@attrs[name]
|
38
|
+
@attrs[name] = @attrs[name].to_s + delim + value.to_s
|
37
39
|
else
|
38
40
|
raise("Multiple #{name} attributes specified")
|
39
41
|
end
|
@@ -90,9 +92,9 @@ module Slim
|
|
90
92
|
|
91
93
|
def hyphen_attr(name, escape, value)
|
92
94
|
if Hash === value
|
93
|
-
if @options[:hyphen_underscore_attrs]
|
95
|
+
if @options[:hyphen_underscore_attrs]
|
94
96
|
value.each do |n, v|
|
95
|
-
hyphen_attr("#{name}-#{n.to_s.
|
97
|
+
hyphen_attr("#{name}-#{n.to_s.tr('_', '-')}", escape, v)
|
96
98
|
end
|
97
99
|
else
|
98
100
|
value.each do |n, v|
|
@@ -100,12 +102,12 @@ module Slim
|
|
100
102
|
end
|
101
103
|
end
|
102
104
|
else
|
103
|
-
attr(name, escape_html(
|
105
|
+
attr(name, escape_html(escape, value))
|
104
106
|
end
|
105
107
|
end
|
106
108
|
|
107
109
|
def escape_html(escape, value)
|
108
|
-
return value
|
110
|
+
return value if !escape || value == true
|
109
111
|
@options[:use_html_safe] ? Temple::Utils.escape_html_safe(value) : Temple::Utils.escape_html(value)
|
110
112
|
end
|
111
113
|
end
|
data/lib/slim/splat/filter.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Slim
|
2
3
|
module Splat
|
3
4
|
# @api private
|
@@ -10,7 +11,7 @@ module Slim
|
|
10
11
|
@splat_options = nil
|
11
12
|
exp = compile(exp)
|
12
13
|
if @splat_options
|
13
|
-
opts = options.to_hash.reject {|k,v| !Filter.options.valid_key?(k) }.inspect
|
14
|
+
opts = options.to_hash.reject { |k, v| !Filter.options.valid_key?(k) }.inspect
|
14
15
|
[:multi, [:code, "#{@splat_options} = #{opts}"], exp]
|
15
16
|
else
|
16
17
|
exp
|
@@ -44,7 +45,7 @@ module Slim
|
|
44
45
|
# @param [Array] attrs Array of temple expressions
|
45
46
|
# @return [Array] Compiled temple expression
|
46
47
|
def on_html_attrs(*attrs)
|
47
|
-
if attrs.any? {|attr| splat?(attr) }
|
48
|
+
if attrs.any? { |attr| splat?(attr) }
|
48
49
|
builder, block = make_builder(attrs)
|
49
50
|
[:multi,
|
50
51
|
block,
|
@@ -85,7 +86,7 @@ module Slim
|
|
85
86
|
attr
|
86
87
|
end
|
87
88
|
end
|
88
|
-
|
89
|
+
[builder, result]
|
89
90
|
end
|
90
91
|
end
|
91
92
|
end
|
data/lib/slim/template.rb
CHANGED
data/lib/slim/translator.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'slim'
|
2
3
|
|
3
4
|
module Slim
|
@@ -62,7 +63,7 @@ module Slim
|
|
62
63
|
end
|
63
64
|
|
64
65
|
def call(exp)
|
65
|
-
@text, @captures = '', []
|
66
|
+
@text, @captures = ''.dup, []
|
66
67
|
result = compile(exp)
|
67
68
|
|
68
69
|
text = @translate.call(@text)
|
@@ -89,7 +90,7 @@ module Slim
|
|
89
90
|
define_options :tr_fn
|
90
91
|
|
91
92
|
def call(exp)
|
92
|
-
@captures_count, @captures_var, @text = 0, unique_name, ''
|
93
|
+
@captures_count, @captures_var, @text = 0, unique_name, ''.dup
|
93
94
|
|
94
95
|
result = compile(exp)
|
95
96
|
|
@@ -109,7 +110,7 @@ module Slim
|
|
109
110
|
def on_slim_output(escape, code, content)
|
110
111
|
@captures_count += 1
|
111
112
|
@text << "%#{@captures_count}"
|
112
|
-
[:capture, "#{@captures_var}[#{@captures_count-1}]", [:slim, :output, escape, code, content]]
|
113
|
+
[:capture, "#{@captures_var}[#{@captures_count - 1}]", [:slim, :output, escape, code, content]]
|
113
114
|
end
|
114
115
|
end
|
115
116
|
end
|
data/lib/slim/version.rb
CHANGED
data/lib/slim.rb
CHANGED
data/slim.gemspec
CHANGED
data/test/core/helper.rb
CHANGED
@@ -62,16 +62,8 @@ class TestSlim < Minitest::Test
|
|
62
62
|
end
|
63
63
|
|
64
64
|
def assert_backtrace(ex, from)
|
65
|
-
|
66
|
-
|
67
|
-
if ex.backtrace[0] !~ /^#{Regexp.escape from}/
|
68
|
-
ex.backtrace[1] =~ /([^\s]+:\d+)/
|
69
|
-
assert_equal from, $1
|
70
|
-
end
|
71
|
-
else
|
72
|
-
ex.backtrace[0] =~ /([^\s]+:\d+)/
|
73
|
-
assert_equal from, $1
|
74
|
-
end
|
65
|
+
ex.backtrace[0] =~ /([^\s]+:\d+)/
|
66
|
+
assert_equal from, $1
|
75
67
|
end
|
76
68
|
|
77
69
|
def assert_ruby_syntax_error(from, source, options = {})
|
@@ -121,7 +113,7 @@ class Env
|
|
121
113
|
end
|
122
114
|
|
123
115
|
def hello_world(text = "Hello World from @env", opts = {})
|
124
|
-
text
|
116
|
+
text = text + (opts.to_a * " ") if opts.any?
|
125
117
|
if block_given?
|
126
118
|
"#{text} #{yield} #{text}"
|
127
119
|
else
|
data/test/core/test_commands.rb
CHANGED
@@ -73,23 +73,19 @@ class TestSlimCommands < Minitest::Test
|
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
prepare_common_test DYNAMIC_TEMPLATE, '--locals', data do |out, err|
|
82
|
-
assert err.empty?
|
83
|
-
assert_equal "<p>Hello from slim!</p>\n", out
|
84
|
-
end
|
76
|
+
def test_locals_json
|
77
|
+
data = '{"name":"from slim"}'
|
78
|
+
prepare_common_test DYNAMIC_TEMPLATE, '--locals', data do |out, err|
|
79
|
+
assert err.empty?
|
80
|
+
assert_equal "<p>Hello from slim!</p>\n", out
|
85
81
|
end
|
82
|
+
end
|
86
83
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
end
|
84
|
+
def test_locals_yaml
|
85
|
+
data = "name: from slim"
|
86
|
+
prepare_common_test DYNAMIC_TEMPLATE, '--locals', data do |out, err|
|
87
|
+
assert err.empty?
|
88
|
+
assert_equal "<p>Hello from slim!</p>\n", out
|
93
89
|
end
|
94
90
|
end
|
95
91
|
|
data/test/core/test_encoding.rb
CHANGED
@@ -8,10 +8,10 @@ class TestSlimEncoding < TestSlim
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def test_binary
|
11
|
-
source = "| \xFF\xFF"
|
11
|
+
source = "| \xFF\xFF".dup
|
12
12
|
source.force_encoding(Encoding::BINARY)
|
13
13
|
|
14
|
-
result = "\xFF\xFF"
|
14
|
+
result = "\xFF\xFF".dup
|
15
15
|
result.force_encoding(Encoding::BINARY)
|
16
16
|
|
17
17
|
out = render(source, default_encoding: 'binary')
|
@@ -115,6 +115,54 @@ h1#title This is my title
|
|
115
115
|
source, shortcut: {'^' => {tag: 'script', attr: 'data-binding', additional_attrs: { type: "application/json" }}}
|
116
116
|
end
|
117
117
|
|
118
|
+
def test_render_with_custom_lambda_shortcut
|
119
|
+
begin
|
120
|
+
Slim::Parser.options[:shortcut]['~'] = {attr: ->(v) {{class: "styled-#{v}", id: "id-#{v}"}}}
|
121
|
+
source = %q{
|
122
|
+
~foo Hello
|
123
|
+
}
|
124
|
+
assert_html '<div class="styled-foo" id="id-foo">Hello</div>', source
|
125
|
+
ensure
|
126
|
+
Slim::Parser.options[:shortcut].delete('~')
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_render_with_custom_lambda_shortcut_and_multiple_values
|
131
|
+
begin
|
132
|
+
Slim::Parser.options[:shortcut]['~'] = {attr: ->(v) {{class: "styled-#{v}"}}}
|
133
|
+
source = %q{
|
134
|
+
~foo~bar Hello
|
135
|
+
}
|
136
|
+
assert_html '<div class="styled-foo styled-bar">Hello</div>', source
|
137
|
+
ensure
|
138
|
+
Slim::Parser.options[:shortcut].delete('~')
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def test_render_with_custom_lambda_shortcut_and_existing_class
|
143
|
+
begin
|
144
|
+
Slim::Parser.options[:shortcut]['~'] = {attr: ->(v) {{class: "styled-#{v}"}}}
|
145
|
+
source = %q{
|
146
|
+
~foo.baz Hello
|
147
|
+
}
|
148
|
+
assert_html '<div class="styled-foo baz">Hello</div>', source
|
149
|
+
ensure
|
150
|
+
Slim::Parser.options[:shortcut].delete('~')
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_render_with_existing_class_and_custom_lambda_shortcut
|
155
|
+
begin
|
156
|
+
Slim::Parser.options[:shortcut]['~'] = {attr: ->(v) {{class: "styled-#{v}"}}}
|
157
|
+
source = %q{
|
158
|
+
.baz~foo Hello
|
159
|
+
}
|
160
|
+
assert_html '<div class="baz styled-foo">Hello</div>', source
|
161
|
+
ensure
|
162
|
+
Slim::Parser.options[:shortcut].delete('~')
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
118
166
|
def test_render_with_text_block
|
119
167
|
source = %q{
|
120
168
|
p
|
@@ -106,6 +106,25 @@ ruby:
|
|
106
106
|
assert_ruby_error NameError,"(__TEMPLATE__):4", source
|
107
107
|
end
|
108
108
|
|
109
|
+
def test_embedded_ruby3
|
110
|
+
source = %q{
|
111
|
+
h1 before
|
112
|
+
ruby:
|
113
|
+
a = 1
|
114
|
+
|
115
|
+
h1 between
|
116
|
+
ruby:
|
117
|
+
b = a + 1
|
118
|
+
|
119
|
+
unknown_ruby_method
|
120
|
+
|
121
|
+
c = 3
|
122
|
+
h1 third
|
123
|
+
}
|
124
|
+
|
125
|
+
assert_ruby_error NameError,"(__TEMPLATE__):10", source
|
126
|
+
end
|
127
|
+
|
109
128
|
def test_embedded_markdown
|
110
129
|
source = %q{
|
111
130
|
markdown:
|
data/test/literate/helper.rb
CHANGED
@@ -8,7 +8,7 @@ Slim::Engine.after Slim::Parser, Temple::Filters::Validator, grammar: Slim::Gra
|
|
8
8
|
Slim::Engine.before :Pretty, Temple::Filters::Validator
|
9
9
|
Slim::Engine.set_options tr: false, logic_less: false
|
10
10
|
|
11
|
-
class
|
11
|
+
class Minitest::Spec
|
12
12
|
def render(source, options = {}, &block)
|
13
13
|
Slim::Template.new(options) { source }.render(self, &block)
|
14
14
|
end
|
data/test/literate/run.rb
CHANGED
@@ -63,7 +63,7 @@ class LiterateTest < Temple::Engine
|
|
63
63
|
def on_html(code)
|
64
64
|
raise Temple::FilterError, 'Html block must be preceded by slim block' unless @in_testcase
|
65
65
|
@in_testcase = false
|
66
|
-
result = " html = #{code.inspect}\n"
|
66
|
+
result = " html = #{code.inspect}\n".dup
|
67
67
|
if @opts.empty?
|
68
68
|
result << " _(render(slim)).must_equal html\nend\n"
|
69
69
|
else
|
@@ -312,4 +312,19 @@ div
|
|
312
312
|
'This is the menu'
|
313
313
|
end
|
314
314
|
end
|
315
|
+
|
316
|
+
def test_render_parent_lambda
|
317
|
+
source = %q{
|
318
|
+
- list
|
319
|
+
== fn
|
320
|
+
p = string
|
321
|
+
}
|
322
|
+
|
323
|
+
assert_html '<fn><p>str</p></fn><fn><p>str</p></fn><fn><p>str</p></fn>',
|
324
|
+
source, scope: {
|
325
|
+
fn: ->(&block) { "<fn>#{block.call}</fn>" },
|
326
|
+
list: [ "item1", "item2", "item3" ],
|
327
|
+
string: "str"
|
328
|
+
}
|
329
|
+
end
|
315
330
|
end
|
@@ -26,11 +26,17 @@ class SlimController < ApplicationController
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def thread_options
|
29
|
-
|
29
|
+
default_shortcut = {'#' => {attr: 'id'}, '.' => {attr: 'class'} }
|
30
|
+
Slim::Engine.with_options(shortcut: default_shortcut.merge({'@' => { attr: params[:attr] }})) do
|
30
31
|
render
|
31
32
|
end
|
32
33
|
end
|
33
34
|
|
35
|
+
def variant
|
36
|
+
request.variant = :testvariant
|
37
|
+
render :normal
|
38
|
+
end
|
39
|
+
|
34
40
|
def content_for
|
35
41
|
@hello = "Hello Slim!"
|
36
42
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
.cute *{class: "nice"} Hello
|