webby 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/History.txt +3 -0
  2. data/Manifest.txt +44 -0
  3. data/README.txt +50 -0
  4. data/Rakefile +29 -0
  5. data/bin/webby +14 -0
  6. data/data/Rakefile +6 -0
  7. data/data/content/css/blueprint/License.txt +21 -0
  8. data/data/content/css/blueprint/Readme.txt +93 -0
  9. data/data/content/css/blueprint/lib/buttons.css +112 -0
  10. data/data/content/css/blueprint/lib/compressed.css +127 -0
  11. data/data/content/css/blueprint/lib/grid.css +177 -0
  12. data/data/content/css/blueprint/lib/img/baseline-black.png +0 -0
  13. data/data/content/css/blueprint/lib/img/baseline.png +0 -0
  14. data/data/content/css/blueprint/lib/img/grid.png +0 -0
  15. data/data/content/css/blueprint/lib/img/icons/cross.png +0 -0
  16. data/data/content/css/blueprint/lib/img/icons/textfield_key.png +0 -0
  17. data/data/content/css/blueprint/lib/img/icons/tick.png +0 -0
  18. data/data/content/css/blueprint/lib/reset.css +37 -0
  19. data/data/content/css/blueprint/lib/typography.css +159 -0
  20. data/data/content/css/blueprint/print.css +75 -0
  21. data/data/content/css/blueprint/screen.css +34 -0
  22. data/data/content/css/site.css +0 -0
  23. data/data/content/index.rhtml +18 -0
  24. data/data/layouts/default.rhtml +55 -0
  25. data/data/tasks/create.rake +7 -0
  26. data/data/templates/page.erb +18 -0
  27. data/lib/webby.rb +67 -0
  28. data/lib/webby/auto_builder.rb +75 -0
  29. data/lib/webby/builder.rb +165 -0
  30. data/lib/webby/file.rb +191 -0
  31. data/lib/webby/main.rb +129 -0
  32. data/lib/webby/pages_db.rb +70 -0
  33. data/lib/webby/renderer.rb +94 -0
  34. data/lib/webby/resource.rb +174 -0
  35. data/lib/webby/utils.rb +24 -0
  36. data/lib/webby/webby_task.rb +136 -0
  37. data/spec/spec.opts +1 -0
  38. data/spec/spec_helper.rb +12 -0
  39. data/spec/webby/file_spec.rb +107 -0
  40. data/tasks/doc.rake +60 -0
  41. data/tasks/gem.rake +112 -0
  42. data/tasks/manifest.rake +39 -0
  43. data/tasks/setup.rb +108 -0
  44. data/tasks/spec.rake +37 -0
  45. 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
@@ -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
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,12 @@
1
+ # $Id: spec_helper.rb 1 2007-08-18 21:39:50Z tim_pease $
2
+
3
+ begin
4
+ require 'webby'
5
+ rescue LoadError
6
+ path = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
7
+ raise if $:.include? path
8
+ $: << path
9
+ retry
10
+ end
11
+
12
+ # EOF
@@ -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