webby 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.
- data/History.txt +3 -0
- data/Manifest.txt +44 -0
- data/README.txt +50 -0
- data/Rakefile +29 -0
- data/bin/webby +14 -0
- data/data/Rakefile +6 -0
- data/data/content/css/blueprint/License.txt +21 -0
- data/data/content/css/blueprint/Readme.txt +93 -0
- data/data/content/css/blueprint/lib/buttons.css +112 -0
- data/data/content/css/blueprint/lib/compressed.css +127 -0
- data/data/content/css/blueprint/lib/grid.css +177 -0
- data/data/content/css/blueprint/lib/img/baseline-black.png +0 -0
- data/data/content/css/blueprint/lib/img/baseline.png +0 -0
- data/data/content/css/blueprint/lib/img/grid.png +0 -0
- data/data/content/css/blueprint/lib/img/icons/cross.png +0 -0
- data/data/content/css/blueprint/lib/img/icons/textfield_key.png +0 -0
- data/data/content/css/blueprint/lib/img/icons/tick.png +0 -0
- data/data/content/css/blueprint/lib/reset.css +37 -0
- data/data/content/css/blueprint/lib/typography.css +159 -0
- data/data/content/css/blueprint/print.css +75 -0
- data/data/content/css/blueprint/screen.css +34 -0
- data/data/content/css/site.css +0 -0
- data/data/content/index.rhtml +18 -0
- data/data/layouts/default.rhtml +55 -0
- data/data/tasks/create.rake +7 -0
- data/data/templates/page.erb +18 -0
- data/lib/webby.rb +67 -0
- data/lib/webby/auto_builder.rb +75 -0
- data/lib/webby/builder.rb +165 -0
- data/lib/webby/file.rb +191 -0
- data/lib/webby/main.rb +129 -0
- data/lib/webby/pages_db.rb +70 -0
- data/lib/webby/renderer.rb +94 -0
- data/lib/webby/resource.rb +174 -0
- data/lib/webby/utils.rb +24 -0
- data/lib/webby/webby_task.rb +136 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/webby/file_spec.rb +107 -0
- data/tasks/doc.rake +60 -0
- data/tasks/gem.rake +112 -0
- data/tasks/manifest.rake +39 -0
- data/tasks/setup.rb +108 -0
- data/tasks/spec.rake +37 -0
- metadata +128 -0
@@ -0,0 +1,174 @@
|
|
1
|
+
# $Id: resource.rb 5 2007-08-22 04:25:49Z tim_pease $
|
2
|
+
|
3
|
+
module Webby
|
4
|
+
|
5
|
+
#
|
6
|
+
#
|
7
|
+
class Resource
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def pages
|
11
|
+
@pages ||= PagesDB.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def layouts
|
15
|
+
@layouts ||= PagesDB.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def clear
|
19
|
+
self.pages.clear
|
20
|
+
self.layouts.clear
|
21
|
+
end
|
22
|
+
end # class << self
|
23
|
+
|
24
|
+
# call-seq:
|
25
|
+
# Resource.new( filename, defaults = {} ) => page
|
26
|
+
#
|
27
|
+
def initialize( fn, defaults = {} )
|
28
|
+
@path = fn.sub(%r/\A(?:\.\/|\/)/o, '').freeze
|
29
|
+
@dir = ::File.dirname(@path).sub(%r/\A[^\/]+\/?/o, '')
|
30
|
+
@filename = ::File.basename(@path).sub(%r/\.\w+\z/o, '')
|
31
|
+
@ext = ::File.extname(@path).sub(%r/\A\.?/o, '')
|
32
|
+
@mtime = ::File.mtime @path
|
33
|
+
|
34
|
+
@rendering = false
|
35
|
+
|
36
|
+
# deal with the meta-data
|
37
|
+
@mdata = ::Webby::File.meta_data(@path)
|
38
|
+
@have_mdata = !@mdata.nil?
|
39
|
+
@mdata = @have_mdata ? defaults.merge(@mdata) : {}
|
40
|
+
@mdata.sanitize!
|
41
|
+
|
42
|
+
self.class.pages << self if is_page? or is_static?
|
43
|
+
self.class.layouts << self if is_layout?
|
44
|
+
end
|
45
|
+
|
46
|
+
# call-seq:
|
47
|
+
# equal?( other ) => true or false
|
48
|
+
#
|
49
|
+
def equal?( other )
|
50
|
+
return false unless self.class == other.class
|
51
|
+
@path == other.path
|
52
|
+
end
|
53
|
+
alias :== :equal?
|
54
|
+
alias :eql? :equal?
|
55
|
+
|
56
|
+
# call-seq:
|
57
|
+
# resource <=> other => -1, 0, +1, or nil
|
58
|
+
#
|
59
|
+
def <=>( other )
|
60
|
+
return unless self.class == other.class
|
61
|
+
@path <=> other.path
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
attr_reader :path, :dir, :filename, :mtime, :ext
|
66
|
+
|
67
|
+
# call-seq:
|
68
|
+
# extension => string
|
69
|
+
#
|
70
|
+
def extension
|
71
|
+
return @mdata['extension'] if @mdata.has_key? 'extension'
|
72
|
+
|
73
|
+
if @mdata.has_key? 'layout'
|
74
|
+
lyt = self.class.layouts.find_by_name @mdata['layout']
|
75
|
+
break if lyt.nil?
|
76
|
+
return lyt.extension
|
77
|
+
end
|
78
|
+
|
79
|
+
@ext
|
80
|
+
end
|
81
|
+
|
82
|
+
def destination
|
83
|
+
return @destination if defined? @destination
|
84
|
+
return @destination = ::Webby.config['output_dir'] if is_layout?
|
85
|
+
|
86
|
+
@destination = File.join(::Webby.config['output_dir'], dir, filename)
|
87
|
+
@destination << '.'
|
88
|
+
@destination << extension
|
89
|
+
@destination
|
90
|
+
end
|
91
|
+
|
92
|
+
# call-seq:
|
93
|
+
# render => string
|
94
|
+
#
|
95
|
+
def render
|
96
|
+
raise Error, "page '#@path' is in a rendering loop" if @rendering
|
97
|
+
|
98
|
+
@rendering = true
|
99
|
+
content = Renderer.new(self).render_page
|
100
|
+
@rendering = false
|
101
|
+
|
102
|
+
return content
|
103
|
+
|
104
|
+
rescue
|
105
|
+
@rendering = false
|
106
|
+
raise
|
107
|
+
end
|
108
|
+
|
109
|
+
# call-seq:
|
110
|
+
# is_layout? => true or false
|
111
|
+
#
|
112
|
+
# Returns +true+ if this resource is a layout.
|
113
|
+
#
|
114
|
+
def is_layout?
|
115
|
+
@is_layout ||=
|
116
|
+
!(%r/\A(?:\.\/|\/)?#{::Webby.config['layout_dir']}\//o =~ @path).nil?
|
117
|
+
end
|
118
|
+
|
119
|
+
# call-seq:
|
120
|
+
# is_static? => true or false
|
121
|
+
#
|
122
|
+
# Returns +true+ if this resource is a static file.
|
123
|
+
#
|
124
|
+
def is_static?
|
125
|
+
!@have_mdata
|
126
|
+
end
|
127
|
+
|
128
|
+
# call-seq:
|
129
|
+
# is_page? => true or false
|
130
|
+
#
|
131
|
+
# Returns +true+ if this resource is a page suitable for rendering.
|
132
|
+
#
|
133
|
+
def is_page?
|
134
|
+
@have_mdata and !is_layout?
|
135
|
+
end
|
136
|
+
|
137
|
+
# call-seq:
|
138
|
+
# dirty? => true or false
|
139
|
+
#
|
140
|
+
# Returns +true+ if this resource is newer than its corresponding output
|
141
|
+
# product. The resource needs to be rendered (if a page or layout) or
|
142
|
+
# copied (if a static file) to the output directory.
|
143
|
+
#
|
144
|
+
def dirty?
|
145
|
+
return @mdata['dirty'] if @mdata.has_key? 'dirty'
|
146
|
+
|
147
|
+
# if the destination file does not exist, then we are dirty
|
148
|
+
return @mdata['dirty'] = true unless test ?e, destination
|
149
|
+
|
150
|
+
# if this file's mtime is larger than the destination file's
|
151
|
+
# mtime, then we are dirty
|
152
|
+
@mdata['dirty'] = @mtime > File.mtime(destination)
|
153
|
+
return @mdata['dirty'] if is_static? or @mdata['dirty']
|
154
|
+
|
155
|
+
# check to see if the layout is dirty, and it it is then we
|
156
|
+
# are dirty, too
|
157
|
+
if @mdata.has_key? 'layout'
|
158
|
+
lyt = self.class.layouts.find_by_name @mdata['layout']
|
159
|
+
break if lyt.nil?
|
160
|
+
return @mdata['dirty'] = true if lyt.dirty?
|
161
|
+
end
|
162
|
+
|
163
|
+
# if we got here, then we are not dirty
|
164
|
+
@mdata['dirty'] = false
|
165
|
+
end
|
166
|
+
|
167
|
+
def method_missing( name, *a, &b )
|
168
|
+
@mdata[name.to_s]
|
169
|
+
end
|
170
|
+
|
171
|
+
end # class Resource
|
172
|
+
end # module Webby
|
173
|
+
|
174
|
+
# EOF
|
data/lib/webby/utils.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# $Id: utils.rb 1 2007-08-18 21:39:50Z tim_pease $
|
2
|
+
|
3
|
+
module Enumerable
|
4
|
+
def injecting( initial )
|
5
|
+
inject(initial) do |memo, obj|
|
6
|
+
yield(memo, obj); memo
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class Hash
|
12
|
+
def sanitize!
|
13
|
+
h = self.injecting({}) do |h, (k, v)|
|
14
|
+
h[k] = case v
|
15
|
+
when 'none', 'nil': nil
|
16
|
+
when 'true', 'yes': true
|
17
|
+
when 'false', 'no': false
|
18
|
+
else v end
|
19
|
+
end
|
20
|
+
self.replace h
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# EOF
|
@@ -0,0 +1,136 @@
|
|
1
|
+
# $Id: webby_task.rb 7 2007-08-22 22:31:08Z tim_pease $
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'rake'
|
5
|
+
require 'rake/tasklib'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rubygems'
|
8
|
+
raise unless gem 'rake'
|
9
|
+
retry
|
10
|
+
end
|
11
|
+
|
12
|
+
module Rake
|
13
|
+
|
14
|
+
# The WebbyTask defines several rake tasks for working with Webby based
|
15
|
+
# websites:
|
16
|
+
#
|
17
|
+
# [:build] Build the site by compiling only those resources in the content
|
18
|
+
# folder that have been modifed recently. If the a content file
|
19
|
+
# has a modification time more recent then its corresponding
|
20
|
+
# output file, then it will be built by this task.
|
21
|
+
#
|
22
|
+
# [:rebuild] Rebuild the entire site from the content folder and store the
|
23
|
+
# results in the output folder.
|
24
|
+
#
|
25
|
+
# [:autobuild] Monitors the content and layout directories for modified
|
26
|
+
# resources and compiles those files as needed. This task
|
27
|
+
# returns only when the user hits Ctrl-C.
|
28
|
+
#
|
29
|
+
# [:create:page] Create a new page in the content folder based on the
|
30
|
+
# template 'page' found in the templates folder. One task
|
31
|
+
# will be created for each file found in the templates
|
32
|
+
# folder.
|
33
|
+
#
|
34
|
+
class WebbyTask < TaskLib
|
35
|
+
|
36
|
+
# Location of the generated website
|
37
|
+
attr_accessor :output_dir
|
38
|
+
|
39
|
+
# Location of the webiste source material
|
40
|
+
attr_accessor :content_dir
|
41
|
+
|
42
|
+
# Location of the layout files for generated pages
|
43
|
+
attr_accessor :layout_dir
|
44
|
+
|
45
|
+
# Location of the page templates
|
46
|
+
attr_accessor :template_dir
|
47
|
+
|
48
|
+
# Array of patterns used to exclude files
|
49
|
+
attr_accessor :exclude
|
50
|
+
|
51
|
+
# Global page attributes (default is {})
|
52
|
+
attr_reader :page_defaults
|
53
|
+
|
54
|
+
# Merge the given _hash_ with the page defaults hash
|
55
|
+
def page_defaults=( hash )
|
56
|
+
@page_defaults.merge! hash
|
57
|
+
end
|
58
|
+
|
59
|
+
# call-seq:
|
60
|
+
# WebbyTask.new {|self| block}
|
61
|
+
#
|
62
|
+
# Create the tasks used by Webby to build a website and to create new
|
63
|
+
# pages in the website.
|
64
|
+
#
|
65
|
+
def initialize
|
66
|
+
@output_dir = 'output'
|
67
|
+
@content_dir = 'content'
|
68
|
+
@layout_dir = 'layouts'
|
69
|
+
@template_dir = 'templates'
|
70
|
+
@exclude = %w(tmp$ bak$ ~$ CVS \.svn)
|
71
|
+
@page_defaults = {
|
72
|
+
'extension' => 'html',
|
73
|
+
'layout' => 'default'
|
74
|
+
}
|
75
|
+
|
76
|
+
yield self if block_given?
|
77
|
+
|
78
|
+
::Webby.config.merge!({
|
79
|
+
'output_dir' => @output_dir,
|
80
|
+
'content_dir' => @content_dir,
|
81
|
+
'layout_dir' => @layout_dir,
|
82
|
+
'template_dir' => @template_dir,
|
83
|
+
'exclude' => @exclude
|
84
|
+
})
|
85
|
+
::Webby.page_defaults.merge! @page_defaults
|
86
|
+
|
87
|
+
define_build_tasks
|
88
|
+
namespace(:create) {define_create_tasks}
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
# Defines the :build and :rebuild tasks
|
95
|
+
#
|
96
|
+
def define_build_tasks
|
97
|
+
desc "build the website"
|
98
|
+
task :build do |t|
|
99
|
+
::Webby::Builder.run
|
100
|
+
end
|
101
|
+
|
102
|
+
desc "rebuild the website"
|
103
|
+
task :rebuild do |t|
|
104
|
+
::Webby::Builder.run :rebuild => true
|
105
|
+
end
|
106
|
+
|
107
|
+
desc "continuously build the website"
|
108
|
+
task :autobuild do |t|
|
109
|
+
::Webby::AutoBuilder.run
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# Scans the templates directory for any files, and creats a corresponding
|
114
|
+
# task for creating a new page based on that template.
|
115
|
+
#
|
116
|
+
def define_create_tasks
|
117
|
+
FileList["#{@template_dir}/*"].each do |template|
|
118
|
+
name = template.pathmap '%n'
|
119
|
+
|
120
|
+
desc "create a new #{name} page"
|
121
|
+
task name do |t|
|
122
|
+
raise "Usage: rake #{t.name} path" unless ARGV.length == 2
|
123
|
+
|
124
|
+
page = t.application.top_level_tasks.pop
|
125
|
+
page = File.join(@content_dir, page)
|
126
|
+
page << '.txt' if File.extname(page).empty?
|
127
|
+
|
128
|
+
::Webby::Builder.create page, :from => template
|
129
|
+
end # task
|
130
|
+
end # each
|
131
|
+
end
|
132
|
+
|
133
|
+
end # class WebbyTask
|
134
|
+
end # module Rake
|
135
|
+
|
136
|
+
# EOF
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
# $Id: file_spec.rb 1 2007-08-18 21:39:50Z tim_pease $
|
2
|
+
|
3
|
+
require 'spec/spec_helper.rb'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
describe Webby::File do
|
7
|
+
|
8
|
+
FN = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'lorem_ipsum.txt'))
|
9
|
+
FN_YAML = FN.gsub %r/\.txt\z/, '_yaml.txt'
|
10
|
+
LINES = [
|
11
|
+
"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nulla orci\n",
|
12
|
+
"ante, aliquet ac, vulputate ut, suscipit et, sapien. Integer elementum\n",
|
13
|
+
"nisi quis magna tincidunt mattis. Aliquam semper. Pellentesque pretium.\n",
|
14
|
+
"Ut a ligula sit amet pede malesuada laoreet. Ut et purus. Morbi turpis\n",
|
15
|
+
"justo, pharetra vitae, consequat a, sodales vitae, tortor. Donec non\n",
|
16
|
+
"massa. Maecenas adipiscing venenatis nisi. Proin vulputate lorem posuere\n",
|
17
|
+
"mi. Cras sagittis. Pellentesque tortor mauris, accumsan vitae, ultrices\n",
|
18
|
+
"vel, tristique ultricies, eros. Donec fringilla hendrerit mauris. Nam in\n",
|
19
|
+
"orci. Curabitur congue consectetuer leo. Donec ut pede. Proin et lorem.\n",
|
20
|
+
"Aliquam eget lacus. In nibh.\n"
|
21
|
+
]
|
22
|
+
|
23
|
+
before do
|
24
|
+
File.open(FN,'w') {|fd| fd.write LINES}
|
25
|
+
File.open(FN_YAML,'w') do |fd|
|
26
|
+
fd.write "--- \n- one\n- two\n- three\n--- \n"
|
27
|
+
fd.write LINES
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
after do
|
32
|
+
File.delete FN if File.exists?(FN)
|
33
|
+
File.delete FN_YAML if File.exists?(FN_YAML)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should return nil for meta-data on regular files' do
|
37
|
+
begin
|
38
|
+
fd = Webby::File.new FN, 'r'
|
39
|
+
fd.meta_data.should == nil
|
40
|
+
|
41
|
+
fd.readlines.should == LINES
|
42
|
+
ensure
|
43
|
+
fd.close
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should add meta-data to the top of a file' do
|
48
|
+
Webby::File.open(FN,'a+') do |fd|
|
49
|
+
fd.meta_data.should == nil
|
50
|
+
fd.meta_data = %w(one two three)
|
51
|
+
end
|
52
|
+
|
53
|
+
Webby::File.open(FN,'r') do |fd|
|
54
|
+
fd.meta_data.should == %w(one two three)
|
55
|
+
end
|
56
|
+
|
57
|
+
File.open(FN_YAML, 'r') do |fd|
|
58
|
+
ary = LINES.dup
|
59
|
+
ary.insert 0, [
|
60
|
+
"--- \n",
|
61
|
+
"- one\n",
|
62
|
+
"- two\n",
|
63
|
+
"- three\n",
|
64
|
+
"--- \n"
|
65
|
+
]
|
66
|
+
fd.readlines.should == ary.flatten
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should remove the meta-data when set to nil' do
|
71
|
+
Webby::File.open(FN_YAML,'a+') do |fd|
|
72
|
+
fd.meta_data.should == %w(one two three)
|
73
|
+
fd.meta_data = nil
|
74
|
+
end
|
75
|
+
|
76
|
+
Webby::File.open(FN_YAML,'r') do |fd|
|
77
|
+
fd.meta_data.should == nil
|
78
|
+
end
|
79
|
+
|
80
|
+
File.open(FN_YAML, 'r') do |fd|
|
81
|
+
fd.readlines.should == LINES
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'should skip the meta-data when reading from the file' do
|
86
|
+
begin
|
87
|
+
fd = Webby::File.new FN_YAML, 'r'
|
88
|
+
fd.meta_data.should == %w(one two three)
|
89
|
+
|
90
|
+
fd.getc.should == ?L; fd.seek 0
|
91
|
+
fd.gets.should == LINES.first; fd.seek 0
|
92
|
+
fd.read(5).should == 'Lorem'; fd.seek 0
|
93
|
+
fd.read_nonblock(11) == 'Lorem ipsum'; fd.seek 0
|
94
|
+
fd.readchar.should == ?L; fd.seek 0
|
95
|
+
fd.readline.should == LINES.first; fd.seek 0
|
96
|
+
fd.readlines.should == LINES; fd.seek 0
|
97
|
+
fd.readpartial(11).should == 'Lorem ipsum'; fd.seek 0
|
98
|
+
fd.sysread(11).should == 'Lorem ipsum'; fd.seek 0
|
99
|
+
|
100
|
+
ensure
|
101
|
+
fd.close
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
end # describe Webby::File
|
106
|
+
|
107
|
+
# EOF
|