slim 0.9.1 → 0.9.2

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.
data/README.md CHANGED
@@ -288,24 +288,29 @@ There are two helpers you could use to validate your Slim syntax:
288
288
  # OS X 10.6 + Ruby 1.9.2, 1000 iterations
289
289
 
290
290
  user system total real
291
- (1) erb 0.420000 0.000000 0.420000 ( 0.429334)
292
- (1) erubis 0.350000 0.000000 0.350000 ( 0.356078)
293
- (1) fast erubis 0.350000 0.000000 0.350000 ( 0.355976)
294
- (1) slim 3.300000 0.010000 3.310000 ( 3.340637)
295
- (1) haml 2.950000 0.000000 2.950000 ( 2.970671)
296
- (1) haml ugly 2.840000 0.010000 2.850000 ( 2.856405)
297
- (2) erb 0.150000 0.000000 0.150000 ( 0.151098)
298
- (2) erubis 0.130000 0.000000 0.130000 ( 0.130713)
299
- (2) fast erubis 0.100000 0.000000 0.100000 ( 0.112199)
300
- (2) slim 0.030000 0.000000 0.030000 ( 0.027752)
301
- (2) haml 0.320000 0.000000 0.320000 ( 0.332581)
302
- (2) haml ugly 0.280000 0.000000 0.280000 ( 0.305250)
303
- (3) erb 0.010000 0.000000 0.010000 ( 0.014402)
304
- (3) erubis 0.010000 0.000000 0.010000 ( 0.015365)
305
- (3) fast erubis 0.010000 0.000000 0.010000 ( 0.012789)
306
- (3) slim 0.010000 0.000000 0.010000 ( 0.015583)
307
- (3) haml 0.120000 0.000000 0.120000 ( 0.120017)
308
- (3) haml ugly 0.100000 0.010000 0.110000 ( 0.117665)
291
+ (1) erb 0.310000 0.000000 0.310000 ( 0.311769)
292
+ (1) erubis 0.250000 0.000000 0.250000 ( 0.252026)
293
+ (1) fast erubis 0.250000 0.000000 0.250000 ( 0.257639)
294
+ (1) slim 3.250000 0.040000 3.290000 ( 3.282734)
295
+ (1) haml 2.230000 0.000000 2.230000 ( 2.237396)
296
+ (1) haml ugly 2.160000 0.000000 2.160000 ( 2.154061)
297
+ (2) erb 0.100000 0.000000 0.100000 ( 0.107232)
298
+ (2) erubis 0.090000 0.000000 0.090000 ( 0.087301)
299
+ (2) fast erubis 0.080000 0.000000 0.080000 ( 0.073382)
300
+ (2) slim 0.020000 0.000000 0.020000 ( 0.017364)
301
+ (2) haml 0.240000 0.010000 0.250000 ( 0.234680)
302
+ (2) haml ugly 0.200000 0.000000 0.200000 ( 0.209600)
303
+ (3) erb 0.010000 0.000000 0.010000 ( 0.010558)
304
+ (3) erubis 0.010000 0.000000 0.010000 ( 0.008676)
305
+ (3) fast erubis 0.010000 0.000000 0.010000 ( 0.009134)
306
+ (3) slim 0.010000 0.000000 0.010000 ( 0.012114)
307
+ (3) haml 0.090000 0.000000 0.090000 ( 0.086450)
308
+ (3) haml ugly 0.070000 0.000000 0.070000 ( 0.078825)
309
+ (4) erb 0.020000 0.000000 0.020000 ( 0.015715)
310
+ (4) erubis 0.010000 0.000000 0.010000 ( 0.014027)
311
+ (4) slim 0.020000 0.000000 0.020000 ( 0.017591)
312
+ (4) haml 0.100000 0.000000 0.100000 ( 0.098249)
313
+ (4) haml ugly 0.090000 0.000000 0.090000 ( 0.089413)
309
314
 
310
315
  1. Uncached benchmark. Template is parsed every time.
311
316
  Activate this benchmark with slow=1.
@@ -319,6 +324,11 @@ There are two helpers you could use to validate your Slim syntax:
319
324
  This is the fastest evaluation strategy because it benchmarks
320
325
  pure execution speed of the generated ruby code.
321
326
 
327
+ 4. Compiled Tilt benchmark. Template is compiled with Tilt, which gives a more
328
+ accurate result of the performance in production mode in frameworks like
329
+ Sinatra, Ramaze and Camping. (Rails still uses its own template
330
+ compilation.)
331
+
322
332
  ## License
323
333
 
324
334
  This project is released under the MIT license.
@@ -335,6 +345,7 @@ This project is released under the MIT license.
335
345
 
336
346
  ## Slim related projects
337
347
 
