slim 0.7.1 → 0.7.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.
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- slim (0.7.0)
5
- temple (~> 0.1.4)
4
+ slim (0.7.2)
5
+ temple (~> 0.1.5)
6
6
  tilt (~> 1.1)
7
7
 
8
8
  GEM
@@ -17,7 +17,7 @@ GEM
17
17
  rake (0.8.7)
18
18
  rcov (0.9.9)
19
19
  rdiscount (1.6.5)
20
- temple (0.1.4)
20
+ temple (0.1.5)
21
21
  tilt (1.1)
22
22
  yard (0.6.1)
23
23
 
@@ -33,6 +33,6 @@ DEPENDENCIES
33
33
  rcov
34
34
  rdiscount
35
35
  slim!
36
- temple (~> 0.1.4)
36
+ temple (~> 0.1.5)
37
37
  tilt (~> 1.1)
38
38
  yard
data/README.md CHANGED
@@ -86,8 +86,6 @@ Here's a quick example to demonstrate what a Slim template looks like:
86
86
 
87
87
  ### Line indicators
88
88
 
89
- __Please note that all line indicators must be followed by a space__
90
-
91
89
  #### `|`
92
90
 
93
91
  > The pipe tells Slim to just copy the line. It essentially escapes any processing.
@@ -148,7 +146,7 @@ __Please note that all line indicators must be followed by a space__
148
146
  body
149
147
  h1 id="headline" Welcome to my site.
150
148
 
151
- Or nest it. __Note:__ Must use a pipe or a backtick (followed by a space) to escape processing
149
+ Or nest it. __Note:__ Must use a pipe or a backtick to escape processing
152
150
 
153
151
  body
154
152
  h1 id="headline"
@@ -19,15 +19,42 @@ let b:ruby_no_expensive = 1
19
19
 
20
20
  " Include Ruby syntax highlighting
21
21
  syn include @slimRuby syntax/ruby.vim
22
+ unlet! b:current_syntax
23
+ " Include Haml syntax highlighting
24
+ syn include @slimHaml syntax/haml.vim
25
+ unlet! b:current_syntax
26
+ " Include Erb syntax highlighting
27
+ syn include @slimErb syntax/eruby.vim
28
+ unlet! b:current_syntax
22
29
 
23
30
  " Include HTML
24
31
  runtime! syntax/html.vim
25
32
  unlet! b:current_syntax
26
33
 
