webby 0.9.2 → 0.9.3

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 (77) hide show
  1. data/History.txt +13 -0
  2. data/Manifest.txt +44 -33
  3. data/Rakefile +2 -2
  4. data/bin/webby +33 -0
  5. data/bin/webby-gen +33 -0
  6. data/examples/presentation/content/presentation/s5/bodybg.gif +0 -0
  7. data/examples/presentation/content/presentation/s5/print.css +25 -1
  8. data/examples/webby/content/release-notes/rel-0-9-3/index.txt +49 -0
  9. data/lib/webby.rb +3 -10
  10. data/lib/webby/apps/generator.rb +41 -48
  11. data/lib/webby/apps/main.rb +22 -0
  12. data/lib/webby/auto_builder.rb +78 -6
  13. data/lib/webby/builder.rb +9 -9
  14. data/lib/webby/core_ext/kernel.rb +5 -0
  15. data/lib/webby/filters/wiki_words.rb +14 -0
  16. data/lib/webby/helpers/url_helper.rb +6 -0
  17. data/lib/webby/journal.rb +126 -0
  18. data/lib/webby/renderer.rb +11 -6
  19. data/lib/webby/resources/meta_file.rb +8 -5
  20. data/lib/webby/stelan/paginator.rb +2 -2
  21. data/lib/webby/tasks/growl.rake +4 -3
  22. data/spec/data/outline/basic.out +81 -0
  23. data/spec/data/outline/basic.txt +25 -0
  24. data/spec/data/outline/no_clobber.out +86 -0
  25. data/spec/data/outline/numbering.out +81 -0
  26. data/spec/data/outline/numbering_only.out +21 -0
  27. data/spec/data/outline/toc_range_1.out +66 -0
  28. data/spec/data/outline/toc_range_2.out +55 -0
  29. data/spec/data/outline/toc_style.out +81 -0
  30. data/spec/data/{Sitefile → site/Sitefile} +0 -0
  31. data/spec/data/{content → site/content}/_partial.txt +0 -0
  32. data/spec/data/{content → site/content}/css/coderay.css +0 -0
  33. data/spec/data/{content → site/content}/css/site.css +0 -0
  34. data/spec/data/{content → site/content}/css/tumblog.css +0 -0
  35. data/spec/data/{content → site/content}/images/tumblog/permalink.gif +0 -0
  36. data/spec/data/{content → site/content}/images/tumblog/rss.gif +0 -0
  37. data/spec/data/{content → site/content}/index.txt +0 -0
  38. data/spec/data/{content → site/content}/photos.txt +0 -0
  39. data/spec/data/{content → site/content}/tumblog/200806/the-noble-chicken/index.txt +0 -0
  40. data/spec/data/{content → site/content}/tumblog/200807/historical-perspectives-on-the-classic-chicken-joke/index.txt +0 -0
  41. data/spec/data/{content → site/content}/tumblog/200807/mad-city-chickens/index.txt +0 -0
  42. data/spec/data/{content → site/content}/tumblog/200807/the-wisdom-of-the-dutch/index.txt +0 -0
  43. data/spec/data/{content → site/content}/tumblog/200807/up-a-tree/index.txt +0 -0
  44. data/spec/data/{content → site/content}/tumblog/index.txt +0 -0
  45. data/spec/data/{content → site/content}/tumblog/rss.txt +0 -0
  46. data/spec/data/{layouts → site/layouts}/default.txt +0 -0
  47. data/spec/data/{layouts → site/layouts}/tumblog/default.txt +0 -0
  48. data/spec/data/{layouts → site/layouts}/tumblog/post.txt +0 -0
  49. data/spec/data/{lib → site/lib}/breadcrumbs.rb +0 -0
  50. data/spec/data/{lib → site/lib}/tumblog_helper.rb +0 -0
  51. data/spec/data/{tasks → site/tasks}/tumblog.rake +0 -0
  52. data/spec/data/{templates → site/templates}/_partial.erb +0 -0
  53. data/spec/data/{templates → site/templates}/atom_feed.erb +0 -0
  54. data/spec/data/{templates → site/templates}/page.erb +0 -0
  55. data/{examples/website → spec/data/site}/templates/presentation.erb +0 -0
  56. data/spec/data/{templates → site/templates}/tumblog/conversation.erb +0 -0
  57. data/spec/data/{templates → site/templates}/tumblog/link.erb +0 -0
  58. data/spec/data/{templates → site/templates}/tumblog/photo.erb +0 -0
  59. data/spec/data/{templates → site/templates}/tumblog/post.erb +0 -0
  60. data/spec/data/{templates → site/templates}/tumblog/quote.erb +0 -0
  61. data/spec/spec_helper.rb +4 -4
  62. data/spec/webby/apps/generator_spec.rb +3 -2
  63. data/spec/webby/filters/basepath_spec.rb +167 -0
  64. data/spec/webby/filters/outline_spec.rb +92 -0
  65. data/spec/webby/renderer_spec.rb +1 -1
  66. data/spec/webby/resources/db_spec.rb +1 -1
  67. data/spec/webby/resources/layout_spec.rb +1 -1
  68. data/spec/webby/resources/meta_file_spec.rb +27 -13
  69. data/spec/webby/resources/page_spec.rb +1 -1
  70. data/spec/webby/resources/resource_spec.rb +1 -1
  71. data/spec/webby/resources_spec.rb +1 -1
  72. data/tasks/gem.rake +93 -32
  73. data/tasks/manifest.rake +3 -4
  74. data/tasks/rubyforge.rake +2 -4
  75. metadata +67 -56
  76. data/lib/webby/tasks/heel.rake +0 -28
  77. data/spec/data/templates/presentation.erb +0 -40
