slim 2.0.2 → 2.0.3
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/.travis.yml +16 -13
- data/CHANGES +9 -0
- data/Gemfile +8 -2
- data/README.jp.md +968 -0
- data/README.md +25 -4
- data/lib/slim/code_attributes.rb +1 -1
- data/lib/slim/command.rb +13 -13
- data/lib/slim/controls.rb +5 -3
- data/lib/slim/end_inserter.rb +7 -6
- data/lib/slim/engine.rb +2 -1
- data/lib/slim/parser.rb +4 -3
- data/lib/slim/splat/builder.rb +13 -15
- data/lib/slim/splat/filter.rb +1 -1
- data/lib/slim/version.rb +1 -1
- data/test/core/test_code_blocks.rb +53 -0
- data/test/core/test_embedded_engines.rb +1 -0
- data/test/literate/TESTS.md +64 -2
- data/test/rails/test/test_slim.rb +4 -2
- metadata +15 -14
data/README.md
CHANGED
@@ -555,7 +555,7 @@ This is the same as
|
|
555
555
|
div class="content"
|
556
556
|
= show_content
|
557
557
|
|
558
|
-
## Helpers and
|
558
|
+
## Helpers, capturing and includes
|
559
559
|
|
560
560
|
If you use Slim you might want to extend your template with some helpers. Assume that you have the following helper
|
561
561
|
|
@@ -574,7 +574,7 @@ module Helpers
|
|
574
574
|
end
|
575
575
|
~~~
|
576
576
|
|
577
|
-
which can be used in Slim as follows
|
577
|
+
which is included in the scope that executes the Slim template code. The helper can then be used in the Slim template as follows
|
578
578
|
|
579
579
|
p
|
580
580
|
= headline do
|
@@ -589,6 +589,25 @@ sugar you can omit the `do` keyword and write only
|
|
589
589
|
' Hello
|
590
590
|
= user.name
|
591
591
|
|
592
|
+
It has been requested many times to support includes of subtemplates in Slim. Up to now this has not been implemented as a core feature
|
593
|
+
but you can easily get it by writing your own helper. The includes will be executed at runtime.
|
594
|
+
|
595
|
+
~~~ruby
|
596
|
+
module Helpers
|
597
|
+
def include_slim(name, options = {}, &block)
|
598
|
+
Slim::Template.new("#{name}.slim", options).render(self, &block)
|
599
|
+
end
|
600
|
+
end
|
601
|
+
~~~
|
602
|
+
|
603
|
+
This helper can then be used as follows
|
604
|
+
|
605
|
+
nav= include_slim 'menu'
|
606
|
+
section= include_slim 'content'
|
607
|
+
|
608
|
+
However this helper doesn't do any caching. You should therefore implement a more intelligent version of the helper which
|
609
|
+
fits your purposes. You should also be aware that most frameworks already bring their own include helper, e.g. Rails has `render`.
|
610
|
+
|
592
611
|
## Text interpolation
|
593
612
|
|
594
613
|
Use standard Ruby interpolation. The text will be html escaped by default.
|
@@ -754,7 +773,8 @@ Slim uses [Tilt](https://github.com/rtomayko/tilt) to compile the generated code
|
|
754
773
|
Slim::Template.new('template.slim', optional_option_hash).render(scope)
|
755
774
|
Slim::Template.new(optional_option_hash) { source }.render(scope)
|
756
775
|
|
757
|
-
The optional option hash can have to options which were documented in the section above.
|
776
|
+
The optional option hash can have to options which were documented in the section above. The scope is the object in which the template
|
777
|
+
code is executed.
|
758
778
|
|
759
779
|
### Sinatra
|
760
780
|
|
@@ -805,7 +825,7 @@ Usage: slimrb [options]
|
|
805
825
|
-v, --version Print version
|
806
826
|
</pre>
|
807
827
|
|
808
|
-
Start 'slimrb', type your code and press Ctrl-d to send EOF. Example usage:
|
828
|
+
Start 'slimrb', type your code and press Ctrl-d to send EOF. In Windows Command Prompt press Ctrl-z, Enter to send EOF. Example usage:
|
809
829
|
|
810
830
|
<pre>
|
811
831
|
$ slimrb
|
@@ -930,6 +950,7 @@ Syntax highlighting:
|
|
930
950
|
* [Textmate / Sublime Text](https://github.com/slim-template/ruby-slim.tmbundle)
|
931
951
|
* [Espresso text editor](https://github.com/slim-template/Slim-Sugar)
|
932
952
|
* [Coda](https://github.com/slim-template/Coda-2-Slim.mode)
|
953
|
+
* [Atom](https://github.com/slim-template/language-slim)
|
933
954
|
|
934
955
|
Template Converters (HAML, ERB, ...):
|
935
956
|
|
data/lib/slim/code_attributes.rb
CHANGED
data/lib/slim/command.rb
CHANGED
@@ -17,13 +17,6 @@ module Slim
|
|
17
17
|
@opts = OptionParser.new(&method(:set_opts))
|
18
18
|
@opts.parse!(@args)
|
19
19
|
process
|
20
|
-
exit 0
|
21
|
-
rescue Exception => ex
|
22
|
-
raise ex if @options[:trace] || SystemExit === ex
|
23
|
-
$stderr.print "#{ex.class}: " if ex.class != RuntimeError
|
24
|
-
$stderr.puts ex.message
|
25
|
-
$stderr.puts ' Use --trace for backtrace.'
|
26
|
-
exit 1
|
27
20
|
end
|
28
21
|
|
29
22
|
private
|
@@ -93,11 +86,6 @@ module Slim
|
|
93
86
|
end
|
94
87
|
end
|
95
88
|
|
96
|
-
unless @options[:output]
|
97
|
-
file = args.shift
|
98
|
-
@options[:output] = file ? File.open(file, 'w') : $stdout
|
99
|
-
end
|
100
|
-
|
101
89
|
result =
|
102
90
|
if @options[:erb]
|
103
91
|
require 'slim/erb_converter'
|
@@ -108,7 +96,19 @@ module Slim
|
|
108
96
|
Template.new(@options[:file]) { @options[:input].read }.render
|
109
97
|
end
|
110
98
|
|
111
|
-
|
99
|
+
rescue Exception => ex
|
100
|
+
raise ex if @options[:trace] || SystemExit === ex
|
101
|
+
$stderr.print "#{ex.class}: " if ex.class != RuntimeError
|
102
|
+
$stderr.puts ex.message
|
103
|
+
$stderr.puts ' Use --trace for backtrace.'
|
104
|
+
exit 1
|
105
|
+
else
|
106
|
+
unless @options[:output]
|
107
|
+
file = args.shift
|
108
|
+
@options[:output] = file ? File.open(file, 'w') : $stdout
|
109
|
+
end
|
110
|
+
@options[:output].puts(result)
|
111
|
+
exit 0
|
112
112
|
end
|
113
113
|
end
|
114
114
|
end
|
data/lib/slim/controls.rb
CHANGED
@@ -3,6 +3,8 @@ module Slim
|
|
3
3
|
class Controls < Filter
|
4
4
|
define_options :disable_capture
|
5
5
|
|
6
|
+
IF_RE = /\A(if|unless)\b|do\s*(\|[^\|]*\|)?\s*$/
|
7
|
+
|
6
8
|
# Handle control expression `[:slim, :control, code, content]`
|
7
9
|
#
|
8
10
|
# @param [String] code Ruby code
|
@@ -21,9 +23,7 @@ module Slim
|
|
21
23
|
# @param [Array] content Temple expression
|
22
24
|
# @return [Array] Compiled temple expression
|
23
25
|
def on_slim_output(escape, code, content)
|
24
|
-
if
|
25
|
-
[:multi, [:escape, escape, [:dynamic, code]], content]
|
26
|
-
else
|
26
|
+
if code =~ IF_RE
|
27
27
|
tmp = unique_name
|
28
28
|
|
29
29
|
[:multi,
|
@@ -43,6 +43,8 @@ module Slim
|
|
43
43
|
|
44
44
|
# Output the content.
|
45
45
|
[:escape, escape, [:dynamic, tmp]]]
|
46
|
+
else
|
47
|
+
[:multi, [:escape, escape, [:dynamic, code]], content]
|
46
48
|
end
|
47
49
|
end
|
48
50
|
|
data/lib/slim/end_inserter.rb
CHANGED
@@ -10,8 +10,9 @@ module Slim
|
|
10
10
|
#
|
11
11
|
# @api private
|
12
12
|
class EndInserter < Filter
|
13
|
-
|
14
|
-
|
13
|
+
IF_RE = /\A(if|unless|else|elsif|when|rescue|ensure)\b|do\s*(\|[^\|]*\|)?\s*$/
|
14
|
+
ELSE_RE = /\A(else|elsif|when|rescue|ensure)\b/
|
15
|
+
END_RE = /\Aend\b/
|
15
16
|
|
16
17
|
# Handle multi expression `[:multi, *exps]`
|
17
18
|
#
|
@@ -24,14 +25,14 @@ module Slim
|
|
24
25
|
|
25
26
|
exps.each do |exp|
|
26
27
|
if control?(exp)
|
27
|
-
raise(Temple::FilterError, 'Explicit end statements are forbidden') if exp[2] =~
|
28
|
+
raise(Temple::FilterError, 'Explicit end statements are forbidden') if exp[2] =~ END_RE
|
28
29
|
|
29
30
|
# Two control code in a row. If this one is *not*
|
30
31
|
# an else block, we should close the previous one.
|
31
|
-
append_end(result) if prev_indent && exp[2] !~
|
32
|
+
append_end(result) if prev_indent && exp[2] !~ ELSE_RE
|
32
33
|
|
33
|
-
# Indent if the control code
|
34
|
-
prev_indent =
|
34
|
+
# Indent if the control code starts a block.
|
35
|
+
prev_indent = exp[2] =~ IF_RE
|
35
36
|
elsif exp[0] != :newline && prev_indent
|
36
37
|
# This is *not* a control code, so we should close the previous one.
|
37
38
|
# Ignores newlines because they will be inserted after each line.
|
data/lib/slim/engine.rb
CHANGED
@@ -7,6 +7,7 @@ module Slim
|
|
7
7
|
# `define_options` when you have to override some default settings.
|
8
8
|
define_options :pretty => false,
|
9
9
|
:sort_attrs => true,
|
10
|
+
:format => :xhtml,
|
10
11
|
:attr_quote => '"',
|
11
12
|
:merge_attrs => {'class' => ' '},
|
12
13
|
:generator => Temple::Generators::ArrayBuffer,
|
@@ -17,7 +18,7 @@ module Slim
|
|
17
18
|
use Slim::Parser, :file, :tabsize, :shortcut, :default_tag, :attr_delims
|
18
19
|
use Slim::Embedded, :enable_engines, :disable_engines, :pretty
|
19
20
|
use Slim::Interpolation
|
20
|
-
use Slim::Splat::Filter, :merge_attrs, :attr_quote, :sort_attrs, :default_tag, :hyphen_attrs
|
21
|
+
use Slim::Splat::Filter, :merge_attrs, :attr_quote, :sort_attrs, :default_tag, :hyphen_attrs, :format
|
21
22
|
use Slim::DoInserter
|
22
23
|
use Slim::EndInserter
|
23
24
|
use Slim::Controls, :disable_capture
|
data/lib/slim/parser.rb
CHANGED
@@ -58,7 +58,7 @@ module Slim
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
keys = Regexp.union @attr_shortcut.keys.sort_by {|k| -k.size }
|
61
|
-
@attr_shortcut_re = /\A(#{keys}+)(
|
61
|
+
@attr_shortcut_re = /\A(#{keys}+)((?:#{WORD_RE}|-)*)/
|
62
62
|
keys = Regexp.union @tag_shortcut.keys.sort_by {|k| -k.size }
|
63
63
|
@tag_re = /\A(?:#{keys}|\*(?=[^\s]+)|(#{WORD_RE}(?:#{WORD_RE}|:|-)*#{WORD_RE}|#{WORD_RE}+))/
|
64
64
|
keys = Regexp.escape options[:attr_delims].keys.join
|
@@ -338,8 +338,9 @@ module Slim
|
|
338
338
|
# Handle output code
|
339
339
|
@line = $'
|
340
340
|
trailing_ws2 = $2.include?('\'') || $2.include?('>')
|
341
|
+
leading_ws2 = $2.include?('<')
|
341
342
|
block = [:multi]
|
342
|
-
@stacks.last
|
343
|
+
@stacks.last.insert(-2, [:static, ' ']) if !leading_ws && $2.include?('<')
|
343
344
|
tag << [:slim, :output, $1 != '=', parse_broken_line, block]
|
344
345
|
@stacks.last << [:static, ' '] if !trailing_ws && trailing_ws2
|
345
346
|
@stacks << block
|
@@ -397,7 +398,7 @@ module Slim
|
|
397
398
|
when boolean_attr_re
|
398
399
|
# Boolean attribute
|
399
400
|
@line = $'
|
400
|
-
attributes << [:html, :attr, $1, [:
|
401
|
+
attributes << [:html, :attr, $1, [:multi]]
|
401
402
|
when end_re
|
402
403
|
# Find ending delimiter
|
403
404
|
@line = $'
|
data/lib/slim/splat/builder.rb
CHANGED
@@ -13,18 +13,8 @@ module Slim
|
|
13
13
|
attr(name, escape ? Temple::Utils.escape_html(value) : value) unless value.empty?
|
14
14
|
elsif @options[:hyphen_attrs].include?(name) && Hash === value
|
15
15
|
hyphen_attr(name, escape, value)
|
16
|
-
|
17
|
-
|
18
|
-
when false, nil
|
19
|
-
# Boolean false attribute
|
20
|
-
return
|
21
|
-
when true
|
22
|
-
# Boolean true attribute
|
23
|
-
value = ''
|
24
|
-
else
|
25
|
-
value = value.to_s
|
26
|
-
end
|
27
|
-
attr(name, escape ? Temple::Utils.escape_html(value) : value)
|
16
|
+
elsif value != false && value != nil
|
17
|
+
attr(name, value != true && escape ? Temple::Utils.escape_html(value) : value)
|
28
18
|
end
|
29
19
|
end
|
30
20
|
|
@@ -37,7 +27,7 @@ module Slim
|
|
37
27
|
def attr(name, value)
|
38
28
|
if @attrs[name]
|
39
29
|
if delim = @options[:merge_attrs][name]
|
40
|
-
@attrs[name] << delim << value
|
30
|
+
@attrs[name] << delim << value.to_s
|
41
31
|
else
|
42
32
|
raise("Multiple #{name} attributes specified")
|
43
33
|
end
|
@@ -59,7 +49,15 @@ module Slim
|
|
59
49
|
def build_attrs
|
60
50
|
attrs = @options[:sort_attrs] ? @attrs.sort_by(&:first) : @attrs
|
61
51
|
attrs.map do |k, v|
|
62
|
-
|
52
|
+
if v == true
|
53
|
+
if @options[:format] == :xhtml
|
54
|
+
" #{k}=#{@options[:attr_quote]}#{@options[:attr_quote]}"
|
55
|
+
else
|
56
|
+
" #{k}"
|
57
|
+
end
|
58
|
+
else
|
59
|
+
" #{k}=#{@options[:attr_quote]}#{v}#{@options[:attr_quote]}"
|
60
|
+
end
|
63
61
|
end.join
|
64
62
|
end
|
65
63
|
|
@@ -71,7 +69,7 @@ module Slim
|
|
71
69
|
hyphen_attr("#{name}-#{n.to_s.gsub('_', '-')}", escape, v)
|
72
70
|
end
|
73
71
|
else
|
74
|
-
attr(name, escape ? Temple::Utils.escape_html(value) : value
|
72
|
+
attr(name, value != true && escape ? Temple::Utils.escape_html(value) : value)
|
75
73
|
end
|
76
74
|
end
|
77
75
|
end
|
data/lib/slim/splat/filter.rb
CHANGED
@@ -2,7 +2,7 @@ module Slim
|
|
2
2
|
module Splat
|
3
3
|
# @api private
|
4
4
|
class Filter < ::Slim::Filter
|
5
|
-
OPTIONS = [:merge_attrs, :attr_quote, :sort_attrs, :default_tag, :hyphen_attrs]
|
5
|
+
OPTIONS = [:merge_attrs, :attr_quote, :sort_attrs, :default_tag, :hyphen_attrs, :format]
|
6
6
|
define_options OPTIONS
|
7
7
|
default_options[:hyphen_attrs] = %w(data aria)
|
8
8
|
|
data/lib/slim/version.rb
CHANGED
@@ -116,4 +116,57 @@ p
|
|
116
116
|
|
117
117
|
assert_html 'Hello Ruby! Hello from within a block! Hello Ruby!', source
|
118
118
|
end
|
119
|
+
|
120
|
+
def test_if_without_content
|
121
|
+
source = %q{
|
122
|
+
- if true
|
123
|
+
}
|
124
|
+
assert_html '', source
|
125
|
+
end
|
126
|
+
|
127
|
+
def test_unless_without_content
|
128
|
+
source = %q{
|
129
|
+
- unless true
|
130
|
+
}
|
131
|
+
assert_html '', source
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_if_with_comment
|
135
|
+
source = %q{
|
136
|
+
- if true
|
137
|
+
/ comment
|
138
|
+
}
|
139
|
+
assert_html '', source
|
140
|
+
end
|
141
|
+
|
142
|
+
def test_control_do_with_comment
|
143
|
+
source = %q{
|
144
|
+
- hello_world "Hello"
|
145
|
+
/ comment
|
146
|
+
}
|
147
|
+
assert_html '', source
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_output_do_with_comment
|
151
|
+
source = %q{
|
152
|
+
= hello_world "Hello"
|
153
|
+
/ comment
|
154
|
+
}
|
155
|
+
assert_html 'Hello', source
|
156
|
+
end
|
157
|
+
|
158
|
+
def test_output_if_without_content
|
159
|
+
source = %q{
|
160
|
+
= if true
|
161
|
+
}
|
162
|
+
assert_html '', source
|
163
|
+
end
|
164
|
+
|
165
|
+
def test_output_if_with_comment
|
166
|
+
source = %q{
|
167
|
+
= if true
|
168
|
+
/ comment
|
169
|
+
}
|
170
|
+
assert_html '', source
|
171
|
+
end
|
119
172
|
end
|
data/test/literate/TESTS.md
CHANGED
@@ -410,6 +410,16 @@ renders as
|
|
410
410
|
49
|
411
411
|
~~~
|
412
412
|
|
413
|
+
~~~ slim
|
414
|
+
=< 7*7
|
415
|
+
~~~
|
416
|
+
|
417
|
+
renders as
|
418
|
+
|
419
|
+
~~~ html
|
420
|
+
49
|
421
|
+
~~~
|
422
|
+
|
413
423
|
The legacy syntax `='` is also supported.
|
414
424
|
|
415
425
|
~~~ slim
|
@@ -705,13 +715,14 @@ You can force a trailing whitespace behind a tag by adding `>`. The legacy synta
|
|
705
715
|
a#closed> class="test" /
|
706
716
|
a#closed> class="test"/
|
707
717
|
a> href='url1' Link1
|
718
|
+
a< href='url1' Link1
|
708
719
|
a' href='url2' Link2
|
709
720
|
~~~
|
710
721
|
|
711
722
|
renders as
|
712
723
|
|
713
724
|
~~~ html
|
714
|
-
<a class="test" id="closed" /> <a class="test" id="closed" /> <a href="url1">Link1</a>
|
725
|
+
<a class="test" id="closed" /> <a class="test" id="closed" /> <a href="url1">Link1</a> <a href="url1">Link1</a><a href="url2">Link2</a>
|
715
726
|
~~~
|
716
727
|
|
717
728
|
If you combine > and =' only one trailing whitespace is added.
|
@@ -721,12 +732,15 @@ a> =' 'Text1'
|
|
721
732
|
a =' 'Text2'
|
722
733
|
a> = 'Text3'
|
723
734
|
a>= 'Text4'
|
735
|
+
a=> 'Text5'
|
736
|
+
a<= 'Text6'
|
737
|
+
a=< 'Text7'
|
724
738
|
~~~
|
725
739
|
|
726
740
|
renders as
|
727
741
|
|
728
742
|
~~~ html
|
729
|
-
<a>Text1</a> <a>Text2</a> <a>Text3</a> <a>Text4</a>
|
743
|
+
<a>Text1</a> <a>Text2</a> <a>Text3</a> <a>Text4</a> <a>Text5</a> <a>Text6</a> <a>Text7</a>
|
730
744
|
~~~
|
731
745
|
|
732
746
|
You can force a leading whitespace before a tag by adding `<`.
|
@@ -1008,6 +1022,28 @@ renders as
|
|
1008
1022
|
<input type="text" /><input type="text" /><input type="text" /><input type="text" /><input type="text" />
|
1009
1023
|
~~~
|
1010
1024
|
|
1025
|
+
If html5 is activated the attributes are written as standalone.
|
1026
|
+
|
1027
|
+
~~~ options
|
1028
|
+
:format => :html
|
1029
|
+
~~~
|
1030
|
+
|
1031
|
+
~~~ slim
|
1032
|
+
- true_value1 = ""
|
1033
|
+
- true_value2 = true
|
1034
|
+
input type="text" disabled=true_value1
|
1035
|
+
input type="text" disabled=true_value2
|
1036
|
+
input type="text" disabled="disabled"
|
1037
|
+
input type="text" disabled=true
|
1038
|
+
input(type="text" disabled)
|
1039
|
+
~~~
|
1040
|
+
|
1041
|
+
renders as
|
1042
|
+
|
1043
|
+
~~~ html
|
1044
|
+
<input disabled="" type="text"><input disabled type="text"><input disabled="disabled" type="text"><input disabled type="text"><input disabled type="text">
|
1045
|
+
~~~
|
1046
|
+
|
1011
1047
|
#### Attribute merging
|
1012
1048
|
|
1013
1049
|
You can configure attributes to be merged if multiple are given (See option `:merge_attrs`). In the default configuration
|
@@ -1160,6 +1196,32 @@ renders to
|
|
1160
1196
|
|
1161
1197
|
#### ID shortcut and class shortcut `.`
|
1162
1198
|
|
1199
|
+
ID and class shortcuts can contain dashes.
|
1200
|
+
|
1201
|
+
~~~ slim
|
1202
|
+
.-test text
|
1203
|
+
#test- text
|
1204
|
+
.--a#b- text
|
1205
|
+
.a--test-123#--b text
|
1206
|
+
~~~
|
1207
|
+
|
1208
|
+
renders as
|
1209
|
+
|
1210
|
+
~~~ html
|
1211
|
+
<div class="-test">
|
1212
|
+
text
|
1213
|
+
</div>
|
1214
|
+
<div id="test-">
|
1215
|
+
text
|
1216
|
+
</div>
|
1217
|
+
<div class="--a" id="b-">
|
1218
|
+
text
|
1219
|
+
</div>
|
1220
|
+
<div class="a--test-123" id="--b">
|
1221
|
+
text
|
1222
|
+
</div>
|
1223
|
+
~~~
|
1224
|
+
|
1163
1225
|
## Text interpolation
|
1164
1226
|
|
1165
1227
|
Use standard Ruby interpolation. The text will be html escaped by default.
|