webby 0.1.0 → 0.2.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.
Files changed (49) hide show
  1. data/History.txt +7 -0
  2. data/Manifest.txt +30 -1
  3. data/Rakefile +6 -2
  4. data/bin/webby +1 -1
  5. data/data/Rakefile +6 -2
  6. data/data/content/{index.rhtml → index.txt} +0 -0
  7. data/data/tasks/create.rake +6 -1
  8. data/data/tasks/deploy.rake +22 -0
  9. data/data/tasks/heel.rake +26 -0
  10. data/data/tasks/setup.rb +27 -0
  11. data/lib/webby.rb +20 -12
  12. data/lib/webby/builder.rb +6 -19
  13. data/lib/webby/main.rb +85 -15
  14. data/lib/webby/pages_db.rb +24 -1
  15. data/lib/webby/renderer.rb +25 -3
  16. data/lib/webby/resource.rb +89 -13
  17. data/lib/webby/webby_task.rb +19 -41
  18. data/tasks/doc.rake +2 -19
  19. data/tasks/gem.rake +14 -41
  20. data/tasks/manifest.rake +1 -1
  21. data/tasks/rubyforge.rake +57 -0
  22. data/tasks/setup.rb +6 -5
  23. data/tasks/spec.rake +3 -3
  24. data/tasks/website.rake +38 -0
  25. data/website/Rakefile +13 -0
  26. data/website/content/css/blueprint/lib/buttons.css +112 -0
  27. data/website/content/css/blueprint/lib/compressed.css +127 -0
  28. data/website/content/css/blueprint/lib/grid.css +177 -0
  29. data/website/content/css/blueprint/lib/img/baseline-black.png +0 -0
  30. data/website/content/css/blueprint/lib/img/baseline.png +0 -0
  31. data/website/content/css/blueprint/lib/img/grid.png +0 -0
  32. data/website/content/css/blueprint/lib/img/icons/cross.png +0 -0
  33. data/website/content/css/blueprint/lib/img/icons/textfield_key.png +0 -0
  34. data/website/content/css/blueprint/lib/img/icons/tick.png +0 -0
  35. data/website/content/css/blueprint/lib/reset.css +37 -0
  36. data/website/content/css/blueprint/lib/typography.css +159 -0
  37. data/website/content/css/blueprint/print.css +75 -0
  38. data/website/content/css/blueprint/screen.css +34 -0
  39. data/website/content/css/site.css +22 -0
  40. data/website/content/download.txt +8 -0
  41. data/website/content/index.txt +28 -0
  42. data/website/content/tutorial.txt +130 -0
  43. data/website/layouts/default.rhtml +49 -0
  44. data/website/tasks/create.rake +11 -0
  45. data/website/tasks/deploy.rake +22 -0
  46. data/website/tasks/heel.rake +26 -0
  47. data/website/tasks/setup.rb +27 -0
  48. data/website/templates/page.erb +8 -0
  49. metadata +33 -14
@@ -1,4 +1,4 @@
1
- # $Id: pages_db.rb 6 2007-08-22 22:25:53Z tim_pease $
1
+ # $Id: pages_db.rb 18 2007-08-28 15:48:17Z tim_pease $
2
2
 
3
3
  module Webby
4
4
 
@@ -7,20 +7,32 @@ module Webby
7
7
  class PagesDB
8
8
  include Enumerable
9
9
 
10
+ # call-seq:
11
+ # PagesDB.new
12
+ #
10
13
  def initialize
11
14
  @db = Hash.new {|h,k| h[k] = []}
12
15
  end
13
16
 
17
+ # call-seq:
18
+ # add( resource )
19
+ #
14
20
  def add( page )
15
21
  @db[page.dir] << page
16
22
  self
17
23
  end
18
24
  alias :<< :add
19
25
 
26
+ # call-seq:
27
+ # clear
28
+ #
20
29
  def clear
21
30
  @db.clear
22
31
  end
23
32
 
33
+ # call-seq:
34
+ # each {|resource| block}
35
+ #
24
36
  def each( &b )
25
37
  keys = @db.keys.sort
