webgen 1.0.0.beta2 → 1.0.0.beta3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (157) hide show
  1. data/COPYING +34 -1
  2. data/Rakefile +1 -8
  3. data/data/webgen/passive_sources/default.metainfo +5 -0
  4. data/data/webgen/passive_sources/stylesheets/api.css +284 -0
  5. data/data/webgen/passive_sources/templates/api.template +151 -0
  6. data/data/webgen/passive_sources/templates/feed.template +4 -0
  7. data/lib/webgen/bundle/built-in/init.rb +12 -3
  8. data/lib/webgen/bundle_loader.rb +8 -2
  9. data/lib/webgen/cli/create_command.rb +3 -1
  10. data/lib/webgen/cli/show_tree_command.rb +4 -3
  11. data/lib/webgen/content_processor.rb +2 -2
  12. data/lib/webgen/content_processor/blocks.rb +2 -2
  13. data/lib/webgen/content_processor/haml.rb +1 -1
  14. data/lib/webgen/content_processor/html_head.rb +5 -4
  15. data/lib/webgen/content_processor/kramdown.rb +3 -1
  16. data/lib/webgen/content_processor/r_doc.rb +16 -3
  17. data/lib/webgen/content_processor/sass.rb +3 -3
  18. data/lib/webgen/content_processor/scss.rb +1 -1
  19. data/lib/webgen/content_processor/tikz.rb +2 -2
  20. data/lib/webgen/context/html_head.rb +1 -1
  21. data/lib/webgen/destination/file_system.rb +2 -1
  22. data/lib/webgen/item_tracker/node_content.rb +4 -4
  23. data/lib/webgen/item_tracker/node_meta_info.rb +6 -6
  24. data/lib/webgen/item_tracker/nodes.rb +1 -1
  25. data/lib/webgen/node.rb +5 -7
  26. data/lib/webgen/node_finder.rb +40 -17
  27. data/lib/webgen/page.rb +10 -0
  28. data/lib/webgen/path.rb +14 -14
  29. data/lib/webgen/path_handler.rb +19 -13
  30. data/lib/webgen/path_handler/api.rb +173 -0
  31. data/lib/webgen/path_handler/base.rb +33 -11
  32. data/lib/webgen/path_handler/copy.rb +2 -27
  33. data/lib/webgen/path_handler/feed.rb +4 -3
  34. data/lib/webgen/path_handler/meta_info.rb +1 -1
  35. data/lib/webgen/path_handler/page_utils.rb +4 -3
  36. data/lib/webgen/path_handler/sitemap.rb +3 -2
  37. data/lib/webgen/path_handler/virtual.rb +7 -2
  38. data/lib/webgen/tag.rb +5 -5
  39. data/lib/webgen/tag/execute_command.rb +1 -1
  40. data/lib/webgen/tag/include_file.rb +1 -1
  41. data/lib/webgen/tag/link.rb +2 -2
  42. data/lib/webgen/tag/menu.rb +1 -1
  43. data/lib/webgen/tag/meta_info.rb +1 -0
  44. data/lib/webgen/tag/relocatable.rb +1 -1
  45. data/lib/webgen/tag/tikz.rb +2 -2
  46. data/lib/webgen/task/create_website.rb +1 -1
  47. data/lib/webgen/test_helper.rb +20 -16
  48. data/lib/webgen/tree.rb +5 -1
  49. data/lib/webgen/version.rb +1 -1
  50. data/lib/webgen/website.rb +8 -8
  51. data/test/webgen/content_processor/test_kramdown.rb +7 -5
  52. data/test/webgen/content_processor/test_sass.rb +4 -0
  53. data/test/webgen/content_processor/test_scss.rb +4 -0
  54. data/test/webgen/content_processor/test_tikz.rb +6 -2
  55. data/test/webgen/destination/test_file_system.rb +3 -4
  56. data/test/webgen/item_tracker/test_missing_node.rb +3 -3
  57. data/test/webgen/item_tracker/test_node_content.rb +9 -12
  58. data/test/webgen/item_tracker/test_node_meta_info.rb +7 -11
  59. data/test/webgen/item_tracker/test_nodes.rb +11 -5
  60. data/test/webgen/path_handler/test_api.rb +111 -0
  61. data/test/webgen/path_handler/test_page_utils.rb +1 -1
  62. data/test/webgen/source/test_file_system.rb +3 -3
  63. data/test/webgen/tag/test_coderay.rb +3 -4
  64. data/test/webgen/tag/test_meta_info.rb +3 -0
  65. data/test/webgen/task/test_create_website.rb +2 -2
  66. data/test/webgen/test_item_tracker.rb +11 -16
  67. data/test/webgen/test_node.rb +2 -0
  68. data/test/webgen/test_node_finder.rb +30 -2
  69. data/test/webgen/test_page.rb +8 -0
  70. data/test/webgen/test_source.rb +11 -18
  71. data/test/webgen/test_tag.rb +1 -1
  72. data/test/webgen/test_tree.rb +8 -8
  73. metadata +8 -88
  74. data/ChangeLog +0 -23710
  75. data/data/webgen/website_bundles/default/README +0 -6
  76. data/data/webgen/website_bundles/default/src/index.page +0 -15
  77. data/data/webgen/website_bundles/style/1024px/README +0 -13
  78. data/data/webgen/website_bundles/style/1024px/src/default.css +0 -188
  79. data/data/webgen/website_bundles/style/1024px/src/default.template +0 -60
  80. data/data/webgen/website_bundles/style/1024px/src/images/background.gif +0 -0
  81. data/data/webgen/website_bundles/style/andreas00/README +0 -13
  82. data/data/webgen/website_bundles/style/andreas00/src/default.css +0 -290
  83. data/data/webgen/website_bundles/style/andreas00/src/default.template +0 -60
  84. data/data/webgen/website_bundles/style/andreas00/src/images/bg.gif +0 -0
  85. data/data/webgen/website_bundles/style/andreas00/src/images/front.jpg +0 -0
  86. data/data/webgen/website_bundles/style/andreas00/src/images/menubg.gif +0 -0
  87. data/data/webgen/website_bundles/style/andreas00/src/images/menubg2.gif +0 -0
  88. data/data/webgen/website_bundles/style/andreas01/README +0 -14
  89. data/data/webgen/website_bundles/style/andreas01/src/default.css +0 -310
  90. data/data/webgen/website_bundles/style/andreas01/src/default.template +0 -62
  91. data/data/webgen/website_bundles/style/andreas01/src/images/bg.gif +0 -0
  92. data/data/webgen/website_bundles/style/andreas01/src/images/front.jpg +0 -0
  93. data/data/webgen/website_bundles/style/andreas01/src/print.css +0 -35
  94. data/data/webgen/website_bundles/style/andreas03/README +0 -14
  95. data/data/webgen/website_bundles/style/andreas03/src/default.css +0 -223
  96. data/data/webgen/website_bundles/style/andreas03/src/default.template +0 -58
  97. data/data/webgen/website_bundles/style/andreas03/src/images/bodybg.png +0 -0
  98. data/data/webgen/website_bundles/style/andreas03/src/images/contbg.png +0 -0
  99. data/data/webgen/website_bundles/style/andreas03/src/images/footerbg.png +0 -0
  100. data/data/webgen/website_bundles/style/andreas03/src/images/gradient1.png +0 -0
  101. data/data/webgen/website_bundles/style/andreas03/src/images/gradient2.png +0 -0
  102. data/data/webgen/website_bundles/style/andreas04/README +0 -15
  103. data/data/webgen/website_bundles/style/andreas04/src/default.css +0 -290
  104. data/data/webgen/website_bundles/style/andreas04/src/default.template +0 -81
  105. data/data/webgen/website_bundles/style/andreas04/src/images/blinkarrow.gif +0 -0
  106. data/data/webgen/website_bundles/style/andreas04/src/images/bodybg.png +0 -0
  107. data/data/webgen/website_bundles/style/andreas04/src/images/contentbg.png +0 -0
  108. data/data/webgen/website_bundles/style/andreas04/src/images/entrybg.png +0 -0
  109. data/data/webgen/website_bundles/style/andreas04/src/images/flash.gif +0 -0
  110. data/data/webgen/website_bundles/style/andreas04/src/images/flash2.gif +0 -0
  111. data/data/webgen/website_bundles/style/andreas04/src/images/globe.gif +0 -0
  112. data/data/webgen/website_bundles/style/andreas04/src/images/globebottom.gif +0 -0
  113. data/data/webgen/website_bundles/style/andreas04/src/images/linkarrow.gif +0 -0
  114. data/data/webgen/website_bundles/style/andreas04/src/images/menuhover.png +0 -0
  115. data/data/webgen/website_bundles/style/andreas05/README +0 -14
  116. data/data/webgen/website_bundles/style/andreas05/src/default.css +0 -33
  117. data/data/webgen/website_bundles/style/andreas05/src/default.template +0 -40
  118. data/data/webgen/website_bundles/style/andreas05/src/images/bodybg.gif +0 -0
  119. data/data/webgen/website_bundles/style/andreas05/src/images/front.png +0 -0
  120. data/data/webgen/website_bundles/style/andreas06/README +0 -14
  121. data/data/webgen/website_bundles/style/andreas06/src/default.css +0 -356
  122. data/data/webgen/website_bundles/style/andreas06/src/default.template +0 -70
  123. data/data/webgen/website_bundles/style/andreas06/src/images/bodybg.gif +0 -0
  124. data/data/webgen/website_bundles/style/andreas06/src/images/boxbg.gif +0 -0
  125. data/data/webgen/website_bundles/style/andreas06/src/images/greypx.gif +0 -0
  126. data/data/webgen/website_bundles/style/andreas06/src/images/header.jpg +0 -0
  127. data/data/webgen/website_bundles/style/andreas06/src/images/innerbg.gif +0 -0
  128. data/data/webgen/website_bundles/style/andreas06/src/images/leaves.jpg +0 -0
  129. data/data/webgen/website_bundles/style/andreas06/src/images/tabs.gif +0 -0
  130. data/data/webgen/website_bundles/style/andreas07/README +0 -15
  131. data/data/webgen/website_bundles/style/andreas07/src/browserfix.css +0 -7
  132. data/data/webgen/website_bundles/style/andreas07/src/default.css +0 -92
  133. data/data/webgen/website_bundles/style/andreas07/src/default.template +0 -42
  134. data/data/webgen/website_bundles/style/andreas07/src/images/bodybg.gif +0 -0
  135. data/data/webgen/website_bundles/style/andreas07/src/images/sidebarbg.gif +0 -0
  136. data/data/webgen/website_bundles/style/andreas08/README +0 -14
  137. data/data/webgen/website_bundles/style/andreas08/src/default.css +0 -224
  138. data/data/webgen/website_bundles/style/andreas08/src/default.template +0 -51
  139. data/data/webgen/website_bundles/style/andreas09/README +0 -14
  140. data/data/webgen/website_bundles/style/andreas09/src/default.css +0 -308
  141. data/data/webgen/website_bundles/style/andreas09/src/default.template +0 -68
  142. data/data/webgen/website_bundles/style/andreas09/src/images/bodybg-black.jpg +0 -0
  143. data/data/webgen/website_bundles/style/andreas09/src/images/bodybg-green.jpg +0 -0
  144. data/data/webgen/website_bundles/style/andreas09/src/images/bodybg-orange.jpg +0 -0
  145. data/data/webgen/website_bundles/style/andreas09/src/images/bodybg-purple.jpg +0 -0
  146. data/data/webgen/website_bundles/style/andreas09/src/images/bodybg-red.jpg +0 -0
  147. data/data/webgen/website_bundles/style/andreas09/src/images/bodybg.jpg +0 -0
  148. data/data/webgen/website_bundles/style/andreas09/src/images/footerbg.jpg +0 -0
  149. data/data/webgen/website_bundles/style/andreas09/src/images/menuhover-black.jpg +0 -0
  150. data/data/webgen/website_bundles/style/andreas09/src/images/menuhover-green.jpg +0 -0
  151. data/data/webgen/website_bundles/style/andreas09/src/images/menuhover-orange.jpg +0 -0
  152. data/data/webgen/website_bundles/style/andreas09/src/images/menuhover-purple.jpg +0 -0
  153. data/data/webgen/website_bundles/style/andreas09/src/images/menuhover-red.jpg +0 -0
  154. data/data/webgen/website_bundles/style/andreas09/src/images/menuhover.jpg +0 -0
  155. data/data/webgen/website_bundles/style/simple/README +0 -6
  156. data/data/webgen/website_bundles/style/simple/src/default.css +0 -84
  157. data/data/webgen/website_bundles/style/simple/src/default.template +0 -36