27
- syntax region slimHtml start="^\s*[^-=]\w" end="$" contains=htmlTagName, htmlArg, htmlString
34
+ setlocal iskeyword+=:
35
+
36
+
37
+ syn region slimHtml start="^\s*[^-=]\w" end="$" contains=htmlTagName,htmlArg,htmlString
38
+ syn region slimControl start="-" end="$" contains=@slimRuby keepend
39
+
40
+ syn match slimFilter /\s*\w\+:\s*/ contained
41
+
42
+ syn match slimCode /^\s*[-=#.].*/ contained
43
+ syn match slimComment /^\(\s\+\)[/].*\(\n\1\s.*\)*/
44
+ syn match slimText /^\(\s\+\)[`|'].*\(\n\1\s.*\)*/
45
+
46
+ syn match slimJs /^\(\s\+\)\<javascript:\>.*\(\n\1\s.*\)*/ contains=@htmlJavaScript,slimFilter
47
+ syn match slimHaml /^\(\s\+\)\<haml:\>.*\(\n\1\s.*\)*/ contains=@slimHaml,slimFilter
48
+ syn match slimHaml /^\(\s\+\)\<erb:\>.*\(\n\1\s.*\)*/ contains=@slimErb,slimFilter
49
+
50
+
51
+ "syn match slimFilter /\s*\<javascript:\>\s*/
52
+
28
53
 
29
- syntax region slimControl start="-" end="$" contains=@slimRuby keepend
30
- syntax region slimOutput start=".*=\s" end="$" contains=@slimRuby keepend
54
+ "contained containedin=slimJs
31
55
 
56
+ hi def link slimText String
57
+ hi def link slimComment Comment
58
+ hi def link slimFilter Special
32
59
 
33
60
  let b:current_syntax = "slim"
@@ -9,15 +9,21 @@ html
9
9
  alert('Hello World');
10
10
  });
11
11
 
12
+ haml:
13
+ #someid.someclass{:this => 'test'} Content in haml
14
+
15
+ erb:
16
+ <%= some_method(@request) %>
17
+
12
18
  body
13
19
  / comment block
14
20
  with multiple lines
15
-
21
+ This is another line
16
22
  h1 = @page_title
17
23
  p#notice.message
18
24
  | Welcome to the the syntax test.
19
25
  This file is to excercise the various markup.
20
-
26
+ This is another line
21
27
  - unless @users.empty?
22
28
  table
23
29
  - for user in users do
@@ -26,6 +32,7 @@ html
26
32
  - else
27
33
  p There are no users.
28
34
 
35
+ / Single comment line
29
36
  #content Hello #{@user.name}! Welcome to the test page!
30
37
  Try out Slim!
31
38
 
@@ -5,6 +5,8 @@ require 'slim/parser'
5
5
  require 'slim/filter'
6
6
  require 'slim/end_inserter'
7
7
  require 'slim/embedded_engine'
8
+ require 'slim/interpolation'
9
+ require 'slim/sections'
8
10
  require 'slim/compiler'
9
11
  require 'slim/engine'
10
12
  require 'slim/template'
@@ -40,6 +40,14 @@ module Slim
40
40
  @options[:compile] = true
41
41
  end
42
42
 
43
+ opts.on('-S', '--sections', :NONE, 'Logic-less sections mode') do
44
+ @options[:sections] = true
45
+ end
46
+
47
+ opts.on('-p', '--pretty', :NONE, 'Produce pretty html') do
48
+ @options[:pretty] = true
49
+ end
50
+
43
51
  opts.on_tail('-h', '--help', 'Show this message') do
44
52
  puts opts
45
53
  exit
@@ -71,9 +79,13 @@ module Slim
71
79
  end
72
80
 
73
81
  if @options[:compile]
74
- @options[:output].puts(Slim::Engine.new(:file => @options[:file]).compile(@options[:input].read))
82
+ @options[:output].puts(Slim::Engine.new(:file => @options[:file],
83
+ :pretty => @options[:pretty],
84
+ :sections => @options[:sections]).compile(@options[:input].read))
75
85
  else
76
- @options[:output].puts(Slim::Template.new(@options[:file]) { @options[:input].read }.render)
86
+ @options[:output].puts(Slim::Template.new(@options[:file],
87
+ :pretty => @options[:pretty],
88
+ :sections => @options[:sections]) { @options[:input].read }.render)
77
89
  end
78
90
  end
79
91
  end
@@ -2,31 +2,6 @@ module Slim
2
2
  # Compiles Slim expressions into Temple::HTML expressions.
3
3
  # @api private
4
4
  class Compiler < Filter
5
- # Handle text expression `[:slim, :text, string]`
6
- #
7
- # @param [String] string Static text
8
- # @return [Array] Compiled temple expression
9
- def on_slim_text(string)
10
- # Interpolate variables in text (#{variable}).
11
- # Split the text into multiple dynamic and static parts.
12
- block = [:multi]
13
- until string.empty?
14
- case string
15
- when /^\\(\#\{[^\}]*\})/
16
- # Escaped interpolation
17
- block << [:static, $1]
18
- when /^\#\{([^\}]*)\}/
19
- # Interpolation
20
- block << [:escape, :dynamic, $1]
21
- when /^([^\#]+|\#)/
22
- # Static text
23
- block << [:static, $&]
24
- end
25
- string = $'
26
- end
27
- block
28
- end
29
-
30
5
  # Handle control expression `[:slim, :control, code, content]`
31
6
  #
32
7
  # @param [String] ruby code
@@ -60,7 +35,7 @@ module Slim
60
35
  # @param [Array] content Temple expression
61
36
  # @return [Array] Compiled temple expression
62
37
  def on_slim_output_block(escape, code, content)
63
- tmp1, tmp2 = tmp_var, tmp_var
38
+ tmp1, tmp2 = tmp_var('capture'), tmp_var('capture')
64
39
 
65
40
  [:multi,
66
41
  # Capture the result of the code in a variable. We can't do
@@ -94,32 +69,22 @@ module Slim
94
69
  end
95
70
  end
96
71
 
97
- # Handle tag expression `[:slim, :tag, name, attrs, content]`
72
+ # Handle tag expression `[:slim, :tag, name, attrs, closed, content]`
98
73
  #
99
74
  # @param [String] name Tag name
100
75
  # @param [Array] attrs Attributes
101
76
  # @param [Array] content Temple expression
102
77
  # @return [Array] Compiled temple expression
103
78
  def on_slim_tag(name, attrs, closed, content)
104
- attrs = attrs.inject([:html, :staticattrs]) do |m, (key, dynamic, value)|
105
- value = if dynamic
106
- [:escape, :dynamic, value]
107
- else
108
- on_slim_text(value)
109
- end
110
- m << [key.to_s, value]
111
- end
112
- [:html, :tag, name, attrs, closed, compile!(content)]
79
+ [:html, :tag, name, compile!(attrs), closed, compile!(content)]
113
80
  end
114
81
 
115
- private
116
-
117
- # Generate unique temporary variable name
82
+ # Handle tag attributes expression `[:slim, :attrs, *attrs]`
118
83
  #
119
- # @return [String] Variable name
120
- def tmp_var
121
- @tmp_var ||= 0
122
- "_slimtmp#{@tmp_var += 1}"
84
+ # @param [Array] attrs Attributes
85
+ # @return [Array] Compiled temple expression
86
+ def on_slim_attrs(*attrs)
87
+ [:html, :staticattrs, *attrs.map {|k, v| [k.to_s, compile!(v)] }]
123
88
  end
124
89
  end
125
90
  end
@@ -64,7 +64,7 @@ module Slim
64
64
  class TagEngine < EmbeddedEngine
65
65
  def on_slim_embedded(engine, *body)
66
66
  content = options[:engine] ? options[:engine].new.on_slim_embedded(engine, *body) : [:multi, *body]
67
- [:slim, :tag, options[:tag], options[:attributes].map {|k, v| [k, false, v] }, false, content]
67
+ [:slim, :tag, options[:tag], [:slim, :attrs, *options[:attributes].map {|k, v| [k, [:static, v]] }], false, content]
68
68
  end
69
69
  end
70
70
 
@@ -2,17 +2,24 @@ module Slim
2
2
  # Slim engine which transforms slim code to executable ruby code
3
3
  # @api public
4
4
  class Engine < Temple::Engine
5
+ # Allow users to set default options, particularly useful in Rails' environment files.
6
+ # For instance, in config/environments/development.rb you probably want:
7
+ # # Indent html for pretty debugging
8
+ # Slim::Engine.set_default_options :pretty => true
9
+ #
10
+ set_default_options :pretty => false,
11
+ :attr_wrapper => '"',
12
+ :format => :html5,
13
+ :id_delimiter => nil
14
+
5
15
  use Slim::Parser, :file
6
- filter :Debugger, :debug, :prefix => 'before end insertion'
7
- use Slim::EndInserter
8
- filter :Debugger, :debug, :prefix => 'after end insertion'
9
16
  use Slim::EmbeddedEngine
17
+ use Slim::Interpolation
18
+ use Slim::Sections, :sections, :dictionary, :dictionary_access
19
+ use Slim::EndInserter
10
20
  use Slim::Compiler
11
- filter :Debugger, :debug, :prefix => 'after compilation'
12
21
  filter :EscapeHTML, :use_html_safe
13
- use Temple::HTML::Pretty, :format, :attr_wrapper, :id_delimiter, :id_concat, :pretty,
14
- :pretty => false, :attr_wrapper => '"', :format => :html5, :id_delimiter => nil
15
- filter :Debugger, :debug, :prefix => 'after html'
22
+ use Temple::HTML::Pretty, :format, :attr_wrapper, :id_delimiter, :pretty
16
23
  filter :MultiFlattener
17
24
  filter :StaticMerger
18
25
  filter :DynamicInliner
@@ -2,6 +2,7 @@ module Slim
2
2
  # Base class for Temple filters used in Slim
3
3
  # @api private
4
4
  class Filter < Temple::Filter
5
+ # Dispatch on_slim_*
5
6
  temple_dispatch :slim
6
7
 
7
8
  def on_slim_control(code, content)
@@ -13,7 +14,19 @@ module Slim
13
14
  end
14
15
 
15
16
  def on_slim_tag(name, attrs, closed, content)
16
- [:slim, :tag, name, attrs, closed, compile!(content)]
17
+ [:slim, :tag, name, compile!(attrs), closed, compile!(content)]
18
+ end
19
+
20
+ def on_slim_attrs(*attrs)
21
+ [:slim, :attrs, *attrs.map {|k, v| [k, compile!(v)] }]
22
+ end
23
+
24
+ # Generate unique temporary variable name
25
+ #
26
+ # @return [String] Variable name
27
+ def tmp_var(prefix)
28
+ @tmp_var ||= 0
29
+ "_slim#{prefix}#{@tmp_var += 1}"
17
30
  end
18
31
  end
19
32
  end
@@ -0,0 +1,30 @@
1
+ module Slim
2
+ # Perform interpolation of #{var_name}
3
+ # @api private
4
+ class Interpolation < Filter
5
+ # Handle text expression `[:slim, :text, string]`
6
+ #
7
+ # @param [String] string Static text
8
+ # @return [Array] Compiled temple expression
9
+ def on_slim_text(string)
10
+ # Interpolate variables in text (#{variable}).
11
+ # Split the text into multiple dynamic and static parts.
12
+ block = [:multi]
13
+ until string.empty?
14
+ case string
15
+ when /^\\(\#\{[^\}]*\})/
16
+ # Escaped interpolation
17
+ block << [:static, $1]
18
+ when /^\#\{([^\}]*)\}/
19
+ # Interpolation
20
+ block << [:slim, :output, true, $1, [:multi]]
21
+ when /^([^\#]+|\#)/
22
+ # Static text
23
+ block << [:static, $&]
24
+ end
25
+ string = $'
26
+ end
27
+ block
28
+ end
29
+ end
30
+ end
@@ -259,11 +259,11 @@ module Slim
259
259
  # Now we'll have to find all the attributes. We'll store these in an
260
260
  # nested array: [[name, value], [name2, value2]]. The value is a piece
261
261
  # of Ruby code.
262
- attributes = []
262
+ attributes = [:slim, :attrs]
263
263
 
264
264
  # Find any literal class/id attributes
265
265
  while line =~ CLASS_ID_REGEX
266
- attributes << [ATTR_SHORTHAND[$1], false, $2]
266
+ attributes << [ATTR_SHORTHAND[$1], [:static, $2]]
267
267
  line = $'
268
268
  end
269
269
 
@@ -282,11 +282,11 @@ module Slim
282
282
  if line =~ QUOTED_VALUE_REGEX
283
283
  # Value is quoted (static)
284
284
  line = $'
285
- attributes << [key, false, $1[1..-2]]
285
+ attributes << [key, [:slim, :text, $1[1..-2]]]
286
286
  else
287
287
  # Value is ruby code
288
288
  line, value = parse_ruby_attribute(orig_line, line, lineno, delimiter)
289
- attributes << [key, true, value]
289
+ attributes << [key, [:slim, :output, true, value, [:multi]]]
290
290
  end
291
291
  end
292
292
 
@@ -2,12 +2,23 @@ require 'slim'
2
2
 
3
3
  module ActionView
4
4
  module TemplateHandlers
5
- # Slim handler for Rails 3
6
- class SlimHandler < TemplateHandler
7
- include Compilable
5
+ raise "Slim supports only Rails 3.x and greater, your Rails version is #{Rails::VERSION::STRING}" if Rails::VERSION::MAJOR < 3
8
6
 
9
- def compile(template)
10
- Slim::Engine.new(:use_html_safe => true).compile(template.source)
7
+ if Rails::VERSION::MAJOR == 3 && Rails::VERSION::MINOR < 1
8
+ # Slim handler for Rails 3.0
9
+ class SlimHandler < TemplateHandler
10
+ include Compilable
11
+
12
+ def compile(template)
13
+ Slim::Engine.new.compile(template.source)
14
+ end
15
+ end
16
+ else
17
+ # Slim handler for Rails 3.1 and greater
18
+ class SlimHandler
19
+ def call(template)
20
+ Slim::Engine.new.compile(template.source)
21
+ end
11
22
  end
12
23
  end
13
24
  end
@@ -0,0 +1,79 @@
1
+ module Slim
2
+ # Handle logic-less mode
3
+ # This filter can be activated with the option "sections"
4
+ # @api private
5
+ class Sections < Filter
6
+ set_default_options :dictionary => 'self',
7
+ :sections => false,
8
+ :dictionary_access => :symbol # :symbol, :string
9
+
10
+ def initialize(opts = {})
11
+ super
12
+ unless [:string, :symbol].include?(@options[:dictionary_access])
13
+ raise "Invalid dictionary access #{@options[:dictionary_access].inspect}"
14
+ end
15
+ end
16
+
17
+ def compile(exp)
18
+ if options[:sections]
19
+ # Store the dictionary in the _slimdict variable
20
+ [:multi,
21
+ [:block, "_slimdict = #{@options[:dictionary]}"],
22
+ super]
23
+ else
24
+ exp
25
+ end
26
+ end
27
+
28
+ # Interpret control blocks as sections or inverted sections
29
+ def on_slim_control(name, content)
30
+ if name =~ /^!\s*(.*)/
31
+ on_slim_inverted_section($1, content)
32
+ else
33
+ on_slim_section(name, content)
34
+ end
35
+ end
36
+
37
+ def on_slim_inverted_section(name, content)
38
+ tmp = tmp_var('section')
39
+ [:multi,
40
+ [:block, "#{tmp} = #{access name}"],
41
+ [:block, "if !#{tmp} || #{tmp}.respond_to?(:empty) && #{tmp}.empty?"],
42
+ compile!(content),
43
+ [:block, 'end']]
44
+ end
45
+
46
+ def on_slim_section(name, content)
47
+ content = compile!(content)
48
+ tmp1, tmp2 = tmp_var('dict'), tmp_var('dict')
49
+
50
+ [:multi,
51
+ [:block, "if #{tmp1} = #{access name}"],
52
+ [:block, "if #{tmp1} == true"],
53
+ content,
54
+ [:block, 'else'],
55
+ [:block, "#{tmp1} = [#{tmp1}] if #{tmp1}.respond_to?(:has_key?) || !#{tmp1}.respond_to?(:map)"],
56
+ [:block, "#{tmp2} = _slimdict"],
57
+ [:block, "#{tmp1}.each do |_slimdict|"],
58
+ content,
59
+ [:block, 'end'],
60
+ [:block, "_slimdict = #{tmp2}"],
61
+ [:block, 'end'],
62
+ [:block, 'end']]
63
+ end
64
+
65
+ def on_slim_output(escape, name, content)
66
+ raise 'Output statements with content are forbidden in sections mode' if !empty_exp?(content)
67
+ [:slim, :output, escape, access(name), content]
68
+ end
69
+
70
+ def access(name)
71
+ case options[:dictionary_access]
72
+ when :symbol
73
+ "_slimdict[#{name.to_sym.inspect}]"
74
+ when :string
75
+ "_slimdict[#{name.to_s.inspect}]"
76
+ end
77
+ end
78
+ end
79
+ end
@@ -1,3 +1,3 @@
1
1
  module Slim
2
- VERSION = "0.7.1"
2
+ VERSION = "0.7.2"
3
3
  end
@@ -1,5 +1,6 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  require File.dirname(__FILE__) + "/lib/slim/version"
3
+ require "date"
3
4
 
4
5
  Gem::Specification.new do |s|
5
6
  s.name = "slim"
@@ -20,7 +21,7 @@ Gem::Specification.new do |s|
20
21
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
22
  s.require_paths = ["lib"]
22
23
 
23
- s.add_runtime_dependency(%q<temple>, ["~> 0.1.4"])
24
+ s.add_runtime_dependency(%q<temple>, ["~> 0.1.5"])
24
25
  s.add_runtime_dependency(%q<tilt>, ["~> 1.1"])
25
26
  s.add_development_dependency(%q<rake>, [">= 0.8.7"])
26
27
  s.add_development_dependency(%q<haml>, [">= 0"])
@@ -20,7 +20,7 @@ class TestSlim < MiniTest::Unit::TestCase
20
20
  end
21
21
 
22
22
  def render(source, options = {}, &block)
23
- Slim::Template.new(options[:file], options) { source }.render(@env, &block)
23
+ Slim::Template.new(options[:file], options) { source }.render(options[:scope] || @env, &block)
24
24
  end
25
25
 
26
26
  def assert_html(expected, source, options = {}, &block)
@@ -0,0 +1,74 @@
1
+ require 'helper'
2
+
3
+ class TestSlimLogicLess < TestSlim
4
+ def test_sections
5
+ source = %q{
6
+ p
7
+ - person
8
+ .name = name
9
+ }
10
+
11
+ hash = {
12
+ :person => [
13
+ { :name => 'Joe', },
14
+ { :name => 'Jack', }
15
+ ]
16
+ }
17
+
18
+ assert_html '<p><div class="name">Joe</div><div class="name">Jack</div></p>', source, :scope => hash, :sections => true
19
+ end
20
+
21
+ def test_sections_string_access
22
+ source = %q{
23
+ p
24
+ - person
25
+ .name = name
26
+ }
27
+
28
+ hash = {
29
+ 'person' => [
30
+ { 'name' => 'Joe', },
31
+ { 'name' => 'Jack', }
32
+ ]
33
+ }
34
+
35
+ assert_html '<p><div class="name">Joe</div><div class="name">Jack</div></p>', source, :scope => hash, :sections => true, :dictionary_access => :string
36
+ end
37
+
38
+ def test_flag_section
39
+ source = %q{
40
+ p
41
+ - show_person
42
+ - person
43
+ .name = name
44
+ - show_person
45
+ | shown
46
+ }
47
+
48
+ hash = {
49
+ :show_person => true,
50
+ :person => [
51
+ { :name => 'Joe', },
52
+ { :name => 'Jack', }
53
+ ]
54
+ }
55
+
56
+ assert_html '<p><div class="name">Joe</div><div class="name">Jack</div>shown</p>', source, :scope => hash, :sections => true
57
+ end
58
+
59
+ def test_inverted_section
60
+ source = %q{
61
+ p
62
+ - person
63
+ .name = name
64
+ -! person
65
+ | No person
66
+ - !person
67
+ | No person 2
68
+ }
69
+
70
+ hash = {}
71
+
72
+ assert_html '<p>No person No person 2</p>', source, :scope => hash, :sections => true
73
+ end
74
+ end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 7
8
- - 1
9
- version: 0.7.1
8
+ - 2
9
+ version: 0.7.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: 2010-11-03 00:00:00 -04:00
19
+ date: 2010-11-09 00:00:00 -05:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -30,8 +30,8 @@ dependencies:
30
30
  segments:
31
31
  - 0
32
32
  - 1
33
- - 4
34
- version: 0.1.4
33
+ - 5
34
+ version: 0.1.5
35
35
  type: :runtime
36
36
  version_requirements: *id001
37
37
  - !ruby/object:Gem::Dependency
@@ -187,8 +187,10 @@ files:
187
187
  - lib/slim/end_inserter.rb
188
188
  - lib/slim/engine.rb
189
189
  - lib/slim/filter.rb
190
+ - lib/slim/interpolation.rb
190
191
  - lib/slim/parser.rb
191
192
  - lib/slim/rails.rb
193
+ - lib/slim/sections.rb
192
194
  - lib/slim/template.rb
193
195
  - lib/slim/version.rb
194
196
  - slim.gemspec
@@ -203,6 +205,7 @@ files:
203
205
  - test/slim/test_html_structure.rb
204
206
  - test/slim/test_parser_errors.rb
205
207
  - test/slim/test_ruby_errors.rb
208
+ - test/slim/test_sections.rb
206
209
  - test/slim/test_slim_template.rb
207
210
  has_rdoc: true
208
211
  homepage: http://github.com/stonean/slim