26
38
  keys.each do |k|
@@ -28,6 +40,9 @@ class PagesDB
28
40
  end
29
41
  end
30
42
 
43
+ # call-seq:
44
+ # find_by_name( name )
45
+ #
31
46
  def find_by_name( name )
32
47
  self.find {|page| page.filename == name}
33
48
  end
@@ -37,6 +52,7 @@ class PagesDB
37
52
  #
38
53
  # Options include:
39
54
  # :sorty_by => 'attribute'
55
+ # :reverse => true
40
56
  #
41
57
  def siblings( page, opts = {} )
42
58
  ary = @db[page.dir].dup
@@ -49,6 +65,13 @@ class PagesDB
49
65
  ary
50
66
  end
51
67
 
68
+ # call-seq:
69
+ # children( page, opts = {} ) => array
70
+ #
71
+ # Options include:
72
+ # :sorty_by => 'attribute'
73
+ # :reverse => true
74
+ #
52
75
  def children( page, opts = {} )
53
76
  rgxp = Regexp.new "\\A#{page.dir}/[^/]+"
54
77
 
@@ -1,4 +1,4 @@
1
- # $Id: renderer.rb 2 2007-08-20 17:55:30Z tim_pease $
1
+ # $Id: renderer.rb 19 2007-08-28 22:48:24Z tim_pease $
2
2
 
3
3
  require 'erb'
4
4
 
@@ -7,7 +7,17 @@ try_require 'redcloth'
7
7
 
8
8
  module Webby
9
9
 
10
+ # The Webby::Renderer is used to _filter_ and _layout_ the text found in the
11
+ # resource page files in the content directory.
10
12
  #
13
+ # A page is filtered based on the settings of the 'filter' option in the
14
+ # page's meta-data information. For example, if 'textile' is specified as
15
+ # a filter, then the page will be run through the RedCloth markup filer.
16
+ # More than one filter can be used on a page; they will be run in the
17
+ # order specified in the meta-data.
18
+ #
19
+ # A page is rendered into a layout specified by the 'layout' option in the
20
+ # page's meta-data information.
11
21
  #
12
22
  class Renderer
13
23
  include ERB::Util
@@ -15,6 +25,10 @@ class Renderer
15
25
  # call-seq:
16
26
  # Renderer.new( page )
17
27
  #
28
+ # Create a new renderer for the given _page_. The renderer will apply the
29
+ # desired filters to the _page_ (from the page's meta-data) and then
30
+ # render the filtered page into the desired layout.
31
+ #
18
32
  def initialize( page )
19
33
  unless page.is_page?
20
34
  raise ArgumentError,
@@ -27,7 +41,12 @@ class Renderer
27
41
  end
28
42
 
29
43
  # call-seq:
30
- # layout_page
44
+ # layout_page => string
45
+ #
46
+ # Apply the desired filters to the page and then render the filtered page
47
+ # into the desired layout. The filters to apply to the page are determined
48
+ # from the page's meta-data. The layout to use is also determined from the
49
+ # page's meta-data.
31
50
  #
32
51
  def layout_page
33
52
  layouts = Resource.layouts
@@ -51,7 +70,10 @@ class Renderer
51
70
  end
52
71
 
53
72
  # call-seq:
54
- # render_page
73
+ # render_page => string
74
+ #
75
+ # Apply the desired filters to the page. The filters to apply are
76
+ # determined from the page's meta-data.
55
77
  #
56
78
  def render_page
57
79
  str = ::Webby::File.read(@page.path)
@@ -1,30 +1,65 @@
1
- # $Id: resource.rb 5 2007-08-22 04:25:49Z tim_pease $
1
+ # $Id: resource.rb 17 2007-08-28 04:11:00Z tim_pease $
2
2
 
3
3
  module Webby
4
4
 
5
+ # A Webby::Resource is any file that can be found in the content directory
6
+ # or in the layout directory. This class contains information about the
7
+ # resources available to Webby. This information includes the resource
8
+ # type (static, page, layout), if the resource is dirty (it needs to be
9
+ # rendered), the output location of the rendered resource, etc.
5
10
  #