@@ -44,7 +44,11 @@
44
44
  <title><%= h(context.node['title']) %></title>
45
45
  <link><%= context.node.feed_link %>"</link>
46
46
  <description><%= h(context.node['description']) %></description>
47
+ <% if context.node['created_at'].kind_of?(Time) %>
48
+ <pubdate><%= context.node['created_at'].rfc822 %></pubdate>
49
+ <% else %>
47
50
  <pubDate><%= Time.now.rfc822 %></pubDate>
51
+ <% end %>
48
52
  <lastBuildDate><%= Time.now.rfc822 %></lastBuildDate>
49
53
  <generator>webgen - Webgen::PathHandler::Feed</generator>
50
54
 
@@ -153,8 +153,8 @@ item_tracker.register('NodeContent')
153
153
 
154
154
  item_tracker.register('NodeMetaInfo')
155
155
  website.blackboard.add_listener(:after_node_created) do |node|
156
- item_tracker.add(node, :node_meta_info, node.alcn)
157
- item_tracker.add(node, :node_meta_info, node.alcn, Webgen::ItemTracker::NodeMetaInfo::CONTENT_MODIFICATION_KEY)
156
+ item_tracker.add(node, :node_meta_info, node)
157
+ item_tracker.add(node, :node_meta_info, node, Webgen::ItemTracker::NodeMetaInfo::CONTENT_MODIFICATION_KEY)
158
158
  end
