webgen 1.0.0.beta3 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/COPYING +23 -1
- data/Rakefile +16 -77
- data/VERSION +1 -1
- data/bin/webgen +0 -0
- data/data/webgen/basic_website_template/ext/init.rb +3 -1
- data/data/webgen/basic_website_template/src/.gitignore +0 -0
- data/data/webgen/basic_website_template/webgen.config +1 -1
- data/data/webgen/bundle_template_files/info.yaml.erb +14 -2
- data/data/webgen/passive_sources/default.metainfo +10 -0
- data/data/webgen/passive_sources/templates/api.template +16 -2
- data/data/webgen/passive_sources/templates/feed.template +5 -5
- data/data/webgen/passive_sources/templates/sitemap.template +1 -1
- data/data/webgen/passive_sources/templates/tag.template +8 -4
- data/lib/webgen/blackboard.rb +21 -5
- data/lib/webgen/bundle/built-in-show-changes/info.yaml +17 -0
- data/lib/webgen/bundle/built-in-show-changes/init.rb +4 -5
- data/lib/webgen/bundle/built-in/info.yaml +1064 -0
- data/lib/webgen/bundle/built-in/init.rb +103 -136
- data/lib/webgen/bundle_loader.rb +82 -9
- data/lib/webgen/cli.rb +12 -8
- data/lib/webgen/cli/commands/create.rb +27 -0
- data/lib/webgen/cli/{create_bundle_command.rb → commands/create_bundle.rb} +2 -2
- data/lib/webgen/cli/{create_command.rb → commands/create_website.rb} +2 -2
- data/lib/webgen/cli/commands/generate.rb +66 -0
- data/lib/webgen/cli/{install_bundle_command.rb → commands/install.rb} +1 -1
- data/lib/webgen/cli/{show_command.rb → commands/show.rb} +6 -4
- data/lib/webgen/cli/{list_bundle_command.rb → commands/show_bundles.rb} +12 -15
- data/lib/webgen/cli/{show_config_command.rb → commands/show_config.rb} +34 -6
- data/lib/webgen/cli/{show_dependencies_command.rb → commands/show_dependencies.rb} +0 -0
- data/lib/webgen/cli/{show_extensions_command.rb → commands/show_extensions.rb} +1 -13
- data/lib/webgen/cli/{show_tree_command.rb → commands/show_tree.rb} +3 -0
- data/lib/webgen/cli/utils.rb +1 -1
- data/lib/webgen/configuration.rb +9 -11
- data/lib/webgen/content_processor/html_head.rb +3 -4
- data/lib/webgen/content_processor/rainpress.rb +21 -0
- data/lib/webgen/content_processor/sass.rb +8 -8
- data/lib/webgen/content_processor/tikz.rb +59 -16
- data/lib/webgen/item_tracker.rb +33 -12
- data/lib/webgen/item_tracker/missing_node.rb +5 -5
- data/lib/webgen/item_tracker/template_chain.rb +52 -0
- data/lib/webgen/misc/dummy_index.rb +78 -0
- data/lib/webgen/node.rb +1 -1
- data/lib/webgen/node_finder.rb +86 -141
- data/lib/webgen/page.rb +5 -5
- data/lib/webgen/path.rb +4 -1
- data/lib/webgen/path_handler.rb +25 -21
- data/lib/webgen/path_handler/api.rb +36 -3
- data/lib/webgen/path_handler/base.rb +20 -4
- data/lib/webgen/path_handler/feed.rb +6 -2
- data/lib/webgen/path_handler/meta_info.rb +4 -2
- data/lib/webgen/path_handler/page.rb +5 -7
- data/lib/webgen/path_handler/sitemap.rb +6 -1
- data/lib/webgen/path_handler/virtual.rb +6 -8
- data/lib/webgen/source/file_system.rb +2 -2
- data/lib/webgen/tag.rb +22 -18
- data/lib/webgen/tag/menu.rb +5 -5
- data/lib/webgen/test_helper.rb +18 -18
- data/lib/webgen/utils/external_command.rb +1 -1
- data/lib/webgen/utils/tag_parser.rb +1 -1
- data/lib/webgen/vendor/rainpress.rb +168 -0
- data/lib/webgen/version.rb +1 -1
- data/lib/webgen/website.rb +10 -10
- data/man/man1/webgen.1 +54 -23
- data/test/test_documentation.rb +27 -4
- data/test/webgen/cli/test_logger.rb +1 -1
- data/test/webgen/content_processor/test_blocks.rb +1 -1
- data/test/webgen/content_processor/test_builder.rb +3 -2
- data/test/webgen/content_processor/test_erb.rb +1 -1
- data/test/webgen/content_processor/test_erubis.rb +2 -2
- data/test/webgen/content_processor/test_fragments.rb +1 -1
- data/test/webgen/content_processor/test_haml.rb +2 -2
- data/test/webgen/content_processor/test_html_head.rb +5 -1
- data/test/webgen/content_processor/test_kramdown.rb +2 -2
- data/test/webgen/content_processor/test_maruku.rb +2 -2
- data/test/webgen/content_processor/test_r_discount.rb +2 -2
- data/test/webgen/content_processor/test_r_doc.rb +1 -1
- data/test/webgen/content_processor/test_rainpress.rb +19 -0
- data/test/webgen/content_processor/test_red_cloth.rb +2 -2
- data/test/webgen/content_processor/test_ruby.rb +1 -1
- data/test/webgen/content_processor/test_sass.rb +8 -6
- data/test/webgen/content_processor/test_scss.rb +3 -3
- data/test/webgen/content_processor/test_tags.rb +1 -1
- data/test/webgen/content_processor/test_tidy.rb +9 -1
- data/test/webgen/content_processor/test_tikz.rb +6 -3
- data/test/webgen/content_processor/test_xmllint.rb +9 -2
- data/test/webgen/destination/test_file_system.rb +4 -4
- data/test/webgen/item_tracker/test_file.rb +1 -1
- data/test/webgen/item_tracker/test_missing_node.rb +1 -1
- data/test/webgen/item_tracker/test_node_content.rb +1 -1
- data/test/webgen/item_tracker/test_node_meta_info.rb +1 -1
- data/test/webgen/item_tracker/test_nodes.rb +2 -4
- data/test/webgen/item_tracker/test_template_chain.rb +36 -0
- data/test/webgen/misc/test_dummy_index.rb +83 -0
- data/test/webgen/path_handler/test_api.rb +6 -46
- data/test/webgen/path_handler/test_base.rb +3 -2
- data/test/webgen/path_handler/test_copy.rb +1 -1
- data/test/webgen/path_handler/test_feed.rb +3 -4
- data/test/webgen/path_handler/test_meta_info.rb +1 -1
- data/test/webgen/path_handler/test_page.rb +1 -1
- data/test/webgen/path_handler/test_page_utils.rb +1 -1
- data/test/webgen/path_handler/test_sitemap.rb +3 -5
- data/test/webgen/path_handler/test_template.rb +1 -1
- data/test/webgen/path_handler/test_virtual.rb +1 -3
- data/test/webgen/source/test_file_system.rb +9 -4
- data/test/webgen/source/test_stacked.rb +1 -1
- data/test/webgen/source/test_tar_archive.rb +2 -2
- data/test/webgen/tag/test_breadcrumb_trail.rb +1 -1
- data/test/webgen/tag/test_coderay.rb +3 -2
- data/test/webgen/tag/test_date.rb +1 -1
- data/test/webgen/tag/test_execute_command.rb +1 -1
- data/test/webgen/tag/test_include_file.rb +1 -1
- data/test/webgen/tag/test_langbar.rb +1 -1
- data/test/webgen/tag/test_link.rb +1 -1
- data/test/webgen/tag/test_menu.rb +12 -30
- data/test/webgen/tag/test_meta_info.rb +1 -1
- data/test/webgen/tag/test_relocatable.rb +1 -1
- data/test/webgen/tag/test_tikz.rb +3 -2
- data/test/webgen/task/test_create_website.rb +2 -2
- data/test/webgen/test_blackboard.rb +11 -3
- data/test/webgen/test_bundle_loader.rb +26 -9
- data/test/webgen/test_cache.rb +1 -1
- data/test/webgen/test_cli.rb +2 -2
- data/test/webgen/test_configuration.rb +8 -9
- data/test/webgen/test_content_processor.rb +1 -1
- data/test/webgen/test_context.rb +1 -1
- data/test/webgen/test_core_ext.rb +1 -1
- data/test/webgen/test_destination.rb +1 -1
- data/test/webgen/test_error.rb +5 -5
- data/test/webgen/test_extension_manager.rb +1 -1
- data/test/webgen/test_item_tracker.rb +26 -5
- data/test/webgen/test_languages.rb +1 -1
- data/test/webgen/test_logger.rb +1 -1
- data/test/webgen/test_node.rb +1 -1
- data/test/webgen/test_node_finder.rb +2 -2
- data/test/webgen/test_page.rb +5 -5
- data/test/webgen/test_path.rb +8 -8
- data/test/webgen/test_rake_task.rb +1 -1
- data/test/webgen/test_source.rb +1 -1
- data/test/webgen/test_tag.rb +16 -24
- data/test/webgen/test_task.rb +1 -1
- data/test/webgen/test_tree.rb +1 -1
- data/test/webgen/test_utils.rb +1 -1
- data/test/webgen/test_website.rb +1 -1
- data/test/webgen/utils/test_tag_parser.rb +1 -1
- metadata +85 -105
- data/lib/webgen/cli/bundle_command.rb +0 -30
- data/lib/webgen/cli/generate_command.rb +0 -25
data/lib/webgen/node.rb
CHANGED
|
@@ -216,7 +216,7 @@ module Webgen
|
|
|
216
216
|
# Return all versions of this node.
|
|
217
217
|
def versions
|
|
218
218
|
tree.node_access[:alcn].select {|alcn, n| n.node_info[:path] == node_info[:path]}.
|
|
219
|
-
each_with_object({}) {|(
|
|
219
|
+
each_with_object({}) {|(_, v), h| h[v['version']] = v}
|
|
220
220
|
end
|
|
221
221
|
|
|
222
222
|
end
|
data/lib/webgen/node_finder.rb
CHANGED
|
@@ -21,116 +21,22 @@ module Webgen
|
|
|
21
21
|
#
|
|
22
22
|
# == Finder options
|
|
23
23
|
#
|
|
24
|
-
#
|
|
25
|
-
# filters available if you are using extension
|
|
26
|
-
#
|
|
27
|
-
# === Non-filter options
|
|
28
|
-
#
|
|
29
|
-
# These options are not used for filtering out nodes but provide additional functionality.
|
|
30
|
-
#
|
|
31
|
-
# [:limit]
|
|
32
|
-
# Value: an integer. Specifies the maximum number of nodes that should be returned. Implies
|
|
33
|
-
# 'flatten = true'.
|
|
34
|
-
#
|
|
35
|
-
# Note that fewer nodes may be returned if fewer nodes match the filter criterias.
|
|
36
|
-
#
|
|
37
|
-
# [:offset]
|
|
38
|
-
# Value: an integer. Specifies how many nodes from the front of the list should *not* be
|
|
39
|
-
# returned. Implies 'flatten = true'.
|
|
40
|
-
#
|
|
41
|
-
# [:levels]
|
|
42
|
-
# Value: one integer (is used as start and end level) or an array with two integers (the start
|
|
43
|
-
# and end levels). All nodes whose hierarchy level in the returned node hierarchy is greater
|
|
44
|
-
# than or equal to the start level and lower than or equal to the end level are used.
|
|
45
|
-
#
|
|
46
|
-
# Only used when the node hierarchy is not flattened.
|
|
47
|
-
#
|
|
48
|
-
# [:flatten]
|
|
49
|
-
# Value: anything except +nil+ or +false+. A flat list of nodes is returned if this option is
|
|
50
|
-
# set, otherwise the nodes are returned in their correct hierarchical order using nested lists.
|
|
51
|
-
#
|
|
52
|
-
# Note that any missing nodes in the hierarchy are automatically added so that traversing the
|
|
53
|
-
# hierarchy is always possible. For example, if we have the tree '/a/b/c' and only nodes +a+ and
|
|
54
|
-
# +c+ are found, node +b+ is automatically added.
|
|
55
|
-
#
|
|
56
|
-
# [:sort]
|
|
57
|
-
# Value: +nil+/+false+, +true+ or a meta information key. If +nil+ or +false+ is specified, no
|
|
58
|
-
# sorting is performed. If +true+ is specified, the meta information +sort_info+ (or if absent,
|
|
59
|
-
# the meta information +title+) is used for sorting. If the compared values are both integers, a
|
|
60
|
-
# numeric comparison is done, else a string comparison. If a meta information key is specified,
|
|
61
|
-
# the value of this meta information is used for comparison of nodes (again, if both compared
|
|
62
|
-
# values are integers, a numeric comparison is done, else a string comparison).
|
|
63
|
-
#
|
|
64
|
-
# [:reverse]
|
|
65
|
-
# Value: +true+ of +false+/+nil+. If this option is set to +true+, the sort order is reversed.
|
|
66
|
-
#
|
|
67
|
-
# === Filter options
|
|
68
|
-
#
|
|
69
|
-
# These options are used for filtering the nodes. All nodes are used by default if no filter
|
|
70
|
-
# options are specified.
|
|
71
|
-
#
|
|
72
|
-
# [:alcn]
|
|
73
|
-
# Value: an alcn pattern or an array of alcn patterns. Nodes that match any of the patterns are
|
|
74
|
-
# used.
|
|
75
|
-
#
|
|
76
|
-
# [:lang]
|
|
77
|
-
# Value: a language code/+nil+/the special value +node+ or an array of these values. Nodes that
|
|
78
|
-
# have one of the specified language codes, are language independent (in case of the value
|
|
79
|
-
# +nil+) or have the same language as the reference node (in case of the value +node+) are
|
|
80
|
-
# used.
|
|
81
|
-
#
|
|
82
|
-
# [:mi]
|
|
83
|
-
# Value: a hash with meta information key to value mappings. Only nodes that have the same
|
|
84
|
-
# values for all meta information keys are used.
|
|
85
|
-
#
|
|
86
|
-
# [:or]
|
|
87
|
-
# Value: a finder option set or an array of finder options sets (specifying option set names is
|
|
88
|
-
# also possible). Nodes that appear in any specified option set are additionally used.
|
|
89
|
-
#
|
|
90
|
-
# [:and]
|
|
91
|
-
# Value: a finder option set or an array of finder options sets (specifying option set names is
|
|
92
|
-
# also possible). Only nodes that appear in all specified option sets are used.
|
|
93
|
-
#
|
|
94
|
-
# [:not]
|
|
95
|
-
# Value: a finder option set or an array of finder options sets (specifying option set names is
|
|
96
|
-
# also possible). Only nodes that do not appear in any specified option set are used.
|
|
97
|
-
#
|
|
98
|
-
# [:absolute_levels]
|
|
99
|
-
# Value: one integer (is used as start and end level) or an array with two integers (the start
|
|
100
|
-
# and end levels). All nodes whose hierarchy level in the node tree are greater than or equal to
|
|
101
|
-
# the start level and lower than or equal to the end level are used.
|
|
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
|
-
#
|
|
106
|
-
# [:ancestors]
|
|
107
|
-
# Value: +true+ or +false+/+nil+. If this filter option is set to +true+, only nodes that are
|
|
108
|
-
# ancestors of the reference node are used. The reference node itself is used as well.
|
|
109
|
-
#
|
|
110
|
-
# [:descendants]
|
|
111
|
-
# Value: +true+ or +false+/+nil+. If this filter option is set to +true+, only nodes that are
|
|
112
|
-
# descendants of the reference node are used. The reference node itself is used as well.
|
|
113
|
-
#
|
|
114
|
-
# [:siblings]
|
|
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.
|
|
24
|
+
# A complete list of the supported finder options can be found in the user documentation! Note
|
|
25
|
+
# that there may also be other 3rd party node filters available if you are using extension
|
|
26
|
+
# bundles!
|
|
126
27
|
#
|
|
127
28
|
# == Implementing a filter module
|
|
128
29
|
#
|
|
129
30
|
# Implementing a filter module is very easy. Just create a module that contains your filter
|
|
130
31
|
# methods and tell the NodeFinder object about it using the #add_filter_module method. A filter
|
|
131
|
-
# method needs to take three arguments:
|
|
32
|
+
# method needs to take three arguments: the Result stucture, the reference node and the filter
|
|
132
33
|
# value.
|
|
133
34
|
#
|
|
35
|
+
# The +result.nodes+ accessor contains the array of nodes that should be manipulated in-place.
|
|
36
|
+
#
|
|
37
|
+
# If a filter uses the reference node in any way, it has to set +result.ref_node_used+ to +true+
|
|
38
|
+
# to allow proper caching!
|
|
39
|
+
#
|
|
134
40
|
# Here is a sample filter module which provides the ability to filter nodes based on the meta
|
|
135
41
|
# information key +category+. The +category+ key contains an array with one or more categories.
|
|
136
42
|
# The value for this category filter is one or more strings and the filter returns those nodes
|
|
@@ -138,9 +44,9 @@ module Webgen
|
|
|
138
44
|
#
|
|
139
45
|
# module CategoryFilter
|
|
140
46
|
#
|
|
141
|
-
# def filter_on_category(
|
|
47
|
+
# def filter_on_category(result, ref_node, categories)
|
|
142
48
|
# categories = [categories].flatten # needed in case categories is a string
|
|
143
|
-
# nodes.select {|n| categories.any? {|c| n['category'].include?(c)}}
|
|
49
|
+
# result.nodes.select! {|n| categories.any? {|c| n['category'].include?(c)}}
|
|
144
50
|
# end
|
|
145
51
|
#
|
|
146
52
|
# end
|
|
@@ -149,6 +55,11 @@ module Webgen
|
|
|
149
55
|
#
|
|
150
56
|
class NodeFinder
|
|
151
57
|
|
|
58
|
+
# Result class used when filtering the nodes.
|
|
59
|
+
#
|
|
60
|
+
# The attribute +ref_node_used+ must not be set to +false+ once it is +true+!
|
|
61
|
+
Result = Struct.new(:nodes, :ref_node_used)
|
|
62
|
+
|
|
152
63
|
# Create a new NodeFinder object for the given website.
|
|
153
64
|
def initialize(website)
|
|
154
65
|
@website = website
|
|
@@ -196,7 +107,7 @@ module Webgen
|
|
|
196
107
|
flatten = true if limit || offset
|
|
197
108
|
levels = [levels || [1, 1_000_000]].flatten.map {|i| i.to_i}
|
|
198
109
|
|
|
199
|
-
nodes = filter_nodes(opts, ref_node)
|
|
110
|
+
nodes, ref_node_used = filter_nodes(opts, ref_node)
|
|
200
111
|
|
|
201
112
|
if flatten
|
|
202
113
|
sort_nodes(nodes, sort, reverse)
|
|
@@ -226,7 +137,7 @@ module Webgen
|
|
|
226
137
|
sort_nodes(nodes, sort, reverse, false)
|
|
227
138
|
end
|
|
228
139
|
|
|
229
|
-
cache_result(opts_or_name, ref_node, nodes)
|
|
140
|
+
cache_result(opts_or_name, ref_node, nodes, ref_node_used)
|
|
230
141
|
end
|
|
231
142
|
|
|
232
143
|
#######
|
|
@@ -234,11 +145,19 @@ module Webgen
|
|
|
234
145
|
#######
|
|
235
146
|
|
|
236
147
|
def cached_result(opts, ref_node)
|
|
237
|
-
|
|
148
|
+
result_cache[opts] || result_cache[[opts, ref_node.alcn]]
|
|
238
149
|
end
|
|
239
150
|
|
|
240
|
-
def cache_result(opts, ref_node, result)
|
|
241
|
-
|
|
151
|
+
def cache_result(opts, ref_node, result, ref_node_used)
|
|
152
|
+
if ref_node_used
|
|
153
|
+
result_cache[[opts, ref_node.alcn]] = result
|
|
154
|
+
else
|
|
155
|
+
result_cache[opts] = result
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def result_cache
|
|
160
|
+
@website.cache.volatile[:node_finder] ||= {}
|
|
242
161
|
end
|
|
243
162
|
|
|
244
163
|
def prepare_options_hash(opts_or_name)
|
|
@@ -260,15 +179,17 @@ module Webgen
|
|
|
260
179
|
nodes = @website.tree.node_access[:alcn].values
|
|
261
180
|
nodes.delete(@website.tree.dummy_root)
|
|
262
181
|
|
|
182
|
+
result = Result.new(nodes, false)
|
|
183
|
+
|
|
263
184
|
opts.each do |filter, value|
|
|
264
185
|
if @mapping.has_key?(filter)
|
|
265
|
-
|
|
186
|
+
send(@mapping[filter], result, ref_node, value)
|
|
266
187
|
else
|
|
267
188
|
@website.logger.warn { "Ignoring unknown node finder filter '#{filter}'" }
|
|
268
189
|
end
|
|
269
190
|
end
|
|
270
191
|
|
|
271
|
-
nodes
|
|
192
|
+
[result.nodes, result.ref_node_used]
|
|
272
193
|
end
|
|
273
194
|
|
|
274
195
|
def sort_nodes(nodes, sort, reverse, flat_mode = true)
|
|
@@ -292,78 +213,102 @@ module Webgen
|
|
|
292
213
|
|
|
293
214
|
# :section: Filter methods
|
|
294
215
|
|
|
295
|
-
def filter_and(
|
|
216
|
+
def filter_and(result, ref_node, opts)
|
|
296
217
|
[opts].flatten.each do |cur_opts|
|
|
297
218
|
cur_opts = prepare_options_hash(cur_opts)
|
|
298
219
|
remove_non_filter_options(cur_opts)
|
|
299
|
-
nodes
|
|
220
|
+
nodes, ref_node_used = filter_nodes(cur_opts, ref_node)
|
|
221
|
+
result.nodes &= nodes
|
|
222
|
+
result.ref_node_used |= ref_node_used
|
|
300
223
|
end
|
|
301
|
-
nodes
|
|
302
224
|
end
|
|
303
225
|
|
|
304
|
-
def filter_or(
|
|
226
|
+
def filter_or(result, ref_node, opts)
|
|
305
227
|
[opts].flatten.each do |cur_opts|
|
|
306
228
|
cur_opts = prepare_options_hash(cur_opts)
|
|
307
229
|
remove_non_filter_options(cur_opts)
|
|
308
|
-
nodes
|
|
230
|
+
nodes, ref_node_used = filter_nodes(cur_opts, ref_node)
|
|
231
|
+
result.nodes |= nodes
|
|
232
|
+
result.ref_node_used |= ref_node_used
|
|
309
233
|
end
|
|
310
|
-
nodes
|
|
311
234
|
end
|
|
312
235
|
|
|
313
|
-
def filter_not(
|
|
236
|
+
def filter_not(result, ref_node, opts)
|
|
314
237
|
[opts].flatten.each do |cur_opts|
|
|
315
238
|
cur_opts = prepare_options_hash(cur_opts)
|
|
316
239
|
remove_non_filter_options(cur_opts)
|
|
317
|
-
nodes
|
|
240
|
+
nodes, ref_node_used = filter_nodes(cur_opts, ref_node)
|
|
241
|
+
result.nodes -= nodes
|
|
242
|
+
result.ref_node_used |= ref_node_used
|
|
318
243
|
end
|
|
319
|
-
nodes
|
|
320
244
|
end
|
|
321
245
|
|
|
322
|
-
def filter_meta_info(
|
|
323
|
-
nodes.keep_if {|n| mi.all? {|key, val| n[key] == val}}
|
|
246
|
+
def filter_meta_info(result, ref_node, mi)
|
|
247
|
+
result.nodes.keep_if {|n| mi.all? {|key, val| n[key] == val}}
|
|
324
248
|
end
|
|
325
249
|
|
|
326
|
-
def filter_alcn(
|
|
250
|
+
def filter_alcn(result, ref_node, alcn)
|
|
251
|
+
result.ref_node_used = true
|
|
327
252
|
alcn = [alcn].flatten.map {|a| Webgen::Path.append(ref_node.alcn, a.to_s)}
|
|
328
|
-
nodes.keep_if {|n| alcn.any? {|a| n =~ a}}
|
|
253
|
+
result.nodes.keep_if {|n| alcn.any? {|a| n =~ a}}
|
|
329
254
|
end
|
|
330
255
|
|
|
331
|
-
def filter_absolute_levels(
|
|
332
|
-
range = [range].flatten.map
|
|
333
|
-
|
|
256
|
+
def filter_absolute_levels(result, ref_node, range)
|
|
257
|
+
range = [range].flatten.map do |i|
|
|
258
|
+
if (i = i.to_i) < 0
|
|
259
|
+
result.ref_node_used = true
|
|
260
|
+
ref_node.level + 1 + i
|
|
261
|
+
else
|
|
262
|
+
i
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
result.nodes.keep_if {|n| n.level >= range.first && n.level <= range.last}
|
|
334
266
|
end
|
|
335
267
|
|
|
336
|
-
def filter_lang(
|
|
337
|
-
langs = [langs].flatten.map
|
|
338
|
-
|
|
268
|
+
def filter_lang(result, ref_node, langs)
|
|
269
|
+
langs = [langs].flatten.map do |l|
|
|
270
|
+
if l == 'node'
|
|
271
|
+
result.ref_node_used = true
|
|
272
|
+
ref_node.lang
|
|
273
|
+
else
|
|
274
|
+
l
|
|
275
|
+
end
|
|
276
|
+
end.uniq
|
|
277
|
+
result.nodes.keep_if {|n| langs.any? {|l| n.lang == l}}
|
|
339
278
|
end
|
|
340
279
|
|
|
341
|
-
def filter_ancestors(
|
|
342
|
-
return
|
|
280
|
+
def filter_ancestors(result, ref_node, enabled)
|
|
281
|
+
return unless enabled
|
|
282
|
+
result.ref_node_used = true
|
|
283
|
+
|
|
343
284
|
nodes = []
|
|
344
285
|
node = ref_node
|
|
345
286
|
until node == node.tree.dummy_root
|
|
346
287
|
nodes.unshift(node)
|
|
347
288
|
node = node.parent
|
|
348
289
|
end
|
|
349
|
-
nodes
|
|
290
|
+
result.nodes = nodes
|
|
350
291
|
end
|
|
351
292
|
|
|
352
|
-
def filter_descendants(
|
|
353
|
-
return
|
|
354
|
-
|
|
293
|
+
def filter_descendants(result, ref_node, enabled)
|
|
294
|
+
return unless enabled
|
|
295
|
+
result.ref_node_used = true
|
|
296
|
+
|
|
297
|
+
result.nodes.keep_if do |n|
|
|
355
298
|
n = n.parent while n != n.tree.dummy_root && n != ref_node
|
|
356
299
|
n == ref_node
|
|
357
300
|
end
|
|
358
301
|
end
|
|
359
302
|
|
|
360
|
-
def filter_siblings(
|
|
361
|
-
return
|
|
303
|
+
def filter_siblings(result, ref_node, value)
|
|
304
|
+
return unless value
|
|
305
|
+
result.ref_node_used = true
|
|
306
|
+
|
|
362
307
|
if value == true
|
|
363
|
-
nodes.keep_if {|n| n.parent == ref_node.parent}
|
|
308
|
+
result.nodes.keep_if {|n| n.parent == ref_node.parent}
|
|
364
309
|
else
|
|
365
310
|
value = [value].flatten.map {|i| (i = i.to_i) < 0 ? ref_node.level + 1 + i : i}
|
|
366
|
-
nodes.keep_if do |n|
|
|
311
|
+
result.nodes.keep_if do |n|
|
|
367
312
|
n.level >= value.first && n.level <= value.last && (n.parent.is_ancestor_of?(ref_node) || n.is_root?)
|
|
368
313
|
end
|
|
369
314
|
end
|
data/lib/webgen/page.rb
CHANGED
|
@@ -18,11 +18,11 @@ module Webgen
|
|
|
18
18
|
|
|
19
19
|
# :stopdoc:
|
|
20
20
|
RE_NEWLINE = /\r?\n/
|
|
21
|
-
RE_META_INFO_START = /\A
|
|
21
|
+
RE_META_INFO_START = /\A---[ \t]*#{RE_NEWLINE}/
|
|
22
22
|
RE_META_INFO = /#{RE_META_INFO_START}.*?#{RE_NEWLINE}(?=---.*?#{RE_NEWLINE}|\Z)/m
|
|
23
|
-
RE_BLOCKS_START_SIMPLE = /^--- (\w+)(
|
|
24
|
-
RE_BLOCKS_START_COMPLEX = /^---
|
|
25
|
-
RE_BLOCKS_START = /^---(?:
|
|
23
|
+
RE_BLOCKS_START_SIMPLE = /^---[ \t]*$|^---[ \t]+(\w+)[ \t]*(?:[ \t]+-+[ \t]*)?$|^$/
|
|
24
|
+
RE_BLOCKS_START_COMPLEX = /^---[ \t]+?(?:[ \t]*((?:\w+:\S*[ \t]*)*))?(?:[ \t]+-+[ \t]*)?$/
|
|
25
|
+
RE_BLOCKS_START = /^---(?:[ \t]+.*?|)(?=#{RE_NEWLINE})/
|
|
26
26
|
RE_BLOCKS = /(?:(#{RE_BLOCKS_START})|\A)#{RE_NEWLINE}?(.*?)(?:(?=#{RE_BLOCKS_START})|\z)/m
|
|
27
27
|
RE_PAGE = /(#{RE_META_INFO})?(.*)/m
|
|
28
28
|
# :startdoc:
|
|
@@ -53,7 +53,7 @@ module Webgen
|
|
|
53
53
|
unless meta_info.kind_of?(Hash)
|
|
54
54
|
raise FormatError, "Invalid structure of meta information block: expected YAML hash but found #{meta_info.class}"
|
|
55
55
|
end
|
|
56
|
-
rescue ArgumentError, SyntaxError => e
|
|
56
|
+
rescue ArgumentError, SyntaxError, YAML::SyntaxError => e
|
|
57
57
|
raise FormatError, "Invalid YAML syntax in meta information block: #{e.message}"
|
|
58
58
|
end
|
|
59
59
|
meta_info
|
data/lib/webgen/path.rb
CHANGED
|
@@ -64,11 +64,14 @@ module Webgen
|
|
|
64
64
|
|
|
65
65
|
# Return +true+ if the given path string matches the given path pattern.
|
|
66
66
|
#
|
|
67
|
+
# If a fragment path (i.e. one which has a hash character somewhere) should be matched, the
|
|
68
|
+
# pattern needs to have a hash character as well.
|
|
69
|
+
#
|
|
67
70
|
# For information on which patterns are supported, have a look at the API documentation of
|
|
68
71
|
# File.fnmatch.
|
|
69
72
|
def self.matches_pattern?(path, pattern, options = File::FNM_DOTMATCH|File::FNM_CASEFOLD|File::FNM_PATHNAME)
|
|
70
73
|
pattern += '/' if path =~ /\/$/ && pattern !~ /\/$|^$/
|
|
71
|
-
File.fnmatch(pattern, path, options)
|
|
74
|
+
(path.to_s.include?('#') ? pattern.include?('#') : true) && File.fnmatch(pattern, path, options)
|
|
72
75
|
end
|
|
73
76
|
|
|
74
77
|
# Construct a localized canonical name from a given canonical name and a language.
|
data/lib/webgen/path_handler.rb
CHANGED
|
@@ -17,14 +17,10 @@ module Webgen
|
|
|
17
17
|
# source to the destination, or a complex things, like generating a whole set of nodes from one
|
|
18
18
|
# input path (e.g. generating a whole image gallery)!
|
|
19
19
|
#
|
|
20
|
-
# The paths that are handled by a path handler are specified via path patterns
|
|
21
|
-
# #create_nodes method of a path handler is called for each source path that
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
# Also note that any method invoked on a Node object that is not defined in the Node class itself
|
|
26
|
-
# is forwarded to the associated path handler, adding the node as first parameter to the parameter
|
|
27
|
-
# list.
|
|
20
|
+
# The paths that are handled by a path handler are generally specified via path patterns. The
|
|
21
|
+
# #create_nodes method of a path handler is called for each source path that should be handled.
|
|
22
|
+
# And when it is time to write out a node, the #content method on the path handler associated with
|
|
23
|
+
# the node is called to retrieve the rendered content of the node.
|
|
28
24
|
#
|
|
29
25
|
# === Tree creation
|
|
30
26
|
#
|
|
@@ -40,10 +36,11 @@ module Webgen
|
|
|
40
36
|
# created before their file nodes.
|
|
41
37
|
#
|
|
42
38
|
# 2. When a path handler is used for creating nodes, all source paths (retrieved by using
|
|
43
|
-
# Webgen::Source#paths method) that match one of the associated patterns
|
|
39
|
+
# Webgen::Source#paths method) that match one of the associated patterns and/or all path with
|
|
40
|
+
# the 'handler' meta information set to the path handler are used.
|
|
44
41
|
#
|
|
45
|
-
# 3. The meta information of a used source path is then updated with the meta information
|
|
46
|
-
#
|
|
42
|
+
# 3. The meta information of a used source path is then updated with the meta information applied
|
|
43
|
+
# by methods registered for the :apply_meta_info_to_path blackboard message.
|
|
47
44
|
#
|
|
48
45
|
# After that the source path is given to the #parse_meta_info! method of the path handler so
|
|
49
46
|
# that meta information of the path can be updated with meta information stored in the content
|
|
@@ -53,7 +50,7 @@ module Webgen
|
|
|
53
50
|
# should be used for creating nodes and each path version is then given to the #create_nodes
|
|
54
51
|
# method of the path handler so that it can create one or more nodes.
|
|
55
52
|
#
|
|
56
|
-
# 4. Nodes returned by
|
|
53
|
+
# 4. Nodes returned by #creates_nodes of a path handler are assumed to have the Node#node_info
|
|
57
54
|
# keys :path and :path_handler and the meta info key 'modified_at' correctly set (this is
|
|
58
55
|
# automatically done if the Webgen::PathHandler::Base#create_node method is used).
|
|
59
56
|
#
|
|
@@ -61,7 +58,8 @@ module Webgen
|
|
|
61
58
|
#
|
|
62
59
|
# Path patterns define which paths are handled by a specific path handler. These patterns are
|
|
63
60
|
# specified when a path handler is registered using #register method. The patterns need to have a
|
|
64
|
-
# format that Dir.glob can handle.
|
|
61
|
+
# format that Dir.glob can handle. Note that a user can always associate any path with a path
|
|
62
|
+
# handler through a meta information path and the 'handler' meta information key.
|
|
65
63
|
#
|
|
66
64
|
# In addition to specifying the patterns a path handler uses, one can also specify the place in
|
|
67
65
|
# the invocation list which the path handler should use. The invocation list is used from the
|
|
@@ -141,23 +139,23 @@ module Webgen
|
|
|
141
139
|
@instances = {}
|
|
142
140
|
@secondary_nodes = {}
|
|
143
141
|
|
|
144
|
-
@website.blackboard.add_listener(:website_generated,
|
|
142
|
+
@website.blackboard.add_listener(:website_generated, 'path_handler') do
|
|
145
143
|
@website.cache[:path_handler_secondary_nodes] = @secondary_nodes
|
|
146
144
|
end
|
|
147
145
|
|
|
148
146
|
used_secondary_paths = {}
|
|
149
147
|
written_nodes = Set.new
|
|
150
|
-
@website.blackboard.add_listener(:before_secondary_nodes_created,
|
|
148
|
+
@website.blackboard.add_listener(:before_secondary_nodes_created, 'path_handler') do |path, source_alcn|
|
|
151
149
|
(used_secondary_paths[source_alcn] ||= Set.new) << path if source_alcn
|
|
152
150
|
end
|
|
153
|
-
@website.blackboard.add_listener(:before_all_nodes_written,
|
|
151
|
+
@website.blackboard.add_listener(:before_all_nodes_written, 'path_handler') do |node|
|
|
154
152
|
used_secondary_paths = {}
|
|
155
153
|
written_nodes = Set.new
|
|
156
154
|
end
|
|
157
|
-
@website.blackboard.add_listener(:after_node_written,
|
|
155
|
+
@website.blackboard.add_listener(:after_node_written, 'path_handler') do |node|
|
|
158
156
|
written_nodes << node.alcn
|
|
159
157
|
end
|
|
160
|
-
@website.blackboard.add_listener(:after_all_nodes_written,
|
|
158
|
+
@website.blackboard.add_listener(:after_all_nodes_written, 'path_handler') do
|
|
161
159
|
@secondary_nodes.delete_if do |path, data|
|
|
162
160
|
if written_nodes.include?(data[1]) && (!used_secondary_paths[data[1]] ||
|
|
163
161
|
!used_secondary_paths[data[1]].include?(path))
|
|
@@ -225,10 +223,16 @@ module Webgen
|
|
|
225
223
|
|
|
226
224
|
time = Benchmark.measure do
|
|
227
225
|
meta_info, rest = @website.ext.source.paths.partition {|path| path.path =~ /[\/.]metainfo$/}
|
|
226
|
+
|
|
227
|
+
used_paths = []
|
|
228
|
+
|
|
229
|
+
@website.blackboard.add_listener(:before_node_created, 'path_handler (temp_populate_tree)') do |path|
|
|
230
|
+
used_paths << path
|
|
231
|
+
end
|
|
228
232
|
create_nodes(meta_info, [:meta_info])
|
|
229
233
|
create_nodes(rest)
|
|
234
|
+
@website.blackboard.remove_listener(:before_node_created, 'path_handler (temp_populate_tree)')
|
|
230
235
|
|
|
231
|
-
used_paths = @website.tree.node_access[:alcn].values.map {|n| n.node_info[:path]}
|
|
232
236
|
unused_paths = rest - used_paths
|
|
233
237
|
@website.logger.vinfo do
|
|
234
238
|
"The following source paths have not been used: #{unused_paths.join(', ')}"
|
|
@@ -258,11 +262,11 @@ module Webgen
|
|
|
258
262
|
at_least_one_node_written = false
|
|
259
263
|
@website.cache.reset_volatile_cache
|
|
260
264
|
@website.blackboard.dispatch_msg(:before_all_nodes_written)
|
|
261
|
-
@website.tree.node_access[:alcn].
|
|
265
|
+
@website.tree.node_access[:alcn].sort_by {|a, n| [n['write_order'].to_s, a]}.each do |name, node|
|
|
262
266
|
begin
|
|
263
267
|
next if node == @website.tree.dummy_root ||
|
|
264
268
|
(node['passive'] && !node['no_output'] && !@website.ext.item_tracker.node_referenced?(node)) ||
|
|
265
|
-
((@website.config['website.dry_run'] || @website.ext.destination.exists?(node.dest_path)) &&
|
|
269
|
+
((@website.config['website.dry_run'] || node['no_output'] || @website.ext.destination.exists?(node.dest_path)) &&
|
|
266
270
|
!@website.ext.item_tracker.node_changed?(node))
|
|
267
271
|
|
|
268
272
|
@website.blackboard.dispatch_msg(:before_node_written, node)
|