11
+ # A resource is a "layout" if the resource is found in the layout
12
+ # directory. Static and page resources are found in the content directory.
13
+ #
14
+ # A resource is considered static only if it *does not* contain a YAML
15
+ # meta-data header at the top of the file. These resources will be copied
16
+ # as-is from the content directory to the output directory.
17
+ #
18
+ # If a resouce does have meta-data, then it will be processed (i.e.
19
+ # rendered/filtered) by Webby, and the rendered results will be written to
20
+ # the output directory.
6
21
  #
7
22
  class Resource
8
23
 
9
24
  class << self
25
+ # Returns the pages hash object.
10
26
  def pages
11
27
  @pages ||= PagesDB.new
12
28
  end
13
29
 
30
+ # Returns the layouts hash object.
14
31
  def layouts
15
32
  @layouts ||= PagesDB.new
16
33
  end
17
34
 
35
+ # Clear the contents of the +layouts+ and the +pages+ hash objects.
18
36
  def clear
19
37
  self.pages.clear
20
38
  self.layouts.clear
21
39
  end
22
40
  end # class << self
23
41
 
42
+ # The full path to the resource file
43
+ attr_reader :path
44
+
45
+ # The directory of the resource excluding the content directory
46
+ attr_reader :dir
47
+
48
+ # The resource filename excluding path and extension
49
+ attr_reader :filename
50
+
51
+ # Extesion of the resource file
52
+ attr_reader :ext
53
+
54
+ # Resource file modification time
55
+ attr_reader :mtime
56
+
24
57
  # call-seq:
25
- # Resource.new( filename, defaults = {} ) => page
58
+ # Resource.new( filename ) => resource
26
59
  #
27
- def initialize( fn, defaults = {} )
60
+ # Creates a new resource object given the _filename_.
61
+ #
62
+ def initialize( fn )
28
63
  @path = fn.sub(%r/\A(?:\.\/|\/)/o, '').freeze
29
64
  @dir = ::File.dirname(@path).sub(%r/\A[^\/]+\/?/o, '')
30
65
  @filename = ::File.basename(@path).sub(%r/\.\w+\z/o, '')
@@ -36,7 +71,9 @@ class Resource
36
71
  # deal with the meta-data
37
72
  @mdata = ::Webby::File.meta_data(@path)
38
73
  @have_mdata = !@mdata.nil?
39
- @mdata = @have_mdata ? defaults.merge(@mdata) : {}
74
+
75
+ @mdata ||= {}
76
+ @mdata = ::Webby.page_defaults.merge(@mdata) if is_page?
40
77
  @mdata.sanitize!
41
78
 
42
79
  self.class.pages << self if is_page? or is_static?
@@ -46,6 +83,9 @@ class Resource
46
83
  # call-seq:
47
84
  # equal?( other ) => true or false
48
85
  #
86
+ # Returns +true+ if the path of this resource is equivalent to the path of
87
+ # the _other_ resource. Returns +false+ if this is not the case.
88
+ #
49
89
  def equal?( other )
50
90
  return false unless self.class == other.class
51
91
  @path == other.path
@@ -56,17 +96,25 @@ class Resource
56
96
  # call-seq:
57
97
  # resource <=> other => -1, 0, +1, or nil
58
98
  #
99
+ # Resource comparison operates on the full path of the resource objects
100
+ # and uses the standard String comparison operator. Returns +nil+ if
101
+ # _other_ is not a Resource instance.
102
+ #
59
103
  def <=>( other )
60
104
  return unless self.class == other.class
61
105
  @path <=> other.path
62
106
  end
63
107
 
64
-
65
- attr_reader :path, :dir, :filename, :mtime, :ext
66
-
67
108
  # call-seq:
68
109
  # extension => string
69
110
  #
111
+ # Returns the extension that will be appended to the output destination
112
+ # filename. The extension is determined by looking at the following:
113
+ #
114
+ # * this resource's meta-data for an 'extension' property
115
+ # * the meta-data of this resource's layout for an 'extension' propery
116
+ # * the extension of this resource file
117
+ #
70
118
  def extension
