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.
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,191 @@
1
+ # $Id: file.rb 2 2007-08-20 17:55:30Z tim_pease $
2
+
3
+ require 'yaml'
4
+
5
+ module Webby
6
+
7
+ # The Webby::File class is identical to the core Ruby file class except for
8
+ # YAML meta-data stored at the top of the file. This meta-data is made
9
+ # available through the <code>meta_data</code> and <code>meta_data=</code>
10
+ # functions.
11
+ #
12
+ # The meta-data data must be found between two YAML block separators "---",
13
+ # each on their own line.
14
+ #
15
+ # Example:
16
+ #
17
+ # ---
18
+ # layout: blog
19
+ # filter: markdown
20
+ # tags:
21
+ # - ruby
22
+ # - web development
23
+ # ---
24
+ # This is a blog entry formatted using MarkDown and tagged as "ruby" and
25
+ # "web development". The layout being used is the "blog" format.
26
+ #
27
+ class File < ::File
28
+
29
+ META_SEP = %r/\A---\s*\r?\n\z/o # :nodoc:
30
+
31
+ class << self
32
+ # call-seq:
33
+ # Webby::File.read( name [, length [, offset]]) => string
34
+ #
35
+ # Opens the file, optionally seeks to the given _offset_, then returns
36
+ # _length_ bytes (defaulting to the rest of the file). +read+ ensures
37
+ # the file is closed before returning.
38
+ #
39
+ def read( name, *args )
40
+ fd = new name, 'r'
41
+ fd.read *args
42
+ ensure
43
+ fd.close
44
+ end
45
+
46
+ # call-seq:
47
+ # Webby::File.readlines( name, sep_string = $/ ) => array
48
+ #
49
+ # Reads the entire file specified by _name_ as individual lines, and
50
+ # returns those lines in an array. Lines are separated by _sep_string_.
51
+ # +readlines+ ensures the file is closed before returning.
52
+ #
53
+ def readlines( name, sep = $/ )
54
+ fd = new name, 'r'
55
+ fd.readlines sep
56
+ ensure
57
+ fd.close
58
+ end
59
+
60
+ # call-seq:
61
+ # Webby::File.meta_data( name ) => object or nil
62
+ #
63
+ # Reads the meta-data from the file specified by _name_. +meta_data+
64
+ # ensures the files is closed before returning.
65
+ #
66
+ def meta_data( name )
67
+ fd = new name, 'r'
68
+ fd.meta_data
69
+ ensure
70
+ fd.close
71
+ end
72
+ end
73
+
74
+ # call-seq:
75
+ # Webby::File.new( filename, mode = "r" ) => file
76
+ # Webby::File.new( filename [, mode [, perm]] ) => file
77
+ #
78
+ # Opens the file named by _filename_ according to _mode_ (default is 'r')
79
+ # and returns a new +Webby::File+ object. See the description of class
80
+ # +IO+ for a description of _mode_. The file _mode_ may optionally be
81
+ # specified as a +Fixnum+ by or-ing together the flags (+O_RDONLY+ etc,
82
+ # again described under +IO+). Optional permission bits may be given in
83
+ # _perm_. These _mode_ and permission bits are platform dependent; on Unix
84
+ # systems, see +open(2)+ for details.
85
+ #
86
+ # f = File.new("testfile", "r")
87
+ # f = File.new("newfile", "w+")
88
+ # f = File.new("newfile", File::CREAT|File::TRUNC|File::RDWR, 0644)
89
+ #
90
+ def initialize( *args )
91
+ super
92
+ @meta_end = end_of_meta_data
93
+ end
94
+
95
+ # call-seq:
96
+ # meta_data
97
+ #
98
+ # Returns the meta-data defined at the top of the file. Returns +nil+ if
99
+ # no meta-data is defined. The meta-data is returned as Ruby objects
100
+ #
101
+ # Meta-data is stored in YAML format between two YAML separators "---" on
102
+ # their own lines.
103
+ #
104
+ def meta_data
105
+ return if @meta_end.nil?
106
+
107
+ cur, meta_end, @meta_end = tell, @meta_end, nil
108
+ seek 0
109
+ return YAML.load(self)
110
+
111
+ ensure
112
+ @meta_end = meta_end if defined? meta_end and meta_end
113
+ seek cur if defined? cur and cur
114
+ end
115
+
116
+ # call-seq
117
+ # meta_data = object
118
+ #
119
+ # Stores the given _object_ as meta-data in YAML format at the top of the
120
+ # file. If the _objectc_ is +nil+, then the meta-data section will be
121
+ # removed from the file.
122
+ #
123
+ # Meta-data is stored in YAML format between two YAML separators "---" on
124
+ # their own lines.
125
+ #
126
+ def meta_data=( data )
127
+ return if data.nil? and @meta_end.nil?
128
+
129
+ seek 0
130
+ lines = readlines
131
+
132
+ truncate 0
133
+ unless data.nil?
134
+ write YAML.dump(data)
135
+ write "--- #$/"
136
+ end
137
+ lines.each {|line| write line}
138
+ ensure
139
+ @meta_end = end_of_meta_data
140
+ seek 0, IO::SEEK_END
141
+ end
142
+
143
+ %w(getc gets read read_nonblock readbytes readchar readline readlines readpartial scanf sysread).each do |m|
144
+ self.class_eval <<-CODE
145
+ def #{m}(*a)
146
+ skip_meta_data
147
+ super
148
+ end
149
+ CODE
150
+ end
151
+
152
+
153
+ private
154
+
155
+ # Moves the file pointer to the end of the meta-data section. Does nothing
156
+ # if there is no meta-data section or if the file pointer is already past
157
+ # the meta-data section.
158
+ #
159
+ def skip_meta_data
160
+ return if @meta_end.nil?
161
+ return if tell >= @meta_end
162
+ seek @meta_end
163
+ end
164
+
165
+ # Returns the position in this file where the meta-data ends and the file
166
+ # data begins. If there is no meta-data in the file, returns +nil+.
167
+ #
168
+ def end_of_meta_data
169
+ cur = tell
170
+
171
+ seek 0
172
+ line = readline
173
+ return unless META_SEP =~ line
174
+
175
+ loop do
176
+ line = readline
177
+ break if META_SEP =~ line
178
+ end
179
+ return tell
180
+
181
+ rescue EOFError
182
+ return
183
+
184
+ ensure
185
+ seek cur
186
+ end
187
+
188
+ end # class File
189
+ end # module Webby
190
+
191
+ # EOF
@@ -0,0 +1,129 @@
1
+ # $Id: main.rb 2 2007-08-20 17:55:30Z tim_pease $
2
+
3
+ require 'fileutils'
4
+ require 'find'
5
+
6
+ module Webby
7
+
8
+ # The Webby::Main class contains all the functionality needed by the +webby+
9
+ # command line application.
10
+ #
11
+ class Main
12
+
13
+ # Directory where the Webby website will be created
14
+ attr_accessor :site
15
+
16
+ # Directory where the prototype Webby website can be found
17
+ attr_accessor :data
18
+
19
+ # call-seq:
20
+ # Main.run( *args ) => nil
21
+ #
22
+ # Create a new instance of Main, and run the +webby+ application given the
23
+ # command line _args_.
24
+ #
25
+ def self.run( *args )
26
+ self.new.run *args
27
+ end
28
+
29
+ # call-seq:
30
+ # run( *args ) => nil
31
+ #
32
+ # Run the +webby+ application given the command line _args_.
33
+ #
34
+ def run( *args )
35
+ abort "Usage: #{$0} /path/to/your/site" unless args.length == 1
36
+
37
+ self.site = args.at 0
38
+ self.data = File.join(::Webby::PATH, 'data')
39
+
40
+ # see if the site already exists
41
+ abort "#{site} already exists" if test ?e, site
42
+
43
+ # copy over files from the data directory
44
+ files = site_files
45
+
46
+ files.keys.sort.each do |dir|
47
+ mkdir dir
48
+ files[dir].each {|file| cp file}
49
+ end
50
+ nil
51
+ end
52
+
53
+ # call-seq:
54
+ # mkdir( dir ) => nil
55
+ #
56
+ # Make a directory in the user specified site location. A message will be
57
+ # displayed to the screen indicating tha the directory is being created.
58
+ #
59
+ def mkdir( dir )
60
+ dir = dir.empty? ? site : ::File.join(site, dir)
61
+ creating dir
62
+ FileUtils.mkdir_p dir
63
+ end
64
+
65
+ # call-seq:
66
+ # cp( file ) => nil
67
+ #
68
+ # Copy a file from the Webby prototype website location to the user
69
+ # specified site location. A message will be displayed to the screen
70
+ # indicating tha the file is being created.
71
+ #
72
+ def cp( file )
73
+ src = ::File.join(data, file)
74
+ dst = ::File.join(site, file)
75
+ creating dst
76
+ FileUtils.cp src, dst
77
+ end
78
+
79
+ # call-seq:
80
+ # creating( msg ) => nil
81
+ #
82
+ # Prints a "creating _msg_" to the screen.
83
+ #
84
+ def creating( msg )
85
+ print "creating "
86
+ puts msg
87
+ end
88
+
89
+ # call-seq:
90
+ # abort( msg ) => nil
91
+ #
92
+ # Prints an abort _msg_ to the screen and then exits the Ruby interpreter.
93
+ #
94
+ def abort( msg )
95
+ puts msg
96
+ puts "Aborting!"
97
+ exit 1
98
+ end
99
+
100
+ # call-seq:
101
+ # site_files => hash
102
+ #
103
+ # Iterates over all the files in the Webby prototype website directory and
104
+ # stores them in a hash.
105
+ #
106
+ def site_files
107
+ exclude = %r/tmp$|bak$|~$|CVS|\.svn/o
108
+
109
+ rgxp = %r/\A#{data}\/?/o
110
+ paths = Hash.new {|h,k| h[k] = []}
111
+
112
+ Find.find(data) do |p|
113
+ next if exclude =~ p
114
+
115
+ if test(?d, p)
116
+ paths[p.sub(rgxp, '')]
117
+ next
118
+ end
119
+ dir = ::File.dirname(p).sub(rgxp, '')
120
+ paths[dir] << p.sub(rgxp, '')
121
+ end
122
+
123
+ paths
124
+ end
125
+
126
+ end # class Main
127
+ end # module Webby
128
+
129
+ # EOF
@@ -0,0 +1,70 @@
1
+ # $Id: pages_db.rb 6 2007-08-22 22:25:53Z tim_pease $
2
+
3
+ module Webby
4
+
5
+ #
6
+ #
7
+ class PagesDB
8
+ include Enumerable
9
+
10
+ def initialize
11
+ @db = Hash.new {|h,k| h[k] = []}
12
+ end
13
+
14
+ def add( page )
15
+ @db[page.dir] << page
16
+ self
17
+ end
18
+ alias :<< :add
19
+
20
+ def clear
21
+ @db.clear
22
+ end
23
+
24
+ def each( &b )
25
+ keys = @db.keys.sort
26
+ keys.each do |k|
27
+ @db[k].sort.each(&b)
28
+ end
29
+ end
30
+
31
+ def find_by_name( name )
32
+ self.find {|page| page.filename == name}
33
+ end
34
+
35
+ # call-seq:
36
+ # siblings( page, opts = {} ) => array
37
+ #
38
+ # Options include:
39
+ # :sorty_by => 'attribute'
40
+ #
41
+ def siblings( page, opts = {} )
42
+ ary = @db[page.dir].dup
43
+ ary.delete page
44
+ return ary unless opts.has_key? :sort_by
45
+
46
+ m = opts[:sort_by]
47
+ ary.sort! {|a,b| a.send(m) <=> b.send(m)}
48
+ ary.reverse! if opts[:reverse]
49
+ ary
50
+ end
51
+
52
+ def children( page, opts = {} )
53
+ rgxp = Regexp.new "\\A#{page.dir}/[^/]+"
54
+
55
+ keys = @db.keys.find_all {|k| rgxp =~ k}
56
+ ary = keys.map {|k| @db[k]}
57
+ ary.flatten!
58
+
59
+ return ary unless opts.has_key? :sort_by
60
+
61
+ m = opts[:sort_by]
62
+ ary.sort! {|a,b| a.send(m) <=> b.send(m)}
63
+ ary.reverse! if opts[:reverse]
64
+ ary
65
+ end
66
+
67
+ end # class PagesDB
68
+ end # module Webby
69
+
70
+ # EOF
@@ -0,0 +1,94 @@
1
+ # $Id: renderer.rb 2 2007-08-20 17:55:30Z tim_pease $
2
+
3
+ require 'erb'
4
+
5
+ try_require 'bluecloth'
6
+ try_require 'redcloth'
7
+
8
+ module Webby
9
+
10
+ #
11
+ #
12
+ class Renderer
13
+ include ERB::Util
14
+
15
+ # call-seq:
16
+ # Renderer.new( page )
17
+ #
18
+ def initialize( page )
19
+ unless page.is_page?
20
+ raise ArgumentError,
21
+ "only page resources can be rendered '#{page.path}'"
22
+ end
23
+
24
+ @page = page
25
+ @pages = Resource.pages
26
+ @content = nil
27
+ end
28
+
29
+ # call-seq:
30
+ # layout_page
31
+ #
32
+ def layout_page
33
+ layouts = Resource.layouts
34
+ obj = @page
35
+ str = @page.render
36
+
37
+ loop do
38
+ lyt = layouts.find_by_name obj.layout
39
+ break if lyt.nil?
40
+
41
+ @content, str = str, ::Webby::File.read(lyt.path)
42
+
43
+ lyt.filter.to_a.each do |filter|
44
+ str = self.send(filter + '_filter', str)
45
+ end
46
+
47
+ @content, obj = nil, lyt
48
+ end
49
+
50
+ str
51
+ end
52
+
53
+ # call-seq:
54
+ # render_page
55
+ #
56
+ def render_page
57
+ str = ::Webby::File.read(@page.path)
58
+
59
+ @page.filter.to_a.each do |filter|
60
+ str = self.send(filter + '_filter', str)
61
+ end
62
+
63
+ str
64
+ end
65
+
66
+ # Render text via ERB using the built in ERB library.
67
+ #
68
+ def erb_filter( str )
69
+ b = binding
70
+ ERB.new(str, nil, '-').result(b)
71
+ end
72
+
73
+ # Render text via markdown using the BlueCloth library.
74
+ #
75
+ def markdown_filter( str )
76
+ BlueCloth.new(str).to_html
77
+ rescue NameError
78
+ $stderr.puts 'ERROR: markdown filter failed (BlueCloth not installed?)'
79
+ exit
80
+ end
81
+
82
+ # Render text via textile using the RedCloth library.
83
+ #
84
+ def textile_filter( str )
85
+ RedCloth.new(str).to_html
86
+ rescue NameError
87
+ $stderr.puts 'ERROR: textile filter failed (RedCloth not installed?)'
88
+ exit
89
+ end
90
+
91
+ end # class Renderer
92
+ end # module Webby
93
+
94
+ # EOF