@@ -12,10 +12,13 @@ class Main
12
12
  self.new.run args
13
13
  end
14
14
 
15
+ attr_reader :cmd_line_options
16
+
15
17
  # Create a new Main webby object for building websites.
16
18
  #
17
19
  def initialize
18
20
  @stdout = $stdout
21
+ @cmd_line_options = {}
19
22
  end
20
23
 
21
24
  # Runs the main webby application. The command line arguments are passed
@@ -44,6 +47,16 @@ class Main
44
47
  opts.on(*options)
45
48
  end
46
49
 
50
+ opts.separator ''
51
+ opts.separator 'autobuild options:'
52
+
53
+ opts.on('--web-server', 'Start a local web server') {
54
+ cmd_line_options[:use_web_server] = true
55
+ }
56
+ opts.on('--no-web-server', 'Do not start a local web server') {
57
+ cmd_line_options[:use_web_server] = false
58
+ }
59
+
47
60
  opts.separator ''
48
61
  opts.separator 'common options:'
49
62
 
@@ -98,6 +111,7 @@ class Main
98
111
  def rake
99
112
  app.init 'webby'
100
113
  app.load_rakefile
114
+ load_command_line_options
101
115
  app.top_level
102
116
  end
103
117
 
@@ -167,6 +181,14 @@ class Main
167
181
  args
168
182
  end
169
183
 
184
+ # Load options from the command line into the ::Webby.site struct
185
+ #
186
+ def load_command_line_options
187
+ cmd_line_options.each do |key, value|
188
+ ::Webby.site.__send__("#{key}=", value)
189
+ end
190
+ end
191
+
170
192
  end # class Main
171
193
  end # module Webby::Apps
172
194
 
@@ -1,4 +1,6 @@
1
1
  require 'directory_watcher'
2
+ require 'launchy'
3
+ require 'webrick'
2
4
 
3
5
  module Webby
4
6
 
@@ -21,13 +23,15 @@ class AutoBuilder
21
23
  self.new.run
22
24
  end
23
25
 
26
+ attr_reader :logger
27
+
24
28
  # call-seq:
25
29
  # AutoBuilder.new
26
30
  #
27
31
  # Create a new AutoBuilder class.
28
32
  #
29
33
  def initialize
30
- @log = Logging::Logger[self]
34
+ @logger = Logging::Logger[self]
31
35
 
32
36
  @builder = Builder.new
33
37
  @builder.load_files
@@ -39,6 +43,8 @@ class AutoBuilder
39
43
  glob << File.join(::Webby.site.layout_dir, '**', '*')
40
44
  glob << File.join(::Webby.site.content_dir, '**', '*')
41
45
  @watcher.glob = glob
46
+
47
+ @web_server = ::Webby.site.use_web_server ? WebServer.new : nil
42
48
  end
