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,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ module Webgen::Tag
4
+
5
+ # Create a link to a given (A)LCN.
6
+ class Link
7
+
8
+ include Webgen::Tag::Base
9
+
10
+ # Return a HTML link to the given (A)LCN.
11
+ def call(tag, body, context)
12
+ if (dest_node = context.ref_node.resolve(param('tag.link.path'), context.dest_node.lang))
13
+ context.dest_node.node_info[:used_meta_info_nodes] << dest_node.absolute_lcn
14
+ context.dest_node.link_to(dest_node, param('tag.link.attr').merge(:lang => context.content_node.lang))
15
+ else
16
+ raise ArgumentError, 'Resolving of path failed'
17
+ end
18
+ rescue ArgumentError, URI::InvalidURIError => e
19
+ log(:error) { "Could not link to path '#{param('tag.link.path')}' in <#{context.ref_node.absolute_lcn}>: #{e.message}" }
20
+ context.dest_node.flag(:dirty)
21
+ ''
22
+ end
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,207 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ module Webgen::Tag
4
+
5
+ # Generates a menu that can be configured extensively.
6
+ class Menu
7
+
8
+ include Webgen::WebsiteAccess
9
+ include Base
10
+
11
+ # Special menu node class. It encapsulates the original node for later access.
12
+ class MenuNode
13
+
14
+ # Array of the child nodes.
15
+ attr_reader :children
16
+
17
+ # The parent node.
18
+ attr_reader :parent
19
+
20
+ # The encapsulated node.
21
+ attr_reader :node
22
+
23
+ # Set to +true+ if the menu node is in the tree of files.
24
+ attr_writer :is_in_tree_of_files
25
+
26
+ # Create a new menu node under +parent+ for the real node +node+.
27
+ def initialize(parent, node)
28
+ @parent = parent
29
+ @node = node
30
+ @children = []
31
+ end
32
+
33
+ # Return +true+ if the menu node is in the menu tree of only files.
34
+ def is_in_tree_of_files?
35
+ @is_in_tree_of_files
36
+ end
37
+
38
+ # Sort recursively all children of the node using the wrapped nodes.
39
+ def sort!
40
+ self.children.sort! {|a,b| a.node <=> b.node}
41
+ self.children.each {|child| child.sort!}
42
+ self
43
+ end
44
+
45
+ # Return the menu tree under the node as nested list of alcn values.
46
+ def to_lcn_list
47
+ self.children.inject([]) {|temp, n| temp << n.node.absolute_lcn; temp += ((t = n.to_lcn_list).empty? ? [] : [t]) }
48
+ end
49
+
50
+ end
51
+
52
+ def initialize #:nodoc:
53
+ website.blackboard.add_listener(:node_changed?, method(:node_changed?))
54
+ end
55
+
56
+ # Generate the menu.
57
+ def call(tag, body, context)
58
+ tree = specific_menu_tree_for(context.content_node)
59
+
60
+ (context.dest_node.node_info[:tag_menu_menus] ||= {})[[@params.to_a.sort, context.content_node.absolute_lcn]] = (tree ? tree.to_lcn_list : nil)
61
+
62
+ if !tree || tree.children.empty?
63
+ ''
64
+ elsif param('tag.menu.nested')
65
+ create_output_nested(context, tree)
66
+ else
67
+ create_output_not_nested(context, tree)
68
+ end
69
+ end
70
+
71
+ #########
72
+ protected
73
+ #########
74
+
75
+ # Check if the menus for +node+ have changed.
76
+ def node_changed?(node)
77
+ return if !node.node_info[:tag_menu_menus]
78
+
79
+ node.node_info[:tag_menu_menus].each do |(params, cn_alcn), cached_tree|
80
+ cn = node.tree[cn_alcn]
81
+ menu_tree = menu_tree_for_lang(cn.lang, cn.tree.root)
82
+
83
+ set_params(params.to_hash)
84
+ tree = build_specific_menu_tree(cn, menu_tree)
85
+ tree_list = tree.to_lcn_list if tree
86
+ set_params({})
87
+
88
+ if (tree.nil? && !cached_tree.nil?) || (tree_list && tree_list != cached_tree) ||
89
+ (tree_list && tree_list.flatten.any? do |alcn|
90
+ (n = node.tree[alcn]) && (r = n.routing_node(cn.lang)) && r != node && r.meta_info_changed?
91
+ end)
92
+ node.flag(:dirty)
93
+ break
94
+ end
95
+ end
96
+ end
97
+
98
+ # Wrapper method for returning the specific menu tree for +content_node+.
99
+ def specific_menu_tree_for(content_node)
100
+ tree = menu_tree_for_lang(content_node.lang, content_node.tree.root)
101
+ if param('tag.menu.used_nodes') == 'fragments'
102
+ @params['tag.menu.start_level'] = param('tag.menu.start_level') + content_node.level
103
+ end
104
+ build_specific_menu_tree(content_node, tree)
105
+ end
106
+
107
+ # Build a menu tree for +content_node+ from the tree +menu_node+.
108
+ def build_specific_menu_tree(content_node, menu_node, level = 1)
109
+ if menu_node.nil? \
110
+ || level > param('tag.menu.max_levels') + param('tag.menu.start_level') - 1 \
111
+ || ((level > param('tag.menu.min_levels') + param('tag.menu.start_level') - 1) \
112
+ && (menu_node.node.level >= content_node.level \
113
+ || (param('tag.menu.show_current_subtree_only') && !content_node.in_subtree_of?(menu_node.node))
114
+ )
115
+ ) \
116
+ || (level == param('tag.menu.start_level') && !content_node.in_subtree_of?(menu_node.node))
117
+ return nil
118
+ end
119
+
120
+ sub_menu_tree = MenuNode.new(nil, menu_node.node)
121
+ menu_tree = MenuNode.new(nil, menu_node.node)
122
+ menu_node.children.each do |child|
123
+ next if param('tag.menu.used_nodes') == 'files' && !child.is_in_tree_of_files?
124
+ menu_tree.children << (this_node = MenuNode.new(menu_tree, child.node))
125
+ sub_node = child.children.length > 0 ? build_specific_menu_tree(content_node, child, level + 1) : nil
126
+ sub_node.children.each {|n| this_node.children << n; sub_menu_tree.children << n} if sub_node
127
+ end
128
+
129
+ if level < param('tag.menu.start_level')
130
+ sub_menu_tree
131
+ else
132
+ menu_tree
133
+ end
134
+ end
135
+
136
+ # Create the nested HTML menu of the +tree+ using the provided +context+.
137
+ def create_output_nested(context, tree, level = 1)
138
+ out = "<ul>"
139
+ tree.children.each do |child|
140
+ menu = child.children.length > 0 ? create_output_nested(context, child, level + 1) : ''
141
+ style, link = menu_item_details(context.dest_node, child.node, context.content_node.lang, level)
142
+
143
+ out << "<li #{style}>#{link}"
144
+ out << menu
145
+ out << "</li>"
146
+ end
147
+ out << "</ul>"
148
+ out
149
+ end
150
+
151
+ # Create the not nested HTML menu of the +tree+ using the provided +context+.
152
+ def create_output_not_nested(context, tree, level = 1)
153
+ submenu = ''
154
+ out = "<ul>"
155
+ tree.children.each do |child|
156
+ submenu << (child.children.length > 0 ? create_output_not_nested(context, child, level + 1) : '')
157
+ style, link = menu_item_details(context.dest_node, child.node, context.content_node.lang, level)
158
+
159
+ out << "<li #{style}>#{link}</li>"
160
+ end
161
+ out << "</ul>"
162
+ out << submenu
163
+ out
164
+ end
165
+
166
+ # Return style information (node is selected, ...) and a link from +dest_node+ to +node+.
167
+ def menu_item_details(dest_node, node, lang, level)
168
+ styles = ['webgen-menu-level' + level.to_s]
169
+ styles << 'webgen-menu-submenu' if node.is_directory? || (node.is_fragment? && node.children.length > 0)
170
+ styles << 'webgen-menu-submenu-inhierarchy' if (node.is_directory? || (node.is_fragment? && node.children.length > 0)) &&
171
+ dest_node.in_subtree_of?(node)
172
+ styles << 'webgen-menu-item-selected' if node == dest_node
173
+ style = "class=\"#{styles.join(' ')}\"" if styles.length > 0
174
+
175
+ link = dest_node.link_to(node, :lang => lang)
176
+
177
+ [style, link]
178
+ end
179
+
180
+ # Return the menu tree for the language +lang+.
181
+ def menu_tree_for_lang(lang, root)
182
+ menus = (website.cache.volatile[:menutrees] ||= {})
183
+ unless menus[lang]
184
+ menus[lang] = create_menu_tree(root, nil, lang)
185
+ menus[lang].sort! if menus[lang]
186
+ end
187
+ menus[lang]
188
+ end
189
+
190
+ # Create and return a menu tree if at least one node is in the menu or +nil+ otherwise.
191
+ def create_menu_tree(node, parent, lang)
192
+ menu_node = MenuNode.new(parent, node)
193
+
194
+ node.children.select do |child|
195
+ child.lang == lang || child.lang.nil? || child.is_directory?
196
+ end.each do |child|
197
+ sub_node = create_menu_tree(child, menu_node, lang)
198
+ menu_node.children << sub_node unless sub_node.nil?
199
+ end
200
+ menu_node.is_in_tree_of_files = (!node.is_fragment? && node['in_menu']) || menu_node.children.any? {|c| c.is_in_tree_of_files?}
201
+
202
+ menu_node.children.empty? ? (node['in_menu'] ? menu_node : nil) : menu_node
203
+ end
204
+
205
+ end
206
+
207
+ end
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ module Webgen::Tag
4
+
5
+ # Provides easy access to the meta information of a node.
6
+ class Metainfo
7
+
8
+ include Base
9
+
10
+ # Return the meta information key specified in +tag+ of the content node.
11
+ def call(tag, body, context)
12
+ output = ''
13
+ if tag == 'lang'
14
+ output = context.content_node.lang
15
+ elsif context.content_node[tag]
16
+ output = context.content_node[tag].to_s
17
+ else
18
+ log(:warn) { "No value for meta info key '#{tag}' in <#{context.ref_node.absolute_lcn}> found in <#{context.content_node.absolute_lcn}>" }
19
+ end
20
+ output
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,54 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'uri'
4
+
5
+ module Webgen::Tag
6
+
7
+ # Makes a path relative. This is very useful for templates. For example, you normally include a
8
+ # stylesheet in a template. If you specify the filename of the stylesheet directly, the reference
9
+ # to the stylesheet in the output file of a page file that is not in the same directory as the
10
+ # template would be invalid.
11
+ #
12
+ # By using the +relocatable+ tag you ensure that the path stays valid.
13
+ class Relocatable
14
+
15
+ include Webgen::Tag::Base
16
+
17
+ # Return the relativized path for the path provided in the tag definition.
18
+ def call(tag, body, context)
19
+ uri_string = param('tag.relocatable.path')
20
+ result = ''
21
+ unless uri_string.nil?
22
+ begin
23
+ uri = URI.parse(uri_string)
24
+ if uri.absolute?
25
+ result = uri_string
26
+ else
27
+ result = resolve_path(uri_string, context)
28
+ end
29
+ if result.empty?
30
+ log(:error) { "Could not resolve path '#{uri_string}' in <#{context.ref_node.absolute_lcn}>" }
31
+ context.dest_node.flag(:dirty)
32
+ end
33
+ rescue URI::InvalidURIError => e
34
+ log(:error) { "Error while parsing path for tag relocatable in <#{context.ref_node.absolute_lcn}>: #{e.message}" }
35
+ context.dest_node.flag(:dirty)
36
+ end
37
+ end
38
+ result
39
+ end
40
+
41
+ #######
42
+ private
43
+ #######
44
+
45
+ # Resolve the path +uri+ using the reference node and return the correct relative path from the
46
+ # destination node.
47
+ def resolve_path(uri, context)
48
+ dest_node = context.ref_node.resolve(uri, context.dest_node.lang)
49
+ (dest_node ? context.dest_node.route_to(dest_node) : '')
50
+ end
51
+
52
+ end
53
+
54
+ end
@@ -0,0 +1,41 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ module Webgen::Tag
4
+
5
+ # Generates a sitemap. The sitemap contains the hierarchy of all pages on the web site.
6
+ class Sitemap
7
+
8
+ include Base
9
+ include Webgen::WebsiteAccess
10
+
11
+ # Create the sitemap.
12
+ def call(tag, body, context)
13
+ tree = website.blackboard.invoke(:create_sitemap, context.dest_node, context.content_node.lang, @params)
14
+ (tree.children.empty? ? '' : output_sitemap(tree, context))
15
+ end
16
+
17
+ #######
18
+ private
19
+ #######
20
+
21
+ # The modified tag base to support the easy specification of common.sitemap.* options.
22
+ def tag_config_base
23
+ 'common.sitemap'
24
+ end
25
+
26
+ # Create the HTML representation of the sitemap nodes in +tree+ in respect to +context+.
27
+ def output_sitemap(tree, context)
28
+ out = "<ul>"
29
+ tree.children.each do |child|
30
+ sub = (child.children.length > 0 ? output_sitemap(child, context) : '')
31
+ out << "<li>" + context.dest_node.link_to(child.node, :lang => child.node.lang || context.content_node.lang)
32
+ out << sub
33
+ out << "</li>"
34
+ end
35
+ out << "</ul>"
36
+ out
37
+ end
38
+
39
+ end
40
+
41
+ end
@@ -0,0 +1,119 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'erb'
4
+ require 'tempfile'
5
+ require 'fileutils'
6
+
7
+ module Webgen::Tag
8
+
9
+ # This tag allows the creation and inclusion of complex graphics using the PGF/TikZ library of
10
+ # LaTeX. You will need a current LaTeX distribution and the +convert+ utility from ImageMagick.
11
+ class TikZ
12
+
13
+ include Webgen::Tag::Base
14
+ include Webgen::WebsiteAccess
15
+
16
+ LATEX_TEMPLATE = <<EOF
17
+ \\nonstopmode \\documentclass{article} \\usepackage{tikz} \\pagestyle{empty}
18
+ <% if param('tag.tikz.libraries') %>
19
+ \\usetikzlibrary{<%= param('tag.tikz.libraries').join(',') %>}
20
+ <% end %>
21
+ \\begin{document}
22
+ <% if param('tag.tikz.opts') %>
23
+ \\begin{tikzpicture}[<%= param('tag.tikz.opts') %>]
24
+ <% else %>
25
+ \\begin{tikzpicture}
26
+ <% end %>
27
+ <%= body %>
28
+ \\end{tikzpicture}
29
+ \\end{document}
30
+ EOF
31
+
32
+ # Create a graphic from the commands in the body of the tag.
33
+ def call(tag, body, context)
34
+ path = param('tag.tikz.path')
35
+ path = Webgen::Common.absolute_path(path, context.ref_node.parent.absolute_lcn)
36
+
37
+ mem_handler = website.cache.instance('Webgen::SourceHandler::Memory')
38
+ src_path = context.ref_node.node_info[:src]
39
+ parent = website.blackboard.invoke(:create_directories, context.ref_node.tree.root, File.dirname(path), src_path)
40
+ params = @params
41
+
42
+ node = website.blackboard.invoke(:create_nodes, parent.tree, parent.absolute_lcn,
43
+ Webgen::Path.new(path, src_path), mem_handler) do |node_parent, node_path|
44
+ mem_handler.create_node(node_parent, node_path, context.ref_node.absolute_lcn) do |pic_node|
45
+ set_params(params)
46
+ document = ERB.new(LATEX_TEMPLATE).result(binding)
47
+ pic_path = compile(document, File.extname(path), context)
48
+ set_params(nil)
49
+ if pic_path
50
+ io = Webgen::Path::SourceIO.new { File.open(pic_path, 'rb') }
51
+ else
52
+ pic_node.flag(:dirty)
53
+ nil
54
+ end
55
+ end
56
+ end.first
57
+ attrs = param('tag.tikz.img_attr').collect {|name,value| "#{name.to_s}=\"#{value}\"" }.sort.unshift('').join(' ')
58
+ "<img src=\"#{context.dest_node.route_to(node)}\"#{attrs} />"
59
+ end
60
+
61
+ #######
62
+ private
63
+ #######
64
+
65
+ # Compile the LaTeX +document+ and convert the resulting PDF to the correct output image format
66
+ # specified by +ext+ (the extension needs to include the dot).
67
+ def compile(document, ext, context)
68
+ file = Tempfile.new('webgen-tikz')
69
+ file.write(document)
70
+ file.close
71
+
72
+ FileUtils.mv(file.path, file.path + '.tex')
73
+ cmd_prefix = "cd #{File.dirname(file.path)}; "
74
+ output = `#{cmd_prefix} pdflatex --shell-escape -interaction=batchmode #{File.basename(file.path)}.tex`
75
+ if $?.exitstatus != 0
76
+ errors = output.scan(/^!(.*\n.*)/).join("\n")
77
+ log(:error) { "There was an error creating a TikZ picture in <#{context.ref_node.absolute_lcn}>: #{errors}"}
78
+ context.dest_node.flag(:dirty)
79
+ nil
80
+ else
81
+ cmd = cmd_prefix + "pdfcrop #{File.basename(file.path)}.pdf #{File.basename(file.path)}.pdf; "
82
+ return unless run_command(cmd, context)
83
+
84
+ render_res, output_res = param('tag.tikz.resolution').split(' ')
85
+ if param('tag.tikz.transparent') && ext =~ /\.png/i
86
+ cmd = cmd_prefix +
87
+ "gs -dSAFER -dBATCH -dNOPAUSE -r#{render_res} -sDEVICE=pngalpha -dGraphicsAlphaBits=4 -dTextAlphaBits=4 " +
88
+ "-sOutputFile=#{File.basename(file.path)}#{ext} #{File.basename(file.path)}.pdf"
89
+ else
90
+ cmd = cmd_prefix + "convert -density #{render_res} #{File.basename(file.path)}.pdf #{File.basename(file.path)}#{ext}"
91
+ end
92
+ return unless run_command(cmd, context)
93
+
94
+ if render_res != output_res
95
+ cmd = cmd_prefix + "identify #{File.basename(file.path)}#{ext}"
96
+ return unless (output = run_command(cmd, context))
97
+ width, height = output.scan(/\s\d+x\d+\s/).first.strip.split('x').collect {|s| s.to_f * output_res.to_f / render_res.to_f }
98
+ cmd = cmd_prefix + "convert -resize #{width}x#{height} #{File.basename(file.path)}#{ext} #{File.basename(file.path)}#{ext}"
99
+ return unless run_command(cmd, context)
100
+ end
101
+ file.path + ext
102
+ end
103
+ end
104
+
105
+ # Runs the command +cmd+ and returns it's output if successful or +nil+ otherwise.
106
+ def run_command(cmd, context)
107
+ output = `#{cmd}`
108
+ if $?.exitstatus != 0
109
+ log(:error) { "There was an error running a command for a TikZ picture in <#{context.ref_node.absolute_lcn}>: #{output}"}
110
+ context.dest_node.flag(:dirty)
111
+ nil
112
+ else
113
+ output
114
+ end
115
+ end
116
+
117
+ end
118
+
119
+ end