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,339 @@
1
+ require 'rbconfig'
2
+ require 'thread'
3
+ require 'tempfile'
4
+
5
+ # :stopdoc:
6
+
7
+ # == Synopsis
8
+ #
9
+ # A class for spawning child processes and ensuring those children continue
10
+ # running.
11
+ #
12
+ # == Details
13
+ #
14
+ # When a spawner is created it is given the command to run in a child
15
+ # process. This child process has +stdin+, +stdout+, and +stderr+ redirected
16
+ # to +/dev/null+ (this works even on Windows). When the child dies for any
17
+ # reason, the spawner will restart a new child process in the exact same
18
+ # manner as the original.
19
+ #
20
+ class Spawner
21
+
22
+ @dev_null = test(?e, "/dev/null") ? "/dev/null" : "NUL:"
23
+
24
+ c = ::Config::CONFIG
25
+ ruby = File.join(c['bindir'], c['ruby_install_name']) << c['EXEEXT']
26
+ @ruby = if system('%s -e exit' % ruby) then ruby
27
+ elsif system('ruby -e exit') then 'ruby'
28
+ else warn 'no ruby in PATH/CONFIG'
29
+ end
30
+
31
+ class << self
32
+ attr_reader :ruby
33
+ attr_reader :dev_null
34
+
35
+ def finalizer( cids )
36
+ pid = $$
37
+ lambda do
38
+ break unless pid == $$
39
+ cids.kill 'TERM', :all
40
+ end # lambda
41
+ end # finalizer
42
+ end
43
+
44
+ # call-seq:
45
+ # Spawner.new( command, *args, opts = {} )
46
+ #
47
+ # Creates a new spawner that will execute the given external _command_ in
48
+ # a sub-process. The calling semantics of <code>Kernel::exec</code> are
49
+ # used to execute the _command_. Any number of optional _args_ can be
50
+ # passed to the _command_.
51
+ #
52
+ # Available options:
53
+ #
54
+ # :spawn => the number of child processes to spawn
55
+ # :pause => wait time (in seconds) before respawning after termination
56
+ # :ruby => the Ruby interpreter to use when spawning children
57
+ # :env => a hash for the child process environment
58
+ # :stdin => stdin child processes will read from
59
+ # :stdout => stdout child processes will write to
60
+ # :stderr => stderr child processes will write to
61
+ #
62
+ # The <code>:env</code> option is used to add environemnt variables to
63
+ # child processes when they are spawned.
64
+ #
65
+ # *Note:* all spawned child processes will use the same stdin, stdout, and
66
+ # stderr if they are given in the options. Otherwise they all default to
67
+ # <code>/dev/null</code> on *NIX and <code>NUL:</code> on Windows.
68
+ #
69
+ def initialize( *args )
70
+ config = {
71
+ :ruby => self.class.ruby,
72
+ :spawn => 1,
73
+ :pause => 0,
74
+ :stdin => self.class.dev_null,
75
+ :stdout => self.class.dev_null,
76
+ :stderr => self.class.dev_null
77
+ }
78
+ config.merge! args.pop if Hash === args.last
79
+ config[:argv] = args
80
+
81
+ raise ArgumentError, 'wrong number of arguments' if args.empty?
82
+
83
+ @stop = true
84
+ @cids = []
85
+ @group = ThreadGroup.new
86
+
87
+ @spawn = config.delete(:spawn)
88
+ @pause = config.delete(:pause)
89
+ @ruby = config.delete(:ruby)
90
+
91
+ @tmp = child_program(config)
92
+
93
+ class << @cids
94
+ # call-seq:
95
+ # sync {block}
96
+ #
97
+ # Executes the given block in a synchronized fashion -- i.e. only a
98
+ # single thread can execute at a time. Uses Mutex under the hood.
99
+ #
100
+ def sync(&b)
101
+ @mutex ||= Mutex.new
102
+ @mutex.synchronize(&b)
103
+ end
104
+
105
+ # call-seq:
106
+ # kill( signal, num ) => number killed
107
+ # kill( signal, :all ) => number killed
108
+ #
109
+ # Send the _signal_ to a given _num_ of child processes or all child
110
+ # processes if <code>:all</code> is given instead of a number. Returns
111
+ # the number of child processes killed.
112
+ #
113
+ def kill( signal, arg )
114
+ return if empty?
115
+
116
+ ary = sync do
117
+ case arg
118
+ when :all; self.dup
119
+ when Integer; self.slice(0,arg)
120
+ else raise ArgumentError end
121
+ end
122
+
123
+ ary.each do |cid|
124
+ begin
125
+ Process.kill(signal, cid)
126
+ rescue SystemCallError
127
+ sync {delete cid}
128
+ end
129
+ end
130
+ ary.length
131
+ end # def kill
132
+ end # class << @cids
133
+
134
+ end # def initialize
135
+
136
+ attr_reader :spawn
137
+ attr_accessor :pause
138
+
139
+ # call-seq:
140
+ # spawner.spawn = num
141
+ #
142
+ # Set the number of child processes to spawn. If the new spawn number is
143
+ # less than the current number, then spawner threads will die
144
+ #
145
+ def spawn=( num )
146
+ num = num.abs
147
+ diff, @spawn = num - @spawn, num
148
+ return unless running?
149
+
150
+ if diff > 0
151
+ diff.times {_spawn}
152
+ elsif diff < 0
153
+ @cids.kill 'TERM', diff.abs
154
+ end
155
+ end
156
+
157
+ # call-seq:
158
+ # start => self
159
+ #
160
+ # Spawn the sub-processes.
161
+ #
162
+ def start
163
+ return self if running?
164
+ @stop = false
165
+
166
+ @cleanup = Spawner.finalizer(@cids)
167
+ ObjectSpace.define_finalizer(self, @cleanup)
168
+
169
+ @spawn.times {_spawn}
170
+ self
171
+ end
172
+
173
+ # call-seq:
174
+ # stop( timeout = 5 ) => self
175
+ #
176
+ # Stop any spawned sub-processes.
177
+ #
178
+ def stop( timeout = 5 )
179
+ return self unless running?
180
+ @stop = true
181
+
182
+ @cleanup.call
183
+ ObjectSpace.undefine_finalizer(self)
184
+
185
+ # the cleanup call sends SIGTERM to all the child processes
186
+ # however, some might still be hanging around, so we are going to wait
187
+ # for a timeout interval and then send a SIGKILL to any remaining child
188
+ # processes
189
+ nap_time = 0.05 * timeout # sleep for 5% of the timeout interval
190
+ timeout = Time.now + timeout
191
+
192
+ until @cids.empty?
193
+ sleep nap_time
194
+ unless Time.now < timeout
195
+ @cids.kill 'KILL', :all
196
+ @cids.clear
197
+ @group.list.each {|t| t.kill}
198
+ break
199
+ end
200
+ end
201
+
202
+ self
203
+ end
204
+
205
+ # call-seq:
206
+ # restart( timeout = 5 )
207
+ #
208
+ def restart( timeout = 5 )
209
+ stop( timeout )
210
+ start
211
+ end
212
+
213
+ # call-seq:
214
+ # running?
215
+ #
216
+ # Returns +true+ if the spawner is currently running; returns +false+
217
+ # otherwise.
218
+ #
219
+ def running?
220
+ !@stop
221
+ end
222
+
223
+ # call-seq:
224
+ # join( timeout = nil ) => spawner or nil
225
+ #
226
+ # The calling thread will suspend execution until all child processes have
227
+ # been stopped. Does not return until all spawner threads have exited (the
228
+ # child processes have been stopped) or until _timeout seconds have
229
+ # passed. If the timeout expires +nil+ will be returned; otherwise the
230
+ # spawner is returned.
231
+ #
232
+ def join( limit = nil )
233
+ loop do
234
+ t = @group.list.first
235
+ break if t.nil?
236
+ return nil unless t.join(limit)
237
+ end
238
+ self
239
+ end
240
+
241
+
242
+ private
243
+
244
+ # call-seq:
245
+ # _spawn => thread
246
+ #
247
+ # Creates a thread that will spawn the sub-process via
248
+ # <code>IO::popen</code>. If the sub-process terminates, it will be
249
+ # respawned until the +stop+ message is sent to this spawner.
250
+ #
251
+ # If an Exception is encountered during the spawning process, a message
252
+ # will be printed to stderr and the thread will exit.
253
+ #
254
+ def _spawn
255
+ t = Thread.new do
256
+ catch(:die) do
257
+ loop do
258
+ begin
259
+ io = IO.popen("#{@ruby} #{@tmp.path}", 'r')
260
+ cid = io.gets.to_i
261
+
262
+ @cids.sync {@cids << cid} if cid > 0
263
+ Process.wait cid
264
+ rescue Exception => e
265
+ STDERR.puts e.inspect
266
+ STDERR.puts e.backtrace.join("\n")
267
+ throw :die
268
+ ensure
269
+ io.close rescue nil
270
+ @cids.sync {
271
+ @cids.delete cid
272
+ throw :die unless @cids.length < @spawn
273
+ }
274
+ end
275
+
276
+ throw :die if @stop
277
+ sleep @pause
278
+
279
+ end # loop
280
+ end # catch(:die)
281
+ end # Thread.new
282
+
283
+ @group.add t
284
+ t
285
+ end
286
+
287
+ # call-seq:
288
+ # child_program( config ) => tempfile
289
+ #
290
+ # Creates a child Ruby program based on the given _config_ hash. The
291
+ # following hash keys are used:
292
+ #
293
+ # :argv => command and arguments passed to <code>Kernel::exec</code>
294
+ # :env => environment variables for the child process
295
+ # :cwd => the current working directory to use for the child process
296
+ # :stdin => stdin the child process will read from
297
+ # :stdout => stdout the child process will write to
298
+ # :stderr => stderr the child process will write to
299
+ #
300
+ def child_program( config )
301
+ config = Marshal.dump(config)
302
+
303
+ tmp = Tempfile.new(self.class.name.downcase)
304
+ tmp.write <<-PROG
305
+ begin
306
+ config = Marshal.load(#{config.inspect})
307
+
308
+ argv = config[:argv]
309
+ env = config[:env]
310
+ cwd = config[:cwd]
311
+ stdin = config[:stdin]
312
+ stdout = config[:stdout]
313
+ stderr = config[:stderr]
314
+
315
+ Dir.chdir cwd if cwd
316
+ env.each {|k,v| ENV[k.to_s] = v.to_s} if env
317
+ rescue Exception => e
318
+ STDERR.warn e
319
+ abort
320
+ end
321
+
322
+ STDOUT.puts Process.pid
323
+ STDOUT.flush
324
+
325
+ STDIN.reopen stdin
326
+ STDOUT.reopen stdout
327
+ STDERR.reopen stderr
328
+
329
+ exec *argv
330
+ PROG
331
+
332
+ tmp.close
333
+ tmp
334
+ end
335
+ end # class Spawner
336
+
337
+ # :startdoc:
338
+
339
+ # EOF
@@ -0,0 +1,27 @@
1
+
2
+ task :configure_basepath do
3
+ Webby.site.base = ENV['BASE'] if ENV.has_key?('BASE')
4
+ end
5
+
6
+ desc "Build the website"
7
+ task :build => :configure_basepath do |t|
8
+ Webby::Builder.run
9
+ end
10
+
11
+ desc "Rebuild the website"
12
+ task :rebuild => :configure_basepath do |t|
13
+ Webby::Builder.run :rebuild => true
14
+ end
15
+
16
+ desc "Continuously build the website"
17
+ task :autobuild => :configure_basepath do |t|
18
+ Webby::AutoBuilder.run
19
+ end
20
+
21
+ desc "Delete the website"
22
+ task :clobber do |t|
23
+ rm_rf Webby.site.output_dir
24
+ mkdir Webby.site.output_dir
25
+ end
26
+
27
+ # EOF
@@ -0,0 +1,22 @@
1
+
2
+ namespace :create do
3
+
4
+ FileList["#{Webby.site.template_dir}/*"].each do |template|
5
+ next unless test(?f, template)
6
+ name = template.pathmap '%n'
7
+
8
+ # if the file is a partial template
9
+ name = $1 if name =~ %r/^_(.*)/
10
+
11
+ desc "Create a new #{name}"
12
+ task name do |t|
13
+ page, title, dir = Webby::Builder.new_page_info
14
+ page = Webby::Builder.create(page, :from => template,
15
+ :locals => {:title => title, :directory => dir})
16
+ exec(::Webby.editor, page) unless ::Webby.editor.nil?
17
+ end
18
+ end # each
19
+
20
+ end # namespace :create
21
+
22
+ # EOF
@@ -0,0 +1,22 @@
1
+
2
+ require 'rake/contrib/sshpublisher'
3
+
4
+ namespace :deploy do
5
+
6
+ desc 'Deploy to the server using rsync'
7
+ task :rsync do
8
+ cmd = "rsync #{SITE.rsync_args.join(' ')} "
9
+ cmd << "#{SITE.output_dir}/ #{SITE.user}@#{SITE.host}:#{SITE.remote_dir}"
10
+ sh cmd
11
+ end
12
+
13
+ desc 'Deploy to the server using ssh'
14
+ task :ssh do
15
+ Rake::SshDirPublisher.new(
16
+ "#{SITE.user}@#{SITE.host}", SITE.remote_dir, SITE.output_dir
17
+ ).upload
18
+ end
19
+
20
+ end # deploy
21
+
22
+ # EOF
@@ -0,0 +1,15 @@
1
+
2
+ unless WINDOWS
3
+
4
+ task :growl do
5
+ Logging::Logger['Webby'].add_appenders(Logging::Appenders::Growl.new(
6
+ "Webby",
7
+ :layout => Logging::Layouts::Pattern.new(:pattern => "%5l - Webby\000%m"),
8
+ :coalesce => true,
9
+ :separator => "\000"
10
+ ))
11
+ end
12
+
13
+ end # unless WINDOWS
14
+
15
+ # EOF
@@ -0,0 +1,28 @@
1
+
2
+ namespace :heel do
3
+
4
+ desc 'Start the heel server to view website (not for Windows)'
5
+ task :start do
6
+ sh "heel --root #{SITE.output_dir} --port #{SITE.heel_port} --daemonize"
7
+ end
8
+
9
+ desc 'Stop the heel server'
10
+ task :stop do
11
+ sh "heel --kill"
12
+ end
13
+
14
+ task :autorun do
15
+ heel_exe = File.join(Gem.bindir, 'heel')
16
+ @heel_spawner = Spawner.new(Spawner.ruby, heel_exe, '--root', SITE.output_dir, '--port', SITE.heel_port.to_s, :pause => 86_400)
17
+ @heel_spawner.start
18
+ end
19
+
20
+ task :autobuild => :autorun do
21
+ at_exit {@heel_spawner.stop if defined? @heel_spawner and not @heel_spawner.nil?}
22
+ end
23
+
24
+ end
25
+
26
+ task :autobuild => 'heel:autobuild'
27
+
28
+ # EOF
@@ -0,0 +1,19 @@
1
+
2
+ namespace :validate do
3
+
4
+ desc 'Validate hyperlinks (exclude exteranl sites)'
5
+ task :internal => :build do
6
+ Webby::LinkValidator.validate(:external => false)
7
+ end
8
+
9
+ desc 'Validate hyperlinks (include external sites)'
10
+ task :external => :build do
11
+ Webby::LinkValidator.validate(:external => true)
12
+ end
13
+
14
+ end # validate
15
+
16
+ desc 'Alias to validate:internal'
17
+ task :validate => 'validate:internal'
18
+
19
+ # EOF
data/lib/webby.rb ADDED
@@ -0,0 +1,227 @@
1
+ # Equivalent to a header guard in C/C++
2
+ # Used to prevent the spec helper from being loaded more than once
3
+ unless defined? ::Webby
4
+
5
+ require 'rubygems'
6
+ require 'logging'
7
+ require 'ostruct'
8
+ require 'date'
9
+
10
+ # Configure Webby to log to STDOUT at the 'info' level
11
+ Logging::Logger['Webby'].level = :info
12
+ Logging::Logger['Webby'].add_appenders(Logging::Appender.stdout)
13
+ Logging::Appender.stdout.layout = Logging::Layouts::Pattern.new(
14
+ :pattern => "[%d] %5l: %m\n", # [date] LEVEL: message
15
+ :date_pattern => "%H:%M:%S" # date == HH:MM:SS
16
+ )
17
+
18
+ module Webby
19
+
20
+ # :stopdoc:
21
+ VERSION = '0.9.0' # :nodoc:
22
+ LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
23
+ PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
24
+ # :startdoc:
25
+
26
+ class Error < StandardError; end # :nodoc:
27
+
28
+ # call-seq:
29
+ # Webby.site => struct
30
+ #
31
+ # Returns a struct containing the configuration parameters for the
32
+ # Webby site. These defaults should be overridden as needed in the
33
+ # site specific Rakefile.
34
+ #
35
+ def self.site
36
+ return @site if defined? @site
37
+ @site = OpenStruct.new(
38
+ :output_dir => 'output',
39
+ :content_dir => 'content',
40
+ :layout_dir => 'layouts',
41
+ :template_dir => 'templates',
42
+ :exclude => %w(tmp$ bak$ ~$ CVS \.svn),
43
+ :page_defaults => {
44
+ 'layout' => 'default'
45
+ },
46
+ :find_by => 'title',
47
+ :base => nil,
48
+ :create_mode => 'page',
49
+ :blog_dir => 'blog',
50
+ :tumblog_dir => 'tumblog',
51
+
52
+ # Items for running the heel webserver
53
+ :heel_port => 4331,
54
+
55
+ # Items used to deploy the website
56
+ :user => ENV['USER'] || ENV['USERNAME'],
57
+ :host => 'example.com',
58
+ :remote_dir => '/not/a/valid/dir',
59
+ :rsync_args => %w(-av),
60
+
61
+ # Global options for HAML and SASS
62
+ :haml_options => {},
63
+ :sass_options => {},
64
+
65
+ # Options passed to the 'tidy' program when the tidy filter is used
66
+ :tidy_options => '-indent -wrap 80',
67
+
68
+ # List of valid URIs (these automatically pass validation)
69
+ :valid_uris => [],
70
+
71
+ # Options for coderay processing
72
+ :coderay => {
73
+ :lang => :ruby,
74
+ :line_numbers => nil,
75
+ :line_number_start => 1,
76
+ :bold_every => 10,
77
+ :tab_width => 8
78
+ },
79
+
80
+ # Options for graphviz processing
81
+ :graphviz => {
82
+ :path => nil,
83
+ :cmd => 'dot',
84
+ :type => 'png'
85
+ },
86
+
87
+ # Options for tex2img processing
88
+ :tex2img => {
89
+ :path => nil,
90
+ :type => 'png',
91
+ :bg => 'white',
92
+ :fg => 'black',
93
+ :resolution => '150x150'
94
+ },
95
+
96
+ # Options for ultraviolet syntax highlighting
97
+ :uv => {
98
+ :lang => 'ruby',
99
+ :line_numbers => false,
100
+ :theme => 'mac_classic'
101
+ },
102
+
103
+ # XPath identifiers used by the basepath filter
104
+ :xpaths => %w(
105
+ /html/head//base[@href]
106
+ /html/head//link[@href]
107
+ //script[@src]
108
+ /html/body[@background]
109
+ /html/body//a[@href]
110
+ /html/body//object[@data]
111
+ /html/body//img[@src]
112
+ /html/body//area[@href]
113
+ /html/body//form[@action]
114
+ /html/body//input[@src]
115
+ )
116
+ # other possible XPaths to include for base path substitution
117
+ # /html/body//object[@usemap]
118
+ # /html/body//img[@usemap]
119
+ # /html/body//input[@usemap]
120
+ )
121
+ end
122
+
123
+ # call-seq
124
+ # Webby.exclude => regexp
125
+ #
126
+ # Returns a regular expression used to exclude resources from the content
127
+ # directory from being processed by Webby. This same regular expression is
128
+ # also used to exclude layouts.
129
+ #
130
+ def self.exclude
131
+ @exclude ||= Regexp.new(site.exclude.join('|'))
132
+ end
133
+
134
+ # call-seq:
135
+ # Webby.editor => string or nil
136
+ #
137
+ # Returns the default editor to use when creating new pages. This editor
138
+ # will be spawned to allow the user to edit the newly created page.
139
+ #
140
+ def self.editor
141
+ return @editor if defined? @editor
142
+
143
+ @editor = if ENV['EDITOR'].nil? or ENV['EDITOR'].empty? then nil
144
+ else ENV['EDITOR'] end
145
+ end
146
+
147
+ # call-seq:
148
+ # cairn => filename
149
+ #
150
+ # The Webby _cairn_ file is used to mark the last time the content was
151
+ # built into the output directory. It is an empty file; only the
152
+ # modification time of the file is important.
153
+ #
154
+ def self.cairn
155
+ @cairn ||= ::File.join(site.output_dir, '.cairn')
156
+ end
157
+
158
+ # Returns the library path for Webby. If any arguments are given,
159
+ # they will be joined to the end of the libray path using
160
+ # <tt>File.join</tt>.
161
+ #
162
+ def self.libpath( *args )
163
+ args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
164
+ end
165
+
166
+ # Returns the path for Webby. If any arguments are given,
167
+ # they will be joined to the end of the path using
168
+ # <tt>File.join</tt>.
169
+ #
170
+ def self.path( *args )
171
+ args.empty? ? PATH : ::File.join(PATH, args.flatten)
172
+ end
173
+
174
+ # call-seq:
175
+ # Webby.require_all_libs_relative_to( filename, directory = nil )
176
+ #
177
+ # Utility method used to rquire all files ending in .rb that lie in the
178
+ # directory below this file that has the same name as the filename passed
179
+ # in. Optionally, a specific _directory_ name can be passed in such that
180
+ # the _filename_ does not have to be equivalent to the directory.
181
+ #
182
+ def self.require_all_libs_relative_to( fname, dir = nil )
183
+ dir ||= ::File.basename(fname, '.*')
184
+ search_me = ::File.expand_path(
185
+ ::File.join(::File.dirname(fname), dir, '*.rb'))
186
+
187
+ Dir.glob(search_me).sort.each {|rb| require rb}
188
+ end
189
+
190
+ # Prints a deprecation warning using the logger. The message states that
191
+ # the given method is being deprecated. An optional message can be give to
192
+ # -- somthing nice and fuzzy about a new method or why this one has to go
193
+ # away; sniff, we'll miss you little buddy.
194
+ #
195
+ def self.deprecated( method, message = nil )
196
+ msg = "'#{method}' has been deprecated"
197
+ msg << "\n\t#{message}" unless message.nil?
198
+ Logging::Logger['Webby'].warn msg
199
+ end
200
+
201
+ end # module Webby
202
+
203
+
204
+ # call-seq:
205
+ # try_require( library, gemname = nil ) => true or false
206
+ #
207
+ # Try to laod the given _library_ using the built-in require, but do not
208
+ # raise a LoadError if unsuccessful. Returns +true+ if the _library_ was
209
+ # successfully loaded; returns +false+ otherwise.
210
+ #
211
+ # If a _gemname_ is given, then the "gem gemname" command will be called
212
+ # before the library is loaded.
213
+ #
214
+ def try_require( lib, gemname = nil )
215
+ gem gemname unless gemname.nil?
216
+ require lib
217
+ true
218
+ rescue LoadError
219
+ false
220
+ end
221
+
222
+ Webby.require_all_libs_relative_to(__FILE__, ::File.join(%w[webby core_ext]))
223
+ Webby.require_all_libs_relative_to(__FILE__)
224
+
225
+ end # unless defined?
226
+
227
+ # EOF