lilu 0.1.0

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.
@@ -0,0 +1,268 @@
1
+ require 'rubygems'
2
+ require 'hpricot'
3
+ require 'active_support'
4
+
5
+ class Hpricot::Elem
6
+ attr_accessor :cache_search
7
+ alias :_search :search
8
+ def search(expr,&block)
9
+ if @_inner_html
10
+ self.inner_html= @_inner_html
11
+ @_inner_html = nil
12
+ end
13
+ if cache_search
14
+ @_search ||= {}
15
+ @_search[expr] || @_search[expr] = _search(expr,&block)
16
+ else
17
+ _search(expr,&block)
18
+ end
19
+ end
20
+
21
+ def _inner_html=(html)
22
+ @_inner_html = html
23
+ end
24
+
25
+ alias :_output :output
26
+ def output(out, opts={})
27
+ if @_inner_html
28
+ if empty? and ElementContent[@stag.name] == :EMPTY
29
+ @stag.output(out, opts.merge(:style => :empty))
30
+ else
31
+ @stag.output(out, opts)
32
+ out << @_inner_html
33
+ if @etag
34
+ @etag.output(out, opts)
35
+ elsif !opts[:preserve]
36
+ ETag.new(@stag.name).output(out,opts)
37
+ end
38
+ end
39
+ else
40
+ _output(out,opts)
41
+ end
42
+ end
43
+
44
+ end
45
+ module Lilu
46
+
47
+ module Version ; MAJOR, MINOR, TINY = 0, 1, 0 ; end
48
+
49
+ class Action
50
+ attr_accessor :element
51
+ attr_reader :renderer
52
+ def initialize(element,renderer)
53
+ @element, @renderer = element, renderer
54
+ renderer.action = self
55
+ end
56
+ end
57
+
58
+
59
+ class Populate < Action
60
+ def for(method,data,&block)
61
+ return element.collect {|e| self.element = e ; renderer.instance_eval { action.for(method,data,&block) } } if element.is_a?(Hpricot::Elements)
62
+
63
+ element.cache_search = true
64
+ update_action = Update.new(element,renderer)
65
+ parent = element.parent
66
+ element_html = element.to_html
67
+ data.send(method) do |*objects|
68
+ update_action.element = element
69
+ update_action.with(block.call(*objects))
70
+
71
+ parent.insert_after(Hpricot.make(element.to_html),element)
72
+ element = Hpricot.make(element_html)
73
+ end
74
+ renderer.action = self
75
+
76
+ Hpricot::Elements[element].remove
77
+ end
78
+ end
79
+
80
+ class Remove < Action
81
+ def initialize(*args)
82
+ super(*args)
83
+ return element.remove if element.is_a?(Hpricot::Elements)
84
+ Hpricot::Elements[element].remove
85
+ end
86
+ end
87
+
88
+ class Replace < Action
89
+ def with(new_element=nil,&block)
90
+ return element.collect {|e| self.element = e ; renderer.instance_eval { action.with(new_element) } } if element.is_a?(Hpricot::Elements)
91
+ case new_element
92
+ when String
93
+ element.swap new_element
94
+ when Hpricot::Elem
95
+ Hpricot::Elements[new_element].remove
96
+ element.parent.insert_after(new_element,element)
97
+ Hpricot::Elements[element].remove
98
+ when Proc
99
+ with(new_element.call.to_s)
100
+ when nil
101
+ with(block.call) if block_given?
102
+ else
103
+ element.swap new_element.to_s
104
+ end
105
+ end
106
+ end
107
+
108
+ class Update < Action
109
+
110
+ def with(arg=nil,&block)
111
+ return element.collect {|e| self.element = e ; renderer.instance_eval { action.with(arg,&block) } } if element.is_a?(Hpricot::Elements)
112
+ case arg
113
+ when Hash
114
+ arg.each_pair do |path,value|
115
+ value = value.call if value.is_a?(Proc)
116
+ case path
117
+ when String
118
+ elem = element.at(path)
119
+ raise ElementNotFound.new("Element #{elem} not found") unless elem
120
+
121
+ saved_element = element
122
+ self.element = elem
123
+ res = with(value,&block)
124
+ self.element = saved_element
125
+ res
126
+ when Replacing
127
+ Replace.new(path.element,renderer).with value.to_s
128
+ when renderer
129
+ element._inner_html = value.to_s
130
+ else
131
+ element[path] = value.to_s
132
+ end
133
+ end
134
+ when Proc
135
+ with arg.call
136
+ when nil
137
+ with renderer.instance_eval(&block) if block_given?
138
+ else
139
+ element._inner_html = arg.to_s
140
+ end
141
+ end
142
+
143
+
144
+ end
145
+
146
+ class Use < Action
147
+ def initialize(*args)
148
+ super(*args)
149
+ raise ArgumentError.new("Use action can not accept :all parameter") if element.is_a?(Hpricot::Elements)
150
+ renderer.doc = element
151
+ end
152
+ end
153
+
154
+ # Experimental stuff
155
+ class Replacing
156
+ attr_reader :element
157
+ def initialize(renderer,element)
158
+ @renderer = renderer
159
+ case element
160
+ when String
161
+ @element = renderer.element_at(element)
162
+ when Hpricot::Elem, Hpricot::Elements
163
+ @element = element
164
+ end
165
+ end
166
+ end
167
+ #
168
+
169
+ class ElementNotFound < Exception
170
+ def initialize(element)
171
+ super("Element #{element} was not found")
172
+ end
173
+ end
174
+
175
+ class Renderer
176
+ attr_accessor :action, :doc
177
+ attr_reader :instructions, :html_source
178
+
179
+ def element
180
+ action.element
181
+ end
182
+
183
+ def initialize(instructions,html_source,local_assignments={})
184
+ @instructions = instructions
185
+ @html_source = html_source
186
+ @doc = Hpricot(@html_source)
187
+ @view = local_assignments["___view"] if local_assignments.is_a?(Hash)
188
+ inject_local_assignments(local_assignments)
189
+ end
190
+
191
+
192
+ def apply
193
+ eval(@instructions) do |*name|
194
+ name = name.first
195
+ name = 'layout' if name.nil?
196
+ instance_variable_get("@content_for_#{name}")
197
+ end
198
+ @doc.to_html
199
+ end
200
+
201
+ %w[update populate remove use replace].each {|method_name| module_eval <<-EOL
202
+ def #{method_name}(*path)
203
+ elem = find_elements(*path)
204
+ path.pop if path.first == :all
205
+ raise ElementNotFound.new(path) unless elem
206
+ Lilu::#{method_name.camelize}.new(elem,self)
207
+ end
208
+ EOL
209
+ }
210
+
211
+
212
+ def mapping(opts={})
213
+ opts
214
+ end
215
+
216
+ # Helper for partials
217
+ def partial(name,opts={})
218
+ render({:partial => name}.merge(opts))
219
+ end
220
+
221
+ # Helper for lambda
222
+ alias_method :L, :lambda
223
+
224
+ def element_at(path)
225
+ doc.at(path)
226
+ end
227
+
228
+ def method_missing(sym,*args)
229
+ return @view.send(sym,*args) if @view and @view.respond_to?(sym)
230
+ return instance_variable_get("@#{sym}") if args.empty? and instance_variables.member? "@#{sym}"
231
+ return @controller.send(sym, *args) if @controller and @controller.respond_to?(sym)
232
+ raise NoMethodError.new(sym.to_s)
233
+ end
234
+
235
+ # Helper for replacing
236
+ def replacing(element)
237
+ Replacing.new(self,element)
238
+ end
239
+
240
+ protected
241
+
242
+ def find_elements(*path)
243
+ path_first, path_second = path[0], path[1]
244
+ case path_first
245
+ when Hpricot::Elem, Hpricot::Elements
246
+ path_first
247
+ when :all
248
+ raise InvalidArgument.new("if :all is specified, second argument with path should be specified as well") unless path_second
249
+ doc.search(path_second)
250
+ else
251
+ doc.at(path_first)
252
+ end
253
+ end
254
+
255
+ def inject_local_assignments(local_assignments)
256
+ case local_assignments
257
+ when Hash
258
+ local_assignments.each_pair {|ivar,val| instance_variable_set(ivar.to_s.starts_with?('@') ? ivar : "@#{ivar}", val) }
259
+ when Binding
260
+ eval("instance_variables",local_assignments).each {|ivar| instance_variable_set(ivar, eval("instance_variable_get('#{ivar}')",local_assignments)) }
261
+ else
262
+ local_assignments.instance_variables.each {|ivar| instance_variable_set(ivar.to_s.starts_with?('@') ? ivar : "@#{ivar}", local_assignments.instance_variable_get(ivar)) }
263
+ end
264
+ end
265
+
266
+ end
267
+
268
+ end
@@ -0,0 +1,22 @@
1
+ module Lilu
2
+ module Camping
3
+ def self.for(app,path)
4
+ app.module_eval do
5
+ include Lilu::Camping
6
+ @@templates = path
7
+ end
8
+ end
9
+
10
+ def render(m,layout=true)
11
+ @content_for_layout = render_lilu(m)
12
+ render_lilu("layout") if layout
13
+ end
14
+
15
+ protected
16
+
17
+ def render_lilu(m)
18
+ Lilu::Renderer.new(IO.read("#{@@templates}/templates/#{m}.lilu"),IO.read("#{@@templates}/templates/#{m}.html"),binding).apply
19
+ end
20
+ end
21
+ end
22
+
@@ -0,0 +1,16 @@
1
+ require File.dirname(__FILE__) + '/lilu'
2
+ module Lilu
3
+ class View
4
+ def initialize(view)
5
+ @view = view
6
+ end
7
+ def render(template, local_assigns = {})
8
+ lilu_file_path = local_assigns[:lilu_file_path]
9
+ local_assigns.delete :lilu_file_path
10
+ @view.instance_eval do
11
+ local_assigns.merge!("content_for_layout" => @content_for_layout,"controller" => @controller,"___view" => self)
12
+ Lilu::Renderer.new(template,IO.read(lilu_file_path.gsub(/#{File.extname(lilu_file_path)}$/,'.html')),@assigns.merge(local_assigns)).apply
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,223 @@
1
+ require File.dirname(__FILE__) + '/../lib/lilu'
2
+ require 'ostruct'
3
+ describe "Newly created ", Lilu::Renderer do
4
+
5
+ before(:each) do
6
+ @instructions = "remove('html')"
7
+ @html_source = "<html></html>"
8
+ @renderer = Lilu::Renderer.new(@instructions,@html_source)
9
+ end
10
+
11
+ it "should load instructions" do
12
+ @renderer.instructions.should == @instructions
13
+ end
14
+
15
+ it "should load html source" do
16
+ @renderer.html_source.should == @html_source
17
+ end
18
+ end
19
+
20
+ describe "Newly created ", Lilu::Renderer, " with local assignments" do
21
+
22
+ before(:all) do
23
+ @test_variable = "Lilu"
24
+ end
25
+
26
+ { "binding" => lambda {|s| s.instance_eval "binding" },
27
+ "Hash with variable names without @ prefix" => { "test_variable" => "Lilu" },
28
+ "Hash with variable names with @ prefix" => { "@test_variable" => "Lilu" },
29
+ "Object with instance variables" => Object.new.instance_eval { @test_variable = "Lilu" ; self}
30
+ }.each_pair do |name, val|
31
+ it "should load instance variable from #{name}" do
32
+ @instructions = "remove('html')"
33
+ @html_source = "<html></html>"
34
+ val = val.call(self) if val.is_a?(Proc) # hack to support binding test
35
+ @renderer = Lilu::Renderer.new(@instructions,@html_source,val)
36
+ @renderer.instance_variable_get(:@test_variable).should == @test_variable
37
+ end
38
+ end
39
+ end
40
+
41
+ describe Lilu::Renderer do
42
+
43
+ %w[update populate remove use replace].each do |verb|
44
+ it "should raise an exception if element is not found when using #{verb} verb" do
45
+ @instructions = %{#{verb}("#some-missing-data") }
46
+ @html_source = %{<div id="some-data">Lola</div>}
47
+ @renderer = Lilu::Renderer.new(@instructions,@html_source)
48
+ lambda { @renderer.apply }.should raise_error(Lilu::ElementNotFound)
49
+ end
50
+ end
51
+
52
+ it "should remove element on remove(path) construct" do
53
+ @instructions = %{remove("#some-data") }
54
+ @html_source = %{<div id="some-data">Lola</div>}
55
+ @renderer = Lilu::Renderer.new(@instructions,@html_source)
56
+ Hpricot(@renderer.apply).at("#some-lilu-data").should be_nil
57
+ end
58
+
59
+ it "should remove all elements on remove(:all,path) construct" do
60
+ @instructions = %{remove(:all,".not-for-public") }
61
+ @html_source = %{<div class="not-for-public">Lola</div><br /><div class="not-for-public">1</div>}
62
+ @renderer = Lilu::Renderer.new(@instructions,@html_source)
63
+ Hpricot(@renderer.apply).to_s.should == "<br />"
64
+ end
65
+
66
+
67
+ it "should update element details on update(path).with(String) construct" do
68
+ @instructions = %{update("#some-data").with("Lilu")}
69
+ @html_source = %{<div id="some-data">Lola</div>}
70
+ @renderer = Lilu::Renderer.new(@instructions,@html_source)
71
+ Hpricot(@renderer.apply).at("#some-data").inner_html.should == "Lilu"
72
+ end
73
+
74
+ it "should update element details on update(path).with Hash construct" do
75
+ @instructions = %{update("#some-data").with :id => "some-lilu-data", "a" => { :href => "/", self => "is here" } }
76
+ @html_source = %{<div id="some-data">Lola <a href="#">is there</a></div>}
77
+ @renderer = Lilu::Renderer.new(@instructions,@html_source)
78
+ result = Hpricot(@renderer.apply)
79
+ result.at("#some-lilu-data").inner_html.should == "Lola <a href=\"/\">is here</a>"
80
+ end
81
+
82
+ it "should populate element details on populate(path).for(:each,@blogs) { block } construct" do
83
+ @blogs = [OpenStruct.new(:url => "http://railsware.com", :blog_id => 1, :name => "Railsware"),OpenStruct.new(:url => "http://railsware.com/", :blog_id => 2, :name => "Railsware!")]
84
+ @instructions = %{populate("#blog-example").for(:each,@blogs) {|blog| mapping 'a' => {:href => blog.url, self => blog.name}, :id => blog.blog_id } }
85
+ @html_source = %{<ul id="blogs"><li id="blog-example"><a href="#">My Blog</a></li></ul>}
86
+ @renderer = Lilu::Renderer.new(@instructions,@html_source,self)
87
+ result = Hpricot(@renderer.apply)
88
+ result.at("#blogs/#2/a")[:href].should == "http://railsware.com/"
89
+ result.at("#blogs/#1/a").inner_html.should == "Railsware"
90
+ result.at("#blogs/#blog-example").should be_nil
91
+ end
92
+
93
+ it "should populate element details on populate(:all,path).for(:each,@blogs) { block } construct" do
94
+ @blogs = [OpenStruct.new(:url => "http://railsware.com", :blog_id => 1, :name => "Railsware")]
95
+ @instructions = %{populate(:all,".blog-example").for(:each,@blogs) {|blog| mapping 'a' => {:href => blog.url, self => blog.name}, :id => blog.blog_id } }
96
+ @html_source = %{<ul id="blogs1"><li id="blog-example" class="blog-example"><a href="#">My Blog</a></li></ul><ul id="blogs2"><li id="blog-example" class="blog-example"><a href="#">My Blog</a></li></ul>}
97
+ @renderer = Lilu::Renderer.new(@instructions,@html_source,self)
98
+ result = Hpricot(@renderer.apply)
99
+ result.at("#blogs1/#1/a")[:href].should == "http://railsware.com"
100
+ result.at("#blogs1/#1/a").inner_html.should == "Railsware"
101
+ result.at("#blogs1/#blog-example").should be_nil
102
+ result.at("#blogs2/#1/a")[:href].should == "http://railsware.com"
103
+ result.at("#blogs2/#1/a").inner_html.should == "Railsware"
104
+ result.at("#blogs2/#blog-example").should be_nil
105
+
106
+ end
107
+
108
+ it "should update all elements, matched by path on update(:all, path).with Hash construct" do
109
+ @instructions = %{update(:all, "a").with :href => "#", self => 'Stay here'}
110
+ @html_source = %{<a href="http://java.net">C'mon, Java!</a><a href="http://www.php.net">Go away!</a>}
111
+ @renderer = Lilu::Renderer.new(@instructions,@html_source)
112
+ result = Hpricot(@renderer.apply)
113
+ (result/"a").each { |elem| elem.inner_html.should == 'Stay here'; elem[:href].should == '#' }
114
+ end
115
+
116
+ it "should update all elements, matched by path on update(:all, path).with Hash construct, taking in account each element content" do
117
+ @instructions = 'update(:all, "a").with :href => L{"#{element[:href]}/download"}, self => L{"Download #{element.inner_html}"}'
118
+ links = {"http://java.net" => "C'mon, Java!", "http://www.php.net" => "Go away!"}
119
+ @html_source = ""
120
+ links.each_pair {|url,name| @html_source << %{<a href="#{url}">#{name}</a>} }
121
+ @renderer = Lilu::Renderer.new(@instructions,@html_source)
122
+ result = Hpricot(@renderer.apply)
123
+ links.each_pair do |url,name|
124
+ result.at("//a[@href='#{url}/download']").inner_html.should == "Download #{name}"
125
+ end
126
+ end
127
+
128
+ it "should update all elements, matched by path on update(:all, path).with Block construct, taking in account each element content" do
129
+ @instructions = 'update(:all, "a").with { mapping :href => "#{element[:href]}/download", self => "Download #{element.inner_html }" }'
130
+ links = {"http://java.net" => "C'mon, Java!", "http://www.php.net" => "Go away!"}
131
+ @html_source = ""
132
+ links.each_pair {|url,name| @html_source << %{<a href="#{url}">#{name}</a>} }
133
+ @renderer = Lilu::Renderer.new(@instructions,@html_source)
134
+ result = Hpricot(@renderer.apply)
135
+ links.each_pair do |url,name|
136
+ result.at("//a[@href='#{url}/download']").inner_html.should == "Download #{name}"
137
+ end
138
+ end
139
+
140
+ it "should update all elements, matched by path on update(:all, path).with Lambda construct, taking in account each element content" do
141
+ @instructions = 'update(:all, "a").with L{ mapping :href => "#{element[:href]}/download", self => "Download #{element.inner_html }" }'
142
+ links = {"http://java.net" => "C'mon, Java!", "http://www.php.net" => "Go away!"}
143
+ @html_source = ""
144
+ links.each_pair {|url,name| @html_source << %{<a href="#{url}">#{name}</a>} }
145
+ @renderer = Lilu::Renderer.new(@instructions,@html_source)
146
+ result = Hpricot(@renderer.apply)
147
+ links.each_pair do |url,name|
148
+ result.at("//a[@href='#{url}/download']").inner_html.should == "Download #{name}"
149
+ end
150
+ end
151
+
152
+ it "should remove everything outside of specified element on use(path)" do
153
+ @instructions = "use('#main')"
154
+ @html_source = '<html><body><div id="main">Blablabla</div></body></html>'
155
+ @renderer = Lilu::Renderer.new(@instructions,@html_source)
156
+ result = Hpricot(@renderer.apply)
157
+ result.to_s.should == '<div id="main">Blablabla</div>'
158
+ end
159
+
160
+ it "should raise ArgumentError if use is called with :all argument" do
161
+ @instructions = "use(:all,'#main')"
162
+ @html_source = '<html><body><div id="main">Blablabla</div></body></html>'
163
+ @renderer = Lilu::Renderer.new(@instructions,@html_source)
164
+ lambda { Hpricot(@renderer.apply) }.should raise_error(ArgumentError)
165
+ end
166
+
167
+ it "should replace element with another using replace().with String construct" do
168
+ @instructions = "replace('#main').with 'Hello!'"
169
+ @html_source = '<html><body><div id="main">Blablabla</div></body></html>'
170
+ @renderer = Lilu::Renderer.new(@instructions,@html_source)
171
+ result = Hpricot(@renderer.apply)
172
+ result.to_s.should == '<html><body>Hello!</body></html>'
173
+ end
174
+
175
+ it "should replace element with another using replace().with Block construct" do
176
+ @instructions = "replace('#main').with { 'Hello!' }"
177
+ @html_source = '<html><body><div id="main">Blablabla</div></body></html>'
178
+ @renderer = Lilu::Renderer.new(@instructions,@html_source)
179
+ result = Hpricot(@renderer.apply)
180
+ result.to_s.should == '<html><body>Hello!</body></html>'
181
+ end
182
+
183
+ it "should replace element with another using replace().with Lambda construct" do
184
+ @instructions = "replace('#main').with L{ 'Hello!' }"
185
+ @html_source = '<html><body><div id="main">Blablabla</div></body></html>'
186
+ @renderer = Lilu::Renderer.new(@instructions,@html_source)
187
+ result = Hpricot(@renderer.apply)
188
+ result.to_s.should == '<html><body>Hello!</body></html>'
189
+ end
190
+
191
+ it "should replace all elements with another using replace(:all,).with String construct" do
192
+ @instructions = "replace(:all,'.main').with 'Hello!'"
193
+ @html_source = '<html><body><div class="main">Blablabla</div><div class="main">Blublublu</div></body></html>'
194
+ @renderer = Lilu::Renderer.new(@instructions,@html_source)
195
+ result = Hpricot(@renderer.apply)
196
+ result.to_s.should == '<html><body>Hello!Hello!</body></html>'
197
+ end
198
+
199
+ it "should replace all elements with another using replace(:all,).with String construct" do
200
+ @instructions = "replace(:all,'.main').with 'Hello!'"
201
+ @html_source = '<html><body><div class="main">Blablabla</div><div class="main">Blublublu</div></body></html>'
202
+ @renderer = Lilu::Renderer.new(@instructions,@html_source)
203
+ result = Hpricot(@renderer.apply)
204
+ result.to_s.should == '<html><body>Hello!Hello!</body></html>'
205
+ end
206
+
207
+ it "should replace element with another using replace().with Element construct" do
208
+ @instructions = "replace('#main').with element_at('#helper')"
209
+ @html_source = '<html><body><div id="main">Blablabla</div><div id="helper">Lilu</div></body></html>'
210
+ @renderer = Lilu::Renderer.new(@instructions,@html_source)
211
+ result = Hpricot(@renderer.apply)
212
+ result.to_s.should == '<html><body><div id="helper">Lilu</div></body></html>'
213
+ end
214
+
215
+ it "should replace all elements with another using replace(:all,).with Element construct" do
216
+ @instructions = "replace(:all,'.main').with element_at('#helper')"
217
+ @html_source = '<html><body><div class="main">Blablabla</div><div class="main">Blublublua</div><div id="helper">Lilu</div></body></html>'
218
+ @renderer = Lilu::Renderer.new(@instructions,@html_source)
219
+ result = Hpricot(@renderer.apply)
220
+ result.to_s.should == '<html><body><div id="helper">Lilu</div></body></html>'
221
+ end
222
+
223
+ end
metadata ADDED
@@ -0,0 +1,55 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.2
3
+ specification_version: 1
4
+ name: lilu
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.1.0
7
+ date: 2007-05-16 00:00:00 +03:00
8
+ summary: View subsystem that allows to keep pure HTML for views
9
+ require_paths:
10
+ - lib
11
+ email: yrashk@verbdev.com
12
+ homepage:
13
+ rubyforge_project:
14
+ description: View subsystem that allows to keep pure HTML for views
15
+ autorequire:
16
+ - rake
17
+ - hpricot
18
+ - lib/lilu
19
+ - lib/lilu_view
20
+ - lib/lilu_camping
21
+ default_executable: fixturease.rb
22
+ bindir: bin
23
+ has_rdoc: false
24
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
25
+ requirements:
26
+ - - ">"
27
+ - !ruby/object:Gem::Version
28
+ version: 0.0.0
29
+ version:
30
+ platform: ruby
31
+ signing_key:
32
+ cert_chain:
33
+ post_install_message:
34
+ authors:
35
+ - Yurii Rashkovskii
36
+ - Michael Holub
37
+ files:
38
+ - lib/lilu.rb
39
+ - lib/lilu_view.rb
40
+ - lib/lilu_camping.rb
41
+ - spec/lilu_spec.rb
42
+ test_files: []
43
+
44
+ rdoc_options: []
45
+
46
+ extra_rdoc_files: []
47
+
48
+ executables: []
49
+
50
+ extensions: []
51
+
52
+ requirements:
53
+ - hprico
54
+ dependencies: []
55
+