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.
Files changed (309) hide show
  1. data/AUTHORS +8 -0
  2. data/COPYING +10 -0
  3. data/GPL +340 -0
  4. data/Rakefile +334 -0
  5. data/THANKS +18 -0
  6. data/bin/webgen +12 -0
  7. data/data/webgen/resources.yaml +3 -0
  8. data/data/webgen/webgui/controller/main.rb +135 -0
  9. data/data/webgen/webgui/overrides/win32console.rb +0 -0
  10. data/data/webgen/webgui/public/css/jquery.autocomplete.css +50 -0
  11. data/data/webgen/webgui/public/css/ramaze_error.css +90 -0
  12. data/data/webgen/webgui/public/css/style.css +55 -0
  13. data/data/webgen/webgui/public/img/headerbg.jpg +0 -0
  14. data/data/webgen/webgui/public/img/webgen_logo.png +0 -0
  15. data/data/webgen/webgui/public/js/jquery.autocomplete.js +15 -0
  16. data/data/webgen/webgui/public/js/jquery.js +32 -0
  17. data/data/webgen/webgui/view/create_website.xhtml +22 -0
  18. data/data/webgen/webgui/view/error.xhtml +64 -0
  19. data/data/webgen/webgui/view/index.xhtml +22 -0
  20. data/data/webgen/webgui/view/manage_website.xhtml +18 -0
  21. data/data/webgen/webgui/view/page.xhtml +40 -0
  22. data/data/webgen/website_skeleton/README +10 -0
  23. data/data/webgen/website_skeleton/Rakefile +40 -0
  24. data/data/webgen/website_skeleton/config.yaml +17 -0
  25. data/data/webgen/website_skeleton/ext/init.rb +10 -0
  26. data/data/webgen/website_styles/1024px/README +13 -0
  27. data/data/webgen/website_styles/1024px/src/default.css +188 -0
  28. data/data/webgen/website_styles/1024px/src/default.template +60 -0
  29. data/data/webgen/website_styles/1024px/src/images/background.gif +0 -0
  30. data/data/webgen/website_styles/andreas00/README +13 -0
  31. data/data/webgen/website_styles/andreas00/src/default.css +290 -0
  32. data/data/webgen/website_styles/andreas00/src/default.template +60 -0
  33. data/data/webgen/website_styles/andreas00/src/images/bg.gif +0 -0
  34. data/data/webgen/website_styles/andreas00/src/images/front.jpg +0 -0
  35. data/data/webgen/website_styles/andreas00/src/images/menubg.gif +0 -0
  36. data/data/webgen/website_styles/andreas00/src/images/menubg2.gif +0 -0
  37. data/data/webgen/website_styles/andreas01/README +14 -0
  38. data/data/webgen/website_styles/andreas01/src/default.css +310 -0
  39. data/data/webgen/website_styles/andreas01/src/default.template +62 -0
  40. data/data/webgen/website_styles/andreas01/src/images/bg.gif +0 -0
  41. data/data/webgen/website_styles/andreas01/src/images/front.jpg +0 -0
  42. data/data/webgen/website_styles/andreas01/src/print.css +35 -0
  43. data/data/webgen/website_styles/andreas03/README +14 -0
  44. data/data/webgen/website_styles/andreas03/src/default.css +223 -0
  45. data/data/webgen/website_styles/andreas03/src/default.template +58 -0
  46. data/data/webgen/website_styles/andreas03/src/images/bodybg.png +0 -0
  47. data/data/webgen/website_styles/andreas03/src/images/contbg.png +0 -0
  48. data/data/webgen/website_styles/andreas03/src/images/footerbg.png +0 -0
  49. data/data/webgen/website_styles/andreas03/src/images/gradient1.png +0 -0
  50. data/data/webgen/website_styles/andreas03/src/images/gradient2.png +0 -0
  51. data/data/webgen/website_styles/andreas04/README +15 -0
  52. data/data/webgen/website_styles/andreas04/src/default.css +290 -0
  53. data/data/webgen/website_styles/andreas04/src/default.template +81 -0
  54. data/data/webgen/website_styles/andreas04/src/images/blinkarrow.gif +0 -0
  55. data/data/webgen/website_styles/andreas04/src/images/bodybg.png +0 -0
  56. data/data/webgen/website_styles/andreas04/src/images/contentbg.png +0 -0
  57. data/data/webgen/website_styles/andreas04/src/images/entrybg.png +0 -0
  58. data/data/webgen/website_styles/andreas04/src/images/flash.gif +0 -0
  59. data/data/webgen/website_styles/andreas04/src/images/flash2.gif +0 -0
  60. data/data/webgen/website_styles/andreas04/src/images/globe.gif +0 -0
  61. data/data/webgen/website_styles/andreas04/src/images/globebottom.gif +0 -0
  62. data/data/webgen/website_styles/andreas04/src/images/linkarrow.gif +0 -0
  63. data/data/webgen/website_styles/andreas04/src/images/menuhover.png +0 -0
  64. data/data/webgen/website_styles/andreas05/README +14 -0
  65. data/data/webgen/website_styles/andreas05/src/default.css +33 -0
  66. data/data/webgen/website_styles/andreas05/src/default.template +40 -0
  67. data/data/webgen/website_styles/andreas05/src/images/bodybg.gif +0 -0
  68. data/data/webgen/website_styles/andreas05/src/images/front.png +0 -0
  69. data/data/webgen/website_styles/andreas06/README +14 -0
  70. data/data/webgen/website_styles/andreas06/src/default.css +354 -0
  71. data/data/webgen/website_styles/andreas06/src/default.template +70 -0
  72. data/data/webgen/website_styles/andreas06/src/images/bodybg.gif +0 -0
  73. data/data/webgen/website_styles/andreas06/src/images/boxbg.gif +0 -0
  74. data/data/webgen/website_styles/andreas06/src/images/greypx.gif +0 -0
  75. data/data/webgen/website_styles/andreas06/src/images/header.jpg +0 -0
  76. data/data/webgen/website_styles/andreas06/src/images/innerbg.gif +0 -0
  77. data/data/webgen/website_styles/andreas06/src/images/leaves.jpg +0 -0
  78. data/data/webgen/website_styles/andreas06/src/images/tabs.gif +0 -0
  79. data/data/webgen/website_styles/andreas07/README +15 -0
  80. data/data/webgen/website_styles/andreas07/src/browserfix.css +7 -0
  81. data/data/webgen/website_styles/andreas07/src/default.css +92 -0
  82. data/data/webgen/website_styles/andreas07/src/default.template +42 -0
  83. data/data/webgen/website_styles/andreas07/src/images/bodybg.gif +0 -0
  84. data/data/webgen/website_styles/andreas07/src/images/sidebarbg.gif +0 -0
  85. data/data/webgen/website_styles/andreas08/README +14 -0
  86. data/data/webgen/website_styles/andreas08/src/default.css +224 -0
  87. data/data/webgen/website_styles/andreas08/src/default.template +51 -0
  88. data/data/webgen/website_styles/andreas09/README +14 -0
  89. data/data/webgen/website_styles/andreas09/src/default.css +308 -0
  90. data/data/webgen/website_styles/andreas09/src/default.template +68 -0
  91. data/data/webgen/website_styles/andreas09/src/images/bodybg-black.jpg +0 -0
  92. data/data/webgen/website_styles/andreas09/src/images/bodybg-green.jpg +0 -0
  93. data/data/webgen/website_styles/andreas09/src/images/bodybg-orange.jpg +0 -0
  94. data/data/webgen/website_styles/andreas09/src/images/bodybg-purple.jpg +0 -0
  95. data/data/webgen/website_styles/andreas09/src/images/bodybg-red.jpg +0 -0
  96. data/data/webgen/website_styles/andreas09/src/images/bodybg.jpg +0 -0
  97. data/data/webgen/website_styles/andreas09/src/images/footerbg.jpg +0 -0
  98. data/data/webgen/website_styles/andreas09/src/images/menuhover-black.jpg +0 -0
  99. data/data/webgen/website_styles/andreas09/src/images/menuhover-green.jpg +0 -0
  100. data/data/webgen/website_styles/andreas09/src/images/menuhover-orange.jpg +0 -0
  101. data/data/webgen/website_styles/andreas09/src/images/menuhover-purple.jpg +0 -0
  102. data/data/webgen/website_styles/andreas09/src/images/menuhover-red.jpg +0 -0
  103. data/data/webgen/website_styles/andreas09/src/images/menuhover.jpg +0 -0
  104. data/data/webgen/website_styles/simple/README +6 -0
  105. data/data/webgen/website_styles/simple/src/default.css +84 -0
  106. data/data/webgen/website_styles/simple/src/default.template +36 -0
  107. data/data/webgen/website_templates/default/README +6 -0
  108. data/data/webgen/website_templates/default/src/index.page +8 -0
  109. data/data/webgen/website_templates/project/README +5 -0
  110. data/data/webgen/website_templates/project/src/about.page +12 -0
  111. data/data/webgen/website_templates/project/src/download.page +15 -0
  112. data/data/webgen/website_templates/project/src/features.page +8 -0
  113. data/data/webgen/website_templates/project/src/index.page +9 -0
  114. data/data/webgen/website_templates/project/src/screenshots.page +18 -0
  115. data/doc/contentprocessor.template +11 -0
  116. data/doc/contentprocessor/blocks.page +129 -0
  117. data/doc/contentprocessor/builder.page +80 -0
  118. data/doc/contentprocessor/erb.page +59 -0
  119. data/doc/contentprocessor/erubis.page +46 -0
  120. data/doc/contentprocessor/fragments.page +25 -0
  121. data/doc/contentprocessor/haml.page +47 -0
  122. data/doc/contentprocessor/maruku.page +41 -0
  123. data/doc/contentprocessor/rdiscount.page +37 -0
  124. data/doc/contentprocessor/rdoc.page +36 -0
  125. data/doc/contentprocessor/redcloth.page +39 -0
  126. data/doc/contentprocessor/sass.page +31 -0
  127. data/doc/contentprocessor/tags.page +73 -0
  128. data/doc/extensions.metainfo +29 -0
  129. data/doc/extensions.page +16 -0
  130. data/doc/extensions.template +17 -0
  131. data/doc/faq.page +219 -0
  132. data/doc/getting_started.page +135 -0
  133. data/doc/index.page +65 -0
  134. data/doc/manual.page +589 -0
  135. data/doc/reference_configuration.page +959 -0
  136. data/doc/reference_metainfo.page +222 -0
  137. data/doc/source/filesystem.page +39 -0
  138. data/doc/source/tararchive.page +40 -0
  139. data/doc/sourcehandler.template +21 -0
  140. data/doc/sourcehandler/copy.page +19 -0
  141. data/doc/sourcehandler/directory.page +27 -0
  142. data/doc/sourcehandler/feed.page +105 -0
  143. data/doc/sourcehandler/metainfo.page +41 -0
  144. data/doc/sourcehandler/page.page +14 -0
  145. data/doc/sourcehandler/sitemap.page +46 -0
  146. data/doc/sourcehandler/template.page +45 -0
  147. data/doc/sourcehandler/virtual.page +49 -0
  148. data/doc/tag.template +25 -0
  149. data/doc/tag/breadcrumbtrail.page +40 -0
  150. data/doc/tag/coderay.page +49 -0
  151. data/doc/tag/date.page +31 -0
  152. data/doc/tag/executecommand.page +26 -0
  153. data/doc/tag/includefile.page +32 -0
  154. data/doc/tag/langbar.page +44 -0
  155. data/doc/tag/link.page +44 -0
  156. data/doc/tag/menu.page +106 -0
  157. data/doc/tag/metainfo.page +29 -0
  158. data/doc/tag/relocatable.page +38 -0
  159. data/doc/tag/sitemap.page +31 -0
  160. data/doc/tag/tikz.page +158 -0
  161. data/doc/upgrading.page +139 -0
  162. data/doc/webgen_page_format.page +129 -0
  163. data/lib/webgen/blackboard.rb +78 -0
  164. data/lib/webgen/cache.rb +87 -0
  165. data/lib/webgen/cli.rb +124 -0
  166. data/lib/webgen/cli/apply_command.rb +64 -0
  167. data/lib/webgen/cli/create_command.rb +66 -0
  168. data/lib/webgen/cli/run_command.rb +22 -0
  169. data/lib/webgen/cli/utils.rb +88 -0
  170. data/lib/webgen/cli/webgui_command.rb +72 -0
  171. data/lib/webgen/common.rb +21 -0
  172. data/lib/webgen/common/sitemap.rb +83 -0
  173. data/lib/webgen/configuration.rb +153 -0
  174. data/lib/webgen/contentprocessor.rb +99 -0
  175. data/lib/webgen/contentprocessor/blocks.rb +60 -0
  176. data/lib/webgen/contentprocessor/builder.rb +30 -0
  177. data/lib/webgen/contentprocessor/context.rb +89 -0
  178. data/lib/webgen/contentprocessor/erb.rb +28 -0
  179. data/lib/webgen/contentprocessor/erubis.rb +40 -0
  180. data/lib/webgen/contentprocessor/fragments.rb +25 -0
  181. data/lib/webgen/contentprocessor/haml.rb +30 -0
  182. data/lib/webgen/contentprocessor/maruku.rb +20 -0
  183. data/lib/webgen/contentprocessor/rdiscount.rb +17 -0
  184. data/lib/webgen/contentprocessor/rdoc.rb +19 -0
  185. data/lib/webgen/contentprocessor/redcloth.rb +17 -0
  186. data/lib/webgen/contentprocessor/sass.rb +20 -0
  187. data/lib/webgen/contentprocessor/tags.rb +136 -0
  188. data/lib/webgen/coreext.rb +13 -0
  189. data/lib/webgen/default_config.rb +215 -0
  190. data/lib/webgen/languages.rb +589 -0
  191. data/lib/webgen/loggable.rb +25 -0
  192. data/lib/webgen/logger.rb +97 -0
  193. data/lib/webgen/node.rb +391 -0
  194. data/lib/webgen/output.rb +82 -0
  195. data/lib/webgen/output/filesystem.rb +69 -0
  196. data/lib/webgen/page.rb +153 -0
  197. data/lib/webgen/path.rb +194 -0
  198. data/lib/webgen/source.rb +54 -0
  199. data/lib/webgen/source/filesystem.rb +61 -0
  200. data/lib/webgen/source/resource.rb +44 -0
  201. data/lib/webgen/source/stacked.rb +55 -0
  202. data/lib/webgen/source/tararchive.rb +73 -0
  203. data/lib/webgen/sourcehandler.rb +226 -0
  204. data/lib/webgen/sourcehandler/base.rb +248 -0
  205. data/lib/webgen/sourcehandler/copy.rb +43 -0
  206. data/lib/webgen/sourcehandler/directory.rb +36 -0
  207. data/lib/webgen/sourcehandler/feed.rb +117 -0
  208. data/lib/webgen/sourcehandler/fragment.rb +68 -0
  209. data/lib/webgen/sourcehandler/memory.rb +43 -0
  210. data/lib/webgen/sourcehandler/metainfo.rb +128 -0
  211. data/lib/webgen/sourcehandler/page.rb +59 -0
  212. data/lib/webgen/sourcehandler/sitemap.rb +60 -0
  213. data/lib/webgen/sourcehandler/template.rb +66 -0
  214. data/lib/webgen/sourcehandler/virtual.rb +110 -0
  215. data/lib/webgen/tag.rb +27 -0
  216. data/lib/webgen/tag/base.rb +170 -0
  217. data/lib/webgen/tag/breadcrumbtrail.rb +70 -0
  218. data/lib/webgen/tag/coderay.rb +31 -0
  219. data/lib/webgen/tag/date.rb +18 -0
  220. data/lib/webgen/tag/executecommand.rb +30 -0
  221. data/lib/webgen/tag/includefile.rb +42 -0
  222. data/lib/webgen/tag/langbar.rb +52 -0
  223. data/lib/webgen/tag/link.rb +26 -0
  224. data/lib/webgen/tag/menu.rb +207 -0
  225. data/lib/webgen/tag/metainfo.rb +25 -0
  226. data/lib/webgen/tag/relocatable.rb +54 -0
  227. data/lib/webgen/tag/sitemap.rb +41 -0
  228. data/lib/webgen/tag/tikz.rb +119 -0
  229. data/lib/webgen/tree.rb +90 -0
  230. data/lib/webgen/version.rb +8 -0
  231. data/lib/webgen/webgentask.rb +152 -0
  232. data/lib/webgen/website.rb +342 -0
  233. data/lib/webgen/websiteaccess.rb +31 -0
  234. data/lib/webgen/websitemanager.rb +127 -0
  235. data/man/man1/webgen.1 +73 -0
  236. data/misc/default.css +384 -0
  237. data/misc/default.template +75 -0
  238. data/misc/htmldoc.metainfo +25 -0
  239. data/misc/htmldoc.virtual +5 -0
  240. data/misc/images/arrow.gif +0 -0
  241. data/misc/images/error.png +0 -0
  242. data/misc/images/headerbg.jpg +0 -0
  243. data/misc/images/important.png +0 -0
  244. data/misc/images/information.png +0 -0
  245. data/misc/images/quote.gif +0 -0
  246. data/misc/images/warning.png +0 -0
  247. data/setup.rb +1585 -0
  248. data/test/helper.rb +45 -0
  249. data/test/test_blackboard.rb +60 -0
  250. data/test/test_cache.rb +59 -0
  251. data/test/test_cli.rb +21 -0
  252. data/test/test_common.rb +18 -0
  253. data/test/test_common_sitemap.rb +58 -0
  254. data/test/test_configuration.rb +68 -0
  255. data/test/test_contentprocessor.rb +33 -0
  256. data/test/test_contentprocessor_blocks.rb +68 -0
  257. data/test/test_contentprocessor_builder.rb +23 -0
  258. data/test/test_contentprocessor_context.rb +40 -0
  259. data/test/test_contentprocessor_erb.rb +23 -0
  260. data/test/test_contentprocessor_erubis.rb +49 -0
  261. data/test/test_contentprocessor_fragments.rb +42 -0
  262. data/test/test_contentprocessor_haml.rb +23 -0
  263. data/test/test_contentprocessor_maruku.rb +29 -0
  264. data/test/test_contentprocessor_rdiscount.rb +17 -0
  265. data/test/test_contentprocessor_rdoc.rb +18 -0
  266. data/test/test_contentprocessor_redcloth.rb +15 -0
  267. data/test/test_contentprocessor_sass.rb +22 -0
  268. data/test/test_contentprocessor_tags.rb +99 -0
  269. data/test/test_languages.rb +67 -0
  270. data/test/test_loggable.rb +32 -0
  271. data/test/test_logger.rb +94 -0
  272. data/test/test_node.rb +367 -0
  273. data/test/test_output_filesystem.rb +60 -0
  274. data/test/test_page.rb +214 -0
  275. data/test/test_path.rb +165 -0
  276. data/test/test_source_filesystem.rb +76 -0
  277. data/test/test_source_resource.rb +28 -0
  278. data/test/test_source_stacked.rb +36 -0
  279. data/test/test_source_tararchive.rb +65 -0
  280. data/test/test_sourcehandler_base.rb +123 -0
  281. data/test/test_sourcehandler_copy.rb +47 -0
  282. data/test/test_sourcehandler_directory.rb +42 -0
  283. data/test/test_sourcehandler_feed.rb +77 -0
  284. data/test/test_sourcehandler_fragment.rb +69 -0
  285. data/test/test_sourcehandler_memory.rb +44 -0
  286. data/test/test_sourcehandler_metainfo.rb +118 -0
  287. data/test/test_sourcehandler_page.rb +65 -0
  288. data/test/test_sourcehandler_sitemap.rb +49 -0
  289. data/test/test_sourcehandler_template.rb +65 -0
  290. data/test/test_sourcehandler_virtual.rb +87 -0
  291. data/test/test_tag_base.rb +85 -0
  292. data/test/test_tag_breadcrumbtrail.rb +91 -0
  293. data/test/test_tag_coderay.rb +32 -0
  294. data/test/test_tag_date.rb +18 -0
  295. data/test/test_tag_executecommand.rb +41 -0
  296. data/test/test_tag_includefile.rb +50 -0
  297. data/test/test_tag_langbar.rb +72 -0
  298. data/test/test_tag_link.rb +69 -0
  299. data/test/test_tag_menu.rb +207 -0
  300. data/test/test_tag_metainfo.rb +19 -0
  301. data/test/test_tag_relocatable.rb +59 -0
  302. data/test/test_tag_sitemap.rb +47 -0
  303. data/test/test_tag_tikz.rb +69 -0
  304. data/test/test_tree.rb +70 -0
  305. data/test/test_webgentask.rb +23 -0
  306. data/test/test_website.rb +98 -0
  307. data/test/test_websiteaccess.rb +25 -0
  308. data/test/test_websitemanager.rb +70 -0
  309. metadata +613 -0
@@ -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,8 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ module Webgen
4
+
5
+ # The version of webgen.
6
+ VERSION = '0.5.8'
7
+
8
+ 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