43
49
 
44
50
  # call-seq:
@@ -53,15 +59,16 @@ class AutoBuilder
53
59
  return if ary.empty?
54
60
 
55
61
  ary.each do |evt|
56
- @log.debug "changed #{evt.path}"
62
+ logger.debug "changed #{evt.path}"
57
63
  next unless test ?f, evt.path
58
64
  next if evt.path =~ ::Webby.exclude
59
65
  Resources.new evt.path
60
66
  end
61
67
 
62
- @builder.run :load_files => false
68
+ logger.info 'running the build'
69
+ @builder.run :load_files => false, :verbose => false
63
70
  rescue => err
64
- @log.error err
71
+ logger.error err
65
72
  end
66
73
 
67
74
  # call-seq:
@@ -71,14 +78,79 @@ class AutoBuilder
71
78
  # Ctrl-C to stop the watcher thread.
72
79
  #
73
80
  def run
74
- @log.info 'starting autobuild (Ctrl-C to stop)'
81
+ logger.info 'starting autobuild (Ctrl-C to stop)'
75
82
 
76
- Signal.trap('INT') {@watcher.stop}
83
+ Signal.trap('INT') {
84
+ @watcher.stop
85
+ @web_server.stop if @web_server
86
+ }
77
87
 
78
88
  @watcher.start
89
+ if @web_server
90
+ @web_server.start
91
+ sleep 0.25
92
+ Launchy.open("http://localhost:#{::Webby.site.heel_port}")
93
+ end
94
+
79
95
  @watcher.join
96
+ @web_server.join if @web_server
80
97
  end
81
98
 
99
+ # Wrapper class around the webrick web server.
100
+ #
101
+ class WebServer
102
+
103
+ # Create a new webrick server configured to serve pages from the output
104
+ # directory. Output will be directed to /dev/null.
105
+ #
106
+ def initialize
107
+ logger = WEBrick::Log.new(Kernel::DEV_NULL, WEBrick::Log::DEBUG)
108
+ access_log = [[ logger, WEBrick::AccessLog::COMBINED_LOG_FORMAT ]]
109
+
110
+ @thread = nil
111
+ @running = false
112
+ @server = WEBrick::HTTPServer.new(
113
+ :BindAddress => 'localhost',
114
+ :Port => ::Webby.site.heel_port,
115
+ :DocumentRoot => ::Webby.site.output_dir,
116
+ :FancyIndexing => true,
117
+ :Logger => logger,
118
+ :AccessLog => access_log
119
+ )
120
+ end
121
+
122
+ # Returns +true+ if the server is running.
123
+ #
124
+ def running?
125
+ @running
126
+ end
127
+
128
+ # Start the webrick server running in a separate thread (so we don't
129
+ # block forever).
130
+ #
131
+ def start
132
+ return if running?
133
+ @running = true
134
+ @thread = Thread.new {@server.start}
135
+ end
136
+
137
+ # Stop the webrick server.
138
+ #
139
+ def stop
140
+ return if not running?
141
+ @running = false
142
+ @server.shutdown
143
+ end
144
+
145
+ # Join on the webserver thread.
146
+ #
147
+ def join
148
+ return if not running?
149
+ @thread.join
150
+ end
151
+
152
+ end # class WebServer
153
+
82
154
  end # class AutoBuilder
83
155
  end # module Webby
84
156
 
@@ -82,7 +82,6 @@ class Builder
82
82
  [args.page, args.title, args.dir]
83
83
  end
84
84
 
85
-
86
85
  private
87
86
 
88
87
  # Returns the binding in the scope of the Builder class object.
@@ -98,7 +97,7 @@ class Builder
98
97
  # layout directories.
99
98
  #
100
99
  def initialize
101
- @log = Logging::Logger[self]
100
+ @logger = Logging::Logger[self]
102
101
  end
103
102
 
104
103
  # call-seq:
@@ -125,24 +124,25 @@ class Builder
125
124
  #
126
125
  def run( opts = {} )
127
126
  opts[:load_files] = true unless opts.has_key?(:load_files)
127
+ verbose = opts.getopt(:verbose, true)
128
128
 
129
129
  unless test(?d, output_dir)
