liquid_assets 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,18 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ gem 'liquid'
7
+ gem 'tilt'
8
+ gem 'sprockets'
9
+ gem 'execjs'
10
+
11
+
12
+ # Add dependencies to develop your gem here.
13
+ # Include everything needed to run rake, tests, features, etc.
14
+ group :development do
15
+ gem "rdoc"
16
+ gem "bundler"
17
+ gem "jeweler"
18
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,37 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ execjs (1.4.0)
5
+ multi_json (~> 1.0)
6
+ git (1.2.5)
7
+ hike (1.2.1)
8
+ jeweler (1.8.4)
9
+ bundler (~> 1.0)
10
+ git (>= 1.2.5)
11
+ rake
12
+ rdoc
13
+ json (1.7.7)
14
+ liquid (2.5.0)
15
+ multi_json (1.6.1)
16
+ rack (1.5.2)
17
+ rake (10.0.3)
18
+ rdoc (4.0.0)
19
+ json (~> 1.4)
20
+ sprockets (2.2.2)
21
+ hike (~> 1.2)
22
+ multi_json (~> 1.0)
23
+ rack (~> 1.0)
24
+ tilt (~> 1.1, != 1.3.0)
25
+ tilt (1.3.5)
26
+
27
+ PLATFORMS
28
+ ruby
29
+
30
+ DEPENDENCIES
31
+ bundler
32
+ execjs
33
+ jeweler
34
+ liquid
35
+ rdoc
36
+ sprockets
37
+ tilt
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013 Nathan Stitt
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,160 @@
1
+ # liquid_assets version 0.1.0
2
+
3
+ ## Description
4
+
5
+ Allows you to use the Liquid template language in Rails, both as
6
+ templates and as JavaScript via the asset_pipeline.
7
+
8
+ **Warning!** This is very rough, and only minimally tested. Version
9
+ 0.1 really does mean 0.1 in this case!
10
+
11
+ Although I'm going to attempt to minimize breaking changes, there may
12
+ be a few as I discover bugs and/or better methods of implementing
13
+ features.
14
+
15
+ My future goals for it are to add template inheritance/override
16
+ support and read template's from active_record. *(probably via a
17
+ supplied Proc)*
18
+
19
+ The Ruby bits are via the standard Liquid http://liquidmarkup.org/
20
+ gem.
21
+
22
+ The JavaScript support is possible through the TinyLiquid
23
+ https://github.com/leizongmin/tinyliquid JavaScript library, which
24
+ execjs calls to compiles the templates to JavaScript. I did have to
25
+ perform a few small modifications to the library in order to get it to
26
+ support partials in the same manner as the Ruby library
27
+
28
+ ## Rationale
29
+ I am currently developing a largish project that has a requirement for
30
+ user edited html that needs to be rendered both as a standard website
31
+ and as a single page Backbone application.
32
+
33
+ I'd originally attempted to use Mustache templates but discarded that
34
+ idea after not being able to do simple things like formatting numbers
35
+ in the views.
36
+
37
+ Liquid templates were ideal, but they lacked a suitable JS
38
+ environment. I then ran across the TinyLiquid project and decided to
39
+ create a gem to unite the two.
40
+
41
+
42
+ ## Usage
43
+
44
+ Set the root in an initializer, i.e. config/initializers/liquid_assets.rb
45
+ The root defaults to app/assets/templates.
46
+
47
+ LiquidAssets::Config.configure do |config|
48
+ config.path_prefix = 'app/assets/templates'
49
+ config.filters = MyFilterModule
50
+ config.template_namespace = 'LQT'
51
+ end
52
+
53
+
54
+ ### Use as Rails views
55
+
56
+ Create a view just like you would with erb, except with .liquid as the extension.
57
+
58
+ app/assets/templates/blog/post.liquid
59
+
60
+ Since the template is written in Liquid, it DOES NOT have access to
61
+ the normal rails helper methods.
62
+
63
+ It does have access to instance variables, but can only interact with
64
+ simple Strings, Numbers, Arrays, & Hashes. An additional restriction
65
+ is that Hashes must use strings for keys, not symbols.
66
+
67
+ I'm sure some of these limitations could be worked around, but my
68
+ needs do not include supporting them at this time. *Patches are welcomed*
69
+
70
+
71
+ By default the filters are set to the Liquid::StandardFilters
72
+ http://liquid.rubyforge.org/classes/Liquid/StandardFilters.html This
73
+ can be changed by including a liquid_filters method on the controller,
74
+ or in application_controller to set system-wide. *(assuming you are
75
+ inheriting from it)*
76
+
77
+ A short example:
78
+
79
+ blog_controller.rb:
80
+
81
+ def show
82
+ @ages={'bob'=>28,'joe'=>23}
83
+ render :template=>'blog/post'
84
+ end
85
+
86
+ app/assets/templates/blog/post.liquid :
87
+
88
+ Bob is {{ages.bob}}, older than Joe - who's only {{ages.joe}}.
89
+
90
+ But this will not since @bob is not a hash.
91
+
92
+ controller:
93
+
94
+ def show
95
+ @old=People.where({:name=>'bob',:age=>100}).first
96
+ render :template=>'blog/post'
97
+ end
98
+
99
+ (contrived) liquid view:
100
+
101
+ Bob's age is {{old.age}}
102
+
103
+ **Hint:** To get it to work, call as_json on your models:
104
+
105
+ @old=People.where({:name=>'bob',:age=>100}).first.as_json
106
+
107
+
108
+ ### Use as AssetPipeline pre-compiled javascript
109
+
110
+ You can include your liquid templates in the asset_pipeline by
111
+ using the standard //= syntax in one of your existing JavaScript files
112
+
113
+ //=require liquid_assets
114
+ //=require templates/blog/post
115
+
116
+ Will compile post.liquid to JavaScript using TinyLiquid and include it like so
117
+
118
+ LQT['templates/blog/post'] = function(locals,filters){ ... }
119
+
120
+ It can be used similar to underscore's JST template.
121
+
122
+ With filters:
123
+
124
+ LQT['templates/blog/post']( { bob:{ age: 23 } }, {
125
+ plusTen: function(num){ return num+10; }
126
+ })
127
+
128
+ Template:
129
+
130
+ Bob will be {{bob.age | plusTen}} in ten years.
131
+
132
+ Renders to:
133
+ Bob will be 33 in ten years.
134
+
135
+ The LQT namespace is short for LiQuid Template, à la JST from underscore.
136
+
137
+ It can be modified by configuring:
138
+
139
+ LiquidAssets::Config.configure do |config|
140
+ config.template_namespace = 'FANCY_NAME'
141
+ end
142
+
143
+ ## Thanks
144
+
145
+ [Shopify](http://www.shopify.com/)
146
+ for creating the liquid template language and Ruby implementation. [leizongmin](https://github.com/leizongmin/tinyliquid) for the
147
+ tinyliquid Javascript support.
148
+
149
+ I cribbed from [hogan_assets](https://github.com/leshill/hogan_assets/), [Poirot](https://github.com/olivernn/poirot) and [Stache](https://github.com/agoragames/stache/) in creating this gem. Good parts
150
+ are thanks to those projects, mistakes are mine.
151
+
152
+
153
+ ## Contributing
154
+ Fork on [github](https://github.com/nathanstitt/liquid_assets), implement your change, submit a pull request.
155
+
156
+
157
+ ## Copyright
158
+
159
+ Copyright (c) 2013 Nathan Stitt. See LICENSE.txt for
160
+ further details.
data/Rakefile ADDED
@@ -0,0 +1,46 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "liquid_assets"
18
+ gem.homepage = "http://github.com/nathanstitt/liquid_assets"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Liquid formmated views and assets}
21
+ gem.description = %Q{Allows you to use Liquid format templates in Rails, both as
22
+ view templates and as compiled JavaScript via the asset_pipeline.}
23
+ gem.email = "nathan@stitt.org"
24
+ gem.authors = ["Nathan Stitt"]
25
+ # dependencies defined in Gemfile
26
+ end
27
+ Jeweler::RubygemsDotOrgTasks.new
28
+
29
+ require 'rake/testtask'
30
+ Rake::TestTask.new(:test) do |test|
31
+ test.libs << 'lib' << 'test'
32
+ test.pattern = 'test/**/test_*.rb'
33
+ test.verbose = true
34
+ end
35
+
36
+ task :default => :test
37
+
38
+ require 'rdoc/task'
39
+ Rake::RDocTask.new do |rdoc|
40
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
41
+ rdoc.main = 'README.md'
42
+ rdoc.rdoc_dir = 'rdoc'
43
+ rdoc.title = "liquid_assets #{version}"
44
+ rdoc.rdoc_files.include('README.md')
45
+ rdoc.rdoc_files.include('lib/liquid_assets/config.rb')
46
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.1
@@ -0,0 +1,102 @@
1
+ require 'yaml'
2
+
3
+ module LiquidAssets
4
+ # Change config options in an initializer:
5
+ #
6
+ # LiquidAssets::Config.template_namespace = 'LT'
7
+ #
8
+ # Or in a block:
9
+ #
10
+ # LiquidAssets::Config.configure do |config|
11
+ # config.path_prefix = 'app/assets/templates'
12
+ # config.filters = MyFilterModule
13
+ # config.template_namespace = 'LQT'
14
+ # end
15
+ #
16
+ # Or change config options in a YAML file (config/liquid_assets.yml):
17
+ #
18
+ # defaults: &defaults
19
+ # path_prefix: 'templates'
20
+ # template_namespace: 'LQT'
21
+ # development:
22
+ # <<: *defaults
23
+ # test:
24
+ # <<: *defaults
25
+ # production:
26
+ # <<: *defaults
27
+
28
+ module Config
29
+ extend self
30
+
31
+ # The environment. Defaults to Rails.env if Rails is detected, otherwise to 'development'
32
+ attr_writer :env
33
+ # Directory to read templates from. Default = app/assets/templates
34
+ attr_writer :path_prefix
35
+ # The name of the global JS object that will contain the templates. Defaults = LQT
36
+ attr_writer :template_namespace
37
+ # A Ruby module implementing the Liquid Filters that are accessible when templates are evaluated as views
38
+ # Javascript filters must be passed as the second parameter given when evaluating a precompiled template
39
+ attr_writer :filters
40
+
41
+ def configure
42
+ yield self
43
+ end
44
+
45
+ def env
46
+ @env ||= if defined? Rails
47
+ Rails.env
48
+ elsif ENV['RACK_ENV']
49
+ ENV['RACK_ENV']
50
+ else
51
+ 'development'
52
+ end
53
+ end
54
+
55
+ def load_yml!
56
+ @path_prefix = yml['path_prefix'] if yml.has_key? 'path_prefix'
57
+ @template_namespace = yml['template_namespace'] if yml.has_key? 'template_namespace'
58
+ end
59
+
60
+ def path_prefix
61
+ @path_prefix ||= File.join('app','assets','templates')
62
+ end
63
+
64
+ def root_path
65
+ if defined? Rails
66
+ Rails.root
67
+ else
68
+ Pathname.new('.')
69
+ end
70
+ end
71
+ def filters
72
+ @filters ||= Liquid::StandardFilters
73
+ end
74
+ def template_namespace
75
+ @template_namespace ||= 'LQT'
76
+ end
77
+
78
+ def yml
79
+ begin
80
+ @yml ||= (YAML.load(IO.read yml_path)[env] rescue nil) || {}
81
+ rescue Psych::SyntaxError
82
+ @yml = {}
83
+ end
84
+ end
85
+
86
+ def yml_exists?
87
+ File.exists? yml_path
88
+ end
89
+
90
+ private
91
+
92
+ def symbolize(hash)
93
+ hash.keys.each do |key|
94
+ hash[(key.to_sym rescue key) || key] = hash.delete(key)
95
+ end
96
+ end
97
+
98
+ def yml_path
99
+ @yml_path ||= root_path.join 'config', 'liquid_assets.yml'
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,25 @@
1
+ require 'liquid_assets/tilt_engine'
2
+
3
+ module LiquidAssets
4
+
5
+ class Engine < ::Rails::Engine
6
+
7
+ initializer "sprockets.liquid_assets", :after => "sprockets.environment", :group => :all do |app|
8
+ next unless app.assets
9
+
10
+ LiquidAssets::Config.load_yml! if LiquidAssets::Config.yml_exists?
11
+
12
+
13
+ ActionView::Template.register_template_handler(:liquid, LiquidAssets::TemplateHandler )
14
+
15
+ app.assets.register_engine(".liquid", ::LiquidAssets::TiltEngine )
16
+
17
+ app.config.to_prepare do
18
+ Liquid::Template.file_system = Liquid::LocalFileSystem.new( Config.root_path )
19
+ ApplicationController.send( :append_view_path, LiquidAssets::Config.path_prefix )
20
+ end
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,52 @@
1
+ require 'liquid'
2
+
3
+ module LiquidAssets
4
+
5
+
6
+ class TemplateHandler
7
+
8
+ def self.call(template)
9
+ # view_path = "#{template.virtual_path}_view"
10
+ # abs_view_path = Rails.root.join('app/views', view_path)
11
+ # Rails.logger.warn "looking for: #{abs_view_path}"
12
+ return "LiquidAssets::TemplateHandler.new(self).render(#{template.source.inspect}, local_assigns)"
13
+ end
14
+
15
+ def initialize(view)
16
+ @view = view
17
+ end
18
+
19
+ def render(template, local_assigns = {})
20
+ @view.controller.headers["Content-Type"] ||= 'text/html; charset=utf-8'
21
+
22
+ assigns = @view.assigns
23
+
24
+ if content = @view.content_for?(:layout)
25
+ assigns["content_for_layout"] = content
26
+ end
27
+ assigns.merge!(local_assigns.stringify_keys)
28
+
29
+ controller = @view.controller
30
+ filters = if controller.respond_to?(:liquid_filters, true)
31
+ controller.send(:liquid_filters)
32
+ else
33
+ Config.filters
34
+ end
35
+
36
+ liquid = ::Liquid::Template.parse(template)
37
+ liquid.render(assigns,
38
+ :filters => filters,
39
+ :registers => {
40
+ :action_view => @view,
41
+ :controller => @view.controller
42
+ } ).html_safe
43
+ end
44
+
45
+ def compilable?
46
+ false
47
+ end
48
+
49
+
50
+ end
51
+
52
+ end
@@ -0,0 +1,54 @@
1
+ require 'tilt'
2
+
3
+ module LiquidAssets
4
+
5
+ class TiltEngine < Tilt::Template
6
+
7
+ self.default_mime_type = 'application/javascript'
8
+
9
+ # def initialize_engine
10
+ # end
11
+
12
+ def evaluate(scope, locals, &block)
13
+
14
+ template_path = TemplatePath.new scope
15
+ template_namespace = LiquidAssets::Config.template_namespace
16
+
17
+ compiled_template = TinyLiquid.compile(data)
18
+
19
+ <<-TEMPLATE
20
+ this.#{template_namespace} || (this.#{template_namespace} = {});
21
+ this.#{template_namespace}[#{template_path.name}] = #{compiled_template};
22
+ TEMPLATE
23
+ end
24
+
25
+ protected
26
+
27
+
28
+ def prepare;
29
+ # NOOP
30
+ end
31
+
32
+ class TemplatePath
33
+ attr_accessor :full_path
34
+
35
+ def initialize(scope)
36
+ self.template_path = scope.logical_path
37
+ self.full_path = scope.pathname
38
+ end
39
+
40
+ def name
41
+ @name ||= relative_path.dump
42
+ end
43
+
44
+ private
45
+
46
+ attr_accessor :template_path
47
+
48
+ def relative_path
49
+ @relative_path ||= template_path.gsub(/^#{LiquidAssets::Config.path_prefix}\/(.*)$/i, "\\1")
50
+ end
51
+ end
52
+ end
53
+
54
+ end
@@ -0,0 +1,41 @@
1
+ # Based on https://github.com/josh/ruby-coffee-script
2
+ require 'execjs'
3
+ require 'pathname'
4
+
5
+ module LiquidAssets
6
+
7
+ class TinyLiquid
8
+
9
+ class << self
10
+ def compile(source, options = {})
11
+ js = context.eval("TinyLiquid.parse(#{source.inspect},{partials_namespace:'#{Config.template_namespace}'}).code")
12
+ # js = context.eval("TinyLiquid.compile(#{source.inspect}, {original: true}).toString()")
13
+ "function(locals,filters){
14
+ var $_tmpbuf, $_html = LQT._FNS.html, $_err = LQT._FNS.err, $_rethrow=LQT._FNS.rethrow, $_merge=LQT._FNS.merge, $_range=LQT._FNS.range, $_array=LQT._FNS.array;
15
+ #{js}
16
+ return $_buf;
17
+ }"
18
+ end
19
+
20
+ private
21
+
22
+ def context
23
+ @context ||= ExecJS.compile(source)
24
+ end
25
+
26
+ def source
27
+ @source ||= path.read
28
+ end
29
+
30
+ def path
31
+ @path ||= assets_path.join('tinyliquid.js')
32
+ end
33
+
34
+ def assets_path
35
+ @assets_path ||= Pathname(__FILE__).dirname.join('..','..','vendor')
36
+ end
37
+ end
38
+
39
+ end
40
+
41
+ end
@@ -0,0 +1,3 @@
1
+ module LiquidAssets
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,21 @@
1
+ require 'liquid_assets/version'
2
+ require 'liquid_assets/config'
3
+ require 'liquid_assets/template_handler'
4
+ require 'liquid_assets/tilt_engine'
5
+ module LiquidAssets
6
+
7
+ extend Config
8
+
9
+ autoload :TinyLiquid, 'liquid_assets/tiny_liquid'
10
+ autoload :TiltEngine, 'liquid_assets/tilt_engine'
11
+
12
+ if defined? Rails
13
+ require 'liquid_assets/engine'
14
+ else
15
+ require 'sprockets'
16
+ Config.load_yml! if Config.yml_exists?
17
+
18
+ Sprockets.register_engine ".liquid", Tilt
19
+
20
+ end
21
+ end
@@ -0,0 +1,76 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "liquid_assets"
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Nathan Stitt"]
12
+ s.date = "2013-03-14"
13
+ s.description = "Allows you to use Liquid format templates in Rails, both as\nview templates and as compiled JavaScript via the asset_pipeline."
14
+ s.email = "nathan@stitt.org"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.md"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ "Gemfile",
22
+ "Gemfile.lock",
23
+ "LICENSE.txt",
24
+ "README.md",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "lib/liquid_assets.rb",
28
+ "lib/liquid_assets/config.rb",
29
+ "lib/liquid_assets/engine.rb",
30
+ "lib/liquid_assets/template_handler.rb",
31
+ "lib/liquid_assets/tilt_engine.rb",
32
+ "lib/liquid_assets/tiny_liquid.rb",
33
+ "lib/liquid_assets/version.rb",
34
+ "liquid_assets.gemspec",
35
+ "test/helper.rb",
36
+ "test/test_liquid_assets.rb",
37
+ "vendor/assets/javascripts/liquid_assets.js",
38
+ "vendor/tinyliquid.js"
39
+ ]
40
+ s.homepage = "http://github.com/nathanstitt/liquid_assets"
41
+ s.licenses = ["MIT"]
42
+ s.require_paths = ["lib"]
43
+ s.rubygems_version = "1.8.23"
44
+ s.summary = "Liquid formmated views and assets"
45
+
46
+ if s.respond_to? :specification_version then
47
+ s.specification_version = 3
48
+
49
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
50
+ s.add_runtime_dependency(%q<liquid>, [">= 0"])
51
+ s.add_runtime_dependency(%q<tilt>, [">= 0"])
52
+ s.add_runtime_dependency(%q<sprockets>, [">= 0"])
53
+ s.add_runtime_dependency(%q<execjs>, [">= 0"])
54
+ s.add_development_dependency(%q<rdoc>, [">= 0"])
55
+ s.add_development_dependency(%q<bundler>, [">= 0"])
56
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
57
+ else
58
+ s.add_dependency(%q<liquid>, [">= 0"])
59
+ s.add_dependency(%q<tilt>, [">= 0"])
60
+ s.add_dependency(%q<sprockets>, [">= 0"])
61
+ s.add_dependency(%q<execjs>, [">= 0"])
62
+ s.add_dependency(%q<rdoc>, [">= 0"])
63
+ s.add_dependency(%q<bundler>, [">= 0"])
64
+ s.add_dependency(%q<jeweler>, [">= 0"])
65
+ end
66
+ else
67
+ s.add_dependency(%q<liquid>, [">= 0"])
68
+ s.add_dependency(%q<tilt>, [">= 0"])
69
+ s.add_dependency(%q<sprockets>, [">= 0"])
70
+ s.add_dependency(%q<execjs>, [">= 0"])
71
+ s.add_dependency(%q<rdoc>, [">= 0"])
72
+ s.add_dependency(%q<bundler>, [">= 0"])
73
+ s.add_dependency(%q<jeweler>, [">= 0"])
74
+ end
75
+ end
76
+