159
159
 
160
160
  item_tracker.register('Nodes')
@@ -169,11 +169,18 @@ website.blackboard.add_listener(:node_resolution_failed) do |path, lang|
169
169
  end
170
170
  end
171
171
 
172
+ ########################################################################
173
+ # The link definitions extension
174
+ website.ext.link_definitions = {}
175
+
176
+
172
177
  ########################################################################
173
178
  # Everything related to the node finder extension
174
179
  require 'webgen/node_finder'
175
180
 
176
181
  website.ext.node_finder = Webgen::NodeFinder.new(website)
182
+ option('node_finder.option_sets', {},
183
+ 'Node finder option sets that can be referenced by name')
177
184
 
178
185
 
179
186
  ########################################################################
@@ -206,7 +213,6 @@ option('path_handler.default_template', 'default.template',
206
213
  website.ext.path_handler = path_handler = Webgen::PathHandler.new(website)
207
214
 
208
215
  # handlers are registered in invocation order
209
-
210
216
  path_handler.register('Directory')
211
217
  path_handler.register('MetaInfo', :patterns => ['/**/metainfo', '/**/*.metainfo'])
212
218
  path_handler.register('Template')
@@ -215,6 +221,7 @@ path_handler.register('Copy')
215
221
  path_handler.register('Feed')
216
222
  path_handler.register('Sitemap')
217
223
  path_handler.register('Virtual')
224
+ path_handler.register('Api')
218
225
 
219
226
 
220
227
  ########################################################################
@@ -260,6 +267,8 @@ option('tag.date.format', '%Y-%m-%d %H:%M:%S',
260
267
  tag.register('MetaInfo', :names => ['meta_info', :default])
261
268
  option('tag.meta_info.escape_html', true,
262
269
  'Special HTML characters in the output will be escaped if true', &true_or_false)
270
+ option('tag.meta_info.mi', nil,
271
+ 'The name of the meta information that should be output', &is_string)
263
272
 
264
273
  tag.register('Relocatable', :names => ['relocatable', 'r'], :mandatory => ['path'])
265
274
  option('tag.relocatable.path', nil,
@@ -44,11 +44,17 @@ module Webgen
44
44
 
45
45
  # Loads all bundles that are marked for auto-loading.
46
46
  def load_autoload_bundles
47
- Gem::Specification.map {|s| s.name }.uniq.each do |gem_name|
47
+ bundles = Gem::Specification.map {|s| s.name }.uniq.map do |gem_name|
48
48
  md = /^webgen-(.*)-bundle$/.match(gem_name)
49
49
  next unless md
50
+ md[1]
51
+ end.compact
50
52
 
51
- bundle_name = md[1]
53
+ bundles += $LOAD_PATH.map do |path|
54
+ Dir[File.join(path, 'webgen/bundle', '*')].map {|d| File.basename(d)}
55
+ end.flatten.compact
56
+
57
+ bundles.each do |bundle_name|
52
58
  file = resolve_init_file(bundle_name)
53
59
  next unless file
54
60
 
@@ -1,6 +1,7 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
 
3
3
  require 'webgen/cli/utils'
4
+ require 'tmpdir'
4
5
 
5
6
  module Webgen
6
7
  module CLI
@@ -48,8 +49,9 @@ DESC
48
49
  raise OptionParser::MissingArgument.new('DIR') if args.length == 0
49
50
  Webgen::Website.new(args[0], Webgen::CLI::Logger.new) do |website|
50
51
  website.logger.verbose = commandparser.verbose
52
+ website.config['website.tmpdir'] = Dir.tmpdir
51
53
  end.execute_task(:create_website, @template)
52
- puts "Created a new webgen website in <#{args[0]}>" + (@template ? "using the '#{template}' template" : '')
54
+ puts "Created a new webgen website in <#{args[0]}>" + (@template ? " using the '#{@template}' template" : '')
53
55
  rescue Webgen::Task::CreateWebsite::Error => e
54
56
  puts "An error occured while creating the website: #{e.message}"
55
57
  end
@@ -56,10 +56,11 @@ DESC
56
56
  children.sort {|a,b| a.alcn <=> b.alcn}.map do |node|
57
57
  sub = collect_data(node.children, selector)
58
58
  if sub.length > 0 ||
59
- ((selector.nil? || node.lcn.include?(selector)) &&
59
+ ((selector.nil? || node.alcn.include?(selector)) &&
60
60
  ((!node.is_fragment? || @show_fragments) &&
61
61
  (!node['passive'] || commandparser.website.ext.item_tracker.node_referenced?(node))))
62
62
  data = [@use_alcn ? node.alcn : node.lcn]
63
+ data << node.alcn
63
64
  data << (@meta_info ? node.meta_info.map {|k,v| "#{k}: #{v.inspect}"} : [])
64
65
  data << sub
65
66
  data
@@ -71,9 +72,9 @@ DESC
71
72
  private :collect_data
72
73
 
73
74
  def print_tree(data, indent = '', selector)
74
- data.each do |name, info, children|
75
+ data.each do |name, alcn, info, children|
75
76
  puts("#{indent}#{Utils.light(Utils.blue(name))}")
76
- info.each {|i| puts("#{indent} #{i}")} if info.length > 0 && (selector.nil? || name.include?(selector))
77
+ info.each {|i| puts("#{indent} #{i}")} if info.length > 0 && (selector.nil? || alcn.include?(selector))
77
78
  print_tree(children, indent + ' ', selector)
78
79
  end
79
80
  end
@@ -104,10 +104,10 @@ module Webgen
104
104
  extension(name).call(context)
105
105
  rescue Webgen::Error => e
106
106
  e.path = context.dest_node if e.path.to_s.empty?
107
+ e.location = "content_processor.#{name}" unless e.location
107
108
  raise
108
109
  rescue Exception => e
109
- ext = extension(name)
110
- raise Webgen::RenderError.new(e, (ext.respond_to?(:name) ? ext.name : nil), context.dest_node)
110
+ raise Webgen::RenderError.new(e, "content_processor.#{name}", context.dest_node)
111
111
  end
112
112
 
113
113
  # Normalize the content processor pipeline.
@@ -77,11 +77,11 @@ module Webgen
77
77
  return ''
78
78
  elsif block_node
79
79
  raise Webgen::RenderError.new("No block named '#{options[:name]}' found in <#{block_node}>",
80
- self.name, context.dest_node,
80
+ 'content_processor.blocks', context.dest_node,
81
81
  context.ref_node, (options[:line_nr_proc].call if options[:line_nr_proc]))
82
82
  else
83
83
  raise Webgen::RenderError.new("No node in the render chain has a block named '#{options[:name]}'",
84
- self.name, context.dest_node,
84
+ 'content_processor.blocks', context.dest_node,
85
85
  context.ref_node, (options[:line_nr_proc].call if options[:line_nr_proc]))
86
86
  end
87
87
  end
@@ -16,7 +16,7 @@ module Webgen
16
16
  context
17
17
  rescue ::Haml::Error => e
18
18
  line = (e.line ? e.line + 1 : Webgen::Error.error_line(e))
19
- raise Webgen::RenderError.new(e, self.class.name, context.dest_node, nil, line)
19
+ raise Webgen::RenderError.new(e, 'content_processor.haml', context.dest_node, nil, line)
20
20
  end
21
21
 
22
22
  end
@@ -14,11 +14,12 @@ module Webgen
14
14
  # processor should be the last in the processing pipeline so that all other processors have been
15
15
  # able to set the data.
16
16
  #
17
- # Use the methods defined on the special Context#html_head object to provide values.
17
+ # Use the methods defined on the special Webgen::Context::HtmlHead::Proxy object which can be
18
+ # accessed via Webgen::Context#html_head to provide values.
18
19
  #
19
20
  # == Internal details
20
21
  #
21
- # The key ':cp_html_head' of 'context.persistent' is used (the normal 'context.options' won't do
22
+ # The key +:cp_html_head+ of +context.persistent+ is used (the normal +context.options+ won't do
22
23
  # because the data needs to be shared 'backwards' during the rendering) and it has to be a Hash
23
24
  # with the following values:
24
25
  #
@@ -85,7 +86,7 @@ module Webgen
85
86
  def self.links_to_translations(context)
86
87
  context.website.tree.translations(context.dest_node).map do |node|
87
88
  next '' if node.alcn == context.dest_node.alcn
88
- context.website.ext.item_tracker.add(context.dest_node, :node_meta_info, node.alcn)
89
+ context.website.ext.item_tracker.add(context.dest_node, :node_meta_info, node)
89
90
 
90
91
  result = "\n<link type=\"text/html\" rel=\"alternate\" hreflang=\"#{node.lang}\" "
91
92
  result << "href=\"#{context.dest_node.route_to(node)}\" "
@@ -103,7 +104,7 @@ module Webgen
103
104
  next path if Webgen::Path.url(path, false).absolute?
104
105
  node = context.content_node.resolve(path, context.dest_node.lang, true)
105
106
  if node
106
- context.website.ext.item_tracker.add(context.dest_node, :node_meta_info, node.alcn)
107
+ context.website.ext.item_tracker.add(context.dest_node, :node_meta_info, node)
107
108
  context.dest_node.route_to(node)
108
109
  else
109
110
  nil
@@ -35,7 +35,9 @@ module Webgen
35
35
 
36
36
  # Convert the content in +context+ to HTML.
37
37
  def self.call(context)
38
- doc = ::Kramdown::Document.new(context.content, context.website.config['content_processor.kramdown.options'])
38
+ options = context.website.config['content_processor.kramdown.options'].dup
39
+ options[:link_defs] = context.website.ext.link_definitions.merge(options[:link_defs] || {})
40
+ doc = ::Kramdown::Document.new(context.content, options)
39
41
  context.content = CustomHtmlConverter.new(doc.root, doc.options, context).convert(doc.root)
40
42
  doc.warnings.each do |warn|
41
43
  context.website.logger.warn { "kramdown warning while parsing <#{context.ref_node}>: #{warn}" }
@@ -1,18 +1,31 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
 
3
3
  require 'webgen/content_processor'
4
- webgen_require 'rdoc/markup/to_html', 'rdoc'
4
+
5
+ ### Hack...
6
+ # Workaround to load the correct version of rdoc. Unusable versions don't have a rdoc/store file and
7
+ # so we can use this to our advantage.
8
+ begin
9
+ # If a useable version is available, this won't fail with a LoadError (but probably a NameError)
10
+ # and will activate the correct version, even if installed via Rubygems.
11
+ require 'rdoc/store'
12
+ rescue LoadError
13
+ webgen_require('rdoc/rdoc', 'rdoc')
14
+ rescue Exception
15
+ end
16
+ require 'rdoc/rdoc'
17
+
5
18
 
6
19
  module Webgen
7
20
  class ContentProcessor
8
21
 
9
22
  # Converts content in RDoc markup (the native Ruby documentation format) to HTML. Needs the newer
10
- # RDoc implementation (version >= 2.4.x).
23
+ # RDoc implementation (version >= 4.0.0).
11
24
  module RDoc
12
25
 
13
26
  # Convert the content in RDoc markup to HTML.
14
27
  def self.call(context)
15
- context.content = ::RDoc::Markup::ToHtml.new.convert(context.content)
28
+ context.content = ::RDoc::Markup::ToHtml.new(::RDoc::Options.new).convert(context.content)
16
29
  context
17
30
  end
18
31
 
@@ -110,7 +110,7 @@ module Webgen
110
110
 
111
111
  if ref_node
112
112
  if dest_node = ref_node.resolve(path, context.dest_node.lang, true)
113
- context.website.ext.item_tracker.add(context.dest_node, :node_meta_info, dest_node.alcn)
113
+ context.website.ext.item_tracker.add(context.dest_node, :node_meta_info, dest_node)
114
114
  path = context.dest_node.route_to(dest_node)
115
115
  end
116
116
  else
@@ -127,7 +127,7 @@ module Webgen
127
127
  context.content = ::Sass::Engine.new(context.content, default_options(context)).render
128
128
  context
129
129
  rescue ::Sass::SyntaxError => e
130
- raise Webgen::RenderError.new(e, self.class.name, context.dest_node, nil, (e.sass_line if e.sass_line))
130
+ raise Webgen::RenderError.new(e, 'content_processor.sass', context.dest_node, nil, (e.sass_line if e.sass_line))
131
131
  end
132
132
 
133
133
  def self.default_options(context) # :nodoc:
@@ -136,7 +136,7 @@ module Webgen
136
136
  opts.merge({
137
137
  :filename => context.ref_node.alcn,
138
138
  :syntax => :sass,
139
- :cache_store => ::Sass::CacheStores::Filesystem.new(context.website.tmpdir('sass')),
139
+ :cache_store => ::Sass::CacheStores::Filesystem.new(context.website.tmpdir('content_processor.sass')),
140
140
  :filesystem_importer => FileSystemImporter,
141
141
  :load_paths => load_paths,
142
142
  :webgen_context => context
@@ -14,7 +14,7 @@ module Webgen
14
14
  context.content = ::Sass::Engine.new(context.content, options).render
15
15
  context
16
16
  rescue ::Sass::SyntaxError => e
17
- raise Webgen::RenderError.new(e, self.class.name, context.dest_node, nil, (e.sass_line if e.sass_line))
17
+ raise Webgen::RenderError.new(e, 'content_processor.scss', context.dest_node, nil, (e.sass_line if e.sass_line))
18
18
  end
19
19
 
20
20
  end
@@ -56,7 +56,7 @@ module Webgen
56
56
  execute("pdflatex -shell-escape -interaction=nonstopmode -halt-on-error #{file}.tex", cwd, context) do |status, stdout, stderr|
57
57
  errors = (stdout+stderr).scan(/^!(.*\n.*)/).join("\n")
58
58
  raise Webgen::RenderError.new("Error while parsing TikZ picture commands with PDFLaTeX: #{errors}",
59
- self.name, context.dest_node, context.ref_node)
59
+ 'content_processor.tikz', context.dest_node, context.ref_node)
60
60
  end
61
61
 
62
62
  execute("pdfcrop #{file}.pdf #{file}.pdf", cwd, context)
@@ -93,7 +93,7 @@ module Webgen
93
93
  yield(status, stdout, stderr)
94
94
  else
95
95
  raise Webgen::RenderError.new("Error while running a command for a TikZ picture: #{stdout + "\n" + stderr}",
96
- self.name, context.dest_node, context.ref_node)
96
+ 'content_processor.tikz', context.dest_node, context.ref_node)
97
97
  end
98
98
  end
99
99
  [status, stdout, stderr]
@@ -43,7 +43,7 @@ module Webgen
43
43
  def type_check!(type) #:nodoc:
44
44
  if ![:css, :js].include?(type)
45
45
  raise Webgen::RenderError.new("Type must either be :css or :js, not #{type}",
46
- self.class.name, @context.dest_node, @context.ref_node)
46
+ "context.html_head", @context.dest_node, @context.ref_node)
47
47
  end
48
48
  end
49
49
  private :type_check!
@@ -37,7 +37,8 @@ module Webgen
37
37
  # Write the +data+ to the given +path+.
38
38
  def write(path, data)
39
39
  dest = File.join(@root, path)
40
- FileUtils.makedirs(File.dirname(dest))
40
+ parent_dir = File.dirname(dest)
41
+ FileUtils.makedirs(parent_dir) unless File.directory?(parent_dir)
41
42
  if path[-1] == ?/
42
43
  FileUtils.makedirs(dest)
43
44
  else
@@ -8,9 +8,9 @@ module Webgen
8
8
  # This class is used to track changes to the content of a node. The content of a node is changed
9
9
  # if any of its dependencies are changed.
10
10
  #
11
- # The item for this tracker is the alcn of the node:
11
+ # The item for this tracker is the node:
12
12
  #
13
- # website.ext.item_tracker.add(some_node, :node_content, my_node.alcn)
13
+ # website.ext.item_tracker.add(some_node, :node_content, my_node)
14
14
  #
15
15
  class NodeContent
16
16
 
@@ -18,8 +18,8 @@ module Webgen
18
18
  @website = website
19
19
  end
20
20
 
21
- def item_id(alcn) #:nodoc:
22
- alcn
21
+ def item_id(node) #:nodoc:
22
+ node.alcn
23
23
  end
24
24
 
25
25
  def item_data(alcn) #:nodoc:
@@ -9,17 +9,17 @@ module Webgen
9
9
  #
10
10
  # Depending on what should be tracked, one needs to provide the following item:
11
11
  #
12
- # [node_alcn, nil]
12
+ # [node, nil]
13
13
  # Tracks changes to the whole meta information of the node, i.e. if any meta information value
14
14
  # changes, a change is detected.
15
15
  #
16
- # [node_alcn, key]
16
+ # [node, key]
17
17
  # Tracks changes to a specific meta information key of the node.
18
18
  #
19
19
  # Here are some examples:
20
20
  #
21
- # website.ext.item_tracker.add(some_node, :node_meta_info, my_node.alcn) # first case
22
- # website.ext.item_tracker.add(some_node, :node_meta_info, my_node.alcn, 'title') # second case
21
+ # website.ext.item_tracker.add(some_node, :node_meta_info, my_node) # first case
22
+ # website.ext.item_tracker.add(some_node, :node_meta_info, my_node, 'title') # second case
23
23
  #
24
24
  class NodeMetaInfo
25
25
 
@@ -29,8 +29,8 @@ module Webgen
29
29
  @website = website
30
30
  end
31
31
 
32
- def item_id(alcn, key = nil) #:nodoc:
33
- [alcn, key]
32
+ def item_id(node, key = nil) #:nodoc:
33
+ [node.alcn, key]
34
34
  end
35
35
 
36
36
  def item_data(alcn, key = nil) #:nodoc:
@@ -51,7 +51,7 @@ module Webgen
51
51
  method_name, options, type = *iid
52
52
  nodes = node_list(method_name, options)
53
53
  old_data != nodes_to_alcn(nodes) ||
54
- nodes.flatten.any? {|n| type == :content ? @website.ext.item_tracker.node_changed?(n) : @website.ext.item_tracker.item_changed?(:node_meta_info, n.alcn)}
54
+ nodes.flatten.any? {|n| type == :content ? @website.ext.item_tracker.node_changed?(n) : @website.ext.item_tracker.item_changed?(:node_meta_info, n)}
55
55
  end
56
56
 
57
57
  def referenced_nodes(iid, alcn_list) #:nodoc:
@@ -12,6 +12,8 @@ module Webgen
12
12
  # information is available through the #[] and #meta_info accessors, the internal processing
13
13
  # information through the #node_info accessor.
14
14
  #
15
+ # This class is not directly used. Instead path handlers define sub-classes that provide handler
16
+ # specific methods. See the basic sub-class Webgen::PathHandler::Base::Node.
15
17
  class Node
16
18
 
17
19
  # The parent node. This is in all but one case a Node object. The one exception is that the
@@ -167,7 +169,8 @@ module Webgen
167
169
  # If the +lang+ parameter is not used, it defaults to the language of the current node.
168
170
  def route_to(node, lang = @lang)
169
171
  my_url = Webgen::Path.url(@dest_path)
170
- other_url = Webgen::Path.url(node.proxy_node(lang).dest_path)
172
+ pnode = node.proxy_node(lang)
173
+ other_url = Webgen::Path.url(pnode['routing_path'] || pnode.dest_path)
171
174
 
172
175
  # resolve any '.' and '..' paths in the target url
173
176
  if other_url.path =~ /\/\.\.?\// && other_url.scheme == 'webgen'
@@ -185,12 +188,7 @@ module Webgen
185
188
  #
186
189
  # If the +lang+ parameter is not used, it defaults to the language of the current node.
187
190
  def proxy_node(lang = @lang)
188
- proxy_path = self['proxy_path']
189
- if proxy_path.nil?
190
- self
191
- else
192
- resolve(proxy_path, lang, true) || self
193
- end
191
+ self['proxy_path'] && resolve(self['proxy_path'], lang, true) || self
194
192
  end
195
193
 
196
194
  # Return a HTML link from this node to the given node.
@@ -61,6 +61,9 @@ module Webgen
61
61
  # the value of this meta information is used for comparison of nodes (again, if both compared
62
62
  # values are integers, a numeric comparison is done, else a string comparison).
63
63
  #
64
+ # [:reverse]
65
+ # Value: +true+ of +false+/+nil+. If this option is set to +true+, the sort order is reversed.
66
+ #
64
67
  # === Filter options
65
68
  #
66
69
  # These options are used for filtering the nodes. All nodes are used by default if no filter
@@ -71,9 +74,9 @@ module Webgen
71
74
  # used.
72
75
  #
73
76
  # [:lang]
74
- # Value: a language code/+nil+/the special value :+node+ or an array of these values. Nodes that
77
+ # Value: a language code/+nil+/the special value +node+ or an array of these values. Nodes that
75
78
  # have one of the specified language codes, are language independent (in case of the value
76
- # +nil+) or have the same language as the reference node (in case of the value :+node+) are
79
+ # +nil+) or have the same language as the reference node (in case of the value +node+) are
77
80
  # used.
78
81
  #
79
82
  # [:mi]
@@ -97,6 +100,9 @@ module Webgen
97
100
  # and end levels). All nodes whose hierarchy level in the node tree are greater than or equal to
98
101
  # the start level and lower than or equal to the end level are used.
99
102
  #
103
+ # Negative numbers, where -1 stands for the reference node, -2 for its parent node and so on,
104
+ # can also be used.
105
+ #
100
106
  # [:ancestors]
101
107
  # Value: +true+ or +false+/+nil+. If this filter option is set to +true+, only nodes that are
102
108
  # ancestors of the reference node are used. The reference node itself is used as well.
@@ -106,8 +112,17 @@ module Webgen
106
112
  # descendants of the reference node are used. The reference node itself is used as well.
107
113
  #
108
114
  # [:siblings]
109
- # Value: +true+ or +false+/+nil+. If this filter option is set to +true+, only nodes that are
110
- # siblings of the reference are node used. The reference node itself is used as well.
115
+ # Value: +true+, +false+/+nil+, or an array with two integers. If this filter option is set to
116
+ # +true+, only nodes that are sibling node of the reference node are used. The reference node
117
+ # itself is used as well. If set to +false+ or +nil+, this filter is ignored.
118
+ #
119
+ # If an array with two numbers is specified, all sibling nodes of the reference node or its
120
+ # parent nodes the hierarchy level of which lies between these numbers are used. The parent
121
+ # nodes and the reference node are used as well if their level lies between the numbers.
122
+ # Counting starts at zero (the root node).
123
+ #
124
+ # Negative numbers, where -1 stands for the reference node, -2 for its parent node and so on,
125
+ # can also be used.
111
126
  #
112
127
  # == Implementing a filter module
113
128
  #
@@ -177,14 +192,14 @@ module Webgen
177
192
  end
178
193
  opts = prepare_options_hash(opts_or_name)
179
194
 
180
- limit, offset, flatten, sort, levels = remove_non_filter_options(opts)
195
+ limit, offset, flatten, sort, levels, reverse = remove_non_filter_options(opts)
181
196
  flatten = true if limit || offset
182
197
  levels = [levels || [1, 1_000_000]].flatten.map {|i| i.to_i}
183
198
 
184
199
  nodes = filter_nodes(opts, ref_node)
185
200
 
186
201
  if flatten
187
- sort_nodes(nodes, sort)
202
+ sort_nodes(nodes, sort, reverse)
188
203
  nodes = nodes[(offset.to_s.to_i)..(limit ? offset.to_s.to_i + limit.to_s.to_i - 1 : -1)] if limit || offset
189
204
  else
190
205
  result = {}
@@ -208,7 +223,7 @@ module Webgen
208
223
  end
209
224
  end
210
225
  nodes = reducer.call(result, 1)
211
- sort_nodes(nodes, sort, false)
226
+ sort_nodes(nodes, sort, reverse, false)
212
227
  end
213
228
 
214
229
  cache_result(opts_or_name, ref_node, nodes)
@@ -237,7 +252,8 @@ module Webgen
237
252
  end
238
253
 
239
254
  def remove_non_filter_options(opts)
240
- [opts.delete(:limit), opts.delete(:offset), opts.delete(:flatten), opts.delete(:sort), opts.delete(:levels)]
255
+ [opts.delete(:limit), opts.delete(:offset), opts.delete(:flatten),
256
+ opts.delete(:sort), opts.delete(:levels), opts.delete(:reverse)]
241
257
  end
242
258
 
243
259
  def filter_nodes(opts, ref_node)
@@ -255,23 +271,23 @@ module Webgen
255
271
  nodes
256
272
  end
257
273
 
258
- def sort_nodes(nodes, sort, flat_mode = true)
274
+ def sort_nodes(nodes, sort, reverse, flat_mode = true)
259
275
  return unless sort
260
276
  if sort == true
261
277
  nodes.sort! do |(a,_),(b,_)|
262
278
  a = (a['sort_info'] && a['sort_info'].to_s) || a['title'].to_s || ''
263
279
  b = (b['sort_info'] && b['sort_info'].to_s) || b['title'].to_s || ''
264
280
  (a = a.to_i; b = b.to_i) if a !~ /\D/ && b !~ /\D/
265
- a <=> b
281
+ (reverse ? b <=> a : a <=> b)
266
282
  end
267
283
  else
268
284
  nodes.sort! do |(a,_),(b,_)|
269
285
  a, b = a[sort].to_s, b[sort].to_s
270
286
  a, b = a.to_i, b.to_i if a !~ /\D/ && b !~ /\D/
271
- a <=> b
287
+ (reverse ? b <=> a : a <=> b)
272
288
  end
273
289
  end
274
- nodes.each {|n, children| sort_nodes(children, sort, flat_mode) if children } unless flat_mode
290
+ nodes.each {|n, children| sort_nodes(children, sort, reverse, flat_mode) if children } unless flat_mode
275
291
  end
276
292
 
277
293
  # :section: Filter methods
@@ -313,12 +329,12 @@ module Webgen
313
329
  end
314
330
 
315
331
  def filter_absolute_levels(nodes, ref_node, range)
316
- range = [range].flatten.map {|i| i.to_i}
332
+ range = [range].flatten.map {|i| (i = i.to_i) < 0 ? ref_node.level + 1 + i : i}
317
333
  nodes.keep_if {|n| n.level >= range.first && n.level <= range.last}
318
334
  end
319
335
 
320
336
  def filter_lang(nodes, ref_node, langs)
321
- langs = [langs].flatten.map {|l| l == :node ? ref_node.lang : l}.uniq
337
+ langs = [langs].flatten.map {|l| l == 'node' ? ref_node.lang : l}.uniq
322
338
  nodes.keep_if {|n| langs.any? {|l| n.lang == l}}
323
339
  end
324
340
 
@@ -341,9 +357,16 @@ module Webgen
341
357
  end
342
358
  end
343
359
 
344
- def filter_siblings(nodes, ref_node, enabled)
345
- return nodes unless enabled
346
- nodes.keep_if { |n| n.parent == ref_node.parent}
360
+ def filter_siblings(nodes, ref_node, value)
361
+ return nodes unless value
362
+ if value == true
363
+ nodes.keep_if {|n| n.parent == ref_node.parent}
364
+ else
365
+ value = [value].flatten.map {|i| (i = i.to_i) < 0 ? ref_node.level + 1 + i : i}
366
+ nodes.keep_if do |n|
367
+ n.level >= value.first && n.level <= value.last && (n.parent.is_ancestor_of?(ref_node) || n.is_root?)
368
+ end
369
+ end
347
370
  end
348
371
 
349
372
  end