TwP-webby 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (174) hide show
  1. data/History.txt +176 -0
  2. data/Manifest.txt +173 -0
  3. data/README.txt +92 -0
  4. data/Rakefile +50 -0
  5. data/bin/webby +8 -0
  6. data/bin/webby-gen +8 -0
  7. data/examples/blog/Sitefile +7 -0
  8. data/examples/blog/tasks/blog.rake +72 -0
  9. data/examples/blog/templates/atom_feed.erb +40 -0
  10. data/examples/blog/templates/blog/month.erb +22 -0
  11. data/examples/blog/templates/blog/post.erb +16 -0
  12. data/examples/blog/templates/blog/year.erb +22 -0
  13. data/examples/presentation/Sitefile +10 -0
  14. data/examples/presentation/content/css/uv/twilight.css +137 -0
  15. data/examples/presentation/content/presentation/_sample_code.txt +10 -0
  16. data/examples/presentation/content/presentation/index.txt +63 -0
  17. data/examples/presentation/content/presentation/s5/blank.gif +0 -0
  18. data/examples/presentation/content/presentation/s5/bodybg.gif +0 -0
  19. data/examples/presentation/content/presentation/s5/framing.css +23 -0
  20. data/examples/presentation/content/presentation/s5/iepngfix.htc +42 -0
  21. data/examples/presentation/content/presentation/s5/opera.css +7 -0
  22. data/examples/presentation/content/presentation/s5/outline.css +15 -0
  23. data/examples/presentation/content/presentation/s5/pretty.css +86 -0
  24. data/examples/presentation/content/presentation/s5/print.css +1 -0
  25. data/examples/presentation/content/presentation/s5/s5-core.css +9 -0
  26. data/examples/presentation/content/presentation/s5/slides.css +3 -0
  27. data/examples/presentation/content/presentation/s5/slides.js +553 -0
  28. data/examples/presentation/layouts/presentation.txt +43 -0
  29. data/examples/presentation/templates/_code_partial.erb +13 -0
  30. data/examples/presentation/templates/presentation.erb +40 -0
  31. data/examples/tumblog/Sitefile +9 -0
  32. data/examples/tumblog/content/css/tumblog.css +308 -0
  33. data/examples/tumblog/content/images/tumblog/permalink.gif +0 -0
  34. data/examples/tumblog/content/images/tumblog/rss.gif +0 -0
  35. data/examples/tumblog/content/tumblog/200806/the-noble-chicken/index.txt +12 -0
  36. data/examples/tumblog/content/tumblog/200807/historical-perspectives-on-the-classic-chicken-joke/index.txt +12 -0
  37. data/examples/tumblog/content/tumblog/200807/mad-city-chickens/index.txt +10 -0
  38. data/examples/tumblog/content/tumblog/200807/the-wisdom-of-the-dutch/index.txt +11 -0
  39. data/examples/tumblog/content/tumblog/200807/up-a-tree/index.txt +13 -0
  40. data/examples/tumblog/content/tumblog/index.txt +37 -0
  41. data/examples/tumblog/content/tumblog/rss.txt +37 -0
  42. data/examples/tumblog/layouts/tumblog/default.txt +44 -0
  43. data/examples/tumblog/layouts/tumblog/post.txt +15 -0
  44. data/examples/tumblog/lib/tumblog_helper.rb +32 -0
  45. data/examples/tumblog/tasks/tumblog.rake +30 -0
  46. data/examples/tumblog/templates/atom_feed.erb +40 -0
  47. data/examples/tumblog/templates/tumblog/conversation.erb +12 -0
  48. data/examples/tumblog/templates/tumblog/link.erb +10 -0
  49. data/examples/tumblog/templates/tumblog/photo.erb +13 -0
  50. data/examples/tumblog/templates/tumblog/post.erb +12 -0
  51. data/examples/tumblog/templates/tumblog/quote.erb +11 -0
  52. data/examples/webby/Sitefile +19 -0
  53. data/examples/webby/content/communicate/index.txt +28 -0
  54. data/examples/webby/content/css/background.gif +0 -0
  55. data/examples/webby/content/css/blueprint/print.css +76 -0
  56. data/examples/webby/content/css/blueprint/screen.css +696 -0
  57. data/examples/webby/content/css/coderay.css +96 -0
  58. data/examples/webby/content/css/site.css +196 -0
  59. data/examples/webby/content/css/uv/twilight.css +137 -0
  60. data/examples/webby/content/index.txt +37 -0
  61. data/examples/webby/content/learn/index.txt +28 -0
  62. data/examples/webby/content/reference/index.txt +204 -0
  63. data/examples/webby/content/release-notes/rel-0-9-0/index.txt +73 -0
  64. data/examples/webby/content/robots.txt +6 -0
  65. data/examples/webby/content/script/jquery.corner.js +152 -0
  66. data/examples/webby/content/script/jquery.js +31 -0
  67. data/examples/webby/content/sitemap.txt +31 -0
  68. data/examples/webby/content/tips_and_tricks/index.txt +96 -0
  69. data/examples/webby/content/tutorial/index.txt +131 -0
  70. data/examples/webby/content/user-manual/index.txt +419 -0
  71. data/examples/webby/layouts/default.txt +49 -0
  72. data/examples/webby/templates/page.erb +10 -0
  73. data/examples/website/Sitefile +7 -0
  74. data/examples/website/content/css/blueprint/License.txt +21 -0
  75. data/examples/website/content/css/blueprint/Readme.txt +100 -0
  76. data/examples/website/content/css/blueprint/compressed/print.css +76 -0
  77. data/examples/website/content/css/blueprint/compressed/screen.css +696 -0
  78. data/examples/website/content/css/blueprint/lib/forms.css +45 -0
  79. data/examples/website/content/css/blueprint/lib/grid.css +193 -0
  80. data/examples/website/content/css/blueprint/lib/grid.png +0 -0
  81. data/examples/website/content/css/blueprint/lib/ie.css +30 -0
  82. data/examples/website/content/css/blueprint/lib/reset.css +39 -0
  83. data/examples/website/content/css/blueprint/lib/typography.css +116 -0
  84. data/examples/website/content/css/blueprint/plugins/buttons/Readme +31 -0
  85. data/examples/website/content/css/blueprint/plugins/buttons/buttons.css +97 -0
  86. data/examples/website/content/css/blueprint/plugins/buttons/icons/cross.png +0 -0
  87. data/examples/website/content/css/blueprint/plugins/buttons/icons/key.png +0 -0
  88. data/examples/website/content/css/blueprint/plugins/buttons/icons/tick.png +0 -0
  89. data/examples/website/content/css/blueprint/plugins/css-classes/Readme +14 -0
  90. data/examples/website/content/css/blueprint/plugins/css-classes/css-classes.css +24 -0
  91. data/examples/website/content/css/blueprint/plugins/fancy-type/Readme +22 -0
  92. data/examples/website/content/css/blueprint/plugins/fancy-type/fancy-type-compressed.css +5 -0
  93. data/examples/website/content/css/blueprint/plugins/fancy-type/fancy-type.css +74 -0
  94. data/examples/website/content/css/blueprint/print.css +68 -0
  95. data/examples/website/content/css/blueprint/screen.css +22 -0
  96. data/examples/website/content/css/coderay.css +111 -0
  97. data/examples/website/content/css/site.css +67 -0
  98. data/examples/website/content/index.txt +19 -0
  99. data/examples/website/layouts/default.txt +58 -0
  100. data/examples/website/lib/breadcrumbs.rb +28 -0
  101. data/examples/website/templates/_partial.erb +10 -0
  102. data/examples/website/templates/page.erb +18 -0
  103. data/examples/website/templates/presentation.erb +40 -0
  104. data/lib/webby/apps/generator.rb +283 -0
  105. data/lib/webby/apps/main.rb +221 -0
  106. data/lib/webby/apps.rb +12 -0
  107. data/lib/webby/auto_builder.rb +83 -0
  108. data/lib/webby/builder.rb +183 -0
  109. data/lib/webby/core_ext/enumerable.rb +11 -0
  110. data/lib/webby/core_ext/hash.rb +28 -0
  111. data/lib/webby/core_ext/kernel.rb +21 -0
  112. data/lib/webby/core_ext/string.rb +163 -0
  113. data/lib/webby/core_ext/time.rb +9 -0
  114. data/lib/webby/filters/basepath.rb +97 -0
  115. data/lib/webby/filters/erb.rb +9 -0
  116. data/lib/webby/filters/haml.rb +18 -0
  117. data/lib/webby/filters/markdown.rb +16 -0
  118. data/lib/webby/filters/outline.rb +309 -0
  119. data/lib/webby/filters/sass.rb +17 -0
  120. data/lib/webby/filters/slides.rb +56 -0
  121. data/lib/webby/filters/textile.rb +16 -0
  122. data/lib/webby/filters/tidy.rb +76 -0
  123. data/lib/webby/filters.rb +91 -0
  124. data/lib/webby/helpers/capture_helper.rb +141 -0
  125. data/lib/webby/helpers/coderay_helper.rb +69 -0
  126. data/lib/webby/helpers/graphviz_helper.rb +136 -0
  127. data/lib/webby/helpers/tag_helper.rb +65 -0
  128. data/lib/webby/helpers/tex_img_helper.rb +133 -0
  129. data/lib/webby/helpers/ultraviolet_helper.rb +63 -0
  130. data/lib/webby/helpers/url_helper.rb +235 -0
  131. data/lib/webby/helpers.rb +30 -0
  132. data/lib/webby/link_validator.rb +152 -0
  133. data/lib/webby/renderer.rb +379 -0
  134. data/lib/webby/resources/db.rb +251 -0
  135. data/lib/webby/resources/file.rb +221 -0
  136. data/lib/webby/resources/layout.rb +63 -0
  137. data/lib/webby/resources/page.rb +118 -0
  138. data/lib/webby/resources/partial.rb +79 -0
  139. data/lib/webby/resources/resource.rb +160 -0
  140. data/lib/webby/resources/static.rb +52 -0
  141. data/lib/webby/resources.rb +96 -0
  142. data/lib/webby/stelan/mktemp.rb +135 -0
  143. data/lib/webby/stelan/paginator.rb +150 -0
  144. data/lib/webby/stelan/spawner.rb +339 -0
  145. data/lib/webby/tasks/build.rake +27 -0
  146. data/lib/webby/tasks/create.rake +22 -0
  147. data/lib/webby/tasks/deploy.rake +22 -0
  148. data/lib/webby/tasks/growl.rake +15 -0
  149. data/lib/webby/tasks/heel.rake +28 -0
  150. data/lib/webby/tasks/validate.rake +19 -0
  151. data/lib/webby.rb +227 -0
  152. data/spec/core_ext/hash_spec.rb +47 -0
  153. data/spec/core_ext/string_spec.rb +110 -0
  154. data/spec/core_ext/time_spec.rb +19 -0
  155. data/spec/spec.opts +1 -0
  156. data/spec/spec_helper.rb +14 -0
  157. data/spec/webby/apps/generator_spec.rb +111 -0
  158. data/spec/webby/apps/main_spec.rb +75 -0
  159. data/spec/webby/helpers/capture_helper_spec.rb +56 -0
  160. data/spec/webby/resources/file_spec.rb +104 -0
  161. data/spec/webby/resources_spec.rb +17 -0
  162. data/tasks/ann.rake +81 -0
  163. data/tasks/bones.rake +21 -0
  164. data/tasks/gem.rake +126 -0
  165. data/tasks/git.rake +41 -0
  166. data/tasks/manifest.rake +49 -0
  167. data/tasks/notes.rake +28 -0
  168. data/tasks/post_load.rake +39 -0
  169. data/tasks/rdoc.rake +51 -0
  170. data/tasks/rubyforge.rake +57 -0
  171. data/tasks/setup.rb +268 -0
  172. data/tasks/spec.rake +55 -0
  173. data/tasks/website.rake +38 -0
  174. metadata +289 -0