71
119
  return @mdata['extension'] if @mdata.has_key? 'extension'
72
120
 
@@ -79,19 +127,39 @@ class Resource
79
127
  @ext
80
128
  end
81
129
 
130
+ # call-seq:
131
+ # destination => string
132
+ #
133
+ # Returns the path in the output directory where the results of rendering
134
+ # this resource should be stored. This path is used to determine if the
135
+ # resource is dirty and in need of rendering.
136
+ #
137
+ # The destination for any resource can be overridden by explicitly setting
138
+ # the 'destination' propery in the resource's meta-data.
139
+ #
82
140
  def destination
83
- return @destination if defined? @destination
84
- return @destination = ::Webby.config['output_dir'] if is_layout?
141
+ return @dest if defined? @dest
142
+ return @dest = ::Webby.config['output_dir'] if is_layout?
85
143
 
86
- @destination = File.join(::Webby.config['output_dir'], dir, filename)
87
- @destination << '.'
88
- @destination << extension
89
- @destination
144
+ @dest = if @mdata.has_key? 'destination' then @mdata['destination']
145
+ else File.join(dir, filename) end
146
+
147
+ @dest = File.join(::Webby.config['output_dir'], @dest)
148
+ @dest << '.'
149
+ @dest << extension
150
+ @dest
90
151
  end
91
152
 
92
153
  # call-seq:
93
154
  # render => string
94
155
  #
156
+ # Creates a new Webby::Renderer instance and uses that instance to render
157
+ # the resource contents using the configured filter(s). The filter(s) to
158
+ # use is defined in the resource's meta-data as the 'filter' key.
159
+ #
160
+ # Note, this only renders this resource. The returned string does not
161
+ # include any layout rendering.
162
+ #
95
163
  def render
96
164
  raise Error, "page '#@path' is in a rendering loop" if @rendering
97
165
 
@@ -164,6 +232,14 @@ class Resource
164
232
  @mdata['dirty'] = false
165
233
  end
166
234
 
235
+ # call-seq:
236
+ # method_missing( symbol [, *args, &block] ) => result
237
+ #
238
+ # Invoked by Ruby when a message is sent to the resource that it cannot
239
+ # handle. The default behavior is to convert _symbol_ to a string and
240
+ # search for that string in the resource's meta-data. If found, the
241
+ # meta-data item is returned; otherwise, +nil+ is returned.
242
+ #
167
243
  def method_missing( name, *a, &b )
168
244
  @mdata[name.to_s]
169
245
  end
@@ -1,4 +1,4 @@
1
- # $Id: webby_task.rb 7 2007-08-22 22:31:08Z tim_pease $
1
+ # $Id: webby_task.rb 15 2007-08-25 19:05:39Z tim_pease $
2
2
 
3
3
  begin
4
4
  require 'rake'
@@ -33,27 +33,22 @@ module Rake
33
33
  #
34
34
  class WebbyTask < TaskLib
35
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
36
+ # Define a setter and getter for each key in the Webby configuration hash
37
+ ::Webby.config.keys.each do |key|
38
+ self.class_eval do
39
+ define_method(key) {::Webby.config[key]}
40
+ define_method(key+'=') {|val| ::Webby.config[key] = val}
41
+ end
42
+ end
50
43
 
51
- # Global page attributes (default is {})
52
- attr_reader :page_defaults
44
+ # Global page attributes
45
+ def page_defaults
46
+ ::Webby.page_defaults
47
+ end
53
48
 
54
49
  # Merge the given _hash_ with the page defaults hash
55
50
  def page_defaults=( hash )
56
- @page_defaults.merge! hash
51
+ ::Webby.page_defaults.merge! hash
57
52
  end
58
53
 
59
54
  # call-seq:
@@ -63,34 +58,17 @@ class WebbyTask < TaskLib
63
58
  # pages in the website.
64
59
  #
65
60
  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
61
  yield self if block_given?
77
62
 
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
63
+ # load any user defined libraries
64
+ glob = File.join(FileUtils.pwd, 'lib', '**', '*.rb')
65
+ Dir.glob(glob).sort.each {|fn| require fn}
86
66
 
