webgen 0.5.8 → 0.5.9
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 +4 -0
- data/ChangeLog +1037 -0
- data/Rakefile +5 -6
- data/THANKS +1 -0
- data/VERSION +1 -1
- data/bin/webgen +1 -1
- data/data/webgen/passive_sources/images/generated_by_webgen.png +0 -0
- data/data/webgen/passive_sources/images/webgen_logo.png +0 -0
- data/data/webgen/passive_sources/stylesheets/coderay-default.css +129 -0
- data/data/webgen/passive_sources/templates/atom_feed.template +38 -0
- data/data/webgen/passive_sources/templates/rss_feed.template +28 -0
- data/data/webgen/passive_sources/templates/sitemap.template +21 -0
- data/data/webgen/resources.yaml +2 -1
- data/data/webgen/website_skeleton/Rakefile +5 -1
- data/doc/contentprocessor/builder.page +2 -2
- data/doc/contentprocessor/erb.page +5 -2
- data/doc/contentprocessor/erubis.page +2 -2
- data/doc/contentprocessor/head.page +21 -0
- data/doc/contentprocessor/tidy.page +14 -0
- data/doc/extensions.page +1 -1
- data/doc/faq.page +2 -2
- data/doc/manual.page +108 -43
- data/doc/reference_configuration.page +83 -5
- data/doc/reference_metainfo.page +24 -4
- data/doc/reference_website_styles.page +2 -2
- data/doc/sourcehandler/feed.page +11 -13
- data/doc/sourcehandler/metainfo.page +10 -3
- data/doc/sourcehandler/page.page +4 -4
- data/doc/sourcehandler/sitemap.page +8 -7
- data/doc/tag/coderay.page +6 -2
- data/doc/tag/includefile.page +1 -1
- data/doc/tag/menu.page +3 -0
- data/lib/webgen/cli/apply_command.rb +1 -1
- data/lib/webgen/cli/utils.rb +2 -2
- data/lib/webgen/common.rb +0 -9
- data/lib/webgen/contentprocessor.rb +18 -3
- data/lib/webgen/contentprocessor/blocks.rb +67 -36
- data/lib/webgen/contentprocessor/builder.rb +5 -2
- data/lib/webgen/contentprocessor/erb.rb +4 -2
- data/lib/webgen/contentprocessor/erubis.rb +5 -2
- data/lib/webgen/contentprocessor/haml.rb +6 -2
- data/lib/webgen/contentprocessor/head.rb +64 -0
- data/lib/webgen/contentprocessor/maruku.rb +3 -1
- data/lib/webgen/contentprocessor/rdiscount.rb +2 -0
- data/lib/webgen/contentprocessor/rdoc.rb +2 -0
- data/lib/webgen/contentprocessor/redcloth.rb +2 -0
- data/lib/webgen/contentprocessor/sass.rb +5 -3
- data/lib/webgen/contentprocessor/tags.rb +40 -24
- data/lib/webgen/contentprocessor/tidy.rb +38 -0
- data/lib/webgen/context.rb +13 -4
- data/lib/webgen/context/render.rb +32 -0
- data/lib/webgen/context/tags.rb +20 -0
- data/lib/webgen/default_config.rb +15 -4
- data/lib/webgen/deprecated.rb +38 -4
- data/lib/webgen/error.rb +135 -0
- data/lib/webgen/node.rb +48 -40
- data/lib/webgen/output.rb +5 -3
- data/lib/webgen/output/filesystem.rb +4 -4
- data/lib/webgen/page.rb +4 -4
- data/lib/webgen/path.rb +161 -58
- data/lib/webgen/source.rb +9 -6
- data/lib/webgen/source/filesystem.rb +1 -1
- data/lib/webgen/source/stacked.rb +13 -5
- data/lib/webgen/source/tararchive.rb +6 -2
- data/lib/webgen/sourcehandler.rb +100 -54
- data/lib/webgen/sourcehandler/base.rb +58 -24
- data/lib/webgen/sourcehandler/copy.rb +6 -5
- data/lib/webgen/sourcehandler/directory.rb +3 -9
- data/lib/webgen/sourcehandler/feed.rb +25 -50
- data/lib/webgen/sourcehandler/fragment.rb +10 -8
- data/lib/webgen/sourcehandler/memory.rb +9 -10
- data/lib/webgen/sourcehandler/metainfo.rb +9 -9
- data/lib/webgen/sourcehandler/page.rb +6 -5
- data/lib/webgen/sourcehandler/sitemap.rb +22 -22
- data/lib/webgen/sourcehandler/template.rb +6 -6
- data/lib/webgen/sourcehandler/virtual.rb +19 -17
- data/lib/webgen/tag/base.rb +27 -27
- data/lib/webgen/tag/breadcrumbtrail.rb +3 -3
- data/lib/webgen/tag/coderay.rb +19 -8
- data/lib/webgen/tag/executecommand.rb +4 -3
- data/lib/webgen/tag/langbar.rb +2 -2
- data/lib/webgen/tag/link.rb +8 -7
- data/lib/webgen/tag/menu.rb +2 -2
- data/lib/webgen/tag/metainfo.rb +1 -1
- data/lib/webgen/tag/relocatable.rb +17 -21
- data/lib/webgen/tag/tikz.rb +7 -10
- data/lib/webgen/tree.rb +7 -7
- data/lib/webgen/version.rb +1 -1
- data/lib/webgen/website.rb +32 -2
- data/misc/default.css +8 -2
- data/misc/default.template +2 -2
- data/misc/logo.svg +313 -0
- data/misc/style.page +1 -1
- data/test/helper.rb +18 -2
- data/test/test_cli.rb +104 -0
- data/test/test_common_sitemap.rb +1 -1
- data/test/test_contentprocessor.rb +8 -2
- data/test/test_contentprocessor_blocks.rb +17 -8
- data/test/test_contentprocessor_builder.rb +13 -2
- data/test/test_contentprocessor_erb.rb +9 -3
- data/test/test_contentprocessor_erubis.rb +9 -3
- data/test/test_contentprocessor_fragments.rb +12 -11
- data/test/test_contentprocessor_haml.rb +11 -2
- data/test/test_contentprocessor_head.rb +44 -0
- data/test/test_contentprocessor_maruku.rb +5 -1
- data/test/test_contentprocessor_rdiscount.rb +4 -0
- data/test/test_contentprocessor_rdoc.rb +4 -0
- data/test/test_contentprocessor_redcloth.rb +5 -1
- data/test/test_contentprocessor_sass.rb +8 -2
- data/test/test_contentprocessor_tags.rb +22 -7
- data/test/test_contentprocessor_tidy.rb +34 -0
- data/test/test_context.rb +39 -0
- data/test/test_error.rb +85 -0
- data/test/test_node.rb +57 -21
- data/test/test_page.rb +23 -5
- data/test/test_path.rb +120 -64
- data/test/test_source_filesystem.rb +1 -1
- data/test/test_source_stacked.rb +19 -6
- data/test/test_sourcehandler_base.rb +63 -50
- data/test/test_sourcehandler_copy.rb +6 -6
- data/test/test_sourcehandler_directory.rb +8 -12
- data/test/test_sourcehandler_feed.rb +15 -7
- data/test/test_sourcehandler_fragment.rb +6 -5
- data/test/test_sourcehandler_main.rb +39 -0
- data/test/test_sourcehandler_memory.rb +4 -4
- data/test/test_sourcehandler_metainfo.rb +20 -11
- data/test/test_sourcehandler_page.rb +10 -10
- data/test/test_sourcehandler_sitemap.rb +24 -5
- data/test/test_sourcehandler_template.rb +18 -15
- data/test/test_sourcehandler_virtual.rb +9 -5
- data/test/test_tag_base.rb +6 -29
- data/test/test_tag_coderay.rb +16 -3
- data/test/test_tag_executecommand.rb +2 -2
- data/test/test_tag_link.rb +5 -4
- data/test/test_tag_menu.rb +15 -15
- data/test/test_tag_metainfo.rb +1 -0
- data/test/test_tag_relocatable.rb +3 -2
- data/test/test_tag_tikz.rb +5 -5
- data/test/test_tree.rb +8 -8
- data/test/test_website.rb +15 -0
- metadata +21 -14
- data/test/test_common.rb +0 -18
|
@@ -17,20 +17,27 @@ module Webgen::Source
|
|
|
17
17
|
# source, it is discarded and not used.
|
|
18
18
|
class Stacked
|
|
19
19
|
|
|
20
|
-
# Return the stack of Webgen::Source
|
|
20
|
+
# Return the stack of mount point to Webgen::Source object maps.
|
|
21
21
|
attr_reader :stack
|
|
22
22
|
|
|
23
|
+
# Specifies whether the result of #paths calls should be cached (default: +false+). If caching
|
|
24
|
+
# is activated, new maps cannot be added to the stacked source anymore!
|
|
25
|
+
attr_accessor :cache_paths
|
|
26
|
+
|
|
23
27
|
# Create a new stack. The optional +map+ parameter can be used to provide initial mappings of
|
|
24
|
-
# mount points to source objects (see #add for details).
|
|
25
|
-
|
|
28
|
+
# mount points to source objects (see #add for details). You cannot add other maps after a call
|
|
29
|
+
# to #paths if +cache_paths+ is +true+
|
|
30
|
+
def initialize(map = {}, cache_paths = false)
|
|
26
31
|
@stack = []
|
|
32
|
+
@cache_paths = cache_paths
|
|
27
33
|
add(map)
|
|
28
34
|
end
|
|
29
35
|
|
|
30
36
|
# Add all mappings found in +maps+ to the stack. The parameter +maps+ should be an array of
|
|
31
|
-
# two-element arrays which contain an absolute
|
|
32
|
-
# source object.
|
|
37
|
+
# two-element arrays which contain an absolute directory (ie. starting and ending with a slash)
|
|
38
|
+
# and a source object.
|
|
33
39
|
def add(maps)
|
|
40
|
+
raise "Cannot add new maps since caching is activated for this source" if defined?(@paths) && @cache_paths
|
|
34
41
|
maps.each do |mp, source|
|
|
35
42
|
raise "Invalid mount point specified: #{mp}" unless mp =~ /^\//
|
|
36
43
|
@stack << [mp, source]
|
|
@@ -41,6 +48,7 @@ module Webgen::Source
|
|
|
41
48
|
# returned by later source objects are not used if a prior source object has returned the same
|
|
42
49
|
# path.
|
|
43
50
|
def paths
|
|
51
|
+
return @paths if defined?(@paths) && @cache_paths
|
|
44
52
|
@paths = Set.new
|
|
45
53
|
@stack.each do |mp, source|
|
|
46
54
|
source.paths.each do |path|
|
|
@@ -5,7 +5,11 @@ require 'webgen/websiteaccess'
|
|
|
5
5
|
require 'webgen/path'
|
|
6
6
|
require 'open-uri'
|
|
7
7
|
require 'zlib'
|
|
8
|
-
|
|
8
|
+
begin
|
|
9
|
+
require 'archive/tar/minitar'
|
|
10
|
+
rescue LoadError
|
|
11
|
+
raise Webgen::LoadError.new('archive/tar/minitar', self.class.name, context.dest_node.alcn, 'archive-tar-minitar')
|
|
12
|
+
end
|
|
9
13
|
|
|
10
14
|
module Webgen
|
|
11
15
|
|
|
@@ -24,7 +28,7 @@ module Webgen
|
|
|
24
28
|
|
|
25
29
|
# Create a new tar archive path object for the entry +entry+.
|
|
26
30
|
def initialize(path, data, mtime, uri)
|
|
27
|
-
super(path) { StringIO.new(data.to_s) }
|
|
31
|
+
super(path) {|mode| StringIO.new(data.to_s, mode) }
|
|
28
32
|
@uri = uri
|
|
29
33
|
@mtime = mtime
|
|
30
34
|
WebsiteAccess.website.cache[[:tararchive_path, @uri, path]] = @mtime if WebsiteAccess.website
|
data/lib/webgen/sourcehandler.rb
CHANGED
|
@@ -28,6 +28,7 @@ module Webgen
|
|
|
28
28
|
# * collects all source paths using the source classes
|
|
29
29
|
# * creates nodes using the source handler classes
|
|
30
30
|
# * writes changed nodes out using an output class
|
|
31
|
+
# * deletes old nodes
|
|
31
32
|
class Main
|
|
32
33
|
|
|
33
34
|
include WebsiteAccess
|
|
@@ -35,88 +36,121 @@ module Webgen
|
|
|
35
36
|
|
|
36
37
|
def initialize #:nodoc:
|
|
37
38
|
website.blackboard.add_service(:create_nodes, method(:create_nodes))
|
|
39
|
+
website.blackboard.add_service(:create_nodes_from_paths, method(:create_nodes_from_paths))
|
|
38
40
|
website.blackboard.add_service(:source_paths, method(:find_all_source_paths))
|
|
39
41
|
website.blackboard.add_listener(:node_meta_info_changed?, method(:meta_info_changed?))
|
|
42
|
+
|
|
43
|
+
website.blackboard.add_listener(:before_node_deleted) do |node|
|
|
44
|
+
website.blackboard.invoke(:output_instance).delete(node.path)
|
|
45
|
+
end if website.config['output.do_deletion']
|
|
40
46
|
end
|
|
41
47
|
|
|
42
|
-
# Render the
|
|
43
|
-
#
|
|
44
|
-
|
|
48
|
+
# Render the current website. Before the actual rendering is done, the sources are checked for
|
|
49
|
+
# changes, i.e. nodes for deleted sources are deleted, nodes for new and changed sources are
|
|
50
|
+
# updated.
|
|
51
|
+
def render
|
|
45
52
|
begin
|
|
46
53
|
website.logger.mark_new_cycle if website.logger
|
|
47
54
|
|
|
48
55
|
puts "Updating tree..."
|
|
49
56
|
time = Benchmark.measure do
|
|
50
57
|
website.cache.reset_volatile_cache
|
|
51
|
-
update_tree
|
|
58
|
+
update_tree
|
|
52
59
|
end
|
|
53
60
|
puts "...done in " + ('%2.4f' % time.real) + ' seconds'
|
|
54
61
|
|
|
55
|
-
if !tree.root
|
|
62
|
+
if !website.tree.root
|
|
56
63
|
puts 'No source files found - maybe not a webgen website?'
|
|
57
64
|
return nil
|
|
58
65
|
end
|
|
59
66
|
|
|
60
67
|
puts "Writing changed nodes..."
|
|
61
68
|
time = Benchmark.measure do
|
|
62
|
-
write_tree
|
|
69
|
+
write_tree
|
|
63
70
|
end
|
|
64
71
|
puts "...done in " + ('%2.4f' % time.real) + ' seconds'
|
|
65
|
-
end while tree.node_access[:alcn].any? {|name,node| node.flagged?(:created) || node.flagged?(:reinit)}
|
|
72
|
+
end while website.tree.node_access[:alcn].any? {|name,node| node.flagged?(:created) || node.flagged?(:reinit)}
|
|
66
73
|
:success
|
|
74
|
+
rescue Webgen::Error
|
|
75
|
+
raise
|
|
76
|
+
rescue Exception => e
|
|
77
|
+
raise Webgen::Error.new(e)
|
|
67
78
|
end
|
|
68
79
|
|
|
69
80
|
#######
|
|
70
81
|
private
|
|
71
82
|
#######
|
|
72
83
|
|
|
73
|
-
# Update the
|
|
74
|
-
def update_tree
|
|
84
|
+
# Update the <tt>website.tree</tt> by creating/reinitializing all needed nodes.
|
|
85
|
+
def update_tree
|
|
75
86
|
unused_paths = Set.new
|
|
87
|
+
referenced_nodes = Set.new
|
|
88
|
+
all_but_passive_paths = Set.new(find_all_source_paths.select {|name, path| !path.passive?}.collect {|name, path| name})
|
|
76
89
|
begin
|
|
77
|
-
used_paths =
|
|
90
|
+
used_paths = all_but_passive_paths - unused_paths
|
|
78
91
|
paths_to_use = Set.new
|
|
79
92
|
nodes_to_delete = Set.new
|
|
93
|
+
passive_nodes = Set.new
|
|
94
|
+
|
|
95
|
+
website.tree.node_access[:alcn].each do |alcn, node|
|
|
96
|
+
next if node == website.tree.dummy_root
|
|
97
|
+
|
|
98
|
+
begin
|
|
99
|
+
used_paths.delete(node.node_info[:src])
|
|
80
100
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
101
|
+
src_path = find_all_source_paths[node.node_info[:src]]
|
|
102
|
+
if !src_path
|
|
103
|
+
nodes_to_delete << node
|
|
104
|
+
elsif (!node.flagged?(:created) && src_path.changed?) || node.meta_info_changed?
|
|
105
|
+
node.flag(:reinit)
|
|
106
|
+
paths_to_use << node.node_info[:src]
|
|
107
|
+
elsif node.changed?
|
|
108
|
+
# nothing to be done here but method node.changed? has to be called
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
if src_path && src_path.passive?
|
|
112
|
+
passive_nodes << node
|
|
113
|
+
elsif src_path
|
|
114
|
+
referenced_nodes += node.node_info[:used_meta_info_nodes] + node.node_info[:used_nodes]
|
|
115
|
+
end
|
|
116
|
+
rescue Webgen::Error => e
|
|
117
|
+
e.alcn = node.alcn unless e.alcn
|
|
118
|
+
raise
|
|
119
|
+
rescue Exception => e
|
|
120
|
+
raise Webgen::Error.new(e, nil, node.alcn)
|
|
94
121
|
end
|
|
95
122
|
end
|
|
96
123
|
|
|
97
|
-
|
|
124
|
+
# add unused passive nodes to node_to_delete set
|
|
125
|
+
unreferenced_passive_nodes, other_passive_nodes = passive_nodes.partition do |pnode|
|
|
126
|
+
!referenced_nodes.include?(pnode.alcn)
|
|
127
|
+
end
|
|
128
|
+
refs = other_passive_nodes.collect {|n| (n.node_info[:used_meta_info_nodes] + n.node_info[:used_nodes]).to_a}.flatten
|
|
129
|
+
unreferenced_passive_nodes.each {|n| nodes_to_delete << n if !refs.include?(n.alcn)}
|
|
130
|
+
|
|
131
|
+
nodes_to_delete.each {|node| website.tree.delete_node(node)}
|
|
98
132
|
used_paths.merge(paths_to_use)
|
|
99
|
-
paths = create_nodes_from_paths(
|
|
133
|
+
paths = create_nodes_from_paths(used_paths.to_a.sort)
|
|
100
134
|
unused_paths.merge(used_paths - paths)
|
|
101
|
-
tree.node_access[:alcn].each {|name, node| tree.delete_node(node) if node.flagged?(:reinit)}
|
|
135
|
+
website.tree.node_access[:alcn].each {|name, node| website.tree.delete_node(node) if node.flagged?(:reinit)}
|
|
102
136
|
website.cache.reset_volatile_cache
|
|
103
137
|
end until used_paths.empty?
|
|
104
138
|
end
|
|
105
139
|
|
|
106
|
-
# Write out all changed nodes of the
|
|
107
|
-
def write_tree
|
|
140
|
+
# Write out all changed nodes of the <tt>website.tree</tt>.
|
|
141
|
+
def write_tree
|
|
108
142
|
output = website.blackboard.invoke(:output_instance)
|
|
109
143
|
|
|
110
|
-
tree.node_access[:alcn].select do |name, node|
|
|
111
|
-
use_node = (node != tree.dummy_root && node.flagged?(:dirty))
|
|
144
|
+
website.tree.node_access[:alcn].select do |name, node|
|
|
145
|
+
use_node = (node != website.tree.dummy_root && node.flagged?(:dirty))
|
|
112
146
|
node.unflag(:dirty_meta_info)
|
|
113
147
|
node.unflag(:created)
|
|
114
148
|
node.unflag(:dirty)
|
|
115
149
|
use_node
|
|
116
150
|
end.sort.each do |name, node|
|
|
117
|
-
next if node['no_output'] || !(content = node.content)
|
|
118
|
-
|
|
119
151
|
begin
|
|
152
|
+
next if node['no_output'] || !(content = node.content)
|
|
153
|
+
|
|
120
154
|
puts " "*4 + name, :verbose
|
|
121
155
|
type = if node.is_directory?
|
|
122
156
|
:directory
|
|
@@ -126,8 +160,11 @@ module Webgen
|
|
|
126
160
|
:file
|
|
127
161
|
end
|
|
128
162
|
output.write(node.path, content, type)
|
|
129
|
-
rescue
|
|
130
|
-
|
|
163
|
+
rescue Webgen::Error => e
|
|
164
|
+
e.alcn = node.alcn unless e.alcn
|
|
165
|
+
raise
|
|
166
|
+
rescue Exception => e
|
|
167
|
+
raise Webgen::RenderError.new(e, nil, node.alcn)
|
|
131
168
|
end
|
|
132
169
|
end
|
|
133
170
|
end
|
|
@@ -135,9 +172,15 @@ module Webgen
|
|
|
135
172
|
# Return a hash with all source paths.
|
|
136
173
|
def find_all_source_paths
|
|
137
174
|
if !defined?(@paths)
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
175
|
+
active_source = Webgen::Source::Stacked.new(website.config['sources'].collect do |mp, name, *args|
|
|
176
|
+
[mp, constant(name).new(*args)]
|
|
177
|
+
end)
|
|
178
|
+
passive_source = Webgen::Source::Stacked.new(website.config['passive_sources'].collect do |mp, name, *args|
|
|
179
|
+
[mp, constant(name).new(*args)]
|
|
180
|
+
end, true)
|
|
181
|
+
passive_source.paths.each {|path| path.passive = true }
|
|
182
|
+
source = Webgen::Source::Stacked.new([['/', active_source], ['/', passive_source]])
|
|
183
|
+
|
|
141
184
|
@paths = {}
|
|
142
185
|
source.paths.each do |path|
|
|
143
186
|
if !(website.config['sourcehandler.ignore'].any? {|pat| File.fnmatch(pat, path, File::FNM_CASEFOLD|File::FNM_DOTMATCH)})
|
|
@@ -155,13 +198,13 @@ module Webgen
|
|
|
155
198
|
|
|
156
199
|
options = (website.config['sourcehandler.casefold'] ? File::FNM_CASEFOLD : 0) |
|
|
157
200
|
(website.config['sourcehandler.use_hidden_files'] ? File::FNM_DOTMATCH : 0)
|
|
158
|
-
find_all_source_paths.values_at(*paths).select do |path|
|
|
201
|
+
find_all_source_paths.values_at(*paths).compact.select do |path|
|
|
159
202
|
patterns.any? {|pat| File.fnmatch(pat, path, options)}
|
|
160
203
|
end
|
|
161
204
|
end
|
|
162
205
|
|
|
163
|
-
# Use the source handlers to create nodes for the +paths+ in the
|
|
164
|
-
def create_nodes_from_paths(
|
|
206
|
+
# Use the source handlers to create nodes for the +paths+ in the <tt>website.tree</tt>.
|
|
207
|
+
def create_nodes_from_paths(paths)
|
|
165
208
|
used_paths = Set.new
|
|
166
209
|
website.config['sourcehandler.invoke'].sort.each do |priority, shns|
|
|
167
210
|
shns.each do |shn|
|
|
@@ -169,36 +212,39 @@ module Webgen
|
|
|
169
212
|
handler_paths = paths_for_handler(shn, paths)
|
|
170
213
|
used_paths.merge(handler_paths)
|
|
171
214
|
handler_paths.sort {|a,b| a.path.length <=> b.path.length}.each do |path|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
215
|
+
if !website.tree[path.parent_path]
|
|
216
|
+
used_paths.merge(create_nodes_from_paths([path.parent_path]))
|
|
217
|
+
end
|
|
218
|
+
create_nodes(path, sh)
|
|
175
219
|
end
|
|
176
220
|
end
|
|
177
221
|
end
|
|
178
222
|
used_paths
|
|
179
223
|
end
|
|
180
224
|
|
|
181
|
-
# Prepare everything to create
|
|
182
|
-
#
|
|
183
|
-
# of the
|
|
184
|
-
# all needed properties.
|
|
185
|
-
def create_nodes(
|
|
186
|
-
if !(parent = tree[parent_path_name])
|
|
187
|
-
raise "The specified parent path <#{parent_path_name}> does not exist"
|
|
188
|
-
end
|
|
225
|
+
# Prepare everything to create from the +path+ using the +source_handler+. If a block is
|
|
226
|
+
# given, the actual creation of the nodes is deferred to it. Otherwise the #create_node method
|
|
227
|
+
# of the +source_handler+ is used. After the nodes are created, it is also checked if they
|
|
228
|
+
# have all needed properties.
|
|
229
|
+
def create_nodes(path, source_handler) #:yields: path
|
|
189
230
|
path = path.dup
|
|
190
231
|
path.meta_info = default_meta_info(path, source_handler.class.name)
|
|
191
232
|
(website.cache[:sourcehandler_path_mi] ||= {})[[path.path, source_handler.class.name]] = path.meta_info.dup
|
|
192
|
-
website.blackboard.dispatch_msg(:before_node_created,
|
|
233
|
+
website.blackboard.dispatch_msg(:before_node_created, path)
|
|
193
234
|
*nodes = if block_given?
|
|
194
|
-
yield(
|
|
235
|
+
yield(path)
|
|
195
236
|
else
|
|
196
|
-
source_handler.create_node(
|
|
237
|
+
source_handler.create_node(path)
|
|
197
238
|
end
|
|
198
239
|
nodes.flatten.compact.each do |node|
|
|
199
240
|
website.blackboard.dispatch_msg(:after_node_created, node)
|
|
200
241
|
end
|
|
201
242
|
nodes
|
|
243
|
+
rescue Webgen::Error => e
|
|
244
|
+
e.alcn = path unless e.alcn
|
|
245
|
+
raise
|
|
246
|
+
rescue Exception => e
|
|
247
|
+
raise Webgen::NodeCreationError.new(e, source_handler.class.name, path)
|
|
202
248
|
end
|
|
203
249
|
|
|
204
250
|
# Return the default meta info for the pair of +path+ and +sh_name+.
|
|
@@ -19,7 +19,7 @@ module Webgen::SourceHandler
|
|
|
19
19
|
#
|
|
20
20
|
# The paths that are handled by a source handler are specified via path patterns (see
|
|
21
21
|
# below). During a webgen run the #create_node method for each source paths that matches a
|
|
22
|
-
# specified path pattern is called. And when it is time to write out the node, the
|
|
22
|
+
# specified path pattern is called. And when it is time to write out the node, the #content
|
|
23
23
|
# method is called to retrieve the rendered content.
|
|
24
24
|
#
|
|
25
25
|
# A source handler must not take any parameters on initialization and when this module is not
|
|
@@ -35,6 +35,7 @@ module Webgen::SourceHandler
|
|
|
35
35
|
# It also provides other utility methods:
|
|
36
36
|
# * #page_from_path
|
|
37
37
|
# * #content
|
|
38
|
+
# * #parent_node
|
|
38
39
|
#
|
|
39
40
|
# == Nodes Created for Paths
|
|
40
41
|
#
|
|
@@ -109,10 +110,11 @@ module Webgen::SourceHandler
|
|
|
109
110
|
# class SimpleCopy
|
|
110
111
|
#
|
|
111
112
|
# include Webgen::SourceHandler::Base
|
|
113
|
+
# include Webgen::WebsiteAccess
|
|
112
114
|
#
|
|
113
|
-
# def create_node(
|
|
115
|
+
# def create_node(path)
|
|
114
116
|
# path.ext += '.copied'
|
|
115
|
-
# super(
|
|
117
|
+
# super(path)
|
|
116
118
|
# end
|
|
117
119
|
#
|
|
118
120
|
# def content(node)
|
|
@@ -151,7 +153,8 @@ module Webgen::SourceHandler
|
|
|
151
153
|
when :year, :month, :day
|
|
152
154
|
ctime = path.meta_info['created_at']
|
|
153
155
|
if !ctime.kind_of?(Time)
|
|
154
|
-
raise "Invalid meta info 'created_at'
|
|
156
|
+
raise Webgen::NodeCreationError.new("Invalid meta info 'created_at', needed because of used output path style",
|
|
157
|
+
self.class.name, path)
|
|
155
158
|
end
|
|
156
159
|
ctime.send(part).to_s.rjust(2, '0')
|
|
157
160
|
when Symbol then path.send(part)
|
|
@@ -181,36 +184,49 @@ module Webgen::SourceHandler
|
|
|
181
184
|
if OutputPathHelpers.public_instance_methods(false).map(&:to_s).include?(method)
|
|
182
185
|
name = send(method, parent, path, use_lang_part)
|
|
183
186
|
name += '/' if path.path =~ /\/$/ && name !~ /\/$/
|
|
184
|
-
if (node = node_exists?(
|
|
185
|
-
name = node.path
|
|
186
|
-
elsif node
|
|
187
|
+
if (node = node_exists?(path, name)) && node.lang != path.meta_info['lang']
|
|
187
188
|
name = send(method, parent, path, (path.meta_info['lang'].nil? ? false : true))
|
|
188
189
|
name += '/' if path.path =~ /\/$/ && name !~ /\/$/
|
|
189
190
|
end
|
|
190
191
|
name
|
|
191
192
|
else
|
|
192
|
-
raise "Unknown method for creating output path: #{
|
|
193
|
+
raise Webgen::NodeCreationError.new("Unknown method for creating output path: #{path.meta_info['output_path']}",
|
|
194
|
+
self.class.name, path)
|
|
193
195
|
end
|
|
194
196
|
end
|
|
195
197
|
|
|
196
|
-
# Check if the node alcn and output path which would be created by #create_node
|
|
198
|
+
# Check if the node alcn and output path which would be created by #create_node exist. The
|
|
197
199
|
# +output_path+ to check for can individually be set.
|
|
198
|
-
def node_exists?(
|
|
199
|
-
|
|
200
|
+
def node_exists?(path, output_path = self.output_path(parent_node(path), path))
|
|
201
|
+
Webgen::WebsiteAccess.website.tree[path.alcn] || (!path.meta_info['no_output'] && Webgen::WebsiteAccess.website.tree[output_path, :path])
|
|
200
202
|
end
|
|
201
203
|
|
|
202
|
-
# Create a node
|
|
203
|
-
#
|
|
204
|
-
#
|
|
205
|
-
#
|
|
206
|
-
#
|
|
207
|
-
#
|
|
208
|
-
|
|
204
|
+
# Create a node from +path+ if it does not already exists or re-initalize an already existing
|
|
205
|
+
# node. The found node or the newly created node is returned afterwards. +nil+ is returned if no
|
|
206
|
+
# node can be created (e.g. when <tt>path.meta_info['draft']</tt> is set).
|
|
207
|
+
#
|
|
208
|
+
# The +options+ parameter can be used for providing the optional parameters:
|
|
209
|
+
#
|
|
210
|
+
# [<tt>:parent</tt>] The parent node under which the new node should be created. If this is not
|
|
211
|
+
# specified (the usual case), the parent node is determined by the
|
|
212
|
+
# #parent_node method.
|
|
213
|
+
#
|
|
214
|
+
# [<tt>:output_path</tt>] The output path that should be used for the node. If this is not
|
|
215
|
+
# specified (the usual case), the output path is determined via the
|
|
216
|
+
# #output_path method.
|
|
217
|
+
#
|
|
218
|
+
# Some additional node information like <tt>:src</tt> and <tt>:processor</tt> is set and the
|
|
219
|
+
# meta information is checked for validness. The created/re-initialized node is yielded if a
|
|
220
|
+
# block is given.
|
|
221
|
+
def create_node(path, options = {})
|
|
209
222
|
return nil if path.meta_info['draft']
|
|
210
|
-
|
|
223
|
+
parent = options[:parent] || parent_node(path)
|
|
224
|
+
output_path = options[:output_path] || self.output_path(parent, path)
|
|
225
|
+
node = node_exists?(path, output_path)
|
|
226
|
+
|
|
211
227
|
if node && (node.node_info[:src] != path.source_path || node.node_info[:processor] != self.class.name)
|
|
212
|
-
log(:warn) { "Node already exists: source = #{path.source_path} | path = #{node.path} | alcn = #{node.
|
|
213
|
-
return node
|
|
228
|
+
log(:warn) { "Node already exists: source = #{path.source_path} | path = #{node.path} | alcn = #{node.alcn}"}
|
|
229
|
+
return node #TODO: think! should nil be returned?
|
|
214
230
|
elsif !node
|
|
215
231
|
node = Webgen::Node.new(parent, output_path, path.cn, path.meta_info)
|
|
216
232
|
elsif node.flagged?(:reinit)
|
|
@@ -218,7 +234,11 @@ module Webgen::SourceHandler
|
|
|
218
234
|
else
|
|
219
235
|
return node
|
|
220
236
|
end
|
|
221
|
-
|
|
237
|
+
|
|
238
|
+
if !node['modified_at'].kind_of?(Time)
|
|
239
|
+
log(:warn) { "Meta information 'modified_at' set to current time in <#{node.alcn}> since its value '#{node['modified_at']}' was of type #{node['modified_at'].class}" } unless node['modified_at'].nil?
|
|
240
|
+
node['modified_at'] = Time.now
|
|
241
|
+
end
|
|
222
242
|
node.node_info[:src] = path.source_path
|
|
223
243
|
node.node_info[:creation_path] = path.path
|
|
224
244
|
node.node_info[:processor] = self.class.name
|
|
@@ -226,7 +246,10 @@ module Webgen::SourceHandler
|
|
|
226
246
|
node
|
|
227
247
|
end
|
|
228
248
|
|
|
229
|
-
# Return the content of the given +node+.
|
|
249
|
+
# Return the content of the given +node+. If the return value is not +nil+ then the node gets
|
|
250
|
+
# written, otherwise it is ignored.
|
|
251
|
+
#
|
|
252
|
+
# This default +content+ method just returns +nil+.
|
|
230
253
|
def content(node)
|
|
231
254
|
nil
|
|
232
255
|
end
|
|
@@ -237,12 +260,23 @@ module Webgen::SourceHandler
|
|
|
237
260
|
begin
|
|
238
261
|
page = Webgen::Page.from_data(path.io.data, path.meta_info)
|
|
239
262
|
rescue Webgen::Page::FormatError => e
|
|
240
|
-
raise "Error reading source path
|
|
263
|
+
raise Webgen::NodeCreationError.new("Error reading source path: #{e.message}",
|
|
264
|
+
self.class.name, path)
|
|
241
265
|
end
|
|
242
266
|
path.meta_info = page.meta_info
|
|
243
267
|
page
|
|
244
268
|
end
|
|
245
269
|
|
|
270
|
+
# Return the parent node for the given +path+.
|
|
271
|
+
def parent_node(path)
|
|
272
|
+
parent_dir = (path.parent_path == '' ? '' : Webgen::Path.new(path.parent_path).alcn)
|
|
273
|
+
if !(parent = Webgen::WebsiteAccess.website.tree[parent_dir])
|
|
274
|
+
raise Webgen::NodeCreationError.new("The needed parent path <#{parent_dir}> does not exist",
|
|
275
|
+
self.class.name, path)
|
|
276
|
+
end
|
|
277
|
+
parent
|
|
278
|
+
end
|
|
279
|
+
|
|
246
280
|
end
|
|
247
281
|
|
|
248
282
|
end
|