TwP-webby 0.9.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 (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