130
- @log.info "creating #{output_dir}"
130
+ journal.create output_dir
131
131
  FileUtils.mkdir output_dir
132
132
  end
133
133
 
134
134
  load_files if opts[:load_files]
135
135
 
136
136
  Resources.pages.each do |page|
137
- next unless page.dirty? or opts[:rebuild]
138
-
139
- @log.info "creating #{page.destination}"
140
-
141
- # make sure the directory exists
142
- FileUtils.mkdir_p ::File.dirname(page.destination)
137
+ unless page.dirty? or opts[:rebuild]
138
+ journal.identical(page.destination) if verbose
139
+ next
140
+ end
143
141
 
144
142
  # copy the resource to the output directory if it is static
145
143
  if page.instance_of? Resources::Static
144
+ FileUtils.mkdir_p ::File.dirname(page.destination)
145
+ journal.create_or_update(page)
146
146
  FileUtils.cp page.path, page.destination
147
147
  FileUtils.chmod 0644, page.destination
148
148
 
@@ -16,6 +16,11 @@ module Kernel
16
16
  STDERR.reopen io.last
17
17
  $stdout, $stderr = STDOUT, STDERR
18
18
  end
19
+
20
+ def journal
21
+ @journal ||= ::Webby::Journal.new
22
+ end
23
+
19
24
  end # module Kernel
20
25
 
21
26
  # EOF