67
+ # create the Webby rake tasks
87
68
  define_build_tasks
88
69
  namespace(:create) {define_create_tasks}
89
70
  end
90
71
 
91
-
92
- private
93
-
94
72
  # Defines the :build and :rebuild tasks
95
73
  #
96
74
  def define_build_tasks
@@ -114,7 +92,7 @@ class WebbyTask < TaskLib
114
92
  # task for creating a new page based on that template.
115
93
  #
116
94
  def define_create_tasks
117
- FileList["#{@template_dir}/*"].each do |template|
95
+ FileList["#{template_dir}/*"].each do |template|
118
96
  name = template.pathmap '%n'
119
97
 
120
98
  desc "create a new #{name} page"
@@ -122,7 +100,7 @@ class WebbyTask < TaskLib
122
100
  raise "Usage: rake #{t.name} path" unless ARGV.length == 2
123
101
 
124
102
  page = t.application.top_level_tasks.pop
125
- page = File.join(@content_dir, page)
103
+ page = File.join(content_dir, page)
126
104
  page << '.txt' if File.extname(page).empty?
127
105
 
128
106
  ::Webby::Builder.create page, :from => template
@@ -1,7 +1,6 @@
1
- # $Id$
1
+ # $Id: doc.rake 11 2007-08-23 15:45:16Z tim_pease $
2
2
 
3
3
  require 'rake/rdoctask'
4
- require 'rake/contrib/sshpublisher'
5
4
 
6
5
  namespace :doc do
7
6
 
@@ -9,7 +8,7 @@ namespace :doc do
9
8
  Rake::RDocTask.new do |rd|
10
9
  rd.main = PROJ.rdoc_main
11
10
  rd.options << '-d' if !WIN32 and `which dot` =~ %r/\/dot/
12
- rd.rdoc_dir = 'doc'
11
+ rd.rdoc_dir = PROJ.rdoc_dir
13
12
 
14
13
  incl = Regexp.new(PROJ.rdoc_include.join('|'))
15
14
  excl = Regexp.new(PROJ.rdoc_exclude.join('|'))
@@ -37,22 +36,6 @@ namespace :doc do
37
36
  rm_r 'ri' rescue nil
38
37
  end
39
38
 
40
- if PROJ.rubyforge_name && HAVE_RUBYFORGE
41
- desc "Publish RDoc to RubyForge"
42
- task :release => %w(doc:clobber_rdoc doc:rdoc) do
43
- config = YAML.load(
44
- File.read(File.expand_path('~/.rubyforge/user-config.yml'))
45
- )
46
-
47
- host = "#{config['username']}@rubyforge.org"
48
- remote_dir = "/var/www/gforge-projects/#{rubyforge_name}/"
49
- remote_dir << PROJ.rdoc_remote_dir || PROJ.name
50
- local_dir = 'doc'
51
-
52
- Rake::SshDirPublisher.new(host, remote_dir, local_dir).upload
53
- end
54
- end
55
-
56
39
  end # namespace :doc
57
40
 
58
41
  task :clobber => %w(doc:clobber_rdoc doc:clobber_ri)
@@ -1,11 +1,10 @@
1
- # $Id$
1
+ # $Id: gem.rake 11 2007-08-23 15:45:16Z tim_pease $
2
2
 
3
3
  require 'rake/gempackagetask'
4
- require 'rubyforge' if PROJ.rubyforge_name && HAVE_RUBYFORGE
5
4
 
6
5
  namespace :gem do
7
6
 
8
- spec = Gem::Specification.new do |s|
7
+ PROJ.spec = Gem::Specification.new do |s|
9
8
  s.name = PROJ.name
10
9
  s.version = PROJ.version
11
10
  s.summary = PROJ.summary
@@ -19,9 +18,6 @@ namespace :gem do
19
18
  PROJ.dependencies.each do |dep|
20
19
  s.add_dependency(*dep)
21
20
  end