348
+ * [Vim files](https://github.com/bbommarito/vim-slim)
338
349
  * [Textmate bundle](https://github.com/fredwu/ruby-slim-textmate-bundle)
339
350
  * [Haml2Slim converter](https://github.com/fredwu/haml2slim)
340
351
  * [Rails 3 Generators](https://github.com/leogalmeida/slim-rails)
data/lib/slim/command.rb CHANGED
@@ -40,6 +40,10 @@ module Slim
40
40
  @options[:compile] = true
41
41
  end
42
42
 
43
+ opts.on('-r', '--rails', :NONE, 'Generate rails compatible code (combine with -c)') do
44
+ @options[:rails] = true
45
+ end
46
+
43
47
  opts.on('-S', '--sections', :NONE, 'Logic-less sections mode') do
44
48
  @options[:sections] = true
45
49
  end
@@ -48,6 +52,10 @@ module Slim
48
52
  @options[:pretty] = true
49
53
  end
50
54
 
55
+ opts.on('-d', '--debug', :NONE, 'Debugging output') do
56
+ @options[:debug] = true
57
+ end
58
+
51
59
  opts.on_tail('-h', '--help', 'Show this message') do
52
60
  puts opts
53
61
  exit
@@ -81,10 +89,16 @@ module Slim
81
89
  if @options[:compile]
82
90
  @options[:output].puts(Slim::Engine.new(:file => @options[:file],
83
91
  :pretty => @options[:pretty],
84
- :sections => @options[:sections]).compile(@options[:input].read))
92
+ :sections => @options[:sections],
93
+ :disable_capture => @options[:rails],
94
+ :debug => @options[:debug],
95
+ :generator => @options[:rails] ?
96
+ Temple::Generators::RailsOutputBuffer :
97
+ Temple::Generators::ArrayBuffer).call(@options[:input].read))
85
98
  else
86
99
  @options[:output].puts(Slim::Template.new(@options[:file],
87
100
  :pretty => @options[:pretty],
101
+ :debug => @options[:debug],
88
102
  :sections => @options[:sections]) { @options[:input].read }.render)
89
103
  end
90
104
  end
data/lib/slim/compiler.rb CHANGED
@@ -12,7 +12,7 @@ module Slim
12
12
  def on_slim_control(code, content)
13
13
  [:multi,
14
14
  [:block, code],
15
- compile!(content)]
15
+ compile(content)]
16
16
  end
17
17
 
18
18
  # Handle comment expression `[:slim, :comment, content]`
@@ -20,7 +20,7 @@ module Slim
20
20
  # @param [Array] content Temple expression
21
21
  # @return [Array] Compiled temple expression
22
22
  def on_slim_comment(content)
23
- [:html, :comment, compile!(content)]
23
+ [:html, :comment, compile(content)]
24
24
  end
25
25
 
26
26
  # Handle output expression `[:slim, :output, escape, code, content]`
@@ -31,7 +31,7 @@ module Slim
31
31
  # @return [Array] Compiled temple expression
32
32
  def on_slim_output(escape, code, content)
33
33
  if empty_exp?(content)
34
- [:multi, escape && options[:auto_escape] ? [:escape, :dynamic, code] : [:dynamic, code], content]
34
+ [:multi, [:escape, escape && options[:auto_escape], [:dynamic, code]], content]
35
35
  else
36
36
  on_slim_output_block(escape, code, content)
37
37
  end
@@ -45,7 +45,7 @@ module Slim
45
45
  # @param [Array] content Temple expression
46
46
  # @return [Array] Compiled temple expression
47
47
  def on_slim_output_block(escape, code, content)
48
- tmp = tmp_var('capture')
48
+ tmp = tmp_var(:output)
49
49
 
50
50
  [:multi,
51
51
  # Capture the result of the code in a variable. We can't do
@@ -60,7 +60,7 @@ module Slim
60
60
  # The capturing can be disabled with the option :disable_capture.
61
61
  # Output code in the block writes directly to the output buffer then.
62
62
  # Rails handles this by replacing the output buffer for helpers (with_output_buffer - braindead!).
63
- options[:disable_capture] ? compile!(content) : [:capture, tmp_var('capture'), compile!(content)],
63
+ options[:disable_capture] ? compile(content) : [:capture, tmp_var(:output), compile(content)],
64
64
 
65
65
  # Close the block.
66
66
  [:block, 'end'],
@@ -74,8 +74,11 @@ module Slim
74
74
  # @param [String] type Directive type
75
75
  # @return [Array] Compiled temple expression
76
76
  def on_slim_directive(type, args)
77
- if type == 'doctype'
77
+ case type
78
+ when 'doctype'
78
79
  [:html, :doctype, args]
80
+ else
81
+ raise "Invalid directive #{type}"
79
82
  end
80
83
  end
81
84
 
@@ -86,7 +89,7 @@ module Slim
86
89
  # @param [Array] content Temple expression
87
90
  # @return [Array] Compiled temple expression
88
91
  def on_slim_tag(name, attrs, closed, content)
89
- [:html, :tag, name, compile!(attrs), closed, compile!(content)]
92
+ [:html, :tag, name, compile(attrs), closed, compile(content)]
90
93
  end
91
94
 
92
95
  # Handle tag attributes expression `[:slim, :attrs, *attrs]`
@@ -94,7 +97,7 @@ module Slim
94
97
  # @param [Array] attrs Attributes
95
98
  # @return [Array] Compiled temple expression
96
99
  def on_slim_attrs(*attrs)
97
- [:html, :staticattrs, *attrs.map {|k, v| [k.to_s, compile!(v)] }]
100
+ [:html, :staticattrs, *attrs.map {|k, v| [k.to_s, compile(v)] }]
98
101
  end
99
102
  end
100
103
  end
@@ -4,21 +4,26 @@ module Slim
4
4
  class EmbeddedEngine < Filter
5
5
  @engines = {}
6
6
 
7
- def self.register(name, klass, options = {})
8
- @engines[name.to_s] = klass.new(options)
9
- end
7
+ class << self
8
+ attr_reader :engines
10
9
 
11
- def self.[](name)
12
- engine = @engines[name.to_s]
13
- raise "Invalid embedded engine #{name}" if !engine
14
- engine.dup
10
+ def register(name, klass, *option_filter)
11
+ local_options = Hash === option_filter.last ? option_filter.pop : nil
12
+ @engines[name.to_s] = [klass, option_filter, local_options]
13
+ end
15
14
  end
16
15
 
17
- def on_slim_embedded(name, *body)
18
- engine = EmbeddedEngine[name]
16
+ def new_engine(name)
17
+ name = name.to_s
19
18
  raise "Embedded engine #{name} is disabled" if (options[:enable_engines] && !options[:enable_engines].include?(name)) ||
20
19
  (options[:disable_engines] && options[:disable_engines].include?(name))
21
- engine.on_slim_embedded(name, *body)
20
+ engine, option_filter, local_options = self.class.engines[name] || raise("Embedded engine #{name} not found")
21
+ filtered_options = Hash[*option_filter.select {|k| options.include?(k) }.map {|k| [k, options[k]] }.flatten]
22
+ engine.new(Temple::Utils::ImmutableHash.new(local_options, filtered_options))
23
+ end
24
+
25
+ def on_slim_embedded(name, *body)
26
+ new_engine(name).on_slim_embedded(name, *body)
22
27
  end
23
28
 
24
29
  def collect_text(body)
@@ -29,40 +34,62 @@ module Slim
29
34
  end
30
35
 
31
36
  class TiltEngine < EmbeddedEngine
37
+ def on_slim_embedded(engine, *body)
38
+ text = collect_text(body)
39
+ engine = Tilt[engine] || raise("Tilt engine #{engine} is not available.")
40
+ tilt_render(engine, text)
41
+ end
42
+
43
+ def tilt_render(engine, text)
44
+ # Static template
45
+ [:static, engine.new { text }.render]
46
+ end
47
+ end
48
+
49
+ class SassEngine < TiltEngine
50
+ def tilt_render(engine, text)
51
+ text = engine.new(:style => (options[:pretty] ? :expanded : :compressed)) { text }.render
52
+ text.chomp!
53
+ [:static, options[:pretty] ? "\n#{text}\n" : text]
54
+ end
55
+ end
56
+
57
+ class DynamicTiltEngine < TiltEngine
32
58
  # Code to collect local variables
33
59
  COLLECT_LOCALS = %q{eval('{' + local_variables.select {|v| v[0] != ?_ }.map {|v| ":#{v}=>#{v}" }.join(',') + '}')}
34
60
 
35
- def on_slim_embedded(engine, *body)
36
- text = collect_text(body)
37
- engine = Tilt[engine]
38
- if options[:precompiled]
39
- # Wrap precompiled code in proc, local variables from out the proc are accessible
40
- # WARNING: This is a bit of a hack. Tilt::Engine#precompiled is protected
41
- precompiled = engine.new { text }.send(:precompiled, {}).first
42
- [:dynamic, "proc { #{precompiled} }.call"]
43
- elsif options[:dynamic]
44
- # Fully dynamic evaluation of the template during runtime (Slow and uncached)
45
- [:dynamic, "#{engine.name}.new { #{text.inspect} }.render(self, #{COLLECT_LOCALS})"]
46
- elsif options[:interpolate]
47
- # Static template with interpolated ruby code
48
- [:slim, :text, engine.new { text }.render]
49
- else
50
- # Static template
51
- [:static, engine.new { text }.render]
52
- end
61
+ def tilt_render(engine, text)
62
+ # Fully dynamic evaluation of the template during runtime (Slow and uncached)
63
+ [:dynamic, "#{engine.name}.new { #{text.inspect} }.render(self, #{COLLECT_LOCALS})"]
64
+ end
65
+ end
66
+
67
+ class PrecompiledTiltEngine < TiltEngine
68
+ def tilt_render(engine, text)
69
+ # Wrap precompiled code in proc, local variables from out the proc are accessible
70
+ # WARNING: This is a bit of a hack. Tilt::Engine#precompiled is protected
71
+ precompiled = engine.new { text }.send(:precompiled, {}).first
72
+ [:dynamic, "proc { #{precompiled} }.call"]
73
+ end
74
+ end
75
+
76
+ class InterpolateTiltEngine < TiltEngine
77
+ def tilt_render(engine, text)
78
+ # Static template with interpolated ruby code
79
+ [:slim, :text, engine.new { text }.render]
53
80
  end
54
81
  end
55
82
 
56
83
  class ERBEngine < EmbeddedEngine
57
84
  def on_slim_embedded(engine, *body)
58
85
  text = collect_text(body)
59
- Temple::ERB::Parser.new(:auto_escape => true).compile(text)
86
+ Temple::ERB::Parser.new(:auto_escape => true).call(text)
60
87
  end
61
88
  end
62
89
 
63
90
  class TagEngine < EmbeddedEngine
64
91
  def on_slim_embedded(engine, *body)
65
- content = options[:engine] ? options[:engine].new.on_slim_embedded(engine, *body) : [:multi, *body]
92
+ content = options[:engine] ? options[:engine].new(options).on_slim_embedded(engine, *body) : [:multi, *body]
66
93
  [:slim, :tag, options[:tag], [:slim, :attrs, *options[:attributes].map {|k, v| [k, [:static, v]] }], false, content]
67
94
  end
68
95
  end
@@ -74,32 +101,33 @@ module Slim
74
101
  end
75
102
 
76
103
  # These engines are executed at compile time, embedded ruby is interpolated
77
- register :markdown, TiltEngine, :interpolate => true
78
- register :textile, TiltEngine, :interpolate => true
79
- register :rdoc, TiltEngine, :interpolate => true
104
+ register :markdown, InterpolateTiltEngine
105
+ register :textile, InterpolateTiltEngine
106
+ register :rdoc, InterpolateTiltEngine
107
+ register :creole, InterpolateTiltEngine
80
108
 
81
109
  # These engines are executed at compile time
82
- register :coffee, TagEngine, :tag => 'script', :attributes => { :type => 'text/javascript' }, :engine => TiltEngine
83
- register :sass, TagEngine, :tag => 'style', :attributes => { :type => 'text/css' }, :engine => TiltEngine
84
- register :scss, TagEngine, :tag => 'style', :attributes => { :type => 'text/css' }, :engine => TiltEngine
85
- register :less, TagEngine, :tag => 'style', :attributes => { :type => 'text/css' }, :engine => TiltEngine
110
+ register :coffee, TagEngine, :tag => 'script', :attributes => { :type => 'text/javascript' }, :engine => TiltEngine
111
+ register :less, TagEngine, :tag => 'style', :attributes => { :type => 'text/css' }, :engine => TiltEngine
112
+ register :sass, TagEngine, :pretty, :tag => 'style', :attributes => { :type => 'text/css' }, :engine => SassEngine
113
+ register :scss, TagEngine, :pretty, :tag => 'style', :attributes => { :type => 'text/css' }, :engine => SassEngine
86
114
 
87
115
  # These engines are precompiled, code is embedded
88
- register :erb, ERBEngine
89
- register :haml, TiltEngine, :precompiled => true
90
- register :nokogiri, TiltEngine, :precompiled => true
91
- register :builder, TiltEngine, :precompiled => true
116
+ register :erb, ERBEngine
117
+ register :haml, PrecompiledTiltEngine
118
+ register :nokogiri, PrecompiledTiltEngine
119
+ register :builder, PrecompiledTiltEngine
92
120
 
93
121
  # These engines are completely executed at runtime (Usage not recommended, no caching!)
94
- register :liquid, TiltEngine, :dynamic => true
95
- register :radius, TiltEngine, :dynamic => true
96
- register :markaby, TiltEngine, :dynamic => true
122
+ register :liquid, DynamicTiltEngine
123
+ register :radius, DynamicTiltEngine
124
+ register :markaby, DynamicTiltEngine
97
125
 
98
126
  # Embedded javascript/css
99
- register :javascript, TagEngine, :tag => 'script', :attributes => { :type => 'text/javascript' }
100
- register :css, TagEngine, :tag => 'style', :attributes => { :type => 'text/css' }
127
+ register :javascript, TagEngine, :tag => 'script', :attributes => { :type => 'text/javascript' }
128
+ register :css, TagEngine, :tag => 'style', :attributes => { :type => 'text/css' }
101
129
 
102
130
  # Embedded ruby code
103
- register :ruby, RubyEngine
131
+ register :ruby, RubyEngine
104
132
  end
105
133
  end
@@ -37,7 +37,7 @@ module Slim
37
37
  prev_indent = false
38
38
  end
39
39
 
40
- result << compile!(exp)
40
+ result << compile(exp)
41
41
  end
42
42
 
43
43
  # The last line can be a control code too.
data/lib/slim/engine.rb CHANGED
@@ -14,12 +14,14 @@ module Slim
14
14
  :id_delimiter => nil,
15
15
  :generator => Temple::Generators::ArrayBuffer
16
16
 
17
+ #
17
18
  # Document all supported options with purpose, type etc.
18
19
  #
19
20
  # Type | Name | Default value | Purpose
20
21
  # --------------------------------------------------------------------------------------------------------------------------------------------
21
22
  # String | :file | nil | Name of parsed file, set automatically by Slim::Template
22
23
  # Integer | :tabsize | 4 | Number of whitespaces per tab (used by the parser)
24
+ # String | :encoding | utf-8 | Set encoding of template
23
25
  # String list | :enable_engines | All enabled | List of enabled embedded engines (whitelist)
24
26
  # String list | :disable_engines | None disabled | List of disabled embedded engines (blacklist)
25
27
  # Boolean | :sections | false | Enable sections mode (logic-less)
@@ -33,9 +35,26 @@ module Slim
33
35
  # String | :attr_wrapper | '"' | Character to wrap attributes in html (can be ' or ")
34
36
  # String | :id_delimiter | '_' | Joining character used if multiple html ids are supplied (e.g. #id1#id2)
35
37
  # Boolean | :pretty | false | Pretty html indenting (This is slower!)
36
- # Class | :generator | ArrayBuffer/RailsOutputBuffer | Temple code generator (defaults generates array buffer)
37
- use Slim::Parser, :file, :tabsize
38
- use Slim::EmbeddedEngine, :enable_engines, :disable_engines
38
+ # Class | :generator | ArrayBuffer/RailsOutputBuffer | Temple code generator (default generator generates array buffer)
39
+ #
40
+ # It is also possible to set all options supported by the generator (option :generator). The standard generators
41
+ # support the options :buffer and :capture_generator.
42
+ #
43
+ # Options can be set at multiple positions. Slim/Temple uses a inheritance mechanism to allow
44
+ # subclasses to overwrite options of the superclass. The option priorities are as follows:
45
+ #
46
+ # Custom (Options passed by the user) > Slim::Template > Slim::Engine > Parser/Filter/Generator (e.g Slim::Parser, Slim::Compiler)
47
+ #
48
+ # It is also possible to set options for superclasses like Temple::Engine. But this will affect all temple template engines then.
49
+ #
50
+ # Slim::Engine > Temple::Engine
51
+ # Slim::Compiler > Temple::Filter
52
+ #
53
+ # It is recommended to set the default settings only once in the code and avoid duplication. Only use
54
+ # `set_default_options` when you have to override some default settings.
55
+ #
56
+ use Slim::Parser, :file, :tabsize, :encoding
57
+ use Slim::EmbeddedEngine, :enable_engines, :disable_engines, :pretty
39
58
  use Slim::Interpolation
40
59
  use Slim::Sections, :sections, :dictionary, :dictionary_access
41
60
  use Slim::EndInserter
@@ -47,6 +66,6 @@ module Slim
47
66
  filter :StaticMerger
48
67
  filter :DynamicInliner
49
68
  filter :Debugger, :debug, :debug_prefix => 'Optimized code'
50
- chain << proc {|options| options[:generator].new }
69
+ use(:Generator) {|exp| options[:generator].new(options).call(exp) }
51
70
  end
52
71
  end
data/lib/slim/filter.rb CHANGED
@@ -1,36 +1,33 @@
1
1
  module Slim
2
2
  # Base class for Temple filters used in Slim
3
+ #
4
+ # This base filter passes everything through and allows
5
+ # to override only some methods without affecting the rest
6
+ # of the expression.
7
+ #
3
8
  # @api private
4
9
  class Filter < Temple::Filter
5
10
  # Dispatch on_slim_*
6
11
  temple_dispatch :slim
7
12
 
8
13
  def on_slim_control(code, content)
9
- [:slim, :control, code, compile!(content)]
14
+ [:slim, :control, code, compile(content)]
10
15
  end
11
16
 
12
17
  def on_slim_comment(content)
13
- [:slim, :comment, compile!(content)]
18
+ [:slim, :comment, compile(content)]
14
19
  end
15
20
 
16
21
  def on_slim_output(code, escape, content)
17
- [:slim, :output, code, escape, compile!(content)]
22
+ [:slim, :output, code, escape, compile(content)]
18
23
  end
19
24
 
20
25
  def on_slim_tag(name, attrs, closed, content)
21
- [:slim, :tag, name, compile!(attrs), closed, compile!(content)]
26
+ [:slim, :tag, name, compile(attrs), closed, compile(content)]
22
27
  end
23
28
 
24
29
  def on_slim_attrs(*attrs)
25
- [:slim, :attrs, *attrs.map {|k, v| [k, compile!(v)] }]
26
- end
27
-
28
- # Generate unique temporary variable name
29
- #
30
- # @return [String] Variable name
31
- def tmp_var(prefix)
32
- @tmp_var ||= 0
33
- "_slim#{prefix}#{@tmp_var += 1}"
30
+ [:slim, :attrs, *attrs.map {|k, v| [k, compile(v)] }]
34
31
  end
35
32
  end
36
33
  end
@@ -1,5 +1,7 @@
1
1
  module Slim
2
- # Perform interpolation of #{var_name}
2
+ # Perform interpolation of #{var_name} in the
3
+ # expressions `[:slim, :text, string]`.
4
+ #
3
5
  # @api private
4
6
  class Interpolation < Filter
5
7
  # Handle text expression `[:slim, :text, string]`
data/lib/slim/parser.rb CHANGED
@@ -4,6 +4,9 @@ module Slim
4
4
  class Parser
5
5
  include Temple::Mixins::Options
6
6
 
7
+ set_default_options :tabsize => 4,
8
+ :encoding => 'utf-8'
9
+
7
10
  class SyntaxError < StandardError
8
11
  attr_reader :error, :file, :line, :lineno, :column
9
12
 
@@ -24,8 +27,6 @@ module Slim
24
27
  end
25
28
  end
26
29
 
27
- default_options[:tabsize] = 4
28
-
29
30
  def initialize(options = {})
30
31
  super
31
32
  @tab = ' ' * @options[:tabsize]
@@ -35,7 +36,9 @@ module Slim
35
36
  #
36
37
  # @param [String] str Slim code
37
38
  # @return [Array] Temple expression representing the code
38
- def compile(str)
39
+ def call(str)
40
+ str.force_encoding(options[:encoding]) if options[:encoding] && str.respond_to?(:force_encoding)
41
+
39
42
  lineno = 0
40
43
  result = [:multi]
41
44
 
@@ -245,7 +248,7 @@ module Slim
245
248
  private
246
249
 
247
250
  ATTR_REGEX = /^\s+(\w[:\w-]*)=/
248
- QUOTED_VALUE_REGEX = /^("[^"]+"|'[^']+')/
251
+ QUOTED_VALUE_REGEX = /^("[^"]*"|'[^']*')/
249
252
  ATTR_SHORTHAND = {
250
253
  '#' => 'id',
251
254
  '.' => 'class',
@@ -277,6 +280,8 @@ module Slim
277
280
 
278
281
  # Find any literal class/id attributes
279
282
  while line =~ CLASS_ID_REGEX
283
+ # The class/id attribute is :static instead of :slim :text,
284
+ # because we don't want text interpolation in .class or #id shortcut
280
285
  attributes << [ATTR_SHORTHAND[$1], [:static, $2]]
281
286
  line = $'
282
287
  end
data/lib/slim/rails.rb CHANGED
@@ -1,32 +1,3 @@
1
+ # TODO: I would say we remove when we reach 1.0
1
2
  require 'slim'
2
-
3
- Slim::Engine.default_options[:generator] = Temple::Generators::RailsOutputBuffer
4
- Slim::Engine.default_options[:disable_capture] = true
5
-
6
- module ActionView
7
- module TemplateHandlers
8
- if Rails::VERSION::MAJOR < 3
9
- raise "Slim supports only Rails 3.x and greater, your Rails version is #{Rails::VERSION::STRING}"
10
- end
11
-
12
- if Rails::VERSION::MAJOR == 3 && Rails::VERSION::MINOR < 1
13
- # Slim handler for Rails 3.0
14
- class SlimHandler < TemplateHandler
15
- include Compilable
16
-
17
- def compile(template)
18
- Slim::Engine.new.compile(template.source)
19
- end
20
- end
21
- else
22
- # Slim handler for Rails 3.1 and greater
23
- class SlimHandler
24
- def self.call(template)
25
- Slim::Engine.new.compile(template.source)
26
- end
27
- end
28
- end
29
- end
30
-
31
- Template.register_template_handler :slim, TemplateHandlers::SlimHandler
32
- end
3
+ puts 'Deprecated: Use `require \'slim\'` instead of `require \'slim/rails\'`'
data/lib/slim/sections.rb CHANGED
@@ -14,7 +14,7 @@ module Slim
14
14
  end
15
15
  end
16
16
 
17
- def compile(exp)
17
+ def call(exp)
18
18
  if options[:sections]
19
19
  # Store the dictionary in the _slimdict variable
20
20
  dictionary = options[:dictionary]
@@ -37,17 +37,17 @@ module Slim
37
37
  end
38
38
 
39
39
  def on_slim_inverted_section(name, content)
40
- tmp = tmp_var('section')
40
+ tmp = tmp_var(:section)
41
41
  [:multi,
42
42
  [:block, "#{tmp} = #{access name}"],
43
43
  [:block, "if !#{tmp} || #{tmp}.respond_to?(:empty) && #{tmp}.empty?"],
44
- compile!(content),
44
+ compile(content),
45
45
  [:block, 'end']]
46
46
  end
47
47
 
48
48
  def on_slim_section(name, content)
49
- content = compile!(content)
50
- tmp1, tmp2 = tmp_var('dict'), tmp_var('dict')
49
+ content = compile(content)
50
+ tmp1, tmp2 = tmp_var(:dict), tmp_var(:dict)
51
51
 
52
52
  [:multi,
53
53
  [:block, "if #{tmp1} = #{access name}"],
data/lib/slim/template.rb CHANGED
@@ -1,9 +1,17 @@
1
1
  module Slim
2
2
  # Tilt template implementation for Slim
3
3
  # @api public
4
- class Template < Temple::Template
5
- engine Slim::Engine
6
- end
4
+ Template = Temple::Templates::Tilt(Slim::Engine, :register_as => :slim)
5
+
6
+ if Object.const_defined?(:Rails)
7
+ # Rails template implementation for Slim
8
+ # @api public
9
+ RailsTemplate = Temple::Templates::Rails(Slim::Engine, :register_as => :slim)
7
10
 
8
- Tilt.register 'slim', Template
11
+ # Use rails-specific generator. This is necessary
12
+ # to support block capturing. Disable the internal slim capturing.
13
+ # Rails takes care of the capturing by itself.
14
+ RailsTemplate.set_default_options :generator => Temple::Generators::RailsOutputBuffer,
15
+ :disable_capture => true
16
+ end
9
17
  end
data/lib/slim/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Slim
2
- VERSION = '0.9.1'
2
+ VERSION = '0.9.2'
3
3
  end
data/lib/slim.rb CHANGED
@@ -12,4 +12,3 @@ require 'slim/engine'
12
12
  require 'slim/template'
13
13
  require 'slim/version'
14
14
  require 'slim/wrapper'
15
- require 'slim/validator'
data/test/helper.rb CHANGED
@@ -14,7 +14,6 @@ class TestSlim < MiniTest::Unit::TestCase
14
14
 
15
15
  def teardown
16
16
  Slim::Sections.set_default_options(:dictionary_access => :wrapped)
17
- Temple::Filters::EscapeHTML.default_options.delete(:use_html_safe)
18
17
  end
19
18
 
20
19
  def render(source, options = {}, &block)
@@ -1,12 +1,12 @@
1
1
  require File.expand_path('../boot', __FILE__)
2
2
 
3
- require "active_model/railtie"
4
- require "active_record/railtie"
5
- require "action_controller/railtie"
6
- require "action_view/railtie"
7
- require "action_mailer/railtie"
3
+ require 'active_model/railtie'
4
+ require 'active_record/railtie'
5
+ require 'action_controller/railtie'
6
+ require 'action_view/railtie'
7
+ require 'action_mailer/railtie'
8
8
 
9
- require "slim/rails"
9
+ require 'slim'
10
10
 
11
11
  module Dummy
12
12
  class Application < Rails::Application
@@ -0,0 +1,42 @@
1
+ require 'helper'
2
+
3
+ class TestSlimChainManipulation < TestSlim
4
+ def test_replace
5
+ source = %q{
6
+ p Test
7
+ }
8
+ chain = proc do |engine|
9
+ engine.replace(Temple::HTML::Pretty, :ReplacementFilter) do |exp|
10
+ [:dynamic, '1+1']
11
+ end
12
+ end
13
+
14
+ assert_html '2', source, :chain => chain
15
+ end
16
+
17
+ def test_before
18
+ source = %q{
19
+ p Test
20
+ }
21
+ chain = proc do |engine|
22
+ engine.before(Slim::Parser, :WrapInput) do |input|
23
+ "p Header\n#{input}\np Footer"
24
+ end
25
+ end
26
+
27
+ assert_html '<p>Header</p><p>Test</p><p>Footer</p>', source, :chain => chain
28
+ end
29
+
30
+ def test_after
31
+ source = %q{
32
+ p Test
33
+ }
34
+ chain = proc do |engine|
35
+ engine.after(Slim::Parser, :ReplaceParsedExp) do |exp|
36
+ [:slim, :output, false, '1+1', [:multi]]
37
+ end
38
+ end
39
+
40
+ assert_html '2', source, :chain => chain
41
+ end
42
+ end
@@ -1,7 +1,25 @@
1
1
  require 'helper'
2
+ begin
3
+ require('creole/template')
4
+ rescue LoadError
5
+ end
2
6
 
3
7
  class TestSlimEmbeddedEngines < TestSlim
4
- def test_render_with_embedded_template
8
+ def test_render_with_haml
9
+ source = %q{
10
+ p
11
+ - text = 'haml'
12
+ haml:
13
+ %b Hello from #{text.upcase}!
14
+ Second Line!
15
+ - if true
16
+ = true
17
+ }
18
+
19
+ assert_html "<p><b>Hello from HAML!</b>\nSecond Line!\ntrue\n</p>", source
20
+ end
21
+
22
+ def test_render_with_erb
5
23
  source = %q{
6
24
  p
7
25
  - text = 'before erb block'
@@ -14,7 +32,7 @@ p
14
32
  assert_html "<p><b>Hello from BEFORE ERB BLOCK!</b>\nSecond Line!\ntrue</p>", source
15
33
  end
16
34
 
17
- def test_render_with_interpolated_embedded_template
35
+ def test_render_with_markdown
18
36
  source = %q{
19
37
  markdown:
20
38
  #Header
@@ -24,6 +42,15 @@ markdown:
24
42
  assert_html "<h1>Header</h1>\n\n<p>Hello from Markdown!\n\"Second Line!\"</p>\n", source
25
43
  end
26
44
 
45
+ def test_render_with_creole
46
+ source = %q{
47
+ creole:
48
+ = head1
49
+ == head2
50
+ }
51
+ assert_html "<h1>head1</h1><h2>head2</h2>", source
52
+ end
53
+
27
54
  def test_render_with_javascript
28
55
  # Keep the trailing space behind "javascript: "!
29
56
  source = %q{
@@ -59,7 +86,7 @@ scss:
59
86
  $color: #f00;
60
87
  body { color: $color; }
61
88
  }
62
- assert_html "<style type=\"text/css\">body {\n color: red; }\n</style>", source
89
+ assert_html "<style type=\"text/css\">body{color:red}</style>", source
63
90
  end
64
91
 
65
92
  def test_disabled_embedded_engine
@@ -262,6 +262,22 @@ p(id="marvin" class="martian" data-info="Illudium Q-36")= output_number
262
262
  assert_html '<p class="martian" data-info="Illudium Q-36" id="marvin">1337</p>', source
263
263
  end
264
264
 
265
+ def test_empty_attribute
266
+ source = %q{
267
+ p(id="marvin" class="" data-info="Illudium Q-36")= output_number
268
+ }
269
+
270
+ assert_html '<p data-info="Illudium Q-36" id="marvin">1337</p>', source
271
+ end
272
+
273
+ def test_dynamic_empty_attribute
274
+ source = %q{
275
+ p(id="marvin" class=nil data-info="Illudium Q-36")= output_number
276
+ }
277
+
278
+ assert_html '<p data-info="Illudium Q-36" id="marvin">1337</p>', source
279
+ end
280
+
265
281
  def test_closed_tag
266
282
  source = %q{
267
283
  closed/
@@ -0,0 +1,45 @@
1
+ require 'helper'
2
+
3
+ class TestSlimPretty < TestSlim
4
+ def setup
5
+ Slim::Engine.set_default_options :pretty => true
6
+ end
7
+
8
+ def teardown
9
+ Slim::Engine.set_default_options :pretty => false
10
+ end
11
+
12
+ def test_pretty_sass
13
+ source = %q{
14
+ doctype 5
15
+ html
16
+ head
17
+ title Hello World!
18
+ sass:
19
+ body
20
+ background-color: red
21
+ body
22
+ #container
23
+ p Hello!
24
+ }
25
+
26
+ result = %q{<!DOCTYPE html>
27
+ <html>
28
+ <head>
29
+ <title>Hello World!</title>
30
+ <style type="text/css">
31
+ body {
32
+ background-color: red;
33
+ }
34
+ </style>
35
+ </head>
36
+ <body>
37
+ <div id="container">
38
+ <p>Hello!</p>
39
+ </div>
40
+ </body>
41
+ </html>}
42
+
43
+ assert_html result, source
44
+ end
45
+ end
@@ -121,7 +121,7 @@ p
121
121
  1+1
122
122
  }
123
123
 
124
- assert_runtime_error 'Invalid embedded engine embed_unknown', source
124
+ assert_runtime_error 'Embedded engine embed_unknown not found', source
125
125
  end
126
126
 
127
127
  def test_explicit_end
@@ -1,6 +1,13 @@
1
1
  require 'helper'
2
2
 
3
3
  class TestSlimTextInterpolation < TestSlim
4
+ def test_interpolation_in_attribute
5
+ source = %q{
6
+ p id="a#{id_helper}b" = hello_world
7
+ }
8
+
9
+ assert_html '<p id="anoticeb">Hello World from @env</p>', source
10
+ end
4
11
 
5
12
  def test_interpolation_in_text
6
13
  source = %q{
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 9
8
- - 1
9
- version: 0.9.1
8
+ - 2
9
+ version: 0.9.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - Andrew Stone
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2011-03-10 00:00:00 -05:00
19
+ date: 2011-03-30 00:00:00 -04:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -29,9 +29,9 @@ dependencies:
29
29
  - !ruby/object:Gem::Version
30
30
  segments:
31
31
  - 0
32
- - 1
33
- - 8
34
- version: 0.1.8
32
+ - 2
33
+ - 0
34
+ version: 0.2.0
35
35
  type: :runtime
36
36
  version_requirements: *id001
37
37
  - !ruby/object:Gem::Dependency
@@ -141,6 +141,19 @@ dependencies:
141
141
  version: "0"
142
142
  type: :development
143
143
  version_requirements: *id009
144
+ - !ruby/object:Gem::Dependency
145
+ name: creole
146
+ prerelease: false
147
+ requirement: &id010 !ruby/object:Gem::Requirement
148
+ none: false
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ segments:
153
+ - 0
154
+ version: "0"
155
+ type: :development
156
+ version_requirements: *id010
144
157
  description: Slim is a template language whose goal is reduce the syntax to the essential parts without becoming cryptic.
145
158
  email:
146
159
  - andy@stonean.com
@@ -169,7 +182,6 @@ files:
169
182
  - lib/slim/rails.rb
170
183
  - lib/slim/sections.rb
171
184
  - lib/slim/template.rb
172
- - lib/slim/validator.rb
173
185
  - lib/slim/version.rb
174
186
  - lib/slim/wrapper.rb
175
187
  - test/helper.rb
@@ -213,6 +225,7 @@ files:
213
225
  - test/integration/rails/dummy/script/rails
214
226
  - test/integration/rails/test_helper.rb
215
227
  - test/integration/rails/test_slim_rails.rb
228
+ - test/slim/test_chain_manipulation.rb
216
229
  - test/slim/test_code_blocks.rb
217
230
  - test/slim/test_code_escaping.rb
218
231
  - test/slim/test_code_evaluation.rb
@@ -222,11 +235,11 @@ files:
222
235
  - test/slim/test_html_escaping.rb
223
236
  - test/slim/test_html_structure.rb
224
237
  - test/slim/test_parser_errors.rb
238
+ - test/slim/test_pretty.rb
225
239
  - test/slim/test_ruby_errors.rb
226
240
  - test/slim/test_sections.rb
227
241
  - test/slim/test_slim_template.rb
228
242
  - test/slim/test_text_interpolation.rb
229
- - test/slim/test_validator.rb
230
243
  - test/slim/test_wrapper.rb
231
244
  has_rdoc: true
232
245
  homepage: http://github.com/stonean/slim
@@ -1,16 +0,0 @@
1
- module Slim
2
- module Validator
3
- class << self
4
- def validate!(source)
5
- Slim::Engine.new.compile(source.to_s)
6
- true
7
- rescue Exception => ex
8
- ex
9
- end
10
-
11
- def valid?(source)
12
- validate!(source) === true
13
- end
14
- end
15
- end
16
- end
@@ -1,47 +0,0 @@
1
- require 'helper'
2
-
3
- class TestSlimValidator < TestSlim
4
- def test_valid_true?
5
- source = %q{
6
- p Slim
7
- }
8
- assert_valid? true, source
9
- end
10
-
11
- def test_valid_false?
12
- source = %q{
13
- p
14
- Slim
15
- }
16
- assert_valid? false, source
17
- end
18
-
19
- def test_valid!
20
- source = %q{
21
- p Slim
22
- }
23
- assert_valid! false, source
24
- end
25
-
26
- def test_invalid!
27
- source = %q{
28
- p
29
- Slim
30
- }
31
- assert_invalid! Slim::Parser::SyntaxError, source
32
- end
33
-
34
- private
35
-
36
- def assert_valid?(expected, source)
37
- assert_equal expected, Slim::Validator.valid?(source)
38
- end
39
-
40
- def assert_valid!(expected, source)
41
- assert_equal true, Slim::Validator.validate!(source)
42
- end
43
-
44
- def assert_invalid!(expected, source)
45
- assert_equal expected, Slim::Validator.validate!(source).class
46
- end
47
- end