brite 0.5
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/HISTORY +16 -0
- data/LICENSE +23 -0
- data/MANIFEST +28 -0
- data/README +42 -0
- data/bin/brite +3 -0
- data/lib/brite/command.rb +85 -0
- data/lib/brite/config.rb +30 -0
- data/lib/brite/layout.rb +36 -0
- data/lib/brite/page.rb +235 -0
- data/lib/brite/part.rb +31 -0
- data/lib/brite/post.rb +37 -0
- data/lib/brite/site.rb +137 -0
- data/lib/brite/template.rb +215 -0
- data/meta/authors +1 -0
- data/meta/contact +1 -0
- data/meta/copyright +1 -0
- data/meta/description +4 -0
- data/meta/homepage +1 -0
- data/meta/license +1 -0
- data/meta/name +1 -0
- data/meta/repository +1 -0
- data/meta/requires +1 -0
- data/meta/ruby +2 -0
- data/meta/subtitle +1 -0
- data/meta/suite +1 -0
- data/meta/summary +1 -0
- data/meta/title +1 -0
- data/meta/version +1 -0
- metadata +101 -0
data/HISTORY
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
= RELEASE HISTORY
|
2
|
+
|
3
|
+
== 0.5 / 2008-10-25
|
4
|
+
|
5
|
+
Brite (formerly Webrite) has been completely rewritten from the ground-up,
|
6
|
+
applying a number of ideas gathered from other systems and adding further
|
7
|
+
innovations. This is still an early release, and in need of features
|
8
|
+
and overt tire-kicking, but hey I'm already using to generate a pretty
|
9
|
+
damn nice looking site.
|
10
|
+
|
11
|
+
Changes:
|
12
|
+
|
13
|
+
* 1 Monumentously Important Enhancment
|
14
|
+
|
15
|
+
* Happy Rebirthday!
|
16
|
+
|
data/LICENSE
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2009 Thomas Sawyer
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
22
|
+
|
23
|
+
|
data/MANIFEST
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
#!mast bin lib meta test [A-Z]*
|
2
|
+
bin/brite
|
3
|
+
lib/brite/command.rb
|
4
|
+
lib/brite/config.rb
|
5
|
+
lib/brite/layout.rb
|
6
|
+
lib/brite/page.rb
|
7
|
+
lib/brite/part.rb
|
8
|
+
lib/brite/post.rb
|
9
|
+
lib/brite/site.rb
|
10
|
+
lib/brite/template.rb
|
11
|
+
meta/authors
|
12
|
+
meta/contact
|
13
|
+
meta/copyright
|
14
|
+
meta/description
|
15
|
+
meta/homepage
|
16
|
+
meta/license
|
17
|
+
meta/name
|
18
|
+
meta/repository
|
19
|
+
meta/requires
|
20
|
+
meta/ruby
|
21
|
+
meta/subtitle
|
22
|
+
meta/suite
|
23
|
+
meta/summary
|
24
|
+
meta/title
|
25
|
+
meta/version
|
26
|
+
LICENSE
|
27
|
+
README
|
28
|
+
HISTORY
|
data/README
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
= Brite
|
2
|
+
|
3
|
+
(The BrightLite of Static Website Generators)
|
4
|
+
|
5
|
+
* home: http://proutils.github.com/brite
|
6
|
+
* source: http://github.com/proutils/brite
|
7
|
+
|
8
|
+
|
9
|
+
== DESCRIPTION
|
10
|
+
|
11
|
+
Brite is an inovative static website/blog generation utility
|
12
|
+
which is extremely easy to use as it is versitle.
|
13
|
+
|
14
|
+
== FEATURES/ISSUES
|
15
|
+
|
16
|
+
* Awesome
|
17
|
+
* Extra Cool
|
18
|
+
* And Dyn-o-mite!
|
19
|
+
|
20
|
+
|
21
|
+
== SYNOPSIS
|
22
|
+
|
23
|
+
For now please see the Brite website and API documentation.
|
24
|
+
|
25
|
+
|
26
|
+
== HOW TO INSTALL
|
27
|
+
|
28
|
+
You know the routine ;)
|
29
|
+
|
30
|
+
$ sudop gem install brite
|
31
|
+
|
32
|
+
If you're old fashion and want to install to a site
|
33
|
+
location, see Setup.rb (http://protuils.github.com/setup).
|
34
|
+
|
35
|
+
|
36
|
+
== COPYRIGHT/LICENSE
|
37
|
+
|
38
|
+
Brite is Copyright (c) 2009 Thomas Sawyer
|
39
|
+
|
40
|
+
It is distributed under the terms of the MIT license.
|
41
|
+
|
42
|
+
|
data/bin/brite
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'brite/site'
|
2
|
+
|
3
|
+
module Brite
|
4
|
+
|
5
|
+
# Webrite command line interface.
|
6
|
+
|
7
|
+
class Command
|
8
|
+
|
9
|
+
def self.start
|
10
|
+
new.start
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(argv=nil)
|
14
|
+
@argv ||= ARGV.dup
|
15
|
+
|
16
|
+
@noharm = @argv.delete('--dryrun') || @argv.delete('--noharm')
|
17
|
+
@debug = @argv.delete('--debug')
|
18
|
+
|
19
|
+
@argv.reject!{ |e| e =~ /^-/ }
|
20
|
+
|
21
|
+
@location = @argv.shift || '.'
|
22
|
+
#@output = @argv.shift
|
23
|
+
end
|
24
|
+
|
25
|
+
#
|
26
|
+
def start
|
27
|
+
begin
|
28
|
+
site.build
|
29
|
+
rescue => e
|
30
|
+
@debug ? raise(e) : puts(e.message)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def site
|
35
|
+
Site.new(
|
36
|
+
:location => @location,
|
37
|
+
:output => @output,
|
38
|
+
:noharm => @noharm,
|
39
|
+
:trace => @trace
|
40
|
+
)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# Command to generate a single part to standard out.
|
46
|
+
#
|
47
|
+
|
48
|
+
class PartCommand
|
49
|
+
|
50
|
+
def self.start
|
51
|
+
new.start
|
52
|
+
end
|
53
|
+
|
54
|
+
def initialize(argv=nil)
|
55
|
+
@argv ||= ARGV.dup
|
56
|
+
end
|
57
|
+
|
58
|
+
def start
|
59
|
+
render(parts)
|
60
|
+
end
|
61
|
+
|
62
|
+
# render a single part to stdout.
|
63
|
+
|
64
|
+
def render(parts)
|
65
|
+
$stdout << Page.new(parts).to_html
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def parts
|
71
|
+
parts = []
|
72
|
+
@argv.each do |x|
|
73
|
+
if /^-/ =~ x
|
74
|
+
parts << [x.sub(/-{1,2}/,'')]
|
75
|
+
else
|
76
|
+
parts.last < x
|
77
|
+
end
|
78
|
+
end
|
79
|
+
Hash[*parts]
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
data/lib/brite/config.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
module Brite
|
4
|
+
|
5
|
+
# Configuration
|
6
|
+
class Config
|
7
|
+
|
8
|
+
#
|
9
|
+
DEFAULTS = {
|
10
|
+
:stencil => 'rhtml',
|
11
|
+
#:format => 'html',
|
12
|
+
:pagelayout => 'page',
|
13
|
+
:postlayout => 'post',
|
14
|
+
:maxchars => 500,
|
15
|
+
}
|
16
|
+
|
17
|
+
attr :defaults
|
18
|
+
|
19
|
+
def initialize
|
20
|
+
if File.exist?('.config/defaults')
|
21
|
+
custom_defaults = YAML.load(File.new('.config/defaults'))
|
22
|
+
else
|
23
|
+
custom_defaults = {}
|
24
|
+
end
|
25
|
+
@defaults = OpenStruct.new(DEFAULTS.merge(custom_defaults))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
data/lib/brite/layout.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
module Brite
|
2
|
+
|
3
|
+
# Layout class
|
4
|
+
class Layout < Page
|
5
|
+
undef_method :save
|
6
|
+
|
7
|
+
#def to_contextual_attributes
|
8
|
+
# { 'site'=>site.to_h }
|
9
|
+
#end
|
10
|
+
|
11
|
+
#
|
12
|
+
def render(attributes={})
|
13
|
+
#attributes = to_contextual_attributes
|
14
|
+
#attributes['content'] = content if content
|
15
|
+
|
16
|
+
output = parts.map{ |part| part.render(stencil, attributes) }.join("\n")
|
17
|
+
|
18
|
+
#@content = output
|
19
|
+
|
20
|
+
attributes = attributes.merge('content'=>output)
|
21
|
+
|
22
|
+
if layout
|
23
|
+
output = site.lookup_layout(layout).render(attributes)
|
24
|
+
end
|
25
|
+
|
26
|
+
output
|
27
|
+
end
|
28
|
+
|
29
|
+
# Layouts have no default layout.
|
30
|
+
def default_layout
|
31
|
+
nil
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
data/lib/brite/page.rb
ADDED
@@ -0,0 +1,235 @@
|
|
1
|
+
require 'brite/part'
|
2
|
+
|
3
|
+
module Brite
|
4
|
+
|
5
|
+
# Page class
|
6
|
+
class Page
|
7
|
+
|
8
|
+
attr :file
|
9
|
+
|
10
|
+
# Template type (rhtml or liquid)
|
11
|
+
attr :stencil
|
12
|
+
|
13
|
+
# Layout name (relative filename less extension)
|
14
|
+
attr :layout
|
15
|
+
|
16
|
+
# Author
|
17
|
+
attr :author
|
18
|
+
|
19
|
+
# Title of page/post
|
20
|
+
attr :title
|
21
|
+
|
22
|
+
# Publish date
|
23
|
+
attr :date
|
24
|
+
|
25
|
+
# Tags (labels)
|
26
|
+
attr :tags
|
27
|
+
|
28
|
+
# Category ("a glorified tag")
|
29
|
+
attr :category
|
30
|
+
|
31
|
+
# rendered output text
|
32
|
+
attr :content
|
33
|
+
|
34
|
+
# output extension (defualt is 'html')
|
35
|
+
attr :extension
|
36
|
+
|
37
|
+
#
|
38
|
+
def initialize(site, file)
|
39
|
+
@site = site
|
40
|
+
@file = file
|
41
|
+
@parts = []
|
42
|
+
parse
|
43
|
+
end
|
44
|
+
|
45
|
+
def name
|
46
|
+
@name ||= file.chomp(File.extname(file))
|
47
|
+
end
|
48
|
+
|
49
|
+
#
|
50
|
+
def url
|
51
|
+
@url ||= name + extension
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
def extension
|
56
|
+
@extension ||= '.html'
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
def root
|
61
|
+
'../' * file.count('/')
|
62
|
+
end
|
63
|
+
|
64
|
+
# TODO
|
65
|
+
#def next
|
66
|
+
# self
|
67
|
+
#end
|
68
|
+
|
69
|
+
# TODO
|
70
|
+
#def previous
|
71
|
+
# self
|
72
|
+
#end
|
73
|
+
|
74
|
+
#
|
75
|
+
def to_h
|
76
|
+
{
|
77
|
+
'url' => url,
|
78
|
+
'author' => author,
|
79
|
+
'title' => title,
|
80
|
+
'date' => date,
|
81
|
+
'tags' => tags,
|
82
|
+
'category' => category,
|
83
|
+
'content' => content
|
84
|
+
}
|
85
|
+
end
|
86
|
+
|
87
|
+
#
|
88
|
+
def save(output=nil)
|
89
|
+
output ||= Dir.pwd # TODO
|
90
|
+
text = render
|
91
|
+
fname = file.chomp(File.extname(file)) + extension
|
92
|
+
if dryrun
|
93
|
+
puts "[DRYRUN] write #{fname}"
|
94
|
+
else
|
95
|
+
puts "write #{fname}"
|
96
|
+
File.open(fname, 'w'){ |f| f << text }
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def to_contextual_attributes
|
101
|
+
{ 'site'=>site.to_h, 'page'=>to_h, 'root'=>root }
|
102
|
+
end
|
103
|
+
|
104
|
+
#
|
105
|
+
def to_liquid
|
106
|
+
to_contextual_attributes
|
107
|
+
end
|
108
|
+
|
109
|
+
protected
|
110
|
+
|
111
|
+
# TODO: Should validate front matter before anything processing.
|
112
|
+
#
|
113
|
+
def render(inherit={})
|
114
|
+
attributes = to_contextual_attributes
|
115
|
+
|
116
|
+
attributes = attributes.merge(inherit)
|
117
|
+
|
118
|
+
#attributes['content'] = content if content
|
119
|
+
|
120
|
+
output = parts.map{ |part| part.render(stencil, attributes) }.join("\n")
|
121
|
+
|
122
|
+
@content = output
|
123
|
+
|
124
|
+
attributes = attributes.merge('content'=>output)
|
125
|
+
if layout
|
126
|
+
renout = site.lookup_layout(layout)
|
127
|
+
raise "No such layout -- #{layout}" unless renout
|
128
|
+
output = renout.render(attributes)
|
129
|
+
end
|
130
|
+
|
131
|
+
output
|
132
|
+
end
|
133
|
+
|
134
|
+
private
|
135
|
+
|
136
|
+
#
|
137
|
+
def site
|
138
|
+
@site
|
139
|
+
end
|
140
|
+
|
141
|
+
#
|
142
|
+
def parts
|
143
|
+
@parts
|
144
|
+
end
|
145
|
+
|
146
|
+
#
|
147
|
+
def dryrun
|
148
|
+
site.dryrun
|
149
|
+
end
|
150
|
+
|
151
|
+
#
|
152
|
+
def parse
|
153
|
+
hold = []
|
154
|
+
text = File.read(file)
|
155
|
+
sect = text.split(/^\-\-\-/)
|
156
|
+
|
157
|
+
if sect.size == 1
|
158
|
+
@prop = {}
|
159
|
+
@parts << Part.new(sect[0], site.defaults.format)
|
160
|
+
else
|
161
|
+
void = sect.shift
|
162
|
+
head = sect.shift
|
163
|
+
head = YAML::load(head)
|
164
|
+
|
165
|
+
parse_header(head)
|
166
|
+
|
167
|
+
sect.each do |body|
|
168
|
+
index = body.index("\n")
|
169
|
+
format = body[0...index].strip
|
170
|
+
format = site.defaults.format if format.empty?
|
171
|
+
text = body[index+1..-1]
|
172
|
+
@parts << Part.new(text, format)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
177
|
+
|
178
|
+
#
|
179
|
+
def parse_header(head)
|
180
|
+
@stencil = head['stencil'] || site.defaults.stencil
|
181
|
+
@author = head['author'] || 'Anonymous'
|
182
|
+
@title = head['title']
|
183
|
+
@date = head['date']
|
184
|
+
@category = head['category']
|
185
|
+
@extension = head['extension']
|
186
|
+
|
187
|
+
self.tags = head['tags']
|
188
|
+
self.layout = head['layout']
|
189
|
+
end
|
190
|
+
|
191
|
+
def layout=(layout)
|
192
|
+
if FalseClass === layout
|
193
|
+
@layout = nil
|
194
|
+
else
|
195
|
+
@layout = layout || default_layout
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
#
|
200
|
+
def tags=(entry)
|
201
|
+
return entry unless entry
|
202
|
+
case entry
|
203
|
+
when String, Symbol
|
204
|
+
entry = entry.to_s.strip
|
205
|
+
if entry.index(/[,;]/)
|
206
|
+
entry = entry.split(/[,;]/)
|
207
|
+
else
|
208
|
+
entry = entry.split(/\s+/)
|
209
|
+
end
|
210
|
+
else
|
211
|
+
entry = entry.to_a.flatten
|
212
|
+
end
|
213
|
+
@tags = entry.map{ |e| e.strip }
|
214
|
+
end
|
215
|
+
|
216
|
+
# Default layout is different for pages vs. posts, so we
|
217
|
+
# use this method to differntiation them.
|
218
|
+
def default_layout
|
219
|
+
site.defaults.pagelayout
|
220
|
+
end
|
221
|
+
|
222
|
+
public
|
223
|
+
|
224
|
+
def to_s
|
225
|
+
file
|
226
|
+
end
|
227
|
+
|
228
|
+
def inspect
|
229
|
+
"<#{self.class}: #{file}>"
|
230
|
+
end
|
231
|
+
|
232
|
+
end
|
233
|
+
|
234
|
+
end
|
235
|
+
|
data/lib/brite/part.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
module Brite
|
2
|
+
|
3
|
+
# A Part is the section of a page. Pages can be segmented into
|
4
|
+
# parts using the '--- FORMAT' notation.
|
5
|
+
#
|
6
|
+
class Part
|
7
|
+
# Markup format (html, rdoc, markdown, textile)
|
8
|
+
attr :format
|
9
|
+
|
10
|
+
# Body of text as given in the part.
|
11
|
+
attr :text
|
12
|
+
|
13
|
+
#
|
14
|
+
def initialize(text, format=nil)
|
15
|
+
@format = format
|
16
|
+
@text = text
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
def render(type, attributes)
|
21
|
+
template_engine.render(type, format, text, attributes)
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
def template_engine
|
26
|
+
TemplateEngine
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
data/lib/brite/post.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'brite/page'
|
2
|
+
|
3
|
+
module Brite
|
4
|
+
|
5
|
+
# Post class
|
6
|
+
class Post < Page
|
7
|
+
|
8
|
+
def default_layout
|
9
|
+
site.defaults.postlayout
|
10
|
+
end
|
11
|
+
|
12
|
+
#def to_contextual_attributes
|
13
|
+
# { 'site' => site.to_h, 'post' => to_h }
|
14
|
+
#end
|
15
|
+
|
16
|
+
=begin
|
17
|
+
#
|
18
|
+
def render(content=nil)
|
19
|
+
attributes = to_contextual_attributes
|
20
|
+
#attributes['page']['content'] = content if content
|
21
|
+
|
22
|
+
output = parts.map{ |part| part.render(stencil, attributes) }.join("\n")
|
23
|
+
|
24
|
+
# content
|
25
|
+
@content = output
|
26
|
+
|
27
|
+
if layout
|
28
|
+
output = site.lookup_layout(layout).render(output)
|
29
|
+
end
|
30
|
+
output
|
31
|
+
end
|
32
|
+
=end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
data/lib/brite/site.rb
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
##
|
2
|
+
# "entia non sunt multiplicanda praeter necessitatem"
|
3
|
+
# --Ockham's razor
|
4
|
+
##
|
5
|
+
|
6
|
+
require 'brite/config'
|
7
|
+
require 'brite/page'
|
8
|
+
require 'brite/post'
|
9
|
+
require 'brite/layout'
|
10
|
+
require 'brite/template'
|
11
|
+
|
12
|
+
#
|
13
|
+
module Brite
|
14
|
+
|
15
|
+
# Site class
|
16
|
+
class Site
|
17
|
+
|
18
|
+
# Location of site.
|
19
|
+
attr :location
|
20
|
+
attr :output
|
21
|
+
|
22
|
+
attr :layouts
|
23
|
+
attr :pages
|
24
|
+
attr :posts
|
25
|
+
|
26
|
+
attr :dryrun
|
27
|
+
attr :verbose
|
28
|
+
|
29
|
+
def initialize(options={})
|
30
|
+
@location = options[:location] || Dir.pwd
|
31
|
+
@output = options[:output] || Dir.pwd
|
32
|
+
@dryrun = options[:dryrun]
|
33
|
+
|
34
|
+
@layouts = []
|
35
|
+
@pages = []
|
36
|
+
@posts = []
|
37
|
+
end
|
38
|
+
|
39
|
+
def tags
|
40
|
+
@tags ||= posts.map{ |p| p.tags }.flatten.uniq.sort
|
41
|
+
end
|
42
|
+
|
43
|
+
def posts_by_tag
|
44
|
+
@posts_by_tag ||= (
|
45
|
+
chart ||= Hash.new{|h,k|h[k]=[]}
|
46
|
+
posts.each do |post|
|
47
|
+
post.tags.each do |tag|
|
48
|
+
chart[tag] << post
|
49
|
+
end
|
50
|
+
end
|
51
|
+
chart
|
52
|
+
)
|
53
|
+
end
|
54
|
+
|
55
|
+
def verbose?
|
56
|
+
true
|
57
|
+
end
|
58
|
+
|
59
|
+
def build
|
60
|
+
Dir.chdir(location) do
|
61
|
+
sort_files
|
62
|
+
if verbose?
|
63
|
+
puts "Layouts: " + layouts.join(", ")
|
64
|
+
puts "Pages: " + pages.join(", ")
|
65
|
+
puts "Posts: " + posts.join(", ")
|
66
|
+
puts
|
67
|
+
end
|
68
|
+
render
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def lookup_layout(name)
|
73
|
+
layouts.find{ |l| name == l.name }
|
74
|
+
end
|
75
|
+
|
76
|
+
def sort_files
|
77
|
+
files = Dir['**/*']
|
78
|
+
files.each do |file|
|
79
|
+
temp = false
|
80
|
+
name = File.basename(file)
|
81
|
+
ext = File.extname(file)
|
82
|
+
case ext
|
83
|
+
when '.layout'
|
84
|
+
layouts << Layout.new(self, file)
|
85
|
+
when '.page' #*%w{.markdown .rdoc .textile .whtml}
|
86
|
+
pages << Page.new(self, file)
|
87
|
+
when '.post'
|
88
|
+
posts << Post.new(self, file)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
posts.sort!{ |a,b| b.date <=> a.date }
|
92
|
+
end
|
93
|
+
|
94
|
+
def render
|
95
|
+
render_posts # renger posts first, so pages can use them
|
96
|
+
render_pages
|
97
|
+
end
|
98
|
+
|
99
|
+
def render_pages
|
100
|
+
pages.each do |page|
|
101
|
+
page.save(output)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def render_posts
|
106
|
+
posts.each do |post|
|
107
|
+
post.save(output)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def config
|
112
|
+
@config ||= Config.new
|
113
|
+
end
|
114
|
+
|
115
|
+
def defaults
|
116
|
+
config.defaults
|
117
|
+
end
|
118
|
+
|
119
|
+
def to_h
|
120
|
+
pbt = {}
|
121
|
+
posts_by_tag.each do |tag, posts|
|
122
|
+
pbt[tag] = posts.map{ |p| p.to_h }
|
123
|
+
end
|
124
|
+
{
|
125
|
+
'posts' => posts.map{ |p| p.to_h },
|
126
|
+
'posts_by_tag' => pbt, #posts_by_tag, #.map{ |t, ps| [t, ps.map{|p|p.to_h}] }
|
127
|
+
'tags' => tags
|
128
|
+
}
|
129
|
+
end
|
130
|
+
|
131
|
+
def to_liquid
|
132
|
+
to_h
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
@@ -0,0 +1,215 @@
|
|
1
|
+
require 'tilt'
|
2
|
+
|
3
|
+
module Brite
|
4
|
+
|
5
|
+
# Stencil controls rendering to a variety
|
6
|
+
# of back-end templating and markup systems.
|
7
|
+
#
|
8
|
+
module TemplateEngine
|
9
|
+
extend self
|
10
|
+
|
11
|
+
#
|
12
|
+
def render(stencil, format, text, attributes)
|
13
|
+
text = render_format(format, text)
|
14
|
+
text = render_stencil(stencil, text, attributes)
|
15
|
+
text
|
16
|
+
end
|
17
|
+
|
18
|
+
#def render_format(format, text)
|
19
|
+
# case format
|
20
|
+
# when 'rdoc'
|
21
|
+
# rdoc(text)
|
22
|
+
# when 'markdown'
|
23
|
+
# rdiscount(text)
|
24
|
+
# when 'textile'
|
25
|
+
# redcloth(text)
|
26
|
+
# when 'haml'
|
27
|
+
# haml(text)
|
28
|
+
# else # html
|
29
|
+
# text
|
30
|
+
# end
|
31
|
+
#end
|
32
|
+
|
33
|
+
# Format Rendering
|
34
|
+
# ----------------
|
35
|
+
|
36
|
+
#
|
37
|
+
def render_format(format, text)
|
38
|
+
case format
|
39
|
+
when /^coderay/
|
40
|
+
coderay(text, format)
|
41
|
+
when 'rdoc' # TODO: Remove when next version of tilt is released.
|
42
|
+
rdoc(text)
|
43
|
+
else
|
44
|
+
if engine = Tilt[format]
|
45
|
+
engine.new{text}.render #(context)
|
46
|
+
else
|
47
|
+
text
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
#
|
53
|
+
#def redcloth(input)
|
54
|
+
# RedCloth.new(input).to_html
|
55
|
+
#end
|
56
|
+
|
57
|
+
#def bluecloth(input)
|
58
|
+
# BlueCloth.new(input).to_html
|
59
|
+
#end
|
60
|
+
|
61
|
+
#def rdiscount(input)
|
62
|
+
# RDiscount.new(input).to_html
|
63
|
+
#end
|
64
|
+
|
65
|
+
def rdoc(input)
|
66
|
+
markup = RDoc::Markup::ToHtml.new
|
67
|
+
markup.convert(input)
|
68
|
+
end
|
69
|
+
|
70
|
+
#def haml(input)
|
71
|
+
# Haml::Engine.new(input).render
|
72
|
+
#end
|
73
|
+
|
74
|
+
def coderay(input, format)
|
75
|
+
require 'coderay'
|
76
|
+
format = format.split('.')[1] || :ruby #:plaintext
|
77
|
+
tokens = CodeRay.scan(input, format.to_sym) #:ruby
|
78
|
+
tokens.div()
|
79
|
+
end
|
80
|
+
|
81
|
+
# Stencil Rendering
|
82
|
+
# -----------------
|
83
|
+
|
84
|
+
#
|
85
|
+
#def render_stencil(stencil, text, attributes)
|
86
|
+
# case stencil
|
87
|
+
# when 'rhtml'
|
88
|
+
# erb(text, attributes)
|
89
|
+
# when 'liquid'
|
90
|
+
# liquid(text, attributes)
|
91
|
+
# else
|
92
|
+
# text
|
93
|
+
# end
|
94
|
+
#end
|
95
|
+
|
96
|
+
#
|
97
|
+
def render_stencil(stencil, text, attributes)
|
98
|
+
if engine = Tilt[stencil]
|
99
|
+
engine.new{text}.render(nil, attributes)
|
100
|
+
else
|
101
|
+
text
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
#
|
106
|
+
#def erb(input, attributes)
|
107
|
+
# template = ERB.new(input)
|
108
|
+
# context = TemplateContext.new(attributes)
|
109
|
+
# result = template.result(context.__binding__)
|
110
|
+
# result
|
111
|
+
#end
|
112
|
+
|
113
|
+
#def liquid(input, attributes)
|
114
|
+
# template = Liquid::Template.parse(input)
|
115
|
+
# result = template.render(attributes, :filters => [TemplateFilters])
|
116
|
+
# result
|
117
|
+
#end
|
118
|
+
|
119
|
+
# Require Dependencies
|
120
|
+
# --------------------
|
121
|
+
|
122
|
+
# TODO: Load engines only if used.
|
123
|
+
|
124
|
+
begin ; require 'rubygems' ; rescue LoadError ; end
|
125
|
+
begin ; require 'erb' ; rescue LoadError ; end
|
126
|
+
begin ; require 'redcloth' ; rescue LoadError ; end
|
127
|
+
begin ; require 'bluecloth' ; rescue LoadError ; end
|
128
|
+
begin ; require 'rdiscount' ; rescue LoadError ; end
|
129
|
+
|
130
|
+
begin
|
131
|
+
require 'liquid'
|
132
|
+
#Liquid::Template.register_filter(TemplateFilters)
|
133
|
+
rescue LoadError
|
134
|
+
end
|
135
|
+
|
136
|
+
begin
|
137
|
+
require 'haml'
|
138
|
+
#Haml::Template.options[:format] = :html5
|
139
|
+
rescue LoadError
|
140
|
+
end
|
141
|
+
|
142
|
+
begin
|
143
|
+
require 'rdoc/markup'
|
144
|
+
require 'rdoc/markup/to_html'
|
145
|
+
rescue LoadError
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
#
|
151
|
+
#
|
152
|
+
#
|
153
|
+
|
154
|
+
#module TemplateFilters
|
155
|
+
|
156
|
+
# NOTE: HTML truncate did not work well.
|
157
|
+
|
158
|
+
# # HTML comment regular expression
|
159
|
+
# REM_RE = %r{<\!--(.*?)-->}
|
160
|
+
#
|
161
|
+
# # HTML tag regular expression
|
162
|
+
# TAG_RE = %r{</?\w+((\s+\w+(\s*=\s*(?:"(.|\n)*?"|'(.|\n)*?'|[^'">\s]+))?)+\s*|\s*)/?>} #'
|
163
|
+
#
|
164
|
+
# #
|
165
|
+
# def truncate_html(html, limit)
|
166
|
+
# return html unless limit
|
167
|
+
#
|
168
|
+
# mask = html.gsub(REM_RE){ |m| "\0" * m.size }
|
169
|
+
# mask = mask.gsub(TAG_RE){ |m| "\0" * m.size }
|
170
|
+
#
|
171
|
+
# i, x = 0, 0
|
172
|
+
#
|
173
|
+
# while i < mask.size && x < limit
|
174
|
+
# x += 1 if mask[i] != "\0"
|
175
|
+
# i += 1
|
176
|
+
# end
|
177
|
+
#
|
178
|
+
# while x > 0 && mask[x,1] == "\0"
|
179
|
+
# x -= 1
|
180
|
+
# end
|
181
|
+
#
|
182
|
+
# return html[0..x]
|
183
|
+
# end
|
184
|
+
|
185
|
+
#end
|
186
|
+
|
187
|
+
# = Clean Rendering Context
|
188
|
+
#
|
189
|
+
# The TemplateContext is is used by ERB.
|
190
|
+
|
191
|
+
class TemplateContext
|
192
|
+
#include TemplateFilters
|
193
|
+
|
194
|
+
instance_methods(true).each{ |m| private m unless m =~ /^__/ }
|
195
|
+
|
196
|
+
def initialize(attributes={})
|
197
|
+
@attributes = attributes
|
198
|
+
end
|
199
|
+
|
200
|
+
def __binding__
|
201
|
+
binding
|
202
|
+
end
|
203
|
+
|
204
|
+
def to_h
|
205
|
+
@attributes
|
206
|
+
end
|
207
|
+
|
208
|
+
def method_missing(s, *a)
|
209
|
+
s = s.to_s
|
210
|
+
@attributes.key?(s) ? @attributes[s] : super
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
end
|
215
|
+
|
data/meta/authors
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Thomas Sawyer
|
data/meta/contact
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
http://googlegroups.com/group/proutils
|
data/meta/copyright
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Copyright (c) 2006,2009 Thomas Sawyer
|
data/meta/description
ADDED
data/meta/homepage
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
http://proutils.github.com/brite
|
data/meta/license
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
GPL
|
data/meta/name
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
brite
|
data/meta/repository
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
git://github.com/proutils/brite.git
|
data/meta/requires
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
tilt
|
data/meta/ruby
ADDED
data/meta/subtitle
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Light Up Your Site
|
data/meta/suite
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
proutils
|
data/meta/summary
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Super Simple Static Site Generation
|
data/meta/title
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Brite
|
data/meta/version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.5
|
metadata
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: brite
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: "0.5"
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Thomas Sawyer
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-11-17 00:00:00 -05:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: tilt
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
description: |-
|
26
|
+
Brite is a remarkably easy to use, light-weight website
|
27
|
+
generator. It supports a variety of backend rendering engines
|
28
|
+
including rhtml via eruby, textile via redcloth, markdown
|
29
|
+
via rdiscount, with others on the way.
|
30
|
+
email: http://googlegroups.com/group/proutils
|
31
|
+
executables:
|
32
|
+
- brite
|
33
|
+
extensions: []
|
34
|
+
|
35
|
+
extra_rdoc_files:
|
36
|
+
- README
|
37
|
+
- MANIFEST
|
38
|
+
- LICENSE
|
39
|
+
- HISTORY
|
40
|
+
files:
|
41
|
+
- bin/brite
|
42
|
+
- lib/brite/command.rb
|
43
|
+
- lib/brite/config.rb
|
44
|
+
- lib/brite/layout.rb
|
45
|
+
- lib/brite/page.rb
|
46
|
+
- lib/brite/part.rb
|
47
|
+
- lib/brite/post.rb
|
48
|
+
- lib/brite/site.rb
|
49
|
+
- lib/brite/template.rb
|
50
|
+
- meta/authors
|
51
|
+
- meta/contact
|
52
|
+
- meta/copyright
|
53
|
+
- meta/description
|
54
|
+
- meta/homepage
|
55
|
+
- meta/license
|
56
|
+
- meta/name
|
57
|
+
- meta/repository
|
58
|
+
- meta/requires
|
59
|
+
- meta/ruby
|
60
|
+
- meta/subtitle
|
61
|
+
- meta/suite
|
62
|
+
- meta/summary
|
63
|
+
- meta/title
|
64
|
+
- meta/version
|
65
|
+
- LICENSE
|
66
|
+
- README
|
67
|
+
- HISTORY
|
68
|
+
- MANIFEST
|
69
|
+
has_rdoc: true
|
70
|
+
homepage: http://proutils.github.com/brite
|
71
|
+
licenses: []
|
72
|
+
|
73
|
+
post_install_message:
|
74
|
+
rdoc_options:
|
75
|
+
- --title
|
76
|
+
- Brite API
|
77
|
+
- --main
|
78
|
+
- README
|
79
|
+
require_paths:
|
80
|
+
- lib
|
81
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: "0"
|
86
|
+
version:
|
87
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: "0"
|
92
|
+
version:
|
93
|
+
requirements: []
|
94
|
+
|
95
|
+
rubyforge_project: brite
|
96
|
+
rubygems_version: 1.3.5
|
97
|
+
signing_key:
|
98
|
+
specification_version: 3
|
99
|
+
summary: Super Simple Static Site Generation
|
100
|
+
test_files: []
|
101
|
+
|