@@ -0,0 +1,283 @@
1
+ require 'fileutils'
2
+ require 'optparse'
3
+
4
+ module Webby::Apps
5
+
6
+ # webby gen template site => creates the tmplate
7
+ # webby gen -h / --help
8
+ # webby gen => same as --help
9
+ #
10
+
11
+ class Generator
12
+
13
+ # Create a new Generator instance and run the +webby+ application given the
14
+ # command line _args_.
15
+ #
16
+ def self.run( args )
17
+ self.new.run args
18
+ end
19
+
20
+ attr_accessor :template, :site
21
+ attr_reader :options
22
+
23
+ # Initialize a new generator object.
24
+ #
25
+ def initialize
26
+ @options = {}
27
+ @site = @template = nil
28
+ @stdout, @stdin = $stdout, $stdin
29
+ end
30
+
31
+ # Run the generator executing the commands specified by the user on the
32
+ # command line.
33
+ #
34
+ def run( args )
35
+ parse args
36
+ create_site
37
+ end
38
+
39
+ # Parse out the command line options found in the args array.
40
+ #
41
+ def parse( args )
42
+ opts = OptionParser.new
43
+ opts.banner = 'Usage: webby-gen [options] template site'
44
+
45
+ opts.separator ''
46
+ opts.separator 'The webby-gen command is used to generate a site from a standard template.'
47
+ opts.separator 'A new site can be created, or an existing site can be added to or updated.'
48
+
49
+ opts.separator ''
50
+ opts.on('-f', '--force',
51
+ 'overwrite files that already exist') {options[:collision] = :force}
52
+ opts.on('-s', '--skip',
53
+ 'skip files that already exist') {options[:collision] = :skip}
54
+ opts.on('-u', '--update',
55
+ 'update rake tasks for the site') {options[:update] = true}
56
+ opts.on('-p', '--pretend',
57
+ 'run but do not make any changes') {options[:pretend] = true}
58
+
59
+ opts.separator ''
60
+ opts.on('-t', '--templates', 'list available templates') {
61
+ ary = templates.map {|t| ::File.basename(t)}
62
+ ary.delete 'webby'
63
+ @stdout.puts "\nAvailable Templates"
64
+ @stdout.puts " #{ary.join(', ')}"
65
+ @stdout.puts
66
+ exit
67
+ }
68
+
69
+ opts.separator ''
70
+ opts.separator 'common options:'
71
+
72
+ opts.on( '-h', '--help', 'show this message' ) {@stdout.puts opts; exit}
73
+ opts.on( '--version', 'show version' ) do
74
+ @stdout.puts "Webby #{::Webby::VERSION}"
75
+ exit
76
+ end
77
+
78
+ # parse the command line arguments
79
+ opts.parse! args
80
+ tmpl, @site = args
81
+
82
+ # if no site was given, see if there is a Sitefile in the current
83
+ # directory
84
+ if site.nil?
85
+ self.site = '.' if test(?f, 'Sitefile')
86
+ end
87
+
88
+ # exit if comand line args are missing
89
+ if site.nil? or tmpl.nil?
90
+ @stdout.puts opts
91
+ exit 1
92
+ end
93
+
94
+ templates.each {|t| self.template = t if t =~ %r/\/#{tmpl}$/}
95
+ if template.nil?
96
+ @stdout.puts opts
97
+ abort "Could not find template '#{tmpl}'"
98
+ end
99
+
100
+ nil
101
+ end
102
+
103
+ # Returns +true+ if we are only going to pretend to do something. All the
104
+ # output messages will be written, but no changes will be made on the
105
+ # disc.
106
+ #
107
+ def pretend?
108
+ options[:pretend] == true
109
+ end
110
+
111
+ # Returns an array of available site templates.
112
+ #
113
+ def templates
114
+ Dir.glob(::Webby.path('examples') / '*').sort
115
+ end
116
+
117
+ # Create the site from the template specified by the user.
118
+ #
119
+ def create_site
120
+ files = site_files
121
+
122
+ # in update mode we only want to update the tasks directory
123
+ if options[:update]
124
+ FileUtils.mkdir_p site unless pretend?
125
+ mkdir 'tasks'
126
+ files['tasks'].sort.each {|file| cp file}
127
+ else
128
+ dirs = files.keys.concat %w[content layouts lib tasks templates]
129
+ dirs.sort!
130
+ dirs.uniq!
131
+
132
+ # create the directories first
133
+ dirs.each do |dir|
134
+ next if dir =~ %r/^output\/.*$/
135
+ mkdir dir
136
+ end
137
+
138
+ # and the create the files under each directory
139
+ dirs.each do |dir|
140
+ next if dir =~ %r/^output(\/.*)?$/
141
+ files[dir].sort.each {|file| cp file}
142
+ end
143
+ end
144
+ end
145
+
146
+ # Make a directory in the user specified site location. A message will be
147
+ # displayed to the screen indicating tha the directory is being created.
148
+ #
149
+ def mkdir( dir )
150
+ dir = dir.empty? ? site : site / dir
151
+ if test ?d, dir
152
+ exists dir
153
+ else
154
+ create dir
155
+ FileUtils.mkdir_p dir unless pretend?
156
+ end
157
+ end
158
+
159
+ # Copy a file from the template location to the user specified site
160
+ # location. A message will be displayed to the screen indicating tha the
161
+ # file is being created.
162
+ #
163
+ def cp( file )
164
+ src = template / file
165
+ dst = site / file
166
+
167
+ if test(?e, dst)
168
+ if identical?(src, dst)
169
+ identical(dst)
170
+ return
171
+ end
172
+
173
+ choice = case options[:collision]
174
+ when :force then :force
175
+ when :skip then :skip
176
+ else force_file_collision?( dst ) end
177
+
178
+ case choice
179
+ when :force then force(dst)
180
+ when :skip then skip(dst); return
181
+ else raise "Invalid collision choice: #{choice.inspect}" end
182
+ else
183
+ create(dst)
184
+ end
185
+ return if pretend?
186
+
187
+ if WINDOWS then win_line_endings(src, dst)
188
+ else FileUtils.cp(src, dst) end
189
+ end
190
+
191
+ # Copy the file from the _src_ location to the _dst_ location and
192
+ # transform the line endings to the windows "\r\n" format.
193
+ #
194
+ def win_line_endings( src, dst )
195
+ case ::File.extname(src)
196
+ when *%w[.png .gif .jpg .jpeg]
197
+ FileUtils.cp src, dst
198
+ else
199
+ ::File.open(dst,'w') do |fd|
200
+ ::File.foreach(src, "\n") do |line|
201
+ line.tr!("\r\n",'')
202
+ fd.puts line
203
+ end
204
+ end
205
+ end
206
+ end
207
+
208
+ %w[exists create force skip identical].each do |m|
209
+ class_eval "def #{m}( msg ) message('#{m}', msg); end"
210
+ end
211
+
212
+ # Print the given message and message type to stdout.
213
+ #
214
+ def message( type, msg )
215
+ msg = msg.sub(%r/#{site}\/?/, '')
216
+ return if msg.empty?
217
+ @stdout.puts "%13s %s" % [type, msg]
218
+ end
219
+
220
+ # Prints an abort message to the screen and then exits the Ruby
221
+ # interpreter. A non-zero return code is used to indicate an error.
222
+ #
223
+ def abort( msg )
224
+ @stdout.puts "\nAborting!"
225
+ @stdout.puts " #{msg}"
226
+ @stdout.puts
227
+ exit 1
228
+ end
229
+
230
+ # Iterates over all the files in the template directory and stores them in
231
+ # a hash.
232
+ #
233
+ def site_files
234
+ exclude = %r/tmp$|bak$|~$|CVS|\.svn/o
235
+
236
+ rgxp = %r/\A#{template}\/?/o
237
+ paths = Hash.new {|h,k| h[k] = []}
238
+
239
+ Find.find(template) do |p|
240
+ next if exclude =~ p
241
+
242
+ if test(?d, p)
243
+ paths[p.sub(rgxp, '')]
244
+ next
245
+ end
246
+ dir = ::File.dirname(p).sub(rgxp, '')
247
+ paths[dir] << p.sub(rgxp, '')
248
+ end
249
+
250
+ paths
251
+ end
252
+
253
+ # Returns +true+ if the source file is identical to the destination file.
254
+ # Returns +false+ if this is not the case.
255
+ #
256
+ def identical?( src, dst )
257
+ # FIXME: this most likely won't work on windows machines
258
+ # because the line endings are modified when the site is gnerated
259
+ source = IO.read(src)
260
+ destination = IO.read(dst)
261
+ source == destination
262
+ end
263
+
264
+ # Ask the user what to do about the file collision.
265
+ #
266
+ def force_file_collision?( dst )
267
+ dst = dst.sub(%r/#{site}\/?/, '')
268
+ @stdout.print "overwrite #{dst}? [(Y)es (n)o (q)uit] "
269
+ @stdout.flush
270
+ case @stdin.gets
271
+ when %r/q/i then abort 'user asked to quit'
272
+ when %r/n/i then :skip
273
+ when %r/y/i then :force
274
+ when %r/\s*/ then :force
275
+ else force_file_collision?(dst) end
276
+ rescue
277
+ retry
278
+ end
279
+
280
+ end # class Generator
281
+ end # module Webby::Apps
282
+
283
+ # EOF
@@ -0,0 +1,221 @@
1
+ require 'optparse'
2
+ require 'rake'
3
+
4
+ module Webby::Apps
5
+
6
+ class Main
7
+
8
+ # Create a new instance of Main, and run the +webby+ application given the
9
+ # command line _args_.
10
+ #
11
+ def self.run( args )
12
+ self.new.run args
13
+ end
14
+
15
+ # Create a new Main webby object for building websites.
16
+ #
17
+ def initialize
18
+ @stdout = $stdout
19
+ end
20
+
21
+ # Runs the main webby application. The command line arguments are passed
22
+ # in to this method as an array of strings. The command line arguments are
23
+ # parsed to figure out which rake task to invoke.
24
+ #
25
+ def run( args )
26
+ args = args.dup
27
+
28
+ parse args
29
+ init args
30
+ rake
31
+ end
32
+
33
+ # Parse the command line _args_ for options and commands to invoke.
34
+ #
35
+ def parse( args )
36
+ opts = OptionParser.new
37
+ opts.banner = 'Usage: webby [options] target [target args]'
38
+
39
+ opts.separator ''
40
+ opts.on('-D', '--describe [PATTERN]', 'describe the tasks (matching optional PATTERN), then exit') {|pattern| app.do_option('--describe', pattern)}
41
+ opts.on('-P', '--prereqs', 'display the tasks and dependencies, then exit') {app.do_option('--prereqs', nil)}
42
+ opts.on('-T', '--tasks [PATTERN]', 'display the tasks (matching optional PATTERN) with descriptions, then exit') {|pattern| app.do_option('--tasks', pattern)}
43
+ opts.on('-t', '--trace', 'turn on invoke/execute tracing, enable full backtrace') {app.do_option('--trace', nil)}
44
+
45
+ opts.separator ''
46
+ opts.separator 'common options:'
47
+
48
+ opts.on_tail( '-h', '--help', 'show this message' ) do
49
+ @stdout.puts opts
50
+ exit
51
+ end
52
+ opts.on_tail( '--version', 'show version' ) do
53
+ @stdout.puts "Webby #{::Webby::VERSION}"
54
+ exit
55
+ end
56
+
57
+ opts.parse! args
58
+
59
+ ARGV.replace Array(args.shift)
60
+ args.delete_if do |arg|
61
+ if %r/^[A-Z_]+=/ =~ arg
62
+ ARGV << arg
63
+ next true
64
+ end
65
+ false
66
+ end
67
+
68
+ args
69
+ end
70
+
71
+ # Initialize the Rake application object and load the core rake tasks, the
72
+ # site specific rake tasks, and the site specific ruby code. Any extra
73
+ # command line arguments are converted into a page name and directory that
74
+ # might get created (depending upon the task invoked).
75
+ #
76
+ def init( args )
77
+ # Make sure we're in a folder with a Sitefile
78
+ app.do_option('--rakefile', 'Sitefile')
79
+ app.do_option('--nosearch', nil)
80
+ app.do_option('--silent', nil)
81
+
82
+ unless app.have_rakefile
83
+ raise RuntimeError, "Sitefile not found"
84
+ end
85
+
86
+ import_default_tasks
87
+ import_website_tasks
88
+ require_lib_files
89
+ capture_command_line_args(args)
90
+ args
91
+ end
92
+
93
+ # Execute the rake command.
94
+ #
95
+ def rake
96
+ app.init 'webby'
97
+ app.load_rakefile
98
+ app.top_level
99
+ end
100
+
101
+ # Return the Rake application object.
102
+ #
103
+ def app
104
+ Rake.application
105
+ end
106
+
107
+ # Search for the "Sitefile" starting in the current directory and working
108
+ # upwards through the filesystem until the root of the filesystem is
109
+ # reached. If a "Sitefile" is not found, a RuntimeError is raised.
110
+ #
111
+ def find_sitefile
112
+ here = Dir.pwd
113
+ while ! app.have_rakefile
114
+ Dir.chdir("..")
115
+ if Dir.pwd == here || options.nosearch
116
+ fail "No Sitefile found"
117
+ end
118
+ here = Dir.pwd
119
+ end
120
+ end
121
+
122
+ def import_default_tasks
123
+ Dir.glob(::Webby.libpath(%w[webby tasks *.rake])).sort.each {|fn| import fn}
124
+ end
125
+
126
+ def import_website_tasks
127
+ Dir.glob(::File.join(%w[tasks *.rake])).sort.each {|fn| import fn}
128
+ end
129
+
130
+ def require_lib_files
131
+ Dir.glob(::File.join(%w[lib ** *.rb])).sort.each {|fn| require fn}
132
+ end
133
+
134
+ def capture_command_line_args(args)
135
+ args = OpenStruct.new(:raw => args)
136
+
137
+ if args.raw.size > 1
138
+ ::Webby.deprecated "multiple arguments used for page title",
139
+ "please quote the page title"
140
+ end
141
+
142
+ dashed = args.raw.join('-').downcase
143
+ spaced = args.raw.join(' ')
144
+ dir = ::File.dirname(dashed)
145
+
146
+ args.dir = ('.' == dir ? '' : dir)
147
+ args.slug = ::Webby::Resources::File.basename(dashed).to_url
148
+ args.title = ::Webby::Resources::File.basename(spaced).titlecase
149
+
150
+ # page should be dir/slug without leading /
151
+ args.page = ::File.join(args.dir, args.slug).gsub(/^\//, '')
152
+
153
+ ::Webby.site.args = args
154
+ Object.const_set(:SITE, Webby.site)
155
+ args
156
+ end
157
+
158
+ end # class Main
159
+ end # module Webby::Apps
160
+
161
+ # :stopdoc:
162
+ # Monkey patches so that rake displays the correct application name in the
163
+ # help messages.
164
+ #
165
+ class Rake::Application
166
+ def display_prerequisites
167
+ tasks.each do |t|
168
+ puts "#{name} #{t.name}"
169
+ t.prerequisites.each { |pre| puts " #{pre}" }
170
+ end
171
+ end
172
+
173
+ def display_tasks_and_comments
174
+ displayable_tasks = tasks.select { |t|
175
+ t.comment && t.name =~ options.show_task_pattern
176
+ }
177
+ if options.full_description
178
+ displayable_tasks.each do |t|
179
+ puts "#{name} #{t.name_with_args}"
180
+ t.full_comment.split("\n").each do |line|
181
+ puts " #{line}"
182
+ end
183
+ puts
184
+ end
185
+ else
186
+ width = displayable_tasks.collect { |t| t.name_with_args.length }.max || 10
187
+ max_column = 80 - name.size - width - 7
188
+ displayable_tasks.each do |t|
189
+ printf "#{name} %-#{width}s # %s\n",
190
+ t.name_with_args, truncate(t.comment, max_column)
191
+ end
192
+ end
193
+ end
194
+
195
+ # Provide standard execption handling for the given block.
196
+ def standard_exception_handling
197
+ begin
198
+ yield
199
+ rescue SystemExit => ex
200
+ # Exit silently with current status
201
+ exit(ex.status)
202
+ rescue SystemExit, GetoptLong::InvalidOption => ex
203
+ # Exit silently
204
+ exit(1)
205
+ rescue Exception => ex
206
+ # Exit with error message
207
+ $stderr.puts "webby aborted!"
208
+ $stderr.puts ex.message
209
+ if options.trace
210
+ $stderr.puts ex.backtrace.join("\n")
211
+ else
212
+ $stderr.puts ex.backtrace.find {|str| str =~ /#{@rakefile}/ } || ""
213
+ $stderr.puts "(See full trace by running task with --trace)"
214
+ end
215
+ exit(1)
216
+ end
217
+ end
218
+ end # class Rake::Application
219
+ # :startdoc:
220
+
221
+ # EOF
data/lib/webby/apps.rb ADDED
@@ -0,0 +1,12 @@
1
+
2
+ module Webby::Apps
3
+
4
+ class << self
5
+ def author() 'Tim Pease'; end
6
+ end
7
+
8
+ end # module Webby::Apps
9
+
10
+ Webby.require_all_libs_relative_to(__FILE__)
11
+
12
+ # EOF
@@ -0,0 +1,83 @@
1
+ require 'directory_watcher'
2
+
3
+ module Webby
4
+
5
+ # The AutoBuilder class is used to monitor the content and layouts folders
6
+ # and to compile the resource files only when they are modified. If a
7
+ # layout is modified, then all resources that depend upon the layout are
8
+ # compiled.
9
+ #
10
+ class AutoBuilder
11
+
12
+ # TODO: hit Ctrl-C once to rebuild everything, and hit it twice to stop the autobuild loop
13
+
14
+ # call-seq:
15
+ # AutoBuilder.run
16
+ #
17
+ # Creates a new AutoBuilder and sets it running. This method will only
18
+ # return when the user presses Ctrl-C.
19
+ #
20
+ def self.run
21
+ self.new.run
22
+ end
23
+
24
+ # call-seq:
25
+ # AutoBuilder.new
26
+ #
27
+ # Create a new AutoBuilder class.
28
+ #
29
+ def initialize
30
+ @log = Logging::Logger[self]
31
+
32
+ @builder = Builder.new
33
+ @watcher = DirectoryWatcher.new '.', :interval => 2
34
+ @watcher.add_observer self
35
+
36
+ glob = []
37
+ glob << File.join(::Webby.site.layout_dir, '**', '*')
38
+ glob << File.join(::Webby.site.content_dir, '**', '*')
39
+ @watcher.glob = glob
40
+ end
41
+
42
+ # call-seq:
43
+ # update( *events )
44
+ #
45
+ # The update method is called by the DirectoryWatcher when files have been
46
+ # modified, added, or deleted. An array of events is passed to his method,
47
+ # and each event contains the event type and the path to the file.
48
+ #
49
+ def update( *events )
50
+ ary = events.find_all {|evt| evt.type != :removed}
51
+ return if ary.empty?
52
+
53
+ ary.each do |evt|
54
+ @log.debug "changed #{evt.path}"
55
+ next unless test ?f, evt.path
56
+ next if evt.path =~ ::Webby.exclude
57
+ Resources.new evt.path
58
+ end
59
+
60
+ @builder.run :load_files => false
61
+ rescue => err
62
+ @log.error err
63
+ end
64
+
65
+ # call-seq:
66
+ # run
67
+ #
68
+ # Starts the DirectoryWatcher running and waits till the user presses
69
+ # Ctrl-C to stop the watcher thread.
70
+ #
71
+ def run
72
+ @log.info 'starting autobuild (Ctrl-C to stop)'
73
+
74
+ Signal.trap('INT') {@watcher.stop}
75
+
76
+ @watcher.start
77
+ @watcher.join
78
+ end
79
+
80
+ end # class AutoBuilder
81
+ end # module Webby
82
+
83
+ # EOF