@@ -0,0 +1,14 @@
1
+
2
+ Webby::Filters.register :wikiwords do |input, cursor|
3
+
4
+ renderer = cursor.renderer
5
+ input.gsub %r/\[\[([^\]]+)\]\]/ do
6
+ name = $1
7
+ renderer.link_to_page(name) {
8
+ %Q(<a class="missing internal">#{name}</a>)
9
+ }
10
+ end
11
+
12
+ end
13
+
14
+ # EOF
@@ -159,6 +159,9 @@ module UrlHelper
159
159
  #
160
160
  def link_to_page( *args )
161
161
  self.link_to(*_find_page(args))
162
+ rescue ::Webby::Error => err
163
+ return yield if block_given?
164
+ raise err
162
165
  end
163
166
 
164
167
  # call-seq:
@@ -184,6 +187,9 @@ module UrlHelper
184
187
  return name if @page == page
185
188
 
186
189
  self.link_to(name, page, link_opts)
190
+ rescue ::Webby::Error => err
191
+ return yield if block_given?
192
+ raise err
187
193
  end
188
194
 
189
195
 
@@ -0,0 +1,126 @@
1
+
2
+ module Webby
3
+
4
+ # The Journal class is used to output simple messages regarding the creation
5
+ # and updating of files when webby applications are run. The output messages
6
+ # will be color coded if the terminal supports the ANSI codes.
7
+ #
8
+ class Journal
9
+
10
+ attr_accessor :colorize
11
+ attr_reader :logger
12
+
13
+ # Create a new journal
14
+ #
15
+ def initialize
16
+ @logger = ::Logging::Logger[self]
17
+ @colorize = ENV.has_key?('TERM')
18
+ end
19
+
20
+ # Output a message of the given _type_ using the option _color_ code. The
21
+ # available codes are as follows:
22
+ #
23
+ # * black
24
+ # * red
25
+ # * green
26
+ # * yellow
27
+ # * blue
28
+ # * magenta
29
+ # * cyan
30
+ # * white
31
+ #
32
+ # The color is specified as a string or a symbol.
33
+ #
34
+ def typed_message( type, msg, color = nil )
35
+ type = type.to_s.rjust(13)
36
+ type = self.send(color, type) unless color.nil?
37
+ logger.info "#{type} #{msg.to_s}"
38
+ end
39
+
40
+ # Output a "create" message or an "update" message depending on whether
41
+ # the given _page_ already has a generated output file or not.
42
+ #
43
+ def create_or_update( page )
44
+ if test(?e, page.destination)
45
+ update(page.destination)
46
+ else
47
+ create(page.destination)
48
+ end
49
+ end
50
+
51
+ # Output a create message.
52
+ #
53
+ def create( msg )
54
+ typed_message('create', msg, (colorize ? :green : nil))
55
+ end
56
+
57
+ # Output an update message.
58
+ #
59
+ def update( msg )
60
+ typed_message('update', msg, (colorize ? :yellow : nil))
61
+ end
62
+
63
+ # Output a force message.
64
+ #
65
+ def force( msg )
66
+ typed_message('force', msg, (colorize ? :red : nil))
67
+ end
68
+
69
+ # Output a skip message.
70
+ #
71
+ def skip( msg )
72
+ typed_message('skip', msg, (colorize ? :yellow : nil))
73
+ end
74
+
75
+ # Output an exists message.
76
+ #
77
+ def exists( msg )
78
+ typed_message('exists', msg, (colorize ? :cyan : nil))
79
+ end
80
+
81
+ # Output an identical message.
82
+ #
83
+ def identical( msg )
84
+ typed_message('identical', msg, (colorize ? :cyan : nil))
85
+ end
86
+
87
+ [ [ :clear , 0 ],
88
+ [ :reset , 0 ], # synonym for :clear
89
+ [ :bold , 1 ],
90
+ [ :dark , 2 ],
91
+ [ :italic , 3 ], # not widely implemented
92
+ [ :underline , 4 ],
93
+ [ :underscore , 4 ], # synonym for :underline
94
+ [ :blink , 5 ],
95
+ [ :rapid_blink , 6 ], # not widely implemented
96
+ [ :negative , 7 ], # no reverse because of String#reverse
97
+ [ :concealed , 8 ],
98
+ [ :strikethrough, 9 ], # not widely implemented
99
+ [ :black , 30 ],
100
+ [ :red , 31 ],
101
+ [ :green , 32 ],
102
+ [ :yellow , 33 ],
103
+ [ :blue , 34 ],
104
+ [ :magenta , 35 ],
105
+ [ :cyan , 36 ],
106
+ [ :white , 37 ],
107
+ [ :on_black , 40 ],
108
+ [ :on_red , 41 ],
109
+ [ :on_green , 42 ],
110
+ [ :on_yellow , 43 ],
111
+ [ :on_blue , 44 ],
112
+ [ :on_magenta , 45 ],
113
+ [ :on_cyan , 46 ],
114
+ [ :on_white , 47 ] ].each do |name,code|
115
+
116
+ class_eval <<-CODE
117
+ def #{name.to_s}( str )
118
+ "\e[#{code}m\#{str}\e[0m"
119
+ end
120
+ CODE
121
+ end
122
+
123
+ end # class Journal
124
+ end # module Webby
125
+
126
+ # EOF
@@ -36,6 +36,9 @@ class Renderer
36
36
  renderer = self.new(page)
37
37
 
38
38
  loop {
39
+ FileUtils.mkdir_p ::File.dirname(page.destination)
40
+ journal.create_or_update(page)
41
+
39
42
  ::File.open(page.destination, 'w') do |fd|
40
43
  fd.write(renderer._layout_page)
41
44
  end
@@ -43,6 +46,8 @@ class Renderer
43
46
  }
44
47
  end
45
48
 
49
+ attr_reader :logger
50
+
46
51
  # call-seq:
47
52
  # Renderer.new( page )
48
53
  #
@@ -64,7 +69,7 @@ class Renderer
64
69
 
65
70
  @_bindings = []
66
71
  @_content_for = {}
67
- @log = Logging::Logger[self]
72
+ @logger = Logging::Logger[self]
68
73
  end
69
74
 
70
75
  # call-seq:
@@ -227,11 +232,11 @@ class Renderer
227
232
 
228
233
  @content
229
234
  rescue ::Webby::Error => err
230
- @log.error "while rendering page '#{@page.path}'"
231
- @log.error err.message
235
+ logger.error "while rendering page '#{@page.path}'"
236
+ logger.error err.message
232
237
  rescue => err
233
- @log.error "while rendering page '#{@page.path}'"
234
- @log.fatal err
238
+ logger.error "while rendering page '#{@page.path}'"
239
+ logger.fatal err
235
240
  exit 1
236
241
  ensure
237
242
  @content = nil
@@ -271,7 +276,7 @@ class Renderer
271
276
  @_content_for.clear
272
277
  @_bindings.clear
273
278
  else
274
- @pager.pager.done
279
+ @pager.pager.reset
275
280
  @pager = nil
276
281
  return false
277
282
  end