piano 0.10.8 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -4,4 +4,5 @@ Gemfile.lock
4
4
  pkg/*
5
5
  views/*
6
6
  test/*
7
- config/*
7
+ config/*
8
+ .sass-cache/*
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ if RUBY_PLATFORM =~ /linux/
6
+ gem "therubyracer"
7
+ end
@@ -190,35 +190,25 @@ Another helper you may find useful is <tt>extract("source_text/html", word_count
190
190
 
191
191
  %p= extract content, 25
192
192
 
193
- === <tt>flash</tt> & <tt>flash?</tt>
193
+ === <tt>link</tt>
194
194
 
195
- Most times on a POST request the server performs an action and you want to give the user some feedback about that action. The data for that feedback has become known as "flash text" steming from the Rails argot.
195
+ No, it does not print an anchor: it strips all strange characters from a string and replaces all whitespace with "-". If the text is too long, it cuts it.
196
196
 
197
- Piano provides <tt>flash</tt> for you, easy to use. A sample
197
+ Really useful when generating uri's for articles, or html id attributes.
198
198
 
199
- ==== Pianofile
199
+ %a(href="/articles/#{article.id}-#{link(article.title)}")= article.title
200
200
 
201
- post "/article/new" do
202
- Article.create params # ActiveRecord-like article creation
203
-
204
- flash "The article was created" # You set the flash text by calling `flash`
205
- # with an argument
206
-
207
- redirect "/articles"
208
- end
201
+ or
202
+
203
+ %h2(id="#{link(subtitle,4)}")= subtitle
204
+
205
+ In this example, the second argument (4) ensures that the link is done with no more than four of the subtitle's words.
209
206
 
210
- ==== articles.haml
207
+ === <tt>flash</tt>
211
208
 
212
- %html
213
- %head
214
- %title Articles index
215
- %body
216
- - if flash? # Checks if any flash text is setted
217
- %output= flash
218
-
219
- <tt>flash</tt> called without an argument destructively returns the flash text. Destructively so further request to <tt>/articles</tt> (which in this case will bring up <tt>articles.haml</tt>) will not display the flash text.
209
+ Piano now comes bundled with https://github.com/SFEley/sinatra-flash so you can use the <tt>flash</tt> helper as in Rails. (0.10.9+)
220
210
 
221
- Internally, <tt>flash</tt> and <tt>flash?</tt> set and check the <tt>session[:flash]</tt> object.
211
+ Please go to the https://github.com/SFEley/sinatra-flash documentation for further reading. Is a nice gem and you might find it really useful.
222
212
 
223
213
  Code is poetry.
224
214
 
@@ -228,18 +218,11 @@ Since parsing YAML, Sass, Haml and CoffeeScript can be quite a burden for the pr
228
218
 
229
219
  Etags cause client side caching. This should not be a problem since the hash changes every time a source file is modified (including the YAML data files), forcing the User-Agent to update its cache, but still is worth noting as I might not be fully aware of cache-related issues that Etag-ging may trigger.
230
220
 
231
- == Gem dependencies
232
-
233
- * sinatra (http://sinatrarb.com)
234
- * haml (http://haml-lang.com)
235
- * sass (http://sass-lang.com)
236
- * coffee-script (http://github.com/josh/ruby-coffee-script)
237
-
238
221
  == Desired (future) features
239
222
 
240
- * Folder paths configurable.
223
+ * Features and specs covering all Piano's functionality.
224
+ * Agnosticism. Currently Piano is kind of HAML&SASS monotheistic.
241
225
  * <tt>style</tt> and <tt>script</tt> helpers working with symbols.
242
- * Further documentation of Piano helpers
243
226
  * More helpers for semantic data handling.
244
227
  * Deploy of sample with command line <tt>--sample</tt> argument.
245
228
  * Online source files edition.
@@ -247,13 +230,9 @@ Etags cause client side caching. This should not be a problem since the hash cha
247
230
  * Now it would be nice to give Piano personalized templates not only to 404 but for all error pages, specially 500
248
231
  * Custom error when there's no data
249
232
 
250
- ==== Done
233
+ == Known issues
251
234
 
252
- * Setup to production enviroment option (why not?!)
253
- * Etag on/off (currently etags are hardcoded on)
254
- * CoffeeScript appears to be working everywhere once <tt>therubyracer</tt> was setup to be suggested for install in no default javascript environment, so the nocoffee option was deleted.
255
- * Default Piano routes are now overridable.
256
- * No longer relevant since Piano is now fully extendable -> Test <tt>use Piano</tt> within a <tt>Sinatra::Base</tt> class.
235
+ * Sinatra::Piano rules break when a route consisting of only a number is passed
257
236
 
258
237
  == Tips
259
238
 
data/bin/piano CHANGED
@@ -28,35 +28,36 @@ unless ARGV.empty?
28
28
  end
29
29
 
30
30
  if args
31
- Piano::Base.port = args[:port] if args[:port]
32
- Piano::Base.environment = args[:environment] if args[:environment]
33
- Piano::Base.etags = args[:etags] if args[:etags]
34
- Piano::Base.views = File.expand_path(Dir.pwd) + "/" +args[:views] if args[:views]
35
- Piano::Base.public = File.expand_path(Dir.pwd) + "/" + args[:public] if args[:public]
31
+ Piano::Base.port = args[:port] if args[:port]
32
+ Piano::Base.environment = args[:environment] if args[:environment]
33
+ Piano::Base.etags = args[:etags] if args[:etags]
34
+ Piano::Base.views = args[:views] if args[:views]
35
+ Piano::Base.public = args[:public] if args[:public]
36
36
  end
37
37
 
38
38
  self.extend Metafun::Delegator
39
39
  self.delegate Piano::Base, :get, :patch, :put, :post, :delete,
40
- :head, :options, :template, :layout,
40
+ :head, :options, :template, :fetch, :layout,
41
41
  :before, :after, :error, :not_found,
42
42
  :configure, :set, :mime_type, :enable,
43
43
  :disable, :use, :development?, :test?,
44
- :production?, :helpers, :settings
44
+ :production?, :helpers, :settings, :play!
45
45
 
46
46
  self.helpers Sinatra::Piano
47
47
 
48
- $LOAD_PATH << Dir.pwd
48
+ $LOAD_PATH << Dir.pwd + "/lib"
49
49
 
50
- if File.exists?(File.expand_path(Dir.pwd) + "/Pianofile")
50
+ if File.exists?("Pianofile")
51
51
  puts "Pianofile found, loading..."
52
- load File.expand_path(Dir.pwd) + "/Pianofile"
52
+ load "Pianofile"
53
53
  end
54
54
 
55
- if File.exist?("controllers") && File.directory?("controllers")
55
+ if File.directory?("controllers")
56
56
  puts "'controllers' directory found, loading '.controller' files"
57
57
  Piano::ControllerLoader.folder "controllers"
58
58
  end
59
59
 
60
60
  require "piano/routes"
61
61
 
62
+ puts "Starting Sinatra from Piano #{Piano::VERSION}"
62
63
  Piano::Base.play!
@@ -1,6 +1,9 @@
1
1
  require "sinatra/base"
2
+ require "sinatra/flash"
3
+
2
4
  require "haml"
3
5
  require "sass"
6
+ require "compass"
4
7
  require "yaml"
5
8
  require "i18n"
6
9
 
@@ -14,33 +17,6 @@ end
14
17
 
15
18
  require "sinatra/piano"
16
19
 
17
- module Piano
18
- class Base < Sinatra::Base
19
- register Sinatra::Piano
20
-
21
- set :root, File.expand_path(Dir.pwd)
22
- set :views, File.expand_path(Dir.pwd)
23
- set :data, File.expand_path(Dir.pwd + "/data")
24
- set :etags, :on
25
- set :i18n_path, File.expand_path(Dir.pwd) + "/config/locale"
26
-
27
- def self.i18n!
28
- return unless Dir.exists? self.i18n_path
29
- dir = Dir.new self.i18n_path
30
- i18n_files = []
31
- dir.each do |file|
32
- if file.end_with?(".yml") or file.end_with?(".yaml")
33
- i18n_files << "#{dir.path}/#{file}"
34
- end
35
- end
36
- I18n.load_path = i18n_files
37
- end
38
-
39
- def self.play!
40
- self.run!
41
- end
42
- end
43
- end
44
-
20
+ require "piano/base"
45
21
  require "piano/controllerloader"
46
22
  require "piano/version"
@@ -0,0 +1,23 @@
1
+ module Piano
2
+ class Base < Sinatra::Base
3
+ register Sinatra::Piano
4
+ register Sinatra::Flash
5
+
6
+ Compass.configuration do |config|
7
+ config.project_path = File.expand_path(Dir.pwd)
8
+ config.sass_dir = File.expand_path(Dir.pwd)
9
+ end
10
+
11
+ # Defaults
12
+ set :root, File.expand_path(Dir.pwd)
13
+ set :views, File.expand_path(Dir.pwd)
14
+ set :sass, Compass.sass_engine_options
15
+ set :data, File.expand_path(Dir.pwd + "/data")
16
+ set :etags, :on
17
+ set :multidomain, :off
18
+
19
+ def self.play!
20
+ self.run!
21
+ end
22
+ end
23
+ end
@@ -2,7 +2,6 @@ module Piano
2
2
  # Handler of .controller files loading
3
3
  class ControllerLoader
4
4
  def self.folder path
5
- $LOAD_PATH << Dir.pwd
6
5
  recursive path do |item|
7
6
  load item
8
7
  end
@@ -2,23 +2,23 @@ module Piano
2
2
  class Base
3
3
  get "/" do
4
4
  @data = data_for "index"
5
- try_haml "index"
5
+ fetch :index
6
6
  end
7
7
 
8
8
  get %r{/(.+?).css$} do |something|
9
9
  content_type :css
10
- sass something
10
+ fetch something, :sass
11
11
  end
12
12
 
13
13
  get %r{/(.+?).js$} do |something|
14
14
  content_type :js
15
- coffee something
15
+ fetch something, :coffee
16
16
  end
17
17
 
18
18
  get "/*" do
19
19
  something = request.path[1..(request.path.length-1)]
20
20
  @data = data_for something
21
- try_haml something
21
+ fetch something
22
22
  end
23
23
  end
24
- end
24
+ end
@@ -1,3 +1,3 @@
1
1
  module Piano
2
- VERSION = "0.10.8"
2
+ VERSION = "0.11.0"
3
3
  end
@@ -2,43 +2,35 @@ module Sinatra
2
2
 
3
3
  # Piano was originally though as a Sinatra extension
4
4
  # That's why the code was defined here
5
- module Piano
5
+ module Piano
6
6
 
7
- # Like Sinatra's/Tilt's `haml`, but adds etags and
8
- # returns a 404 with some hints if the haml is not found
9
- def try_haml(template)
10
- file_name = "#{pwd}/#{template}.haml"
11
- bad_luck file_name unless File.exists? file_name
12
-
13
- if etags?
14
- hash = hash_for template, :haml
15
- hash += hash_for "data/#{template}", :yaml if File.exists? "#{pwd}/data/#{template}.yaml"
16
- etag hash
7
+ # Replacemente for :try_haml, :sass & :coffee. Agnostic
8
+ # Work in progress
9
+ def fetch *args
10
+ resource = args.shift
11
+ unless args.empty?
12
+ type = args.shift
13
+ else
14
+ type = :haml
17
15
  end
18
- haml template.to_sym
19
- end
20
-
21
- # Loads and parses a `sass` template from the :views directory.
22
- # Adds an etag if `etags?` is enabled and returns 404 and hints
23
- # if it can't find the .sass file.
24
- def sass(template)
25
- file_name = "#{pwd}/#{template}.sass"
26
- bad_luck file_name unless File.exists? file_name
16
+
17
+ file_name = "#{settings.views}/#{resource}.#{type}"
18
+ return bad_luck file_name unless File.exists? file_name
27
19
 
28
- etag hash_for(template, :sass) if etags?
29
- Sass.compile File.read(file_name), :syntax => :sass
30
- end
31
-
32
- # Loads and parses a `coffee-script` template from the :views
33
- # directory.
34
- # Adds an etag if `etags?` is enabled and returns 404 and hints
35
- # if it can't find the .coffee file.
36
- def coffee(template)
37
- file_name = "#{pwd}/#{template}.coffee"
38
- bad_luck file_name unless File.exists? file_name
20
+ if etags?
21
+ if type == :haml
22
+ hash = hash_for resource, :haml
23
+ if File.exists? "#{settings.views}/#{settings.data}/#{resource}.yaml"
24
+ hash += hash_for "#{settings.data}/#{resource}", :yaml
25
+ end
26
+
27
+ etag hash
28
+ else
29
+ etag hash_for(resource, type)
30
+ end
31
+ end
39
32
 
40
- etag hash_for(template, :coffee) if etags?
41
- CoffeeScript.compile(File.read(file_name))
33
+ send type, resource.to_sym, *args # Send the template to Sinatra to take care of it
42
34
  end
43
35
 
44
36
  # Loads and parses the YAML data from the data directory
@@ -48,18 +40,13 @@ module Sinatra
48
40
  end
49
41
 
50
42
  # Sugar: formats a css stylesheet <link /> tag with the input
51
- def style(path)
52
- "<link rel='stylesheet' type='text/css' href='#{path}' />"
43
+ def style path, more = ""
44
+ "<link rel='stylesheet' type='text/css' href='#{path}' #{more} />"
53
45
  end
54
46
 
55
47
  # Sugar: formats a javascript <script> tag with the input
56
- def script(path)
57
- "<script type='text/javascript' src='#{path}'></script>"
58
- end
59
-
60
- # Returns the path to the :views directory
61
- def pwd
62
- settings.views
48
+ def script path, more = ""
49
+ "<script type='text/javascript' src='#{path}' #{more} ></script>"
63
50
  end
64
51
 
65
52
  # Fails. Shouts a 404 response and prints hints
@@ -69,7 +56,7 @@ module Sinatra
69
56
  def bad_luck(path)
70
57
  content_type :html
71
58
  if settings.environment == :production
72
- if File.exists? "#{pwd}/404.haml"
59
+ if File.exists? "#{settings.views}/404.haml"
73
60
  @data = data_for "404"
74
61
  halt 404, haml(:"404")
75
62
  else
@@ -83,7 +70,7 @@ module Sinatra
83
70
  # Builds a hash for a file within the :views directory
84
71
  # Note: I feel like this functionality should be private
85
72
  def hash_for(name, type)
86
- "#{name}.#{type} - " + File.mtime("#{pwd}/#{name}.#{type}").to_s
73
+ "#{name}.#{type} - " + File.mtime("#{settings.views}/#{name}.#{type}").to_s
87
74
  end
88
75
 
89
76
  # Makes an extract out of the given text with the default length
@@ -130,30 +117,7 @@ module Sinatra
130
117
  true
131
118
  end
132
119
  end
133
-
134
- # Returns the session[:flash] if is defined, nil otherwise
135
- def flash?
136
- session[:flash]
137
- end
138
-
139
- # If an argument is passed, it sets the `session[:flash]` to the passed argument
140
- #
141
- # Otherwise, returns `session[:flash]` and removes `:flash` from the `session`
142
- # hash to make it available for subsequent requests.
143
- def flash data = nil
144
- if data
145
- session[:flash] = data
146
- else
147
- flash_text = session[:flash]
148
- session.delete :flash
149
- return flash_text
150
- end
151
- end
152
-
153
- # Non implemented yet
154
- def t(key)
155
- I18n.translate key
156
- end
120
+
157
121
  end
158
122
 
159
123
  register Piano
@@ -14,8 +14,10 @@ Gem::Specification.new do |s|
14
14
 
15
15
  s.rubyforge_project = "piano"
16
16
  s.add_dependency "sinatra", ">= 1.2.6"
17
+ s.add_dependency "sinatra-flash", ">= 0.3.0"
17
18
  s.add_dependency "haml", ">= 3.1.1"
18
19
  s.add_dependency "sass", ">= 3.1.1"
20
+ s.add_dependency "compass", ">= 0.12.2"
19
21
  s.add_dependency "coffee-script", ">= 2.2.0"
20
22
  s.add_dependency "i18n", ">= 0.6.0"
21
23
  s.add_dependency "metafun"
metadata CHANGED
@@ -1,98 +1,167 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: piano
3
- version: !ruby/object:Gem::Version
4
- version: 0.10.8
3
+ version: !ruby/object:Gem::Version
4
+ hash: 51
5
5
  prerelease:
6
+ segments:
7
+ - 0
8
+ - 11
9
+ - 0
10
+ version: 0.11.0
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Xavier Via
9
14
  autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
- date: 2012-01-08 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
17
+
18
+ date: 2012-07-27 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
15
21
  name: sinatra
16
- requirement: &5684900 !ruby/object:Gem::Requirement
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
17
24
  none: false
18
- requirements:
19
- - - ! '>='
20
- - !ruby/object:Gem::Version
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 19
29
+ segments:
30
+ - 1
31
+ - 2
32
+ - 6
21
33
  version: 1.2.6
22
34
  type: :runtime
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: sinatra-flash
23
38
  prerelease: false
24
- version_requirements: *5684900
25
- - !ruby/object:Gem::Dependency
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ hash: 19
45
+ segments:
46
+ - 0
47
+ - 3
48
+ - 0
49
+ version: 0.3.0
50
+ type: :runtime
51
+ version_requirements: *id002
52
+ - !ruby/object:Gem::Dependency
26
53
  name: haml
27
- requirement: &5684180 !ruby/object:Gem::Requirement
54
+ prerelease: false
55
+ requirement: &id003 !ruby/object:Gem::Requirement
28
56
  none: false
29
- requirements:
30
- - - ! '>='
31
- - !ruby/object:Gem::Version
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ hash: 1
61
+ segments:
62
+ - 3
63
+ - 1
64
+ - 1
32
65
  version: 3.1.1
33
66
  type: :runtime
34
- prerelease: false
35
- version_requirements: *5684180
36
- - !ruby/object:Gem::Dependency
67
+ version_requirements: *id003
68
+ - !ruby/object:Gem::Dependency
37
69
  name: sass
38
- requirement: &5683620 !ruby/object:Gem::Requirement
70
+ prerelease: false
71
+ requirement: &id004 !ruby/object:Gem::Requirement
39
72
  none: false
40
- requirements:
41
- - - ! '>='
42
- - !ruby/object:Gem::Version
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ hash: 1
77
+ segments:
78
+ - 3
79
+ - 1
80
+ - 1
43
81
  version: 3.1.1
44
82
  type: :runtime
83
+ version_requirements: *id004
84
+ - !ruby/object:Gem::Dependency
85
+ name: compass
45
86
  prerelease: false
46
- version_requirements: *5683620
47
- - !ruby/object:Gem::Dependency
87
+ requirement: &id005 !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ hash: 43
93
+ segments:
94
+ - 0
95
+ - 12
96
+ - 2
97
+ version: 0.12.2
98
+ type: :runtime
99
+ version_requirements: *id005
100
+ - !ruby/object:Gem::Dependency
48
101
  name: coffee-script
49
- requirement: &5682760 !ruby/object:Gem::Requirement
102
+ prerelease: false
103
+ requirement: &id006 !ruby/object:Gem::Requirement
50
104
  none: false
51
- requirements:
52
- - - ! '>='
53
- - !ruby/object:Gem::Version
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ hash: 7
109
+ segments:
110
+ - 2
111
+ - 2
112
+ - 0
54
113
  version: 2.2.0
55
114
  type: :runtime
56
- prerelease: false
57
- version_requirements: *5682760
58
- - !ruby/object:Gem::Dependency
115
+ version_requirements: *id006
116
+ - !ruby/object:Gem::Dependency
59
117
  name: i18n
60
- requirement: &5681280 !ruby/object:Gem::Requirement
118
+ prerelease: false
119
+ requirement: &id007 !ruby/object:Gem::Requirement
61
120
  none: false
62
- requirements:
63
- - - ! '>='
64
- - !ruby/object:Gem::Version
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ hash: 7
125
+ segments:
126
+ - 0
127
+ - 6
128
+ - 0
65
129
  version: 0.6.0
66
130
  type: :runtime
67
- prerelease: false
68
- version_requirements: *5681280
69
- - !ruby/object:Gem::Dependency
131
+ version_requirements: *id007
132
+ - !ruby/object:Gem::Dependency
70
133
  name: metafun
71
- requirement: &5680880 !ruby/object:Gem::Requirement
134
+ prerelease: false
135
+ requirement: &id008 !ruby/object:Gem::Requirement
72
136
  none: false
73
- requirements:
74
- - - ! '>='
75
- - !ruby/object:Gem::Version
76
- version: '0'
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ hash: 3
141
+ segments:
142
+ - 0
143
+ version: "0"
77
144
  type: :runtime
78
- prerelease: false
79
- version_requirements: *5680880
80
- description: Out-of-the-box sinatra server for web site sketching using haml + sass
81
- + coffee-script
82
- email:
145
+ version_requirements: *id008
146
+ description: Out-of-the-box sinatra server for web site sketching using haml + sass + coffee-script
147
+ email:
83
148
  - xavierviacanel@gmail.com
84
- executables:
149
+ executables:
85
150
  - piano
86
151
  - piano~
87
152
  extensions: []
153
+
88
154
  extra_rdoc_files: []
89
- files:
155
+
156
+ files:
90
157
  - .gitignore
158
+ - Gemfile
91
159
  - README.rdoc
92
160
  - Rakefile
93
161
  - bin/piano
94
162
  - bin/piano~
95
163
  - lib/piano.rb
164
+ - lib/piano/base.rb
96
165
  - lib/piano/controllerloader.rb
97
166
  - lib/piano/routes.rb
98
167
  - lib/piano/version.rb
@@ -104,28 +173,36 @@ files:
104
173
  - sample/style.sass
105
174
  homepage: http://github.com/xaviervia/piano
106
175
  licenses: []
176
+
107
177
  post_install_message:
108
178
  rdoc_options: []
109
- require_paths:
179
+
180
+ require_paths:
110
181
  - lib
111
- required_ruby_version: !ruby/object:Gem::Requirement
182
+ required_ruby_version: !ruby/object:Gem::Requirement
112
183
  none: false
113
- requirements:
114
- - - ! '>='
115
- - !ruby/object:Gem::Version
116
- version: '0'
117
- required_rubygems_version: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ hash: 3
188
+ segments:
189
+ - 0
190
+ version: "0"
191
+ required_rubygems_version: !ruby/object:Gem::Requirement
118
192
  none: false
119
- requirements:
120
- - - ! '>='
121
- - !ruby/object:Gem::Version
122
- version: '0'
193
+ requirements:
194
+ - - ">="
195
+ - !ruby/object:Gem::Version
196
+ hash: 3
197
+ segments:
198
+ - 0
199
+ version: "0"
123
200
  requirements: []
201
+
124
202
  rubyforge_project: piano
125
- rubygems_version: 1.8.10
203
+ rubygems_version: 1.8.15
126
204
  signing_key:
127
205
  specification_version: 3
128
- summary: Out-of-the-box sinatra server for web site sketching using haml + sass +
129
- coffee-script
206
+ summary: Out-of-the-box sinatra server for web site sketching using haml + sass + coffee-script
130
207
  test_files: []
131
- has_rdoc:
208
+