nolate 0.0.1

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/LICENSE ADDED
@@ -0,0 +1,26 @@
1
+ Copyright (c) 2011, Salvatore Sanfilippo <antirez at gmail dot com>
2
+
3
+ All rights reserved.
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are
7
+ met:
8
+
9
+ * Redistributions of source code must retain the above copyright
10
+ notice, this list of conditions and the following disclaimer.
11
+
12
+ * Redistributions in binary form must reproduce the above copyright
13
+ notice, this list of conditions and the following disclaimer in the
14
+ documentation and/or other materials provided with the distribution.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
+ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README ADDED
@@ -0,0 +1,108 @@
1
+ Nolate - NO LAme TEmplate system
2
+
3
+ OVERVIEW
4
+ --------
5
+
6
+ Nolate is a template system similar to erb that is designed for not consuming
7
+ some huge amount of CPU without a good reason. It is written in pure Ruby.
8
+ Nolate is distributed under a two clause BSD license for max freedom.
9
+
10
+ Templates can include code inside <%= %> that is evaluated with eval() and
11
+ substituted to the string.
12
+
13
+ Also occurrences of <%#something%> are substituted with the value of the
14
+ hash field :something of an additional hash passed to nolate() or nlt()
15
+ functions.
16
+
17
+ IS IT SUPER FAST?
18
+ -----------------
19
+
20
+ Fast enough that a small template substitution is not measurable by the
21
+ apache benchmark against a sample Sinatra application.
22
+ Surprisingly this is not as common as it should be.
23
+
24
+ HOW TO USE IT?
25
+ --------------
26
+
27
+ Nolate consists of just a few functions. The first is nolate() that is the core
28
+ of the template system:
29
+
30
+ nolate("The sum is <%= 2+2 %> Also substitute <%#myfield%> ok",
31
+ {:myfield => 10})
32
+
33
+ The array is optional, if you don't have <%#%> style substitutions you can
34
+ simply omit it.
35
+
36
+ The second function is nlt(), and is used to also handle loading the template
37
+ from a 'views' directory. The above example can be translated using nlt()
38
+ just creating a file 'views/index.nlt' with the following content:
39
+
40
+ The sum is <%= 2+2 %> Also substitute <%#myfield%> ok
41
+
42
+ Then we can use nlt() calling:
43
+
44
+ nlt("index.nlt", {:myfield => "something"})
45
+
46
+ the nlt() funciton will take care to cache templates into memory.
47
+ In order to flush this templates to force reloading just call the third and
48
+ final provided function:
49
+
50
+ nlt_flush_templates()
51
+
52
+ It is possible to pass the template name as a symbol like in:
53
+
54
+ nlt(:index)
55
+
56
+ nlt will add ".nlt" at the end of the name when it is a symbol.
57
+
58
+ SUPPORTED SUBSTITUTIONS
59
+ -----------------------
60
+
61
+ <%= somecode %> Evaluates somecode and substitutes the return value.
62
+ <% somecode %> Evaluates somecode.
63
+ <%#filed_name%> Substituted the value of the specified filed of the hash
64
+ passed to nolate() or nlt() as optional argument.
65
+
66
+ It is possible to interleave template and Ruby code together like in the
67
+ following example:
68
+
69
+ <% (0..5).each{|x| %>
70
+ <li><%=x%></li>
71
+ <% } %>
72
+
73
+ USING LAYOUTS
74
+ -------------
75
+
76
+ Nolate suppots the concept of layout. You can specify to use a layout using
77
+ the following call:
78
+
79
+ nlt_set_layout(:layout)
80
+
81
+ The above call specifies to use "views/layout.nlt" as template.
82
+
83
+ The layout is a normal nolate template that contains somewhere a
84
+ substitution in the form of: <%#content%>. When a layout is set what happens
85
+ is that all the calls to nolate() or nlt() are processed, then the result
86
+ is substituted to the layout template.
87
+
88
+ The layout template can also include any other standard nolate substitution
89
+ and code evaluation.
90
+
91
+ It is possible to change layout at runtime, or to disable the layout setting
92
+ it to nil.
93
+
94
+ CONTRIBUTE
95
+ ----------
96
+
97
+ Please send me pull requests: http://github.com/antirez/nolate
98
+
99
+ So far thank you to:
100
+
101
+ @soveran
102
+ @brmichel
103
+ @JEG2
104
+ Emmanuel Oga (https://github.com/EmmanuelOga)
105
+ @czarneckid
106
+
107
+ It is not too late...
108
+ Salvatore
data/bench.rb ADDED
@@ -0,0 +1,40 @@
1
+ load "lib/nolate.rb"
2
+
3
+ def bench(descr, times)
4
+ start = Time.now.to_f
5
+ times.times { yield }
6
+ elapsed = Time.now.to_f - start
7
+ reqsec = times / elapsed
8
+ puts "#{descr.ljust(25)}: #{(reqsec).to_i.to_s.rjust(10)} requests/second"
9
+ $template = ""
10
+ end
11
+
12
+ TEMPLATE = <<-TEMPLATE * 3
13
+ <html>
14
+ <body>
15
+ Long template with all the features Yeah!. 2 + 2 is: <%= # 2+2 = 4
16
+ 2+2
17
+ %>
18
+
19
+ <%= @x %>
20
+
21
+ <% @x %>
22
+
23
+ <%#periquin%>
24
+
25
+ <% (1..2).each{|x| %>
26
+ Number <%= x %>
27
+ <% } %>
28
+
29
+ </body></html>
30
+ TEMPLATE
31
+
32
+ TIMES = 30_000
33
+
34
+ bench("empty template" , TIMES) { nolate("") }
35
+ bench("small constant template" , TIMES) { nolate("nosub") }
36
+ bench("simple substitution" , TIMES) { nolate("simple <%= 'sub' %>") }
37
+ bench("hash substitution" , TIMES) { nolate("hash sub <%#x%>") }
38
+ bench("testview2 file template" , TIMES) { nlt(:testview2) }
39
+ bench("big template .nlt", TIMES/5) { @x = 1; nlt(:bigtemplate, :x => 1) }
40
+ bench("big template (#{TEMPLATE.length} bytes)", TIMES/10) { @x = 1; nolate(TEMPLATE, :x => 1) }
data/example.rb ADDED
@@ -0,0 +1,5 @@
1
+ load 'nolate.rb'
2
+
3
+ hash = {:title => "Hello World!"}
4
+ @ivar = "Instance Variable Content"
5
+ puts nlt(:example,hash) # Check views/example.nlt for more info
data/lib/nolate.rb ADDED
@@ -0,0 +1,127 @@
1
+ # NOLATE, A NO LAme TEmplate system
2
+ #
3
+ # Please read the README file for more information
4
+ #
5
+ # Copyright (c) 2011, Salvatore Sanfilippo <antirez at gmail dot com>
6
+ #
7
+ # All rights reserved.
8
+ #
9
+ # Redistribution and use in source and binary forms, with or without
10
+ # modification, are permitted provided that the following conditions are
11
+ # met:
12
+ #
13
+ # * Redistributions of source code must retain the above copyright
14
+ # notice, this list of conditions and the following disclaimer.
15
+ #
16
+ # * Redistributions in binary form must reproduce the above copyright
17
+ # notice, this list of conditions and the following disclaimer in the
18
+ # documentation and/or other materials provided with the distribution.
19
+ #
20
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24
+ # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ #
32
+
33
+ def nlt_empty_binding(__sub_)
34
+ __sub = __sub_
35
+ return binding()
36
+ end
37
+
38
+ def nlt_templates
39
+ $nolate_templates ||= {}
40
+ end
41
+
42
+ def nlt_flush_templates
43
+ $nolate_templates = {}
44
+ end
45
+
46
+ def nlt_set_layout(layout)
47
+ $nolate_layout = layout
48
+ end
49
+
50
+ def nlt_parse(str)
51
+ i = -1 # I wish I had map.with_index in 1.8 :(
52
+ prev_was_eval = false # Previous token was an :eval?
53
+ str.split(/<%(.*?)%>/m).map do |s|
54
+ i, first_char = i + 1, s[0..0]
55
+ newlines = s.count("\n")
56
+ if i % 2 == 0
57
+ j = 0
58
+ if prev_was_eval and s != "\n" and s != "\r\n"
59
+ j += 1 if s[j..j] == "\r"
60
+ j += 1 if s[j..j] == "\n"
61
+ end
62
+ prev_was_eval = false
63
+ [:verb, s[j..-1].inspect, newlines]
64
+ elsif first_char == "="
65
+ prev_was_eval = false
66
+ [:evalo, s[1..-1], newlines]
67
+ elsif first_char == "#"
68
+ prev_was_eval = false
69
+ [:sub, s[1..-1].to_sym, newlines]
70
+ else
71
+ prev_was_eval = true
72
+ [:eval, s, 0]
73
+ end
74
+ end
75
+ end
76
+
77
+ def nlt_compile(template)
78
+ s = "__=[]; "
79
+ nlt_parse(template).each do |action, param, newlines|
80
+ case action
81
+ when :evalo then s << "__<<(#{param}).to_s; "
82
+ when :eval then s << "#{param}; "
83
+ when :sub then s << "__<< __sub[#{param.to_sym.inspect}]; "
84
+ when :verb then s << "__<<#{param}; "
85
+ end
86
+ s << "\n"*newlines
87
+ end
88
+ s << "\n__.join"
89
+ end
90
+
91
+ def nlt_eval(code, sub = {}, opt = {}, file="evaluated_string")
92
+ # Make sure that nested calls will not substitute the layout
93
+ saved = @nolate_no_layout
94
+ @nolate_no_layout = true
95
+ content = eval(code, nlt_empty_binding(sub), file, 1)
96
+ @nolate_no_layout = saved
97
+
98
+ # And... make sure that the layout will not trigger an infinite recursion
99
+ # substituting itself forever.
100
+ if $nolate_layout and !@nolate_no_layout and !(opt[:layout] == false)
101
+ saved = $nolate_layout
102
+ if !opt[:layout]
103
+ use = $nolate_layout
104
+ else
105
+ use = opt[:layout]
106
+ end
107
+ $nolate_layout = nil
108
+ content = nlt(use,{:content => content})
109
+ $nolate_layout = saved
110
+ end
111
+ content
112
+ end
113
+
114
+ def nlt(viewname, sub={}, opt={})
115
+ viewname = "#{viewname}.nlt" if viewname.is_a?(Symbol)
116
+ unless nlt_templates[viewname]
117
+ filename = "views/#{viewname}"
118
+ raise "NOLATE error: no template at #{filename}" \
119
+ unless File.exists?(filename)
120
+ nlt_templates[viewname] = nlt_compile(File.read(filename))
121
+ end
122
+ nlt_eval(nlt_templates[viewname], sub, opt, "views/#{viewname}")
123
+ end
124
+
125
+ def nolate(str, sub={}, opt={})
126
+ nlt_eval(nlt_compile(str), sub, opt)
127
+ end
data/nolate.gemspec ADDED
@@ -0,0 +1,39 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.specification_version = 2 if s.respond_to? :specification_version=
5
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
6
+
7
+ s.name = %q{nolate}
8
+ s.version = "0.0.1"
9
+ s.summary = %q{Ruby Template System}
10
+ s.description = %q{Pure Ruby template engine optimized for speed}
11
+ s.authors = ["Salvatore Sanfilippo","Michel Martens","Bruno Michel","Emmanuel Oga"]
12
+ s.autorequire = %q{nolate}
13
+ s.date = %q{2011-04-05}
14
+ s.email = %q{antirez@gmail.com}
15
+ s.extra_rdoc_files = ["LICENSE"]
16
+ s.homepage = %q{http://github.com/antirez/nolaote}
17
+ s.require_paths = ["lib"]
18
+ s.rubygems_version = %q{1.5.0}
19
+
20
+ s.files = %w{
21
+ LICENSE
22
+ README
23
+ bench.rb
24
+ example.rb
25
+ nolate.gemspec
26
+ test.rb
27
+ lib/nolate.rb
28
+ views/bigtemplate.nlt
29
+ views/example.nlt
30
+ views/layout.nlt
31
+ views/layout2.nlt
32
+ views/layout3.nlt
33
+ views/testview.nlt
34
+ views/testview2.nlt
35
+ views/testview3.nlt
36
+ views/testview4.nlt
37
+ views/testview5.nlt
38
+ }
39
+ end
data/test.rb ADDED
@@ -0,0 +1,63 @@
1
+ require 'test/unit'
2
+ load 'lib/nolate.rb'
3
+
4
+ class MyExampleClass
5
+ def method_one
6
+ @x = "Hello"
7
+ nolate("<%= @x %>")
8
+ end
9
+
10
+ def method_two
11
+ @x = "World"
12
+ nlt(:testview3)
13
+ end
14
+ end
15
+
16
+ class NolateTest < Test::Unit::TestCase
17
+ def test_basic
18
+ assert_equal("",nolate(""))
19
+ assert_equal("nosub",nolate("nosub"))
20
+ assert_equal("simple sub",nolate("simple <%= 'sub' %>"))
21
+ assert_equal("hash sub 1",nolate("hash sub <%#x%>",{:x => 1}))
22
+ assert_equal("just eval",nolate("just ev<% 'sub' %>al"))
23
+ assert_equal("test 4 view\n",nlt(:testview))
24
+ assert_equal("test 4 view\n",nlt("testview.nlt"))
25
+ assert_equal("<html>\n<body>\n4\n</body>\n</html>\n",nlt(:testview2))
26
+ assert_equal("3",nolate("<%x=2%><%=x+1%>"))
27
+ assert_equal("Hello",MyExampleClass.new.method_one)
28
+ assert_equal("World\n",MyExampleClass.new.method_two)
29
+ end
30
+
31
+ def test_iter
32
+ assert_equal(<<-OUTPUT, nlt(:testview4))
33
+ Number 1
34
+ Number 2
35
+ Number 3
36
+ Number 4
37
+
38
+ OUTPUT
39
+ end
40
+
41
+ def test_layout
42
+ nlt_set_layout(:layout)
43
+ assert_equal("Header\n2+2=4\nFooter\n",nolate("2+2=<%= 2+2 %>"))
44
+ nlt_set_layout(:layout2)
45
+ assert_equal("Header\nciao\nnested call\nFooter\n",nolate("ciao"))
46
+ nlt_set_layout(:layout)
47
+ assert_equal("2+2=4",nolate("2+2=<%= 2+2 %>",{},{:layout => false}))
48
+ assert_equal("Other Header\n2+2=4\nOther Footer\n",
49
+ nolate("2+2=<%= 2+2 %>",{},{:layout => :layout3}))
50
+ end
51
+
52
+ def test_error_lines
53
+ # Make sure that compiled template and template have the code in the
54
+ # same lines, so that eval() will report good error traces.
55
+ text = File.read("views/testview5.nlt").to_a
56
+ compiled = nlt_compile(File.read("views/testview5.nlt")).split("\n")
57
+ assert(text[3] =~ /title/ && compiled[3] =~ /title/)
58
+ assert(text[8] =~ /each/ && compiled[8] =~ /each/)
59
+ assert(text[22] =~ /4\+4/ && compiled[22] =~ /4\+4/)
60
+ assert(text[29] =~ /ivar/ && compiled[29] =~ /ivar/)
61
+ assert(text[36] =~ /else/ && compiled[36] =~ /else/)
62
+ end
63
+ end
@@ -0,0 +1,51 @@
1
+ <html>
2
+ <body>
3
+ Long template with all the features Yeah!. 2 + 2 is: <%= # 2+2 = 4
4
+ 2+2
5
+ %>
6
+
7
+ <%= @x %>
8
+
9
+ <% @x %>
10
+
11
+ <%#periquin%>
12
+
13
+ <% (1..2).each{|x| %>
14
+ Number <%= x %>
15
+ <% } %>
16
+
17
+ </body></html>
18
+ <html>
19
+ <body>
20
+ Long template with all the features Yeah!. 2 + 2 is: <%= # 2+2 = 4
21
+ 2+2
22
+ %>
23
+
24
+ <%= @x %>
25
+
26
+ <% @x %>
27
+
28
+ <%#periquin%>
29
+
30
+ <% (1..2).each{|x| %>
31
+ Number <%= x %>
32
+ <% } %>
33
+
34
+ </body></html>
35
+ <html>
36
+ <body>
37
+ Long template with all the features Yeah!. 2 + 2 is: <%= # 2+2 = 4
38
+ 2+2
39
+ %>
40
+
41
+ <%= @x %>
42
+
43
+ <% @x %>
44
+
45
+ <%#periquin%>
46
+
47
+ <% (1..2).each{|x| %>
48
+ Number <%= x %>
49
+ <% } %>
50
+
51
+ </body></html>
data/views/example.nlt ADDED
@@ -0,0 +1,37 @@
1
+ <html>
2
+ <head>
3
+ <title>
4
+ Test <%#title%>
5
+ </title>
6
+ <body>
7
+
8
+ <h1>List of items<h1>
9
+ <% (0..5).each{|x| %>
10
+ <li><%=x%></li>
11
+ <% } %>
12
+
13
+ <p>
14
+ You can access the substitutions hash from Ruby code inside the template
15
+ using the __sub variable name:
16
+
17
+ :title is set to -> <%= __sub[:title].inspect %>
18
+ </p>
19
+
20
+ <p>
21
+ Another way to pass values to the template is via instance variables that
22
+ are accessible without any special convention:
23
+
24
+ @ivar is set to <%= @ivar.inspect %>
25
+ </p>
26
+
27
+ <p>
28
+ Example of conditional:
29
+ <% if false %>
30
+ Ruby is lame
31
+ <% else %>
32
+ Ruby is a cool programming language
33
+ <% end %>
34
+ </p>
35
+
36
+ </body>
37
+ </html>
data/views/layout.nlt ADDED
@@ -0,0 +1,3 @@
1
+ Header
2
+ <%#content%>
3
+ Footer
data/views/layout2.nlt ADDED
@@ -0,0 +1,6 @@
1
+ Header
2
+ <%#content%>
3
+ <%=
4
+ nolate("nested call")
5
+ %>
6
+ Footer
data/views/layout3.nlt ADDED
@@ -0,0 +1,3 @@
1
+ Other Header
2
+ <%#content%>
3
+ Other Footer
@@ -0,0 +1 @@
1
+ test <%= 2+2 %> view
@@ -0,0 +1,8 @@
1
+ <html>
2
+ <body>
3
+ <%=
4
+ # 2+2 = 4
5
+ 2+2
6
+ %>
7
+ </body>
8
+ </html>
@@ -0,0 +1 @@
1
+ <%= @x %>
@@ -0,0 +1,3 @@
1
+ <% (1..4).each{|x| %>
2
+ Number <%= x %>
3
+ <% } %>
@@ -0,0 +1,43 @@
1
+ <html>
2
+ <head>
3
+ <title>
4
+ Test <%#title%>
5
+ </title>
6
+ <body>
7
+
8
+ <h1>List of items<h1>
9
+ <% (0..5).each{|x| %>
10
+ <li><%=x%></li>
11
+ <% } %>
12
+
13
+ <p>
14
+ You can access the substitutions hash from Ruby code inside the template
15
+ using the __sub variable name:
16
+
17
+ :title is set to -> <%= __sub[:title].inspect %>
18
+ </p>
19
+
20
+ <%
21
+ # Example
22
+ # Error
23
+ 4+4
24
+ %>
25
+
26
+ <p>
27
+ Another way to pass values to the template is via instance variables that
28
+ are accessible without any special convention:
29
+
30
+ @ivar is set to <%= @ivar.inspect %>
31
+ </p>
32
+
33
+ <p>
34
+ Example of conditional:
35
+ <% if false %>
36
+ Ruby is lame
37
+ <% else %>
38
+ Ruby is a cool programming language
39
+ <% end %>
40
+ </p>
41
+
42
+ </body>
43
+ </html>
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nolate
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Salvatore Sanfilippo
14
+ - Michel Martens
15
+ - Bruno Michel
16
+ - Emmanuel Oga
17
+ autorequire: nolate
18
+ bindir: bin
19
+ cert_chain: []
20
+
21
+ date: 2011-04-05 00:00:00 Z
22
+ dependencies: []
23
+
24
+ description: Pure Ruby template engine optimized for speed
25
+ email: antirez@gmail.com
26
+ executables: []
27
+
28
+ extensions: []
29
+
30
+ extra_rdoc_files:
31
+ - LICENSE
32
+ files:
33
+ - LICENSE
34
+ - README
35
+ - bench.rb
36
+ - example.rb
37
+ - nolate.gemspec
38
+ - test.rb
39
+ - lib/nolate.rb
40
+ - views/bigtemplate.nlt
41
+ - views/example.nlt
42
+ - views/layout.nlt
43
+ - views/layout2.nlt
44
+ - views/layout3.nlt
45
+ - views/testview.nlt
46
+ - views/testview2.nlt
47
+ - views/testview3.nlt
48
+ - views/testview4.nlt
49
+ - views/testview5.nlt
50
+ homepage: http://github.com/antirez/nolaote
51
+ licenses: []
52
+
53
+ post_install_message:
54
+ rdoc_options: []
55
+
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ hash: 3
64
+ segments:
65
+ - 0
66
+ version: "0"
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ hash: 3
73
+ segments:
74
+ - 0
75
+ version: "0"
76
+ requirements: []
77
+
78
+ rubyforge_project:
79
+ rubygems_version: 1.7.1
80
+ signing_key:
81
+ specification_version: 2
82
+ summary: Ruby Template System
83
+ test_files: []
84
+