nolate 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
+