thewoolleyman-webgen 0.5.8.20090419
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/AUTHORS +8 -0
- data/COPYING +10 -0
- data/GPL +340 -0
- data/Rakefile +334 -0
- data/THANKS +18 -0
- data/bin/webgen +12 -0
- data/data/webgen/resources.yaml +3 -0
- data/data/webgen/webgui/controller/main.rb +135 -0
- data/data/webgen/webgui/overrides/win32console.rb +0 -0
- data/data/webgen/webgui/public/css/jquery.autocomplete.css +50 -0
- data/data/webgen/webgui/public/css/ramaze_error.css +90 -0
- data/data/webgen/webgui/public/css/style.css +55 -0
- data/data/webgen/webgui/public/img/headerbg.jpg +0 -0
- data/data/webgen/webgui/public/img/webgen_logo.png +0 -0
- data/data/webgen/webgui/public/js/jquery.autocomplete.js +15 -0
- data/data/webgen/webgui/public/js/jquery.js +32 -0
- data/data/webgen/webgui/view/create_website.xhtml +22 -0
- data/data/webgen/webgui/view/error.xhtml +64 -0
- data/data/webgen/webgui/view/index.xhtml +22 -0
- data/data/webgen/webgui/view/manage_website.xhtml +18 -0
- data/data/webgen/webgui/view/page.xhtml +40 -0
- data/data/webgen/website_skeleton/README +10 -0
- data/data/webgen/website_skeleton/Rakefile +40 -0
- data/data/webgen/website_skeleton/config.yaml +17 -0
- data/data/webgen/website_skeleton/ext/init.rb +10 -0
- data/data/webgen/website_styles/1024px/README +13 -0
- data/data/webgen/website_styles/1024px/src/default.css +188 -0
- data/data/webgen/website_styles/1024px/src/default.template +60 -0
- data/data/webgen/website_styles/1024px/src/images/background.gif +0 -0
- data/data/webgen/website_styles/andreas00/README +13 -0
- data/data/webgen/website_styles/andreas00/src/default.css +290 -0
- data/data/webgen/website_styles/andreas00/src/default.template +60 -0
- data/data/webgen/website_styles/andreas00/src/images/bg.gif +0 -0
- data/data/webgen/website_styles/andreas00/src/images/front.jpg +0 -0
- data/data/webgen/website_styles/andreas00/src/images/menubg.gif +0 -0
- data/data/webgen/website_styles/andreas00/src/images/menubg2.gif +0 -0
- data/data/webgen/website_styles/andreas01/README +14 -0
- data/data/webgen/website_styles/andreas01/src/default.css +310 -0
- data/data/webgen/website_styles/andreas01/src/default.template +62 -0
- data/data/webgen/website_styles/andreas01/src/images/bg.gif +0 -0
- data/data/webgen/website_styles/andreas01/src/images/front.jpg +0 -0
- data/data/webgen/website_styles/andreas01/src/print.css +35 -0
- data/data/webgen/website_styles/andreas03/README +14 -0
- data/data/webgen/website_styles/andreas03/src/default.css +223 -0
- data/data/webgen/website_styles/andreas03/src/default.template +58 -0
- data/data/webgen/website_styles/andreas03/src/images/bodybg.png +0 -0
- data/data/webgen/website_styles/andreas03/src/images/contbg.png +0 -0
- data/data/webgen/website_styles/andreas03/src/images/footerbg.png +0 -0
- data/data/webgen/website_styles/andreas03/src/images/gradient1.png +0 -0
- data/data/webgen/website_styles/andreas03/src/images/gradient2.png +0 -0
- data/data/webgen/website_styles/andreas04/README +15 -0
- data/data/webgen/website_styles/andreas04/src/default.css +290 -0
- data/data/webgen/website_styles/andreas04/src/default.template +81 -0
- data/data/webgen/website_styles/andreas04/src/images/blinkarrow.gif +0 -0
- data/data/webgen/website_styles/andreas04/src/images/bodybg.png +0 -0
- data/data/webgen/website_styles/andreas04/src/images/contentbg.png +0 -0
- data/data/webgen/website_styles/andreas04/src/images/entrybg.png +0 -0
- data/data/webgen/website_styles/andreas04/src/images/flash.gif +0 -0
- data/data/webgen/website_styles/andreas04/src/images/flash2.gif +0 -0
- data/data/webgen/website_styles/andreas04/src/images/globe.gif +0 -0
- data/data/webgen/website_styles/andreas04/src/images/globebottom.gif +0 -0
- data/data/webgen/website_styles/andreas04/src/images/linkarrow.gif +0 -0
- data/data/webgen/website_styles/andreas04/src/images/menuhover.png +0 -0
- data/data/webgen/website_styles/andreas05/README +14 -0
- data/data/webgen/website_styles/andreas05/src/default.css +33 -0
- data/data/webgen/website_styles/andreas05/src/default.template +40 -0
- data/data/webgen/website_styles/andreas05/src/images/bodybg.gif +0 -0
- data/data/webgen/website_styles/andreas05/src/images/front.png +0 -0
- data/data/webgen/website_styles/andreas06/README +14 -0
- data/data/webgen/website_styles/andreas06/src/default.css +354 -0
- data/data/webgen/website_styles/andreas06/src/default.template +70 -0
- data/data/webgen/website_styles/andreas06/src/images/bodybg.gif +0 -0
- data/data/webgen/website_styles/andreas06/src/images/boxbg.gif +0 -0
- data/data/webgen/website_styles/andreas06/src/images/greypx.gif +0 -0
- data/data/webgen/website_styles/andreas06/src/images/header.jpg +0 -0
- data/data/webgen/website_styles/andreas06/src/images/innerbg.gif +0 -0
- data/data/webgen/website_styles/andreas06/src/images/leaves.jpg +0 -0
- data/data/webgen/website_styles/andreas06/src/images/tabs.gif +0 -0
- data/data/webgen/website_styles/andreas07/README +15 -0
- data/data/webgen/website_styles/andreas07/src/browserfix.css +7 -0
- data/data/webgen/website_styles/andreas07/src/default.css +92 -0
- data/data/webgen/website_styles/andreas07/src/default.template +42 -0
- data/data/webgen/website_styles/andreas07/src/images/bodybg.gif +0 -0
- data/data/webgen/website_styles/andreas07/src/images/sidebarbg.gif +0 -0
- data/data/webgen/website_styles/andreas08/README +14 -0
- data/data/webgen/website_styles/andreas08/src/default.css +224 -0
- data/data/webgen/website_styles/andreas08/src/default.template +51 -0
- data/data/webgen/website_styles/andreas09/README +14 -0
- data/data/webgen/website_styles/andreas09/src/default.css +308 -0
- data/data/webgen/website_styles/andreas09/src/default.template +68 -0
- data/data/webgen/website_styles/andreas09/src/images/bodybg-black.jpg +0 -0
- data/data/webgen/website_styles/andreas09/src/images/bodybg-green.jpg +0 -0
- data/data/webgen/website_styles/andreas09/src/images/bodybg-orange.jpg +0 -0
- data/data/webgen/website_styles/andreas09/src/images/bodybg-purple.jpg +0 -0
- data/data/webgen/website_styles/andreas09/src/images/bodybg-red.jpg +0 -0
- data/data/webgen/website_styles/andreas09/src/images/bodybg.jpg +0 -0
- data/data/webgen/website_styles/andreas09/src/images/footerbg.jpg +0 -0
- data/data/webgen/website_styles/andreas09/src/images/menuhover-black.jpg +0 -0
- data/data/webgen/website_styles/andreas09/src/images/menuhover-green.jpg +0 -0
- data/data/webgen/website_styles/andreas09/src/images/menuhover-orange.jpg +0 -0
- data/data/webgen/website_styles/andreas09/src/images/menuhover-purple.jpg +0 -0
- data/data/webgen/website_styles/andreas09/src/images/menuhover-red.jpg +0 -0
- data/data/webgen/website_styles/andreas09/src/images/menuhover.jpg +0 -0
- data/data/webgen/website_styles/simple/README +6 -0
- data/data/webgen/website_styles/simple/src/default.css +84 -0
- data/data/webgen/website_styles/simple/src/default.template +36 -0
- data/data/webgen/website_templates/default/README +6 -0
- data/data/webgen/website_templates/default/src/index.page +8 -0
- data/data/webgen/website_templates/project/README +5 -0
- data/data/webgen/website_templates/project/src/about.page +12 -0
- data/data/webgen/website_templates/project/src/download.page +15 -0
- data/data/webgen/website_templates/project/src/features.page +8 -0
- data/data/webgen/website_templates/project/src/index.page +9 -0
- data/data/webgen/website_templates/project/src/screenshots.page +18 -0
- data/doc/contentprocessor.template +11 -0
- data/doc/contentprocessor/blocks.page +129 -0
- data/doc/contentprocessor/builder.page +80 -0
- data/doc/contentprocessor/erb.page +59 -0
- data/doc/contentprocessor/erubis.page +46 -0
- data/doc/contentprocessor/fragments.page +25 -0
- data/doc/contentprocessor/haml.page +47 -0
- data/doc/contentprocessor/maruku.page +41 -0
- data/doc/contentprocessor/rdiscount.page +37 -0
- data/doc/contentprocessor/rdoc.page +36 -0
- data/doc/contentprocessor/redcloth.page +39 -0
- data/doc/contentprocessor/sass.page +31 -0
- data/doc/contentprocessor/tags.page +73 -0
- data/doc/extensions.metainfo +29 -0
- data/doc/extensions.page +16 -0
- data/doc/extensions.template +17 -0
- data/doc/faq.page +219 -0
- data/doc/getting_started.page +135 -0
- data/doc/index.page +65 -0
- data/doc/manual.page +589 -0
- data/doc/reference_configuration.page +959 -0
- data/doc/reference_metainfo.page +222 -0
- data/doc/source/filesystem.page +39 -0
- data/doc/source/tararchive.page +40 -0
- data/doc/sourcehandler.template +21 -0
- data/doc/sourcehandler/copy.page +19 -0
- data/doc/sourcehandler/directory.page +27 -0
- data/doc/sourcehandler/feed.page +105 -0
- data/doc/sourcehandler/metainfo.page +41 -0
- data/doc/sourcehandler/page.page +14 -0
- data/doc/sourcehandler/sitemap.page +46 -0
- data/doc/sourcehandler/template.page +45 -0
- data/doc/sourcehandler/virtual.page +49 -0
- data/doc/tag.template +25 -0
- data/doc/tag/breadcrumbtrail.page +40 -0
- data/doc/tag/coderay.page +49 -0
- data/doc/tag/date.page +31 -0
- data/doc/tag/executecommand.page +26 -0
- data/doc/tag/includefile.page +32 -0
- data/doc/tag/langbar.page +44 -0
- data/doc/tag/link.page +44 -0
- data/doc/tag/menu.page +106 -0
- data/doc/tag/metainfo.page +29 -0
- data/doc/tag/relocatable.page +38 -0
- data/doc/tag/sitemap.page +31 -0
- data/doc/tag/tikz.page +158 -0
- data/doc/upgrading.page +139 -0
- data/doc/webgen_page_format.page +129 -0
- data/lib/webgen/blackboard.rb +78 -0
- data/lib/webgen/cache.rb +87 -0
- data/lib/webgen/cli.rb +124 -0
- data/lib/webgen/cli/apply_command.rb +64 -0
- data/lib/webgen/cli/create_command.rb +66 -0
- data/lib/webgen/cli/run_command.rb +22 -0
- data/lib/webgen/cli/utils.rb +88 -0
- data/lib/webgen/cli/webgui_command.rb +72 -0
- data/lib/webgen/common.rb +21 -0
- data/lib/webgen/common/sitemap.rb +83 -0
- data/lib/webgen/configuration.rb +153 -0
- data/lib/webgen/contentprocessor.rb +99 -0
- data/lib/webgen/contentprocessor/blocks.rb +60 -0
- data/lib/webgen/contentprocessor/builder.rb +30 -0
- data/lib/webgen/contentprocessor/context.rb +89 -0
- data/lib/webgen/contentprocessor/erb.rb +28 -0
- data/lib/webgen/contentprocessor/erubis.rb +40 -0
- data/lib/webgen/contentprocessor/fragments.rb +25 -0
- data/lib/webgen/contentprocessor/haml.rb +30 -0
- data/lib/webgen/contentprocessor/maruku.rb +20 -0
- data/lib/webgen/contentprocessor/rdiscount.rb +17 -0
- data/lib/webgen/contentprocessor/rdoc.rb +19 -0
- data/lib/webgen/contentprocessor/redcloth.rb +17 -0
- data/lib/webgen/contentprocessor/sass.rb +20 -0
- data/lib/webgen/contentprocessor/tags.rb +136 -0
- data/lib/webgen/coreext.rb +13 -0
- data/lib/webgen/default_config.rb +215 -0
- data/lib/webgen/languages.rb +589 -0
- data/lib/webgen/loggable.rb +25 -0
- data/lib/webgen/logger.rb +97 -0
- data/lib/webgen/node.rb +391 -0
- data/lib/webgen/output.rb +82 -0
- data/lib/webgen/output/filesystem.rb +69 -0
- data/lib/webgen/page.rb +153 -0
- data/lib/webgen/path.rb +194 -0
- data/lib/webgen/source.rb +54 -0
- data/lib/webgen/source/filesystem.rb +61 -0
- data/lib/webgen/source/resource.rb +44 -0
- data/lib/webgen/source/stacked.rb +55 -0
- data/lib/webgen/source/tararchive.rb +73 -0
- data/lib/webgen/sourcehandler.rb +226 -0
- data/lib/webgen/sourcehandler/base.rb +248 -0
- data/lib/webgen/sourcehandler/copy.rb +43 -0
- data/lib/webgen/sourcehandler/directory.rb +36 -0
- data/lib/webgen/sourcehandler/feed.rb +117 -0
- data/lib/webgen/sourcehandler/fragment.rb +68 -0
- data/lib/webgen/sourcehandler/memory.rb +43 -0
- data/lib/webgen/sourcehandler/metainfo.rb +128 -0
- data/lib/webgen/sourcehandler/page.rb +59 -0
- data/lib/webgen/sourcehandler/sitemap.rb +60 -0
- data/lib/webgen/sourcehandler/template.rb +66 -0
- data/lib/webgen/sourcehandler/virtual.rb +110 -0
- data/lib/webgen/tag.rb +27 -0
- data/lib/webgen/tag/base.rb +170 -0
- data/lib/webgen/tag/breadcrumbtrail.rb +70 -0
- data/lib/webgen/tag/coderay.rb +31 -0
- data/lib/webgen/tag/date.rb +18 -0
- data/lib/webgen/tag/executecommand.rb +30 -0
- data/lib/webgen/tag/includefile.rb +42 -0
- data/lib/webgen/tag/langbar.rb +52 -0
- data/lib/webgen/tag/link.rb +26 -0
- data/lib/webgen/tag/menu.rb +207 -0
- data/lib/webgen/tag/metainfo.rb +25 -0
- data/lib/webgen/tag/relocatable.rb +54 -0
- data/lib/webgen/tag/sitemap.rb +41 -0
- data/lib/webgen/tag/tikz.rb +119 -0
- data/lib/webgen/tree.rb +90 -0
- data/lib/webgen/version.rb +8 -0
- data/lib/webgen/webgentask.rb +152 -0
- data/lib/webgen/website.rb +342 -0
- data/lib/webgen/websiteaccess.rb +31 -0
- data/lib/webgen/websitemanager.rb +127 -0
- data/man/man1/webgen.1 +73 -0
- data/misc/default.css +384 -0
- data/misc/default.template +75 -0
- data/misc/htmldoc.metainfo +25 -0
- data/misc/htmldoc.virtual +5 -0
- data/misc/images/arrow.gif +0 -0
- data/misc/images/error.png +0 -0
- data/misc/images/headerbg.jpg +0 -0
- data/misc/images/important.png +0 -0
- data/misc/images/information.png +0 -0
- data/misc/images/quote.gif +0 -0
- data/misc/images/warning.png +0 -0
- data/setup.rb +1585 -0
- data/test/helper.rb +45 -0
- data/test/test_blackboard.rb +60 -0
- data/test/test_cache.rb +59 -0
- data/test/test_cli.rb +21 -0
- data/test/test_common.rb +18 -0
- data/test/test_common_sitemap.rb +58 -0
- data/test/test_configuration.rb +68 -0
- data/test/test_contentprocessor.rb +33 -0
- data/test/test_contentprocessor_blocks.rb +68 -0
- data/test/test_contentprocessor_builder.rb +23 -0
- data/test/test_contentprocessor_context.rb +40 -0
- data/test/test_contentprocessor_erb.rb +23 -0
- data/test/test_contentprocessor_erubis.rb +49 -0
- data/test/test_contentprocessor_fragments.rb +42 -0
- data/test/test_contentprocessor_haml.rb +23 -0
- data/test/test_contentprocessor_maruku.rb +29 -0
- data/test/test_contentprocessor_rdiscount.rb +17 -0
- data/test/test_contentprocessor_rdoc.rb +18 -0
- data/test/test_contentprocessor_redcloth.rb +15 -0
- data/test/test_contentprocessor_sass.rb +22 -0
- data/test/test_contentprocessor_tags.rb +99 -0
- data/test/test_languages.rb +67 -0
- data/test/test_loggable.rb +32 -0
- data/test/test_logger.rb +94 -0
- data/test/test_node.rb +367 -0
- data/test/test_output_filesystem.rb +60 -0
- data/test/test_page.rb +214 -0
- data/test/test_path.rb +165 -0
- data/test/test_source_filesystem.rb +76 -0
- data/test/test_source_resource.rb +28 -0
- data/test/test_source_stacked.rb +36 -0
- data/test/test_source_tararchive.rb +65 -0
- data/test/test_sourcehandler_base.rb +123 -0
- data/test/test_sourcehandler_copy.rb +47 -0
- data/test/test_sourcehandler_directory.rb +42 -0
- data/test/test_sourcehandler_feed.rb +77 -0
- data/test/test_sourcehandler_fragment.rb +69 -0
- data/test/test_sourcehandler_memory.rb +44 -0
- data/test/test_sourcehandler_metainfo.rb +118 -0
- data/test/test_sourcehandler_page.rb +65 -0
- data/test/test_sourcehandler_sitemap.rb +49 -0
- data/test/test_sourcehandler_template.rb +65 -0
- data/test/test_sourcehandler_virtual.rb +87 -0
- data/test/test_tag_base.rb +85 -0
- data/test/test_tag_breadcrumbtrail.rb +91 -0
- data/test/test_tag_coderay.rb +32 -0
- data/test/test_tag_date.rb +18 -0
- data/test/test_tag_executecommand.rb +41 -0
- data/test/test_tag_includefile.rb +50 -0
- data/test/test_tag_langbar.rb +72 -0
- data/test/test_tag_link.rb +69 -0
- data/test/test_tag_menu.rb +207 -0
- data/test/test_tag_metainfo.rb +19 -0
- data/test/test_tag_relocatable.rb +59 -0
- data/test/test_tag_sitemap.rb +47 -0
- data/test/test_tag_tikz.rb +69 -0
- data/test/test_tree.rb +70 -0
- data/test/test_webgentask.rb +23 -0
- data/test/test_website.rb +98 -0
- data/test/test_websiteaccess.rb +25 -0
- data/test/test_websitemanager.rb +70 -0
- metadata +613 -0
data/lib/webgen/tree.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'webgen/websiteaccess'
|
4
|
+
require 'webgen/node'
|
5
|
+
|
6
|
+
module Webgen
|
7
|
+
|
8
|
+
# Represents a tree of nodes.
|
9
|
+
class Tree
|
10
|
+
|
11
|
+
include WebsiteAccess
|
12
|
+
|
13
|
+
# The dummy root. This is the default node that gets created when the Tree is created sothat the
|
14
|
+
# real root node can be treated like any other node. It has only one child, namely the real root
|
15
|
+
# node of the tree.
|
16
|
+
attr_reader :dummy_root
|
17
|
+
|
18
|
+
# Direct access to the hashes for node resolving. Only use this for reading purposes! If you
|
19
|
+
# just want to get a specific node for an alcn/acn/output path, use #node instead.
|
20
|
+
attr_reader :node_access
|
21
|
+
|
22
|
+
# The hash containing processing information for each node. This is normally not accessed
|
23
|
+
# directly but via the Node#node_info method.
|
24
|
+
attr_reader :node_info
|
25
|
+
|
26
|
+
# Create a new Tree object.
|
27
|
+
def initialize
|
28
|
+
@node_access = {:alcn => {}, :acn => {}, :path => {}}
|
29
|
+
@node_info = {}
|
30
|
+
@dummy_root = Node.new(self, '', '')
|
31
|
+
end
|
32
|
+
|
33
|
+
# The real root node of the tree.
|
34
|
+
def root
|
35
|
+
@dummy_root.children.first
|
36
|
+
end
|
37
|
+
|
38
|
+
# Access a node via a +path+ of a specific +type+. If type is +alcn+ then +path+ has to be an
|
39
|
+
# absolute localized canonical name, if type is +acn+ then +path+ has to be an absolute
|
40
|
+
# canonical name and if type is +path+ then +path+ needs to be an output path.
|
41
|
+
#
|
42
|
+
# Returns the requested Node or +nil+ if such a node does not exist.
|
43
|
+
def node(path, type = :alcn)
|
44
|
+
(type == :acn ? @node_access[type][path] && @node_access[type][path].first : @node_access[type][path])
|
45
|
+
end
|
46
|
+
alias_method :[], :node
|
47
|
+
|
48
|
+
# A utility method called by Node#initialize. This method should not be used directly!
|
49
|
+
def register_node(node)
|
50
|
+
if @node_access[:alcn].has_key?(node.absolute_lcn)
|
51
|
+
raise "Can't have two nodes with same absolute lcn: #{node.absolute_lcn}"
|
52
|
+
else
|
53
|
+
@node_access[:alcn][node.absolute_lcn] = node
|
54
|
+
end
|
55
|
+
(@node_access[:acn][node.absolute_cn] ||= []) << node
|
56
|
+
register_path(node)
|
57
|
+
end
|
58
|
+
|
59
|
+
# A utility method called by Node#reinit. This method should not be used directly!
|
60
|
+
def register_path(node)
|
61
|
+
return if node['no_output']
|
62
|
+
if @node_access[:path].has_key?(node.path)
|
63
|
+
raise "Can't have two nodes with same output path: #{node.path}"
|
64
|
+
else
|
65
|
+
@node_access[:path][node.path] = node
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Delete the node identified by +node_or_alcn+ and all of its children from the tree.
|
70
|
+
#
|
71
|
+
# The message <tt>:before_node_deleted</tt> is sent with the to-be-deleted node before this node
|
72
|
+
# is actually deleted from the tree.
|
73
|
+
def delete_node(node_or_alcn)
|
74
|
+
n = node_or_alcn.kind_of?(Node) ? node_or_alcn : @node_access[:alcn][node_or_alcn]
|
75
|
+
return if n.nil? || n == @dummy_root
|
76
|
+
|
77
|
+
n.children.dup.each {|child| delete_node(child)}
|
78
|
+
|
79
|
+
website.blackboard.dispatch_msg(:before_node_deleted, n)
|
80
|
+
n.parent.children.delete(n)
|
81
|
+
@node_access[:alcn].delete(n.absolute_lcn)
|
82
|
+
@node_access[:acn][n.absolute_cn].delete(n)
|
83
|
+
@node_access[:path].delete(n.path)
|
84
|
+
|
85
|
+
node_info.delete(n.absolute_lcn)
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
# -*- ruby -*-
|
4
|
+
#
|
5
|
+
#--
|
6
|
+
# webgentask.rb:
|
7
|
+
#
|
8
|
+
# Define a task library for running webgen
|
9
|
+
#
|
10
|
+
# Copyright (C) 2007 Jeremy Hinegardner
|
11
|
+
#
|
12
|
+
# Tasks restructuration by Massimiliano Filacchioni
|
13
|
+
# Modifications for 0.5.0 by Thomas Leitner
|
14
|
+
#
|
15
|
+
# This program is free software; you can redistribute it and/or modify
|
16
|
+
# it under the terms of the GNU General Public License as published by
|
17
|
+
# the Free Software Foundation; either version 2 of the License, or (at
|
18
|
+
# your option) any later version.
|
19
|
+
#
|
20
|
+
# This program is distributed in the hope that it will be useful, but
|
21
|
+
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
22
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
23
|
+
# General Public License for more details.
|
24
|
+
#
|
25
|
+
# You should have received a copy of the GNU General Public License
|
26
|
+
# along with this program; if not, write to the Free Software
|
27
|
+
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
28
|
+
# USA
|
29
|
+
#
|
30
|
+
#++
|
31
|
+
#
|
32
|
+
|
33
|
+
require 'rake'
|
34
|
+
require 'rake/tasklib'
|
35
|
+
|
36
|
+
module Webgen
|
37
|
+
|
38
|
+
##
|
39
|
+
# Task library to manage a webgen website.
|
40
|
+
#
|
41
|
+
# It is assumed that you have already used the 'webgen' command to create the website directory
|
42
|
+
# for the site.
|
43
|
+
#
|
44
|
+
# == Basics
|
45
|
+
#
|
46
|
+
# require 'webgen/webgentask'
|
47
|
+
#
|
48
|
+
# Webgen::WebgenTask.new
|
49
|
+
#
|
50
|
+
# == Attributes
|
51
|
+
#
|
52
|
+
# The attributes available in the new block are:
|
53
|
+
#
|
54
|
+
# [directory]
|
55
|
+
# the root directory of the webgen site (default <tt>Dir.pwd</tt>)
|
56
|
+
# [config]
|
57
|
+
# the config block for setting additional configuration options
|
58
|
+
# [clobber_outdir]
|
59
|
+
# remove webgens output directory on clobber (default +false+)
|
60
|
+
#
|
61
|
+
# == Tasks Provided
|
62
|
+
#
|
63
|
+
# The tasks provided are :
|
64
|
+
#
|
65
|
+
# [webgen]
|
66
|
+
# render the webgen website
|
67
|
+
# [clobber_webgen]
|
68
|
+
# remove all the files created during generation
|
69
|
+
#
|
70
|
+
# == Integrate webgen in other project
|
71
|
+
#
|
72
|
+
# To integrate webgen tasks in another project you can use rake namespaces. For example assuming
|
73
|
+
# webgen's site directory is +webgen+ under the main project directory use the following code
|
74
|
+
# fragment in project Rakefile:
|
75
|
+
#
|
76
|
+
# require 'webgen/webgentask'
|
77
|
+
#
|
78
|
+
# namespace :dev do
|
79
|
+
# Webgen::WebgenTask.new do |site|
|
80
|
+
# site.directory = File.join(Dir.pwd, "webgen")
|
81
|
+
# site.clobber_outdir = true
|
82
|
+
# site.config_block = lambda |config|
|
83
|
+
# config['website.lang'] = 'de'
|
84
|
+
# end
|
85
|
+
# end
|
86
|
+
# end
|
87
|
+
#
|
88
|
+
# task :clobber => ['dev:clobber_webgen']
|
89
|
+
#
|
90
|
+
# This will create the following tasks:
|
91
|
+
#
|
92
|
+
# * dev:webgen
|
93
|
+
# * dev:clobber_webgen
|
94
|
+
#
|
95
|
+
# and add dev:clobber_webgen to the main clobber task.
|
96
|
+
#
|
97
|
+
class WebgenTask < ::Rake::TaskLib
|
98
|
+
|
99
|
+
# The directory of the webgen website. This would be the directory of your <tt>config.yaml</tt>
|
100
|
+
# file. Or the parent directory of the <tt>src/</tt> directory for webgen.
|
101
|
+
#
|
102
|
+
# The default for this is assumed to be <tt>Dir.pwd</tt>
|
103
|
+
attr_accessor :directory
|
104
|
+
|
105
|
+
# The configuration block that is invoked when the Webgen::Website object is initialized. This
|
106
|
+
# can be used to set configuration parameters and to avoid having a <tt>config.yaml</tt> file
|
107
|
+
# lying around.
|
108
|
+
attr_accessor :config_block
|
109
|
+
|
110
|
+
# During the clobber, should webgen's output directory be clobbered. The default is false.
|
111
|
+
attr_accessor :clobber_outdir
|
112
|
+
|
113
|
+
# Create webgen tasks. You can override the task name with the parameter +name+.
|
114
|
+
def initialize(name = 'webgen')
|
115
|
+
@name = name
|
116
|
+
@directory = Dir.pwd
|
117
|
+
@clobber_outdir = false
|
118
|
+
@config_block = nil
|
119
|
+
|
120
|
+
yield self if block_given?
|
121
|
+
|
122
|
+
define
|
123
|
+
end
|
124
|
+
|
125
|
+
#######
|
126
|
+
private
|
127
|
+
#######
|
128
|
+
|
129
|
+
def define # :nodoc:
|
130
|
+
desc "Render the webgen website"
|
131
|
+
task @name, :verbosity, :log_level do |t, args|
|
132
|
+
require 'webgen/website'
|
133
|
+
website = Webgen::Website.new(@directory, Webgen::Logger.new($stdout), &@config_block)
|
134
|
+
website.logger.verbosity = args[:verbosity].to_s.intern unless args[:verbosity].to_s.empty?
|
135
|
+
website.logger.level = args[:log_level].to_i if args[:log_level]
|
136
|
+
website.render
|
137
|
+
end
|
138
|
+
|
139
|
+
task :clobber => paste('clobber_', @name)
|
140
|
+
|
141
|
+
desc "Remove webgen products"
|
142
|
+
task paste('clobber_', @name) do
|
143
|
+
require 'webgen/website'
|
144
|
+
website = Webgen::Website.new(@directory, Webgen::Logger.new($stdout), &@config_block)
|
145
|
+
website.clean(@clobber_outdir)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
152
|
+
|
@@ -0,0 +1,342 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
##
|
4
|
+
# Welcome to the API documentation of wegen!
|
5
|
+
#
|
6
|
+
# Have a look at the base <a href=Webgen.html>webgen module</a> which provides a good starting point!
|
7
|
+
|
8
|
+
|
9
|
+
# Standard lib requires
|
10
|
+
require 'logger'
|
11
|
+
require 'set'
|
12
|
+
require 'fileutils'
|
13
|
+
require 'facets/symbol/to_proc'
|
14
|
+
|
15
|
+
# Requirements for Website
|
16
|
+
require 'webgen/coreext'
|
17
|
+
require 'webgen/loggable'
|
18
|
+
require 'webgen/logger'
|
19
|
+
require 'webgen/configuration'
|
20
|
+
require 'webgen/websiteaccess'
|
21
|
+
require 'webgen/blackboard'
|
22
|
+
require 'webgen/cache'
|
23
|
+
require 'webgen/tree'
|
24
|
+
|
25
|
+
# Files for autoloading
|
26
|
+
require 'webgen/common'
|
27
|
+
require 'webgen/source'
|
28
|
+
require 'webgen/output'
|
29
|
+
require 'webgen/sourcehandler'
|
30
|
+
require 'webgen/contentprocessor'
|
31
|
+
require 'webgen/tag'
|
32
|
+
|
33
|
+
# Load other needed files
|
34
|
+
require 'webgen/path'
|
35
|
+
require 'webgen/node'
|
36
|
+
require 'webgen/page'
|
37
|
+
|
38
|
+
|
39
|
+
# The Webgen namespace houses all classes/modules used by webgen.
|
40
|
+
#
|
41
|
+
# = webgen
|
42
|
+
#
|
43
|
+
# webgen is a command line application for generating a web site from templates and content
|
44
|
+
# files. Despite this fact, the implementation also provides adequate support for using webgen as a
|
45
|
+
# library and *full* *support* for extending it.
|
46
|
+
#
|
47
|
+
# == Extending webgen
|
48
|
+
#
|
49
|
+
# webgen can be extended very easily. Any file called <tt>init.rb</tt> put into the <tt>ext/</tt>
|
50
|
+
# directory of the website or into one of its sub-directories is automatically loaded on
|
51
|
+
# Website#init.
|
52
|
+
#
|
53
|
+
# You can extend webgen in several ways. However, no magic or special knowledge is needed since
|
54
|
+
# webgen relies on the power of Ruby itself. So, for example, an extension is just a normal Ruby
|
55
|
+
# class. Most extension types provide a Base module for mixing into an extension which provides
|
56
|
+
# default implementations for needed methods.
|
57
|
+
#
|
58
|
+
# Following are links to detailed descriptions on how to develop specific types of extensions:
|
59
|
+
#
|
60
|
+
# [Webgen::Source] Information on how to implement a class that provides source paths for
|
61
|
+
# webgen. For example, one could implement a source class that uses a database as
|
62
|
+
# backend.
|
63
|
+
#
|
64
|
+
# [Webgen::Output] Information on how to implement a class that writes content to an output
|
65
|
+
# location. The default output class just writes to the file system. One could, for
|
66
|
+
# example, implement an output class that writes the generated files to multiple
|
67
|
+
# locations or to a remote server.
|
68
|
+
#
|
69
|
+
# [Webgen::ContentProcessor] Information on how to develop an extension that processes the
|
70
|
+
# content. For example, markup-to-HTML converters are implemented as
|
71
|
+
# content processors in webgen.
|
72
|
+
#
|
73
|
+
# [Webgen::SourceHandler::Base] Information on how to implement a class that handles objects of type
|
74
|
+
# source Path and creates Node instances. For example,
|
75
|
+
# Webgen::SourceHandler::Page handles the conversion of <tt>.page</tt>
|
76
|
+
# files to <tt>.html</tt> files.
|
77
|
+
#
|
78
|
+
# [Webgen::Tag::Base] Information on how to implement a webgen tag. webgen tags are used to provide
|
79
|
+
# an easy way for users to include dynamic content such as automatically
|
80
|
+
# generated menus.
|
81
|
+
#
|
82
|
+
# == Blackboard services
|
83
|
+
#
|
84
|
+
# The Blackboard class provides an easy communication facility between objects. It implements the
|
85
|
+
# Observer pattern on the one side and allows the definition of services on the other side. One
|
86
|
+
# advantage of a service over the direct use of an object instance method is that the caller does
|
87
|
+
# not need to how to find the object that provides the service. It justs uses the Website#blackboard
|
88
|
+
# instance. An other advantage is that one can easily exchange the place where the service was
|
89
|
+
# defined without breaking extensions that rely on it.
|
90
|
+
#
|
91
|
+
# Following is a list of all services available in the stock webgen distribution by the name and the
|
92
|
+
# method that implements it (which is useful for looking up the parameters of service).
|
93
|
+
#
|
94
|
+
# <tt>:create_fragment_nodes</tt>:: SourceHandler::Fragment#create_fragment_nodes
|
95
|
+
# <tt>:templates_for_node</tt>:: SourceHandler::Template#templates_for_node
|
96
|
+
# <tt>:parse_html_headers</tt>:: SourceHandler::Fragment#parse_html_headers
|
97
|
+
# <tt>:output_instance</tt>:: Output.instance
|
98
|
+
# <tt>:content_processor_names</tt>:: ContentProcessor.list
|
99
|
+
# <tt>:content_processor</tt>:: ContentProcessor.for_name
|
100
|
+
# <tt>:create_sitemap</tt>:: Common::Sitemap#create_sitemap
|
101
|
+
# <tt>:create_directories</tt>:: SourceHandler::Directory#create_directories
|
102
|
+
# <tt>:create_nodes</tt>:: SourceHandler::Main#create_nodes
|
103
|
+
# <tt>:source_paths</tt>:: SourceHandler::Main#find_all_source_paths
|
104
|
+
#
|
105
|
+
# Following is the list of all messages that can be listened to:
|
106
|
+
#
|
107
|
+
# <tt>:node_flagged</tt>::
|
108
|
+
# See Node#flag
|
109
|
+
#
|
110
|
+
# <tt>:node_unflagged</tt>::
|
111
|
+
# See Node#unflag
|
112
|
+
#
|
113
|
+
# <tt>:node_changed?</tt>::
|
114
|
+
# See Node#changed?
|
115
|
+
# <tt>:node_meta_info_changed?</tt>::
|
116
|
+
# See Node#meta_info_changed?
|
117
|
+
#
|
118
|
+
# <tt>:before_node_created</tt>::
|
119
|
+
# Sent by the <tt>:create_nodes</tt> service before a node is created (handled by a source handler)
|
120
|
+
# with the +parent+ and the +path+ as arguments.
|
121
|
+
#
|
122
|
+
# <tt>:after_node_created</tt>::
|
123
|
+
# Sent by the <tt>:create_nodes</tt> service after a node has been created with the created node
|
124
|
+
# as argument.
|
125
|
+
#
|
126
|
+
# <tt>:before_node_deleted</tt>::
|
127
|
+
# See Tree#delete_node
|
128
|
+
#
|
129
|
+
# == Other places to look at
|
130
|
+
#
|
131
|
+
# Here is a list of modules/classes that are primarily used throughout webgen or provide useful
|
132
|
+
# methods for developing extensions:
|
133
|
+
#
|
134
|
+
# Common, Tree, Node, Path, Cache, Page
|
135
|
+
|
136
|
+
module Webgen
|
137
|
+
|
138
|
+
# Returns the data directory for webgen.
|
139
|
+
def self.data_dir
|
140
|
+
unless defined?(@@data_dir)
|
141
|
+
require 'rbconfig'
|
142
|
+
@@data_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'data', 'webgen'))
|
143
|
+
@@data_dir = File.expand_path(File.join(Config::CONFIG["datadir"], "webgen")) if !File.exists?(@@data_dir)
|
144
|
+
raise "Could not find webgen data directory! This is a bug, report it please!" unless File.directory?(@@data_dir)
|
145
|
+
end
|
146
|
+
@@data_dir
|
147
|
+
end
|
148
|
+
|
149
|
+
|
150
|
+
# Represents a webgen website and is used to render it.
|
151
|
+
#
|
152
|
+
# Normally, webgen is used from the command line via the +webgen+ command or from Rakefiles via
|
153
|
+
# Webgen::WebgenTask. However, you can also easily use webgen as a library and this class provides
|
154
|
+
# the interface for this usage!
|
155
|
+
#
|
156
|
+
# Since a webgen website is, basically, just a directory, the only parameter needed for creating a
|
157
|
+
# new Website object is the website directory. After that you can work with the website:
|
158
|
+
#
|
159
|
+
# * If you want to render the website, you just need to call Website#render which initializes the
|
160
|
+
# website and does all the rendering. When the method call returns, everything has been rendered.
|
161
|
+
#
|
162
|
+
# * If you want to remove the generated output, you just need to invoke Website#clean and it will
|
163
|
+
# be done.
|
164
|
+
#
|
165
|
+
# * Finally, if you want to retrieve data from the website, you first have to call Website#init to
|
166
|
+
# initialize the website. After that you can use the various accessors to retrieve the needed
|
167
|
+
# data. *Note*: This is generally only useful if the website has been rendered because otherwise
|
168
|
+
# there is no data to retrieve.
|
169
|
+
#
|
170
|
+
class Website
|
171
|
+
|
172
|
+
# Raised when the configuration file of the website is invalid.
|
173
|
+
class ConfigFileInvalid < RuntimeError; end
|
174
|
+
|
175
|
+
include Loggable
|
176
|
+
|
177
|
+
# The website configuration. Can only be used after #init has been called (which is
|
178
|
+
# automatically done in #render).
|
179
|
+
attr_reader :config
|
180
|
+
|
181
|
+
# The blackboard used for inter-object communication. Can only be used after #init has been
|
182
|
+
# called.
|
183
|
+
attr_reader :blackboard
|
184
|
+
|
185
|
+
# A cache to store information that should be available between runs. Can only be used after
|
186
|
+
# #init has been called.
|
187
|
+
attr_reader :cache
|
188
|
+
|
189
|
+
# The internal data structure used to store information about individual nodes.
|
190
|
+
attr_reader :tree
|
191
|
+
|
192
|
+
# The logger used for logging. If set to +nil+, logging is disabled.
|
193
|
+
attr_accessor :logger
|
194
|
+
|
195
|
+
# The website directory.
|
196
|
+
attr_reader :directory
|
197
|
+
|
198
|
+
# Create a new webgen website for the website in the directory +dir+. You can provide a
|
199
|
+
# block (has to take the configuration object as parameter) for adjusting the configuration
|
200
|
+
# values during the initialization.
|
201
|
+
def initialize(dir, logger=Webgen::Logger.new($stdout, false), &block)
|
202
|
+
@blackboard = nil
|
203
|
+
@cache = nil
|
204
|
+
@config = nil
|
205
|
+
@logger = logger
|
206
|
+
@config_block = block
|
207
|
+
@directory = dir
|
208
|
+
end
|
209
|
+
|
210
|
+
# Define a service +service_name+ provided by the instance of +klass+. The parameter +method+
|
211
|
+
# needs to define the method which should be invoked when the service is invoked. Can only be
|
212
|
+
# used after #init has been called.
|
213
|
+
def autoload_service(service_name, klass, method = service_name)
|
214
|
+
blackboard.add_service(service_name) {|*args| cache.instance(klass).send(method, *args)}
|
215
|
+
end
|
216
|
+
|
217
|
+
# Initialize the configuration, blackboard and cache objects and load the default configuration
|
218
|
+
# as well as website specific extension files. An already existing configuration/blackboard is
|
219
|
+
# deleted!
|
220
|
+
def init
|
221
|
+
execute_in_env do
|
222
|
+
@blackboard = Blackboard.new
|
223
|
+
@config = Configuration.new
|
224
|
+
|
225
|
+
load 'webgen/default_config.rb'
|
226
|
+
Dir.glob(File.join(@directory, 'ext', '**/init.rb')) {|f| load(f)}
|
227
|
+
read_config_file
|
228
|
+
|
229
|
+
@config_block.call(@config) if @config_block
|
230
|
+
restore_tree_and_cache
|
231
|
+
end
|
232
|
+
self
|
233
|
+
end
|
234
|
+
|
235
|
+
# Render the website (after calling #init if the website is not already initialized) and return
|
236
|
+
# a status code not equal to +nil+ if rendering was successful.
|
237
|
+
def render
|
238
|
+
result = nil
|
239
|
+
execute_in_env do
|
240
|
+
init unless @config
|
241
|
+
|
242
|
+
puts "Starting webgen..."
|
243
|
+
shm = SourceHandler::Main.new
|
244
|
+
result = shm.render(@tree)
|
245
|
+
save_tree_and_cache if result
|
246
|
+
puts "Finished"
|
247
|
+
|
248
|
+
if @logger && @logger.log_output.length > 0
|
249
|
+
puts "\nLog messages:"
|
250
|
+
puts @logger.log_output
|
251
|
+
end
|
252
|
+
end
|
253
|
+
result
|
254
|
+
end
|
255
|
+
|
256
|
+
# Clean the website directory from all generated output files (including the cache file). If
|
257
|
+
# +del_outdir+ is +true+, then the base output directory is also deleted. When a delete
|
258
|
+
# operation fails, the error is silently ignored and the clean operation continues.
|
259
|
+
#
|
260
|
+
# Note: Uses the configured output instance for the operations!
|
261
|
+
def clean(del_outdir = false)
|
262
|
+
init
|
263
|
+
execute_in_env do
|
264
|
+
output = @blackboard.invoke(:output_instance)
|
265
|
+
@tree.node_access[:alcn].each do |name, node|
|
266
|
+
next if node.is_fragment? || node['no_output'] || node.path == '/' || node == @tree.dummy_root
|
267
|
+
output.delete(node.path) rescue nil
|
268
|
+
end
|
269
|
+
|
270
|
+
if @config['website.cache'].first == :file
|
271
|
+
FileUtils.rm(File.join(@directory, @config['website.cache'].last)) rescue nil
|
272
|
+
end
|
273
|
+
|
274
|
+
if del_outdir
|
275
|
+
output.delete('/') rescue nil
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
# The provided block is executed within a proper environment sothat any object can access the
|
281
|
+
# Website object.
|
282
|
+
def execute_in_env
|
283
|
+
set_back = Thread.current[:webgen_website].nil?
|
284
|
+
Thread.current[:webgen_website] = self
|
285
|
+
yield
|
286
|
+
ensure
|
287
|
+
Thread.current[:webgen_website] = nil if set_back
|
288
|
+
end
|
289
|
+
|
290
|
+
#######
|
291
|
+
private
|
292
|
+
#######
|
293
|
+
|
294
|
+
# Restore the tree and the cache from +website.cache+ and returns the Tree object.
|
295
|
+
def restore_tree_and_cache
|
296
|
+
@cache = Cache.new
|
297
|
+
@tree = Tree.new
|
298
|
+
data = if config['website.cache'].first == :file
|
299
|
+
cache_file = File.join(@directory, config['website.cache'].last)
|
300
|
+
File.open(cache_file, 'rb') {|f| f.read} if File.exists?(cache_file)
|
301
|
+
else
|
302
|
+
config['website.cache'].last
|
303
|
+
end
|
304
|
+
cache_data, @tree = Marshal.load(data) rescue nil
|
305
|
+
@cache.restore(cache_data) if cache_data
|
306
|
+
end
|
307
|
+
|
308
|
+
# Save the +tree+ and the +cache+ to +website.cache+.
|
309
|
+
def save_tree_and_cache
|
310
|
+
cache_data = [@cache.dump, @tree]
|
311
|
+
if config['website.cache'].first == :file
|
312
|
+
cache_file = File.join(@directory, config['website.cache'].last)
|
313
|
+
File.open(cache_file, 'wb') {|f| Marshal.dump(cache_data, f)}
|
314
|
+
else
|
315
|
+
config['website.cache'][1] = Marshal.dump(cache_data)
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
# Update the configuration object for the website with infos found in the configuration file.
|
320
|
+
def read_config_file
|
321
|
+
file = File.join(@directory, 'config.yaml')
|
322
|
+
if File.exists?(file)
|
323
|
+
begin
|
324
|
+
config = YAML::load(File.read(file)) || {}
|
325
|
+
raise 'Structure of config file is not valid, has to be a Hash' if !config.kind_of?(Hash)
|
326
|
+
config.each do |key, value|
|
327
|
+
case key
|
328
|
+
when *Webgen::Configuration::Helpers.public_instance_methods(false).map(&:to_s) then @config.send(key, value)
|
329
|
+
else @config[key] = value
|
330
|
+
end
|
331
|
+
end
|
332
|
+
rescue RuntimeError, ArgumentError => e
|
333
|
+
raise ConfigFileInvalid, "Configuration invalid: " + e.message
|
334
|
+
end
|
335
|
+
elsif File.exists?(File.join(@directory, 'config.yml'))
|
336
|
+
log(:warn) { "No configuration file called config.yaml found (there is a config.yml - spelling error?)" }
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
end
|
341
|
+
|
342
|
+
end
|