22
- if PROJ.rubyforge_name && HAVE_RUBYFORGE
23
- s.add_dependency('rubyforge', ">= #{::RubyForge::VERSION}")
24
- end
25
21
  s.add_dependency('rake', ">= #{RAKEVERSION}")
26
22
 
27
23
  s.files = PROJ.files
@@ -32,8 +28,15 @@ namespace :gem do
32
28
  dirs = Dir['{lib,ext}']
33
29
  s.require_paths = dirs unless dirs.empty?
34
30
 
35
- rdoc_files = PROJ.files.grep %r/txt$/
36
- rdoc_files.delete 'Manifest.txt'
31
+ incl = Regexp.new(PROJ.rdoc_include.join('|'))
32
+ excl = PROJ.rdoc_exclude.dup.concat %w[\.rb$ ^(\.\/|\/)?ext]
33
+ excl = Regexp.new(excl.join('|'))
34
+ rdoc_files = PROJ.files.find_all do |fn|
35
+ case fn
36
+ when excl: false
37
+ when incl: true
38
+ else false end
39
+ end
37
40
  s.rdoc_options = PROJ.rdoc_opts + ['--main', PROJ.rdoc_main]
38
41
  s.extra_rdoc_files = rdoc_files
39
42
  s.has_rdoc = true
@@ -57,17 +60,17 @@ namespace :gem do
57
60
 
58
61
  desc 'Show information about the gem'
59
62
  task :debug do
60
- puts spec.to_ruby
63
+ puts PROJ.spec.to_ruby
61
64
  end
62
65
 
63
- Rake::GemPackageTask.new(spec) do |pkg|
66
+ Rake::GemPackageTask.new(PROJ.spec) do |pkg|
64
67
  pkg.need_tar = PROJ.need_tar
65
68
  pkg.need_zip = PROJ.need_zip
66
69
  end
67
70
 
68
71
  desc 'Install the gem'
69
72
  task :install => [:clobber, :package] do
70
- sh "#{SUDO} #{GEM} install pkg/#{spec.file_name}"
73
+ sh "#{SUDO} #{GEM} install pkg/#{PROJ.spec.file_name}"
71
74
  end
72
75
 
73
76
  desc 'Uninstall the gem'
@@ -75,36 +78,6 @@ namespace :gem do
75
78
  sh "#{SUDO} #{GEM} uninstall -v '#{PROJ.version}' #{PROJ.name}"
76
79
  end
77
80
 
78
- if PROJ.rubyforge_name && HAVE_RUBYFORGE
79
- desc 'Package and upload to RubyForge'
80
- task :release => [:clobber, :package] do |t|
81
- v = ENV['VERSION'] or abort 'Must supply VERSION=x.y.z'
82
- abort "Versions don't match #{v} vs #{PROJ.version}" if v != PROJ.version
83
- pkg = "pkg/#{spec.full_name}"
84
-
85
- if $DEBUG then
86
- puts "release_id = rf.add_release #{PROJ.rubyforge_name.inspect}, #{PROJ.name.inspect}, #{PROJ.version.inspect}, \"#{pkg}.tgz\""
87
- puts "rf.add_file #{PROJ.rubyforge_name.inspect}, #{PROJ.name.inspect}, release_id, \"#{pkg}.gem\""
88
- end
89
-
90
- rf = RubyForge.new
91
- puts 'Logging in'
92
- rf.login
93
-
94
- c = rf.userconfig
95
- c['release_notes'] = PROJ.description if PROJ.description
96
- c['release_changes'] = PROJ.changes if PROJ.changes
97
- c['preformatted'] = true
98
-
99
- files = [(PROJ.need_tar ? "#{pkg}.tgz" : nil),
100
- (PROJ.need_zip ? "#{pkg}.zip" : nil),
101
- "#{pkg}.gem"].compact
102
-
103
- puts "Releasing #{PROJ.name} v. #{PROJ.version}"
104
- rf.add_release PROJ.rubyforge_name, PROJ.name, PROJ.version, *files
105
- end
106
- end
107
-
108
81
  end # namespace :gem
109
82
 
110
83
  task :clobber => 'gem:clobber_package'