webgen 1.0.0.beta2 → 1.0.0.beta3
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.
- data/COPYING +34 -1
- data/Rakefile +1 -8
- data/data/webgen/passive_sources/default.metainfo +5 -0
- data/data/webgen/passive_sources/stylesheets/api.css +284 -0
- data/data/webgen/passive_sources/templates/api.template +151 -0
- data/data/webgen/passive_sources/templates/feed.template +4 -0
- data/lib/webgen/bundle/built-in/init.rb +12 -3
- data/lib/webgen/bundle_loader.rb +8 -2
- data/lib/webgen/cli/create_command.rb +3 -1
- data/lib/webgen/cli/show_tree_command.rb +4 -3
- data/lib/webgen/content_processor.rb +2 -2
- data/lib/webgen/content_processor/blocks.rb +2 -2
- data/lib/webgen/content_processor/haml.rb +1 -1
- data/lib/webgen/content_processor/html_head.rb +5 -4
- data/lib/webgen/content_processor/kramdown.rb +3 -1
- data/lib/webgen/content_processor/r_doc.rb +16 -3
- data/lib/webgen/content_processor/sass.rb +3 -3
- data/lib/webgen/content_processor/scss.rb +1 -1
- data/lib/webgen/content_processor/tikz.rb +2 -2
- data/lib/webgen/context/html_head.rb +1 -1
- data/lib/webgen/destination/file_system.rb +2 -1
- data/lib/webgen/item_tracker/node_content.rb +4 -4
- data/lib/webgen/item_tracker/node_meta_info.rb +6 -6
- data/lib/webgen/item_tracker/nodes.rb +1 -1
- data/lib/webgen/node.rb +5 -7
- data/lib/webgen/node_finder.rb +40 -17
- data/lib/webgen/page.rb +10 -0
- data/lib/webgen/path.rb +14 -14
- data/lib/webgen/path_handler.rb +19 -13
- data/lib/webgen/path_handler/api.rb +173 -0
- data/lib/webgen/path_handler/base.rb +33 -11
- data/lib/webgen/path_handler/copy.rb +2 -27
- data/lib/webgen/path_handler/feed.rb +4 -3
- data/lib/webgen/path_handler/meta_info.rb +1 -1
- data/lib/webgen/path_handler/page_utils.rb +4 -3
- data/lib/webgen/path_handler/sitemap.rb +3 -2
- data/lib/webgen/path_handler/virtual.rb +7 -2
- data/lib/webgen/tag.rb +5 -5
- data/lib/webgen/tag/execute_command.rb +1 -1
- data/lib/webgen/tag/include_file.rb +1 -1
- data/lib/webgen/tag/link.rb +2 -2
- data/lib/webgen/tag/menu.rb +1 -1
- data/lib/webgen/tag/meta_info.rb +1 -0
- data/lib/webgen/tag/relocatable.rb +1 -1
- data/lib/webgen/tag/tikz.rb +2 -2
- data/lib/webgen/task/create_website.rb +1 -1
- data/lib/webgen/test_helper.rb +20 -16
- data/lib/webgen/tree.rb +5 -1
- data/lib/webgen/version.rb +1 -1
- data/lib/webgen/website.rb +8 -8
- data/test/webgen/content_processor/test_kramdown.rb +7 -5
- data/test/webgen/content_processor/test_sass.rb +4 -0
- data/test/webgen/content_processor/test_scss.rb +4 -0
- data/test/webgen/content_processor/test_tikz.rb +6 -2
- data/test/webgen/destination/test_file_system.rb +3 -4
- data/test/webgen/item_tracker/test_missing_node.rb +3 -3
- data/test/webgen/item_tracker/test_node_content.rb +9 -12
- data/test/webgen/item_tracker/test_node_meta_info.rb +7 -11
- data/test/webgen/item_tracker/test_nodes.rb +11 -5
- data/test/webgen/path_handler/test_api.rb +111 -0
- data/test/webgen/path_handler/test_page_utils.rb +1 -1
- data/test/webgen/source/test_file_system.rb +3 -3
- data/test/webgen/tag/test_coderay.rb +3 -4
- data/test/webgen/tag/test_meta_info.rb +3 -0
- data/test/webgen/task/test_create_website.rb +2 -2
- data/test/webgen/test_item_tracker.rb +11 -16
- data/test/webgen/test_node.rb +2 -0
- data/test/webgen/test_node_finder.rb +30 -2
- data/test/webgen/test_page.rb +8 -0
- data/test/webgen/test_source.rb +11 -18
- data/test/webgen/test_tag.rb +1 -1
- data/test/webgen/test_tree.rb +8 -8
- metadata +8 -88
- data/ChangeLog +0 -23710
- data/data/webgen/website_bundles/default/README +0 -6
- data/data/webgen/website_bundles/default/src/index.page +0 -15
- data/data/webgen/website_bundles/style/1024px/README +0 -13
- data/data/webgen/website_bundles/style/1024px/src/default.css +0 -188
- data/data/webgen/website_bundles/style/1024px/src/default.template +0 -60
- data/data/webgen/website_bundles/style/1024px/src/images/background.gif +0 -0
- data/data/webgen/website_bundles/style/andreas00/README +0 -13
- data/data/webgen/website_bundles/style/andreas00/src/default.css +0 -290
- data/data/webgen/website_bundles/style/andreas00/src/default.template +0 -60
- data/data/webgen/website_bundles/style/andreas00/src/images/bg.gif +0 -0
- data/data/webgen/website_bundles/style/andreas00/src/images/front.jpg +0 -0
- data/data/webgen/website_bundles/style/andreas00/src/images/menubg.gif +0 -0
- data/data/webgen/website_bundles/style/andreas00/src/images/menubg2.gif +0 -0
- data/data/webgen/website_bundles/style/andreas01/README +0 -14
- data/data/webgen/website_bundles/style/andreas01/src/default.css +0 -310
- data/data/webgen/website_bundles/style/andreas01/src/default.template +0 -62
- data/data/webgen/website_bundles/style/andreas01/src/images/bg.gif +0 -0
- data/data/webgen/website_bundles/style/andreas01/src/images/front.jpg +0 -0
- data/data/webgen/website_bundles/style/andreas01/src/print.css +0 -35
- data/data/webgen/website_bundles/style/andreas03/README +0 -14
- data/data/webgen/website_bundles/style/andreas03/src/default.css +0 -223
- data/data/webgen/website_bundles/style/andreas03/src/default.template +0 -58
- data/data/webgen/website_bundles/style/andreas03/src/images/bodybg.png +0 -0
- data/data/webgen/website_bundles/style/andreas03/src/images/contbg.png +0 -0
- data/data/webgen/website_bundles/style/andreas03/src/images/footerbg.png +0 -0
- data/data/webgen/website_bundles/style/andreas03/src/images/gradient1.png +0 -0
- data/data/webgen/website_bundles/style/andreas03/src/images/gradient2.png +0 -0
- data/data/webgen/website_bundles/style/andreas04/README +0 -15
- data/data/webgen/website_bundles/style/andreas04/src/default.css +0 -290
- data/data/webgen/website_bundles/style/andreas04/src/default.template +0 -81
- data/data/webgen/website_bundles/style/andreas04/src/images/blinkarrow.gif +0 -0
- data/data/webgen/website_bundles/style/andreas04/src/images/bodybg.png +0 -0
- data/data/webgen/website_bundles/style/andreas04/src/images/contentbg.png +0 -0
- data/data/webgen/website_bundles/style/andreas04/src/images/entrybg.png +0 -0
- data/data/webgen/website_bundles/style/andreas04/src/images/flash.gif +0 -0
- data/data/webgen/website_bundles/style/andreas04/src/images/flash2.gif +0 -0
- data/data/webgen/website_bundles/style/andreas04/src/images/globe.gif +0 -0
- data/data/webgen/website_bundles/style/andreas04/src/images/globebottom.gif +0 -0
- data/data/webgen/website_bundles/style/andreas04/src/images/linkarrow.gif +0 -0
- data/data/webgen/website_bundles/style/andreas04/src/images/menuhover.png +0 -0
- data/data/webgen/website_bundles/style/andreas05/README +0 -14
- data/data/webgen/website_bundles/style/andreas05/src/default.css +0 -33
- data/data/webgen/website_bundles/style/andreas05/src/default.template +0 -40
- data/data/webgen/website_bundles/style/andreas05/src/images/bodybg.gif +0 -0
- data/data/webgen/website_bundles/style/andreas05/src/images/front.png +0 -0
- data/data/webgen/website_bundles/style/andreas06/README +0 -14
- data/data/webgen/website_bundles/style/andreas06/src/default.css +0 -356
- data/data/webgen/website_bundles/style/andreas06/src/default.template +0 -70
- data/data/webgen/website_bundles/style/andreas06/src/images/bodybg.gif +0 -0
- data/data/webgen/website_bundles/style/andreas06/src/images/boxbg.gif +0 -0
- data/data/webgen/website_bundles/style/andreas06/src/images/greypx.gif +0 -0
- data/data/webgen/website_bundles/style/andreas06/src/images/header.jpg +0 -0
- data/data/webgen/website_bundles/style/andreas06/src/images/innerbg.gif +0 -0
- data/data/webgen/website_bundles/style/andreas06/src/images/leaves.jpg +0 -0
- data/data/webgen/website_bundles/style/andreas06/src/images/tabs.gif +0 -0
- data/data/webgen/website_bundles/style/andreas07/README +0 -15
- data/data/webgen/website_bundles/style/andreas07/src/browserfix.css +0 -7
- data/data/webgen/website_bundles/style/andreas07/src/default.css +0 -92
- data/data/webgen/website_bundles/style/andreas07/src/default.template +0 -42
- data/data/webgen/website_bundles/style/andreas07/src/images/bodybg.gif +0 -0
- data/data/webgen/website_bundles/style/andreas07/src/images/sidebarbg.gif +0 -0
- data/data/webgen/website_bundles/style/andreas08/README +0 -14
- data/data/webgen/website_bundles/style/andreas08/src/default.css +0 -224
- data/data/webgen/website_bundles/style/andreas08/src/default.template +0 -51
- data/data/webgen/website_bundles/style/andreas09/README +0 -14
- data/data/webgen/website_bundles/style/andreas09/src/default.css +0 -308
- data/data/webgen/website_bundles/style/andreas09/src/default.template +0 -68
- data/data/webgen/website_bundles/style/andreas09/src/images/bodybg-black.jpg +0 -0
- data/data/webgen/website_bundles/style/andreas09/src/images/bodybg-green.jpg +0 -0
- data/data/webgen/website_bundles/style/andreas09/src/images/bodybg-orange.jpg +0 -0
- data/data/webgen/website_bundles/style/andreas09/src/images/bodybg-purple.jpg +0 -0
- data/data/webgen/website_bundles/style/andreas09/src/images/bodybg-red.jpg +0 -0
- data/data/webgen/website_bundles/style/andreas09/src/images/bodybg.jpg +0 -0
- data/data/webgen/website_bundles/style/andreas09/src/images/footerbg.jpg +0 -0
- data/data/webgen/website_bundles/style/andreas09/src/images/menuhover-black.jpg +0 -0
- data/data/webgen/website_bundles/style/andreas09/src/images/menuhover-green.jpg +0 -0
- data/data/webgen/website_bundles/style/andreas09/src/images/menuhover-orange.jpg +0 -0
- data/data/webgen/website_bundles/style/andreas09/src/images/menuhover-purple.jpg +0 -0
- data/data/webgen/website_bundles/style/andreas09/src/images/menuhover-red.jpg +0 -0
- data/data/webgen/website_bundles/style/andreas09/src/images/menuhover.jpg +0 -0
- data/data/webgen/website_bundles/style/simple/README +0 -6
- data/data/webgen/website_bundles/style/simple/src/default.css +0 -84
- data/data/webgen/website_bundles/style/simple/src/default.template +0 -36
data/lib/webgen/page.rb
CHANGED
|
@@ -112,6 +112,16 @@ module Webgen
|
|
|
112
112
|
@blocks = blocks
|
|
113
113
|
end
|
|
114
114
|
|
|
115
|
+
# Convert the Page object back into a string.
|
|
116
|
+
def to_s
|
|
117
|
+
str = ""
|
|
118
|
+
str << @meta_info.to_yaml
|
|
119
|
+
blocks.each do |name, value|
|
|
120
|
+
str << "--- #{name}\n" << value.gsub(/^---.*?$/) {|m| "\\#{m}" } << (value =~ /\n$/ ? "" : "\n")
|
|
121
|
+
end
|
|
122
|
+
str
|
|
123
|
+
end
|
|
124
|
+
|
|
115
125
|
end
|
|
116
126
|
|
|
117
127
|
end
|
data/lib/webgen/path.rb
CHANGED
|
@@ -29,7 +29,7 @@ module Webgen
|
|
|
29
29
|
#
|
|
30
30
|
# * Path.url
|
|
31
31
|
# * Path.append
|
|
32
|
-
# * Path.matches_pattern
|
|
32
|
+
# * Path.matches_pattern?
|
|
33
33
|
# * Path.lcn
|
|
34
34
|
#
|
|
35
35
|
class Path
|
|
@@ -44,7 +44,7 @@ module Webgen
|
|
|
44
44
|
# Construct an internal URL for the given +path+ which can be an acn/alcn/absolute path.
|
|
45
45
|
#
|
|
46
46
|
# If the parameter +make_absolute+ is +true+, then a relative URL will be made absolute by
|
|
47
|
-
# prepending the special URL 'webgen
|
|
47
|
+
# prepending the special URL 'webgen://webgen.localhost/'.
|
|
48
48
|
def self.url(path, make_absolute = true)
|
|
49
49
|
url = URI.parse(URI::DEFAULT_PARSER.escape(path, URL_UNSAFE_PATTERN))
|
|
50
50
|
url = WEBGEN_BASE_URI + url unless url.absolute? || !make_absolute
|
|
@@ -57,9 +57,9 @@ module Webgen
|
|
|
57
57
|
# needs to have a trailing slash! The +path+ parameter doesn't need to be absolute and may
|
|
58
58
|
# contain path patterns.
|
|
59
59
|
def self.append(base, path)
|
|
60
|
-
raise(ArgumentError, 'base needs to start with a slash (i.e. be an absolute path)') unless base
|
|
60
|
+
raise(ArgumentError, 'base needs to start with a slash (i.e. be an absolute path)') unless base[0] == ?/
|
|
61
61
|
url = url(base) + url(path, false)
|
|
62
|
-
url.path
|
|
62
|
+
url.path << (url.fragment.nil? ? '' : "##{url.fragment}")
|
|
63
63
|
end
|
|
64
64
|
|
|
65
65
|
# Return +true+ if the given path string matches the given path pattern.
|
|
@@ -67,7 +67,7 @@ module Webgen
|
|
|
67
67
|
# For information on which patterns are supported, have a look at the API documentation of
|
|
68
68
|
# File.fnmatch.
|
|
69
69
|
def self.matches_pattern?(path, pattern, options = File::FNM_DOTMATCH|File::FNM_CASEFOLD|File::FNM_PATHNAME)
|
|
70
|
-
pattern += '/' if path
|
|
70
|
+
pattern += '/' if path =~ /\/$/ && pattern !~ /\/$|^$/
|
|
71
71
|
File.fnmatch(pattern, path, options)
|
|
72
72
|
end
|
|
73
73
|
|
|
@@ -162,13 +162,13 @@ module Webgen
|
|
|
162
162
|
#
|
|
163
163
|
# Triggers analyzation of the path if invoked.
|
|
164
164
|
def cn
|
|
165
|
-
if meta_info['cn']
|
|
165
|
+
if meta_info['cn']
|
|
166
166
|
tmp_cn = custom_cn
|
|
167
167
|
else
|
|
168
|
-
tmp_cn = basename
|
|
169
|
-
(ext.length > 0 ?
|
|
168
|
+
tmp_cn = basename.dup << (use_version_for_cn? ? "-#{meta_info['version']}" : '') <<
|
|
169
|
+
(ext.length > 0 ? ".#{ext}" : '')
|
|
170
170
|
end
|
|
171
|
-
tmp_cn
|
|
171
|
+
tmp_cn << (@path =~ /.\/$/ ? '/' : '')
|
|
172
172
|
end
|
|
173
173
|
|
|
174
174
|
# The localized canonical name created from the +path+.
|
|
@@ -183,7 +183,7 @@ module Webgen
|
|
|
183
183
|
# Triggers analyzation of the path if invoked.
|
|
184
184
|
def acn
|
|
185
185
|
if @path =~ /#/
|
|
186
|
-
self.class.new(parent_path).acn
|
|
186
|
+
self.class.new(parent_path).acn << cn
|
|
187
187
|
else
|
|
188
188
|
parent_path + cn
|
|
189
189
|
end
|
|
@@ -194,7 +194,7 @@ module Webgen
|
|
|
194
194
|
# Triggers analyzation of the path if invoked.
|
|
195
195
|
def alcn
|
|
196
196
|
if @path =~ /#/
|
|
197
|
-
self.class.new(parent_path).alcn
|
|
197
|
+
self.class.new(parent_path).alcn << lcn
|
|
198
198
|
else
|
|
199
199
|
parent_path + lcn
|
|
200
200
|
end
|
|
@@ -270,7 +270,7 @@ module Webgen
|
|
|
270
270
|
end
|
|
271
271
|
|
|
272
272
|
def to_s #:nodoc:
|
|
273
|
-
@path
|
|
273
|
+
@path
|
|
274
274
|
end
|
|
275
275
|
alias_method :to_str, :to_s
|
|
276
276
|
|
|
@@ -317,7 +317,7 @@ module Webgen
|
|
|
317
317
|
@meta_info['sort_info'] ||= match_data[1].to_i unless match_data[1].nil?
|
|
318
318
|
@basename = match_data[2]
|
|
319
319
|
@meta_info['lang'] ||= Webgen::LanguageManager.language_for_code(match_data[3]) if match_data[3]
|
|
320
|
-
@ext = (@meta_info['lang'].nil? && !match_data[3].nil? ? match_data[3]
|
|
320
|
+
@ext = (@meta_info['lang'].nil? && !match_data[3].nil? ? match_data[3] << '.' : '') << match_data[4].to_s
|
|
321
321
|
end
|
|
322
322
|
end
|
|
323
323
|
|
|
@@ -354,7 +354,7 @@ module Webgen
|
|
|
354
354
|
''
|
|
355
355
|
end
|
|
356
356
|
end
|
|
357
|
-
self.meta_info['cn'].gsub(CN_SEGMENTS, &replace_segment).gsub(/\/+$/, '')
|
|
357
|
+
self.meta_info['cn'].to_s.gsub(CN_SEGMENTS, &replace_segment).gsub(/\/+$/, '')
|
|
358
358
|
end
|
|
359
359
|
|
|
360
360
|
end
|
data/lib/webgen/path_handler.rb
CHANGED
|
@@ -146,19 +146,24 @@ module Webgen
|
|
|
146
146
|
end
|
|
147
147
|
|
|
148
148
|
used_secondary_paths = {}
|
|
149
|
+
written_nodes = Set.new
|
|
149
150
|
@website.blackboard.add_listener(:before_secondary_nodes_created, self) do |path, source_alcn|
|
|
150
151
|
(used_secondary_paths[source_alcn] ||= Set.new) << path if source_alcn
|
|
151
152
|
end
|
|
152
|
-
@website.blackboard.add_listener(:
|
|
153
|
+
@website.blackboard.add_listener(:before_all_nodes_written, self) do |node|
|
|
153
154
|
used_secondary_paths = {}
|
|
155
|
+
written_nodes = Set.new
|
|
154
156
|
end
|
|
155
157
|
@website.blackboard.add_listener(:after_node_written, self) do |node|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
158
|
+
written_nodes << node.alcn
|
|
159
|
+
end
|
|
160
|
+
@website.blackboard.add_listener(:after_all_nodes_written, self) do |node|
|
|
161
|
+
@secondary_nodes.delete_if do |path, data|
|
|
162
|
+
if written_nodes.include?(data[1]) && (!used_secondary_paths[data[1]] ||
|
|
163
|
+
!used_secondary_paths[data[1]].include?(path))
|
|
164
|
+
data[2].each {|alcn| @website.tree.delete_node(@website.tree[alcn])}
|
|
165
|
+
true
|
|
166
|
+
end
|
|
162
167
|
end
|
|
163
168
|
end
|
|
164
169
|
end
|
|
@@ -208,7 +213,7 @@ module Webgen
|
|
|
208
213
|
|
|
209
214
|
# Return the instance of the path handler class with the given name.
|
|
210
215
|
def instance(handler)
|
|
211
|
-
@instances[handler] ||= extension(handler).new(@website)
|
|
216
|
+
@instances[handler.intern] ||= extension(handler).new(@website)
|
|
212
217
|
end
|
|
213
218
|
|
|
214
219
|
|
|
@@ -216,7 +221,7 @@ module Webgen
|
|
|
216
221
|
#
|
|
217
222
|
# Can only be called once because the tree can only be populated once!
|
|
218
223
|
def populate_tree
|
|
219
|
-
raise Webgen::NodeCreationError.new("Can't populate tree twice",
|
|
224
|
+
raise Webgen::NodeCreationError.new("Can't populate tree twice", 'path_handler') if @website.tree.root
|
|
220
225
|
|
|
221
226
|
time = Benchmark.measure do
|
|
222
227
|
meta_info, rest = @website.ext.source.paths.partition {|path| path.path =~ /[\/.]metainfo$/}
|
|
@@ -268,9 +273,10 @@ module Webgen
|
|
|
268
273
|
@website.blackboard.dispatch_msg(:after_node_written, node, content)
|
|
269
274
|
rescue Webgen::Error => e
|
|
270
275
|
e.path = node.alcn if e.path.to_s.empty?
|
|
276
|
+
e.location = "path_handler.#{node.node_info[:path_handler]}" unless e.location
|
|
271
277
|
raise
|
|
272
278
|
rescue Exception => e
|
|
273
|
-
raise Webgen::RenderError.new(e,
|
|
279
|
+
raise Webgen::RenderError.new(e, "path_handler.#{node.node_info[:path_handler]}", node)
|
|
274
280
|
end
|
|
275
281
|
end
|
|
276
282
|
@website.blackboard.dispatch_msg(:after_all_nodes_written)
|
|
@@ -325,7 +331,7 @@ module Webgen
|
|
|
325
331
|
# alcn from which these nodes are created!
|
|
326
332
|
def create_secondary_nodes(path, content = '', source_alcn = nil)
|
|
327
333
|
if (sn = @secondary_nodes[path]) && sn[1] != source_alcn
|
|
328
|
-
raise Webgen::NodeCreationError.new("Duplicate secondary path name <#{path}>",
|
|
334
|
+
raise Webgen::NodeCreationError.new("Duplicate secondary path name <#{path}>", 'path_handler', path)
|
|
329
335
|
end
|
|
330
336
|
@website.blackboard.dispatch_msg(:before_secondary_nodes_created, path, source_alcn)
|
|
331
337
|
|
|
@@ -388,10 +394,10 @@ module Webgen
|
|
|
388
394
|
end
|
|
389
395
|
rescue Webgen::Error => e
|
|
390
396
|
e.path = path.to_s if e.path.to_s.empty?
|
|
391
|
-
e.location =
|
|
397
|
+
e.location = "path_handler.#{handler}" unless e.location
|
|
392
398
|
raise
|
|
393
399
|
rescue Exception => e
|
|
394
|
-
raise Webgen::NodeCreationError.new(e,
|
|
400
|
+
raise Webgen::NodeCreationError.new(e, "path_handler.#{handler}", path)
|
|
395
401
|
end
|
|
396
402
|
private :create_nodes_with_path_handler
|
|
397
403
|
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
require 'time'
|
|
4
|
+
require 'shellwords'
|
|
5
|
+
require 'webgen/path_handler/base'
|
|
6
|
+
require 'webgen/path_handler/page_utils'
|
|
7
|
+
require 'webgen/context'
|
|
8
|
+
require 'webgen/path'
|
|
9
|
+
require 'webgen/content_processor/r_doc'
|
|
10
|
+
|
|
11
|
+
module Webgen
|
|
12
|
+
class PathHandler
|
|
13
|
+
|
|
14
|
+
# Path handler for Ruby API documentation via rdoc.
|
|
15
|
+
class Api
|
|
16
|
+
|
|
17
|
+
include Base
|
|
18
|
+
include PageUtils
|
|
19
|
+
|
|
20
|
+
# The mandatory meta info keys that need to be set on an api path.
|
|
21
|
+
MANDATORY_INFOS = %W[rdoc_options]
|
|
22
|
+
|
|
23
|
+
# Create the feed nodes.
|
|
24
|
+
def create_nodes(path, blocks)
|
|
25
|
+
if MANDATORY_INFOS.any? {|t| path.meta_info[t].nil?}
|
|
26
|
+
raise Webgen::NodeCreationError.new("At least one of #{MANDATORY_INFOS.join('/')} is missing",
|
|
27
|
+
"path_handler.api", path)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
path['api_name'] ||= path.basename
|
|
31
|
+
path['dir_name'] ||= path.basename
|
|
32
|
+
|
|
33
|
+
cache_dir = @website.tmpdir(File.join('path_handler.api', path['api_name']))
|
|
34
|
+
rdoc = rdoc_object(path['rdoc_options'], cache_dir)
|
|
35
|
+
output_flag_file = rdoc.output_flag_file(cache_dir)
|
|
36
|
+
|
|
37
|
+
dir_node = create_directory(path, Webgen::Path.new(path.parent_path + path['dir_name'] + '/'), false)
|
|
38
|
+
|
|
39
|
+
rdoc.store.all_classes_and_modules.sort.each do |klass|
|
|
40
|
+
klass_node = create_page_node_for_class(path, dir_node, klass, output_flag_file)
|
|
41
|
+
klass.each_method {|method| create_fragment_node_for_method(path, klass_node, method)}
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
nil
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Create a directory for the path, applying needed meta information from the api path.
|
|
48
|
+
#
|
|
49
|
+
# Also creates the parent directories when necessary.
|
|
50
|
+
def create_directory(api_path, path, set_proxy_path = true)
|
|
51
|
+
if (dir = @website.tree[path.alcn])
|
|
52
|
+
return dir
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
parent_path = Webgen::Path.new(path.parent_path)
|
|
56
|
+
if !@website.tree[parent_path.alcn]
|
|
57
|
+
create_directory(api_path, parent_path)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
path['modified_at'] = api_path['modified_at']
|
|
61
|
+
path['handler'] = 'directory'
|
|
62
|
+
path['proxy_path'] ||= "../#{path.basename}.html" if set_proxy_path
|
|
63
|
+
@website.ext.path_handler.create_secondary_nodes(path).first
|
|
64
|
+
end
|
|
65
|
+
private :create_directory
|
|
66
|
+
|
|
67
|
+
# Create the RDoc instance and use it for generating the API data.
|
|
68
|
+
#
|
|
69
|
+
# If possible, cached data available under +cache_dir+ is used.
|
|
70
|
+
def rdoc_object(options, cache_dir)
|
|
71
|
+
start_time = Time.now
|
|
72
|
+
|
|
73
|
+
rdoc = RDoc::RDoc.new
|
|
74
|
+
rdoc.options = rdoc_options(options)
|
|
75
|
+
rdoc.store = rdoc_store(rdoc.options, cache_dir)
|
|
76
|
+
|
|
77
|
+
rdoc.exclude = rdoc.options.exclude
|
|
78
|
+
rdoc.last_modified.replace(rdoc.setup_output_dir(cache_dir, false))
|
|
79
|
+
|
|
80
|
+
if !(rdoc.parse_files(rdoc.options.files)).empty?
|
|
81
|
+
rdoc.store.complete(rdoc.options.visibility)
|
|
82
|
+
rdoc.store.save
|
|
83
|
+
rdoc.update_output_dir(cache_dir, start_time, rdoc.last_modified)
|
|
84
|
+
end
|
|
85
|
+
rdoc.store.load_all
|
|
86
|
+
|
|
87
|
+
# We need a dummy generator with some methods
|
|
88
|
+
rdoc.generator = Object.new
|
|
89
|
+
def (rdoc.generator).class_dir; nil; end
|
|
90
|
+
def (rdoc.generator).file_dir; nil; end
|
|
91
|
+
|
|
92
|
+
rdoc
|
|
93
|
+
end
|
|
94
|
+
protected :rdoc_object
|
|
95
|
+
|
|
96
|
+
# Return a fully initialized RDoc::Options object.
|
|
97
|
+
#
|
|
98
|
+
# Some of the user specified options may not be used if they would interfere with this class'
|
|
99
|
+
# job.
|
|
100
|
+
def rdoc_options(user_options)
|
|
101
|
+
user_options = Shellwords.split(user_options) if user_options.kind_of?(String)
|
|
102
|
+
options = RDoc::Options.new
|
|
103
|
+
options.parse(user_options)
|
|
104
|
+
options.verbosity = 0
|
|
105
|
+
options.dry_run = false
|
|
106
|
+
options.update_output_dir = true
|
|
107
|
+
options.force_output = false
|
|
108
|
+
options.finish
|
|
109
|
+
options
|
|
110
|
+
end
|
|
111
|
+
protected :rdoc_options
|
|
112
|
+
|
|
113
|
+
# Return a fully initialized RDoc::Store object.
|
|
114
|
+
def rdoc_store(options, cache_dir)
|
|
115
|
+
store = RDoc::Store.new(cache_dir)
|
|
116
|
+
store.encoding = options.encoding
|
|
117
|
+
store.dry_run = options.dry_run
|
|
118
|
+
store.main = options.main_page
|
|
119
|
+
store.title = options.title
|
|
120
|
+
store.load_cache
|
|
121
|
+
store
|
|
122
|
+
end
|
|
123
|
+
protected :rdoc_store
|
|
124
|
+
|
|
125
|
+
# Create a page node for the given class +klass+ and return it.
|
|
126
|
+
#
|
|
127
|
+
# A link definition entry for the class is also created.
|
|
128
|
+
def create_page_node_for_class(api_path, dir_node, klass, output_flag_file)
|
|
129
|
+
klass_path_str = klass.http_url(dir_node.alcn)
|
|
130
|
+
|
|
131
|
+
create_directory(api_path, Webgen::Path.new(File.dirname(klass_path_str) + '/'))
|
|
132
|
+
|
|
133
|
+
path = Webgen::Path.new(klass_path_str, 'handler' => 'page', 'modified_at' => api_path['modified_at'],
|
|
134
|
+
'title' => "#{klass.type} #{klass.full_name}", 'api_class' => klass.full_name,
|
|
135
|
+
'api_name' => api_path['api_name'], 'template' => api_path['api_template'])
|
|
136
|
+
node = @website.ext.path_handler.create_secondary_nodes(path).first
|
|
137
|
+
|
|
138
|
+
node.node_info[:api_class_object] = klass
|
|
139
|
+
@website.ext.item_tracker.add(node, :file, output_flag_file)
|
|
140
|
+
add_link_definition(api_path, klass.full_name, node.alcn, klass.full_name)
|
|
141
|
+
|
|
142
|
+
node
|
|
143
|
+
end
|
|
144
|
+
protected :create_page_node_for_class
|
|
145
|
+
|
|
146
|
+
# Create a fragment node for the given method.
|
|
147
|
+
#
|
|
148
|
+
# A link definition entry for the method is also created.
|
|
149
|
+
def create_fragment_node_for_method(api_path, klass_node, method)
|
|
150
|
+
method_url = "#{klass_node.alcn}##{method.aref}"
|
|
151
|
+
path = Webgen::Path.new(method_url,
|
|
152
|
+
{'handler' => 'copy', 'modified_at' => api_path['modified_at'],
|
|
153
|
+
'pipeline' => [], 'no_output' => true, 'title' => method.name})
|
|
154
|
+
@website.ext.path_handler.create_secondary_nodes(path)
|
|
155
|
+
add_link_definition(api_path, method.full_name, method_url, method.full_name)
|
|
156
|
+
end
|
|
157
|
+
protected :create_fragment_node_for_method
|
|
158
|
+
|
|
159
|
+
# Add a link definition for the given node.
|
|
160
|
+
def add_link_definition(api_path, link_name, url, title)
|
|
161
|
+
link = if api_path['prefix_for_link_defs']
|
|
162
|
+
"#{api_path['api_name']}:#{link_name}"
|
|
163
|
+
else
|
|
164
|
+
link_name
|
|
165
|
+
end
|
|
166
|
+
@website.ext.link_definitions[link] = [url, title]
|
|
167
|
+
end
|
|
168
|
+
protected :add_link_definition
|
|
169
|
+
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
end
|
|
173
|
+
end
|
|
@@ -4,6 +4,7 @@ require 'webgen/path_handler'
|
|
|
4
4
|
require 'webgen/error'
|
|
5
5
|
require 'webgen/node'
|
|
6
6
|
require 'webgen/path'
|
|
7
|
+
require 'webgen/utils'
|
|
7
8
|
|
|
8
9
|
module Webgen
|
|
9
10
|
class PathHandler
|
|
@@ -27,10 +28,18 @@ module Webgen
|
|
|
27
28
|
#
|
|
28
29
|
module Base
|
|
29
30
|
|
|
30
|
-
# This is the
|
|
31
|
-
#
|
|
31
|
+
# This is the Node sub class used by the Base#create_node method if a path handler class does
|
|
32
|
+
# not specify another Node class.
|
|
32
33
|
class Node < Webgen::Node
|
|
33
34
|
|
|
35
|
+
# Does exactly the same as Node#route_to but also automatically adds the necessary item
|
|
36
|
+
# tracking information.
|
|
37
|
+
def route_to(node, lang = @lang)
|
|
38
|
+
tree.website.ext.item_tracker.add(self, :node_meta_info, node)
|
|
39
|
+
tree.website.ext.item_tracker.add(self, :node_meta_info, node.proxy_node(lang))
|
|
40
|
+
super
|
|
41
|
+
end
|
|
42
|
+
|
|
34
43
|
# Return the result of the #content method on the associated path handler or +nil+ if the
|
|
35
44
|
# associated path handler does not have a #content method.
|
|
36
45
|
def content
|
|
@@ -60,18 +69,19 @@ module Webgen
|
|
|
60
69
|
# Create a node from +path+, if possible, yield the fully initialized node if a block is given
|
|
61
70
|
# and return it.
|
|
62
71
|
#
|
|
63
|
-
# The node class to be used for the created node can be specified via
|
|
64
|
-
#
|
|
65
|
-
#
|
|
66
|
-
# If no node can be created (e.g. when 'path.meta_info['draft']' is set), +nil+ is returned.
|
|
72
|
+
# The node class to be used for the to-be-created node can be specified via
|
|
73
|
+
# `path.meta_info['node_class']`. If this node processing information is not set, the
|
|
74
|
+
# Base::Node class is used.
|
|
67
75
|
#
|
|
68
76
|
# The parent node under which the new node should be created can optionally be specified via
|
|
69
|
-
# 'path.meta_info['parent_alcn']'. This
|
|
70
|
-
# existing node.
|
|
77
|
+
# 'path.meta_info['parent_alcn']'. This node processing information has to be set to the alcn
|
|
78
|
+
# of an existing node.
|
|
79
|
+
#
|
|
80
|
+
# If no node can be created (e.g. when 'path.meta_info['draft']' is set), +nil+ is returned.
|
|
71
81
|
#
|
|
72
82
|
# On the created node, the node information +:path+ is set to the given path and
|
|
73
83
|
# +:path_handler+ to the path handler instance.
|
|
74
|
-
def create_node(path
|
|
84
|
+
def create_node(path)
|
|
75
85
|
return nil if path.meta_info['draft']
|
|
76
86
|
parent = parent_node(path)
|
|
77
87
|
dest_path = self.dest_path(parent, path)
|
|
@@ -95,7 +105,7 @@ module Webgen
|
|
|
95
105
|
path.meta_info['modified_at'] = Time.now
|
|
96
106
|
end
|
|
97
107
|
|
|
98
|
-
node =
|
|
108
|
+
node = node_class(path).new(parent, path.cn, dest_path, path.meta_info.dup)
|
|
99
109
|
node.node_info[:path] = path
|
|
100
110
|
node.node_info[:path_handler] = self
|
|
101
111
|
|
|
@@ -220,10 +230,22 @@ module Webgen
|
|
|
220
230
|
# Check if the node alcn or the destination path, which would be created by #create_node for
|
|
221
231
|
# the given paths, exists.
|
|
222
232
|
def node_exists?(path, dest_path)
|
|
223
|
-
@website.tree[path.alcn] || (!path.meta_info['no_output'] && @website.tree
|
|
233
|
+
@website.tree[path.alcn] || (!path.meta_info['no_output'] && @website.tree.node(dest_path, :dest_path))
|
|
224
234
|
end
|
|
225
235
|
protected :node_exists?
|
|
226
236
|
|
|
237
|
+
# Retrieve the node class that should be used for the given path.
|
|
238
|
+
def node_class(path)
|
|
239
|
+
if String === (klass = path.meta_info['node_class'])
|
|
240
|
+
Webgen::Utils.const_for_name(klass) rescue Node
|
|
241
|
+
elsif String === (klass = path.meta_info['base_node_class'])
|
|
242
|
+
Webgen::Utils.const_for_name(klass) rescue Node
|
|
243
|
+
else
|
|
244
|
+
Node
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
protected :node_class
|
|
248
|
+
|
|
227
249
|
end
|
|
228
250
|
|
|
229
251
|
end
|