razor 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +19 -0
- data/README +0 -0
- data/bin/razor +7 -0
- data/lib/razor.rb +58 -0
- data/lib/razor/generable.rb +142 -0
- data/lib/razor/renderer.rb +120 -0
- data/lib/razor/runner.rb +82 -0
- data/lib/razor/template.rb +192 -0
- data/lib/version.rb +3 -0
- metadata +97 -0
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (C) 2011 by Ferreira, Christopher
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the Software), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README
ADDED
File without changes
|
data/bin/razor
ADDED
data/lib/razor.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'version'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
require 'razor/generable'
|
6
|
+
require 'highline'
|
7
|
+
|
8
|
+
module Razor
|
9
|
+
|
10
|
+
class << self
|
11
|
+
attr :get
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.create(name)
|
15
|
+
Dir.mkdir name
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.generate(src, dest)
|
19
|
+
site = Site.new(src, dest)
|
20
|
+
FileUtils.rm_r(dest) rescue nil
|
21
|
+
site.generate
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.server(port, src)
|
25
|
+
require 'rack'
|
26
|
+
port = (port and port.to_i or 9000)
|
27
|
+
on_request = lambda do |env|
|
28
|
+
page = Razor.http_request src, env['PATH_INFO']
|
29
|
+
p page.dest_name rescue nil
|
30
|
+
if page
|
31
|
+
[
|
32
|
+
200,
|
33
|
+
{ 'Content-Type' =>
|
34
|
+
Rack::Mime.mime_type(page.dest_ext) },
|
35
|
+
[ page.contents ]
|
36
|
+
]
|
37
|
+
else
|
38
|
+
[
|
39
|
+
404,
|
40
|
+
{ 'Content-Type' => 'text/html' },
|
41
|
+
[ 'Page Not Found' ]
|
42
|
+
]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
Rack::Handler::WEBrick.run(on_request, :Port => port) { |server|
|
46
|
+
trap(:INT) { server.stop }
|
47
|
+
trap(:TERM) { server.stop }
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.http_request(src, url)
|
52
|
+
url = url[1..-1].sub(/\/+/, '/')
|
53
|
+
site = Site.new(src, '')
|
54
|
+
file = site.http(url)
|
55
|
+
file and file.request
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
require 'razor/template'
|
4
|
+
|
5
|
+
module Razor
|
6
|
+
|
7
|
+
class Generable
|
8
|
+
|
9
|
+
attr_reader :parent, :src_name
|
10
|
+
|
11
|
+
def initialize(parent, src_name)
|
12
|
+
@parent = parent
|
13
|
+
@src_name = src_name
|
14
|
+
end
|
15
|
+
|
16
|
+
alias dest_name src_name
|
17
|
+
|
18
|
+
def src
|
19
|
+
@src ||= File.join(parent.src, src_name)
|
20
|
+
end
|
21
|
+
|
22
|
+
def dest
|
23
|
+
@dest ||= File.join(parent.dest, dest_name)
|
24
|
+
end
|
25
|
+
|
26
|
+
def url
|
27
|
+
@url ||= File.join(parent.url, dest_name)
|
28
|
+
end
|
29
|
+
|
30
|
+
def http(url)
|
31
|
+
url.empty? and return self
|
32
|
+
return nil
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
class GenerableFile < Generable
|
38
|
+
|
39
|
+
def contents
|
40
|
+
File.read(src, :mode=>'rb')
|
41
|
+
end
|
42
|
+
|
43
|
+
def generate
|
44
|
+
File.open(dest, 'wb') { |f| f << contents }
|
45
|
+
end
|
46
|
+
|
47
|
+
def request
|
48
|
+
self
|
49
|
+
end
|
50
|
+
|
51
|
+
def dest_ext
|
52
|
+
File.extname(dest_name)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
class Directory < Generable
|
57
|
+
|
58
|
+
attr_reader :files
|
59
|
+
|
60
|
+
def initialize(parent, src_name)
|
61
|
+
super(parent, src_name)
|
62
|
+
@files = Dir.entries(src).reject { |filename|
|
63
|
+
filename =~ /^[\._].*/ or filename=='Rakefile'
|
64
|
+
}.map { |filename|
|
65
|
+
if File.directory? File.join(src,filename)
|
66
|
+
Directory.new(self, filename)
|
67
|
+
elsif filename =~ /^[^~].*\.rb$/
|
68
|
+
TemplateFile.new(self, filename)
|
69
|
+
else
|
70
|
+
RegularFile.new(self, filename)
|
71
|
+
end
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
def generate
|
76
|
+
Dir.mkdir(dest)
|
77
|
+
@files.each(&:generate)
|
78
|
+
end
|
79
|
+
|
80
|
+
def http(url)
|
81
|
+
s = super(url)
|
82
|
+
s and return s
|
83
|
+
name, *rest = url.split('/')
|
84
|
+
file = @files.find { |f| f.dest_name == name }
|
85
|
+
file or return nil
|
86
|
+
file.http(rest*'/')
|
87
|
+
end
|
88
|
+
|
89
|
+
def request
|
90
|
+
@files.find { |f| f.dest_name == 'index.html' }
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
class Site < Directory
|
95
|
+
|
96
|
+
attr_reader :src, :dest
|
97
|
+
def initialize(src, dest)
|
98
|
+
Template.reset_instances!
|
99
|
+
@src, @dest = src, dest
|
100
|
+
layouts = File.join(src, '_layout/')
|
101
|
+
Template.path = layouts
|
102
|
+
Dir.chdir(layouts) { load './layouts.rb' }
|
103
|
+
super(nil, nil)
|
104
|
+
end
|
105
|
+
|
106
|
+
def url
|
107
|
+
'/'
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
class RegularFile < GenerableFile
|
112
|
+
|
113
|
+
def dest_name
|
114
|
+
# delete first '~' if needed.
|
115
|
+
super =~ /([^~].+)/
|
116
|
+
return $1
|
117
|
+
end
|
118
|
+
|
119
|
+
def generate
|
120
|
+
FileUtils.cp(src, dest)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
class TemplateFile < GenerableFile
|
125
|
+
|
126
|
+
def initialize(parent, src_name)
|
127
|
+
super(parent, src_name)
|
128
|
+
@template = Template.eval(self)
|
129
|
+
end
|
130
|
+
|
131
|
+
def dest_name
|
132
|
+
ext = @template.class.get_extension
|
133
|
+
src_name.sub(/rb$/, ext)
|
134
|
+
end
|
135
|
+
|
136
|
+
def contents
|
137
|
+
@template.render
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'bluecloth'
|
2
|
+
require 'sass'
|
3
|
+
|
4
|
+
module Razor
|
5
|
+
|
6
|
+
class Renderer
|
7
|
+
|
8
|
+
class Getter
|
9
|
+
|
10
|
+
class << self
|
11
|
+
|
12
|
+
attr_reader :renderers, :extensions
|
13
|
+
|
14
|
+
def define_renderer(name, renderer)
|
15
|
+
@renderers[name] = renderer
|
16
|
+
class_eval(<<-END)
|
17
|
+
def #{name}(string)
|
18
|
+
self.class.renderers[#{name.inspect}].new(string)
|
19
|
+
end
|
20
|
+
END
|
21
|
+
end
|
22
|
+
|
23
|
+
def define_extension(name, renderer)
|
24
|
+
@extensions[".#{name}"] = renderer
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
@renderers = {}
|
30
|
+
@extensions = {}
|
31
|
+
|
32
|
+
attr :renderer
|
33
|
+
|
34
|
+
def initialize(path, proc)
|
35
|
+
@path = path
|
36
|
+
if proc
|
37
|
+
@renderer = instance_exec &proc
|
38
|
+
else
|
39
|
+
@renderer = instance_exec { nil }
|
40
|
+
end
|
41
|
+
if @renderer.is_a? String or @renderer.is_a? NilClass
|
42
|
+
@renderer = Renderer.new(@renderer)
|
43
|
+
end
|
44
|
+
return @renderer
|
45
|
+
end
|
46
|
+
|
47
|
+
def from_file(filename)
|
48
|
+
filepath = File.join(@path, filename)
|
49
|
+
str = (File.read(filepath, :mode=>'rb') rescue nil)
|
50
|
+
ext = File.extname filename
|
51
|
+
renderer = self.class.extensions[ext]
|
52
|
+
renderer ||= Renderer
|
53
|
+
return renderer.new(str)
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
class << self
|
59
|
+
|
60
|
+
def get(path, proc)
|
61
|
+
Getter.new(path, proc).renderer
|
62
|
+
end
|
63
|
+
|
64
|
+
def name_ext(n)
|
65
|
+
name(n)
|
66
|
+
extension(n)
|
67
|
+
end
|
68
|
+
|
69
|
+
def name(n)
|
70
|
+
Getter.define_renderer(n, self)
|
71
|
+
end
|
72
|
+
|
73
|
+
def extension(ext)
|
74
|
+
Getter.define_extension(ext, self)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
attr :string
|
79
|
+
|
80
|
+
def initialize(string)
|
81
|
+
@string = string
|
82
|
+
end
|
83
|
+
|
84
|
+
def layout_render(context)
|
85
|
+
@string.nil? and return context['yield']
|
86
|
+
render(context)
|
87
|
+
end
|
88
|
+
|
89
|
+
def valid?
|
90
|
+
!!@string
|
91
|
+
end
|
92
|
+
|
93
|
+
def render(context)
|
94
|
+
@string.nil? and return ''
|
95
|
+
Mustache.render(@string, context)
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
class BlueRenderer < Renderer
|
101
|
+
|
102
|
+
name_ext 'markdown'
|
103
|
+
|
104
|
+
def render(context)
|
105
|
+
BlueCloth.new(super(context)).to_html
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
class ScssRenderer < Renderer
|
111
|
+
|
112
|
+
name_ext 'scss'
|
113
|
+
|
114
|
+
def render(context)
|
115
|
+
Sass::Engine.new(super(context), :syntax=>:scss ).render
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
data/lib/razor/runner.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'highline'
|
3
|
+
|
4
|
+
require 'razor'
|
5
|
+
|
6
|
+
module Razor
|
7
|
+
|
8
|
+
HL = HighLine.new
|
9
|
+
|
10
|
+
class Runner
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@options = {}
|
14
|
+
|
15
|
+
@options_parser = OptionParser.new { |opt|
|
16
|
+
|
17
|
+
opt.banner = "Usage: razor COMMAND"
|
18
|
+
|
19
|
+
opt.separator ""
|
20
|
+
opt.separator "Commands :"
|
21
|
+
opt.separator " generate [OPTIONS] [SOURCE DESTINATION] : Generates the web directory from source."
|
22
|
+
opt.separator " server [OPTIONS] [SOURCE] : Runs a webrick server which renders page on the fly."
|
23
|
+
opt.separator ""
|
24
|
+
opt.separator "Options : "
|
25
|
+
|
26
|
+
opt.on("-p PORT", "--port PORT", "Set the local server port") do |port|
|
27
|
+
@options[:port] = port
|
28
|
+
end
|
29
|
+
|
30
|
+
opt.on_tail("-v", "--version", "Show Version") do
|
31
|
+
@options[:version] = true
|
32
|
+
end
|
33
|
+
|
34
|
+
opt.on_tail("-h", "--help", "Show this message") do
|
35
|
+
@options[:help] = true
|
36
|
+
end
|
37
|
+
|
38
|
+
opt.separator ""
|
39
|
+
|
40
|
+
}
|
41
|
+
@options_parser.parse!
|
42
|
+
|
43
|
+
unless ARGV.empty?
|
44
|
+
args = ARGV.clone
|
45
|
+
ARGV.replace []
|
46
|
+
if respond_to? args[0]
|
47
|
+
send *args
|
48
|
+
else
|
49
|
+
HL.say "Unknown Command #{args[0]}"
|
50
|
+
HL.say @options_parser.to_s
|
51
|
+
end
|
52
|
+
else
|
53
|
+
if @options[:version]
|
54
|
+
HL.say Razor::Version
|
55
|
+
else
|
56
|
+
HL.say @options_parser.to_s
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def _check_arguments(bool)
|
62
|
+
return if bool
|
63
|
+
HL.say 'Arguments Error'
|
64
|
+
HL.say @options_parser.to_s
|
65
|
+
exit
|
66
|
+
end
|
67
|
+
|
68
|
+
def generate(*args)
|
69
|
+
_check_arguments args.size < 3
|
70
|
+
args = ['.', '_site'] if args.empty?
|
71
|
+
args << File.join(args[0], '_site') if args.size==1
|
72
|
+
Razor.generate *args
|
73
|
+
end
|
74
|
+
|
75
|
+
def server(url=nil)
|
76
|
+
url = '.' if url.nil?
|
77
|
+
Razor.server(@options[:port], url)
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
@@ -0,0 +1,192 @@
|
|
1
|
+
require 'mustache'
|
2
|
+
require 'razor/renderer'
|
3
|
+
|
4
|
+
module Razor
|
5
|
+
|
6
|
+
class Template
|
7
|
+
|
8
|
+
class << self
|
9
|
+
|
10
|
+
attr_reader :definition, :playout, :instances
|
11
|
+
|
12
|
+
def inherited(subclass)
|
13
|
+
@subclasses << subclass
|
14
|
+
subclass.class_initialize
|
15
|
+
end
|
16
|
+
|
17
|
+
def class_initialize
|
18
|
+
@subclasses = []
|
19
|
+
@definition = Class.new(superclass.definition)
|
20
|
+
@playout = superclass.playout
|
21
|
+
@fields = {}
|
22
|
+
@instances = []
|
23
|
+
end
|
24
|
+
|
25
|
+
def reset_instances!
|
26
|
+
@instances = []
|
27
|
+
@subclasses.each(&:reset_instances!)
|
28
|
+
end
|
29
|
+
|
30
|
+
def eval(templatefile)
|
31
|
+
@@last_evaluated = nil
|
32
|
+
@@last_templatefile = templatefile
|
33
|
+
Kernel.eval(File.read(templatefile.src), TOPLEVEL_BINDING)
|
34
|
+
return @@last_evaluated
|
35
|
+
end
|
36
|
+
|
37
|
+
def extension(ext)
|
38
|
+
@extension = ext
|
39
|
+
end
|
40
|
+
|
41
|
+
def path=(path)
|
42
|
+
@@path = path
|
43
|
+
end
|
44
|
+
|
45
|
+
def get_extension
|
46
|
+
if superclass.respond_to? :get_extension
|
47
|
+
@extension or superclass.get_extension
|
48
|
+
else
|
49
|
+
@extension
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def layout(str=nil, &block)
|
54
|
+
@playout = str ? lambda { str } : block
|
55
|
+
end
|
56
|
+
|
57
|
+
def field(name, default=nil)
|
58
|
+
if name =~ /^(field|contents)$/
|
59
|
+
raise "Try to create a #{name.inspect} field"
|
60
|
+
end
|
61
|
+
attr_accessor name
|
62
|
+
@fields["@#{name}"] = default
|
63
|
+
@definition.field(name)
|
64
|
+
end
|
65
|
+
|
66
|
+
def fields
|
67
|
+
if superclass.respond_to? :fields
|
68
|
+
superclass.fields.merge(@fields)
|
69
|
+
else
|
70
|
+
@fields
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def new(*args, &block)
|
75
|
+
instance = super(*args, &block)
|
76
|
+
@instances << instance
|
77
|
+
@@last_evaluated = instance
|
78
|
+
return instance
|
79
|
+
end
|
80
|
+
|
81
|
+
def all
|
82
|
+
@subclasses.inject(@instances) { |ary, subclass|
|
83
|
+
ary + subclass.instances
|
84
|
+
}
|
85
|
+
end
|
86
|
+
|
87
|
+
def layout_render(instance)
|
88
|
+
render(Mustache::Context.new(instance))
|
89
|
+
end
|
90
|
+
|
91
|
+
def render(context)
|
92
|
+
renderer = Renderer.get(@@path, @playout)
|
93
|
+
if superclass.respond_to? :render
|
94
|
+
if renderer.valid?
|
95
|
+
context.push('yield' => renderer.layout_render(context))
|
96
|
+
end
|
97
|
+
superclass.render(context)
|
98
|
+
else
|
99
|
+
if renderer.valid?
|
100
|
+
renderer.layout_render(context)
|
101
|
+
else
|
102
|
+
context['yield']
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
@extension = ''
|
110
|
+
@playout = nil
|
111
|
+
@fields = {}
|
112
|
+
@instances = []
|
113
|
+
@subclasses = []
|
114
|
+
|
115
|
+
attr_accessor :contents
|
116
|
+
|
117
|
+
def initialize(*args, &block)
|
118
|
+
@templatefile = @@last_templatefile
|
119
|
+
@contents = lambda { '' }
|
120
|
+
self.class.fields.each { |iv|
|
121
|
+
instance_variable_set(*iv)
|
122
|
+
}
|
123
|
+
if block_given?
|
124
|
+
self.class.definition.new(self, &block)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def url
|
129
|
+
@templatefile.url
|
130
|
+
end
|
131
|
+
|
132
|
+
def field(name, value)
|
133
|
+
(class<<self; self; end).class_eval { attr name }
|
134
|
+
instance_variable_set("@#{name}", value)
|
135
|
+
end
|
136
|
+
|
137
|
+
def yield
|
138
|
+
Renderer.get(@templatefile.parent.src, @contents).render(self)
|
139
|
+
end
|
140
|
+
|
141
|
+
def render
|
142
|
+
self.class.layout_render(self)
|
143
|
+
end
|
144
|
+
|
145
|
+
@definition = Class.new {
|
146
|
+
|
147
|
+
def self.field(name)
|
148
|
+
class_eval(<<-END)
|
149
|
+
def #{name}(val)
|
150
|
+
@tpl.#{name} = val
|
151
|
+
end
|
152
|
+
END
|
153
|
+
end
|
154
|
+
|
155
|
+
def initialize(tpl, &block)
|
156
|
+
@tpl = tpl
|
157
|
+
instance_exec &block
|
158
|
+
end
|
159
|
+
|
160
|
+
def field(name, value)
|
161
|
+
@tpl.field(name, value)
|
162
|
+
end
|
163
|
+
|
164
|
+
def contents(str=nil, &block)
|
165
|
+
@tpl.contents = str ? lambda { str } : block
|
166
|
+
end
|
167
|
+
|
168
|
+
def template_eval(&block)
|
169
|
+
@tpl.instance_eval(&block)
|
170
|
+
end
|
171
|
+
|
172
|
+
}
|
173
|
+
|
174
|
+
end
|
175
|
+
|
176
|
+
class Page < Template
|
177
|
+
|
178
|
+
extension 'html'
|
179
|
+
|
180
|
+
layout { from_file 'page.html' }
|
181
|
+
|
182
|
+
end
|
183
|
+
|
184
|
+
class StyleSheet < Template
|
185
|
+
|
186
|
+
extension 'css'
|
187
|
+
|
188
|
+
layout { from_file 'stylesheet.css' }
|
189
|
+
|
190
|
+
end
|
191
|
+
|
192
|
+
end
|
data/lib/version.rb
ADDED
metadata
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: razor
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Ferreira Christopher
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-03-09 00:00:00.000000000 +01:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: commander
|
17
|
+
requirement: &18858180 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '4'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *18858180
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: mustache
|
28
|
+
requirement: &18857660 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: *18857660
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: rack
|
39
|
+
requirement: &18857180 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
type: :runtime
|
46
|
+
prerelease: false
|
47
|
+
version_requirements: *18857180
|
48
|
+
description: ! '''Razor is a static website generator. Describe layouts and pages
|
49
|
+
in ruby. Write them with html and Mustache.
|
50
|
+
|
51
|
+
The concept behind razor is simple : layouts are described by classes, nested layouts
|
52
|
+
by subclasses and pages by instances of these classes.''
|
53
|
+
|
54
|
+
'
|
55
|
+
email: aumgn@free.fr
|
56
|
+
executables:
|
57
|
+
- razor
|
58
|
+
extensions: []
|
59
|
+
extra_rdoc_files: []
|
60
|
+
files:
|
61
|
+
- README
|
62
|
+
- LICENSE
|
63
|
+
- lib/razor.rb
|
64
|
+
- lib/razor/generable.rb
|
65
|
+
- lib/razor/runner.rb
|
66
|
+
- lib/razor/renderer.rb
|
67
|
+
- lib/razor/template.rb
|
68
|
+
- lib/version.rb
|
69
|
+
- bin/razor
|
70
|
+
has_rdoc: true
|
71
|
+
homepage: https://github.com/aumgn/razor
|
72
|
+
licenses:
|
73
|
+
- MIT License. See LICENSE file.
|
74
|
+
post_install_message:
|
75
|
+
rdoc_options: []
|
76
|
+
require_paths:
|
77
|
+
- lib
|
78
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
79
|
+
none: false
|
80
|
+
requirements:
|
81
|
+
- - ! '>='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
86
|
+
requirements:
|
87
|
+
- - ! '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
requirements: []
|
91
|
+
rubyforge_project:
|
92
|
+
rubygems_version: 1.5.2
|
93
|
+
signing_key:
|
94
|
+
specification_version: 3
|
95
|
+
summary: Razor is a static website generator. Describe layouts and pages in ruby.
|
96
|
+
Write them with html and Mustache.
|
97
|
+
test_files: []
|