webgen 0.5.8 → 0.5.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. data/COPYING +4 -0
  2. data/ChangeLog +1037 -0
  3. data/Rakefile +5 -6
  4. data/THANKS +1 -0
  5. data/VERSION +1 -1
  6. data/bin/webgen +1 -1
  7. data/data/webgen/passive_sources/images/generated_by_webgen.png +0 -0
  8. data/data/webgen/passive_sources/images/webgen_logo.png +0 -0
  9. data/data/webgen/passive_sources/stylesheets/coderay-default.css +129 -0
  10. data/data/webgen/passive_sources/templates/atom_feed.template +38 -0
  11. data/data/webgen/passive_sources/templates/rss_feed.template +28 -0
  12. data/data/webgen/passive_sources/templates/sitemap.template +21 -0
  13. data/data/webgen/resources.yaml +2 -1
  14. data/data/webgen/website_skeleton/Rakefile +5 -1
  15. data/doc/contentprocessor/builder.page +2 -2
  16. data/doc/contentprocessor/erb.page +5 -2
  17. data/doc/contentprocessor/erubis.page +2 -2
  18. data/doc/contentprocessor/head.page +21 -0
  19. data/doc/contentprocessor/tidy.page +14 -0
  20. data/doc/extensions.page +1 -1
  21. data/doc/faq.page +2 -2
  22. data/doc/manual.page +108 -43
  23. data/doc/reference_configuration.page +83 -5
  24. data/doc/reference_metainfo.page +24 -4
  25. data/doc/reference_website_styles.page +2 -2
  26. data/doc/sourcehandler/feed.page +11 -13
  27. data/doc/sourcehandler/metainfo.page +10 -3
  28. data/doc/sourcehandler/page.page +4 -4
  29. data/doc/sourcehandler/sitemap.page +8 -7
  30. data/doc/tag/coderay.page +6 -2
  31. data/doc/tag/includefile.page +1 -1
  32. data/doc/tag/menu.page +3 -0
  33. data/lib/webgen/cli/apply_command.rb +1 -1
  34. data/lib/webgen/cli/utils.rb +2 -2
  35. data/lib/webgen/common.rb +0 -9
  36. data/lib/webgen/contentprocessor.rb +18 -3
  37. data/lib/webgen/contentprocessor/blocks.rb +67 -36
  38. data/lib/webgen/contentprocessor/builder.rb +5 -2
  39. data/lib/webgen/contentprocessor/erb.rb +4 -2
  40. data/lib/webgen/contentprocessor/erubis.rb +5 -2
  41. data/lib/webgen/contentprocessor/haml.rb +6 -2
  42. data/lib/webgen/contentprocessor/head.rb +64 -0
  43. data/lib/webgen/contentprocessor/maruku.rb +3 -1
  44. data/lib/webgen/contentprocessor/rdiscount.rb +2 -0
  45. data/lib/webgen/contentprocessor/rdoc.rb +2 -0
  46. data/lib/webgen/contentprocessor/redcloth.rb +2 -0
  47. data/lib/webgen/contentprocessor/sass.rb +5 -3
  48. data/lib/webgen/contentprocessor/tags.rb +40 -24
  49. data/lib/webgen/contentprocessor/tidy.rb +38 -0
  50. data/lib/webgen/context.rb +13 -4
  51. data/lib/webgen/context/render.rb +32 -0
  52. data/lib/webgen/context/tags.rb +20 -0
  53. data/lib/webgen/default_config.rb +15 -4
  54. data/lib/webgen/deprecated.rb +38 -4
  55. data/lib/webgen/error.rb +135 -0
  56. data/lib/webgen/node.rb +48 -40
  57. data/lib/webgen/output.rb +5 -3
  58. data/lib/webgen/output/filesystem.rb +4 -4
  59. data/lib/webgen/page.rb +4 -4
  60. data/lib/webgen/path.rb +161 -58
  61. data/lib/webgen/source.rb +9 -6
  62. data/lib/webgen/source/filesystem.rb +1 -1
  63. data/lib/webgen/source/stacked.rb +13 -5
  64. data/lib/webgen/source/tararchive.rb +6 -2
  65. data/lib/webgen/sourcehandler.rb +100 -54
  66. data/lib/webgen/sourcehandler/base.rb +58 -24
  67. data/lib/webgen/sourcehandler/copy.rb +6 -5
  68. data/lib/webgen/sourcehandler/directory.rb +3 -9
  69. data/lib/webgen/sourcehandler/feed.rb +25 -50
  70. data/lib/webgen/sourcehandler/fragment.rb +10 -8
  71. data/lib/webgen/sourcehandler/memory.rb +9 -10
  72. data/lib/webgen/sourcehandler/metainfo.rb +9 -9
  73. data/lib/webgen/sourcehandler/page.rb +6 -5
  74. data/lib/webgen/sourcehandler/sitemap.rb +22 -22
  75. data/lib/webgen/sourcehandler/template.rb +6 -6
  76. data/lib/webgen/sourcehandler/virtual.rb +19 -17
  77. data/lib/webgen/tag/base.rb +27 -27
  78. data/lib/webgen/tag/breadcrumbtrail.rb +3 -3
  79. data/lib/webgen/tag/coderay.rb +19 -8
  80. data/lib/webgen/tag/executecommand.rb +4 -3
  81. data/lib/webgen/tag/langbar.rb +2 -2
  82. data/lib/webgen/tag/link.rb +8 -7
  83. data/lib/webgen/tag/menu.rb +2 -2
  84. data/lib/webgen/tag/metainfo.rb +1 -1
  85. data/lib/webgen/tag/relocatable.rb +17 -21
  86. data/lib/webgen/tag/tikz.rb +7 -10
  87. data/lib/webgen/tree.rb +7 -7
  88. data/lib/webgen/version.rb +1 -1
  89. data/lib/webgen/website.rb +32 -2
  90. data/misc/default.css +8 -2
  91. data/misc/default.template +2 -2
  92. data/misc/logo.svg +313 -0
  93. data/misc/style.page +1 -1
  94. data/test/helper.rb +18 -2
  95. data/test/test_cli.rb +104 -0
  96. data/test/test_common_sitemap.rb +1 -1
  97. data/test/test_contentprocessor.rb +8 -2
  98. data/test/test_contentprocessor_blocks.rb +17 -8
  99. data/test/test_contentprocessor_builder.rb +13 -2
  100. data/test/test_contentprocessor_erb.rb +9 -3
  101. data/test/test_contentprocessor_erubis.rb +9 -3
  102. data/test/test_contentprocessor_fragments.rb +12 -11
  103. data/test/test_contentprocessor_haml.rb +11 -2
  104. data/test/test_contentprocessor_head.rb +44 -0
  105. data/test/test_contentprocessor_maruku.rb +5 -1
  106. data/test/test_contentprocessor_rdiscount.rb +4 -0
  107. data/test/test_contentprocessor_rdoc.rb +4 -0
  108. data/test/test_contentprocessor_redcloth.rb +5 -1
  109. data/test/test_contentprocessor_sass.rb +8 -2
  110. data/test/test_contentprocessor_tags.rb +22 -7
  111. data/test/test_contentprocessor_tidy.rb +34 -0
  112. data/test/test_context.rb +39 -0
  113. data/test/test_error.rb +85 -0
  114. data/test/test_node.rb +57 -21
  115. data/test/test_page.rb +23 -5
  116. data/test/test_path.rb +120 -64
  117. data/test/test_source_filesystem.rb +1 -1
  118. data/test/test_source_stacked.rb +19 -6
  119. data/test/test_sourcehandler_base.rb +63 -50
  120. data/test/test_sourcehandler_copy.rb +6 -6
  121. data/test/test_sourcehandler_directory.rb +8 -12
  122. data/test/test_sourcehandler_feed.rb +15 -7
  123. data/test/test_sourcehandler_fragment.rb +6 -5
  124. data/test/test_sourcehandler_main.rb +39 -0
  125. data/test/test_sourcehandler_memory.rb +4 -4
  126. data/test/test_sourcehandler_metainfo.rb +20 -11
  127. data/test/test_sourcehandler_page.rb +10 -10
  128. data/test/test_sourcehandler_sitemap.rb +24 -5
  129. data/test/test_sourcehandler_template.rb +18 -15
  130. data/test/test_sourcehandler_virtual.rb +9 -5
  131. data/test/test_tag_base.rb +6 -29
  132. data/test/test_tag_coderay.rb +16 -3
  133. data/test/test_tag_executecommand.rb +2 -2
  134. data/test/test_tag_link.rb +5 -4
  135. data/test/test_tag_menu.rb +15 -15
  136. data/test/test_tag_metainfo.rb +1 -0
  137. data/test/test_tag_relocatable.rb +3 -2
  138. data/test/test_tag_tikz.rb +5 -5
  139. data/test/test_tree.rb +8 -8
  140. data/test/test_website.rb +15 -0
  141. metadata +21 -14
  142. data/test/test_common.rb +0 -18
@@ -21,7 +21,7 @@ require 'webgen/websiteaccess'
21
21
  # the actual processing. And the +initialize+ method must not take any parameters!
22
22
  #
23
23
  # Tag classes *can* also choose to not use this module. If they don't use it they have to provide
24
- # the following methods: +set_params+, +create_tag_params+, +call+.
24
+ # the following methods: +set_params+, +create_tag_params+, +create_params_hash+, +call+.
25
25
  #
26
26
  # == Tag parameters
27
27
  #
@@ -50,8 +50,8 @@ require 'webgen/websiteaccess'
50
50
  #
51
51
  # def call(tag, body, context)
52
52
  # result = param('do_reverse') ? body.reverse : body
53
- # result += "Node: " + context.content_node.absolute_lcn + " (" + context.content_node['title'] + ")"
54
- # result += "Reference node: " + context.ref_node.absolute_lcn
53
+ # result += "Node: " + context.content_node.alcn + " (" + context.content_node['title'] + ")"
54
+ # result += "Reference node: " + context.ref_node.alcn
55
55
  # result
56
56
  # end
57
57
  #
@@ -65,17 +65,36 @@ module Webgen::Tag::Base
65
65
  include Webgen::Loggable
66
66
  include Webgen::WebsiteAccess
67
67
 
68
- # Return a hash with parameter values extracted from the string +tag_config+.
68
+ # Create a hash with parameter values extracted from the string +tag_config+ and return it.
69
69
  def create_tag_params(tag_config, ref_node)
70
70
  begin
71
71
  config = YAML::load("--- #{tag_config}")
72
72
  rescue ArgumentError => e
73
- log(:error) { "Could not parse the tag params '#{tag_config}' in <#{ref_node.absolute_lcn}>: #{e.message}" }
74
- config = {}
73
+ raise Webgen::RenderError.new("Could not parse the tag params '#{tag_config}': #{e.message}",
74
+ self.class.name, nil, ref_node.alcn)
75
75
  end
76
76
  create_params_hash(config, ref_node)
77
77
  end
78
78
 
79
+ # Create and return the parameter hash from +config+ which needs to be a Hash, a String or +nil+.
80
+ def create_params_hash(config, node)
81
+ params = tag_params_list
82
+ result = case config
83
+ when Hash then create_from_hash(config, params, node)
84
+ when String then create_from_string(config, params, node)
85
+ when NilClass then {}
86
+ else
87
+ raise Webgen::RenderError.new("Invalid parameter type (#{config.class})",
88
+ self.class.name, nil, node.alcn)
89
+ end
90
+
91
+ unless params.all? {|k| !website.config.meta_info[k][:mandatory] || result.has_key?(k)}
92
+ raise Webgen::RenderError.new("Not all mandatory parameters set", self.class.name, nil, node.alcn)
93
+ end
94
+
95
+ result
96
+ end
97
+
79
98
  # Set the current parameter configuration to +params+.
80
99
  def set_params(params)
81
100
  @params = params
@@ -122,25 +141,6 @@ module Webgen::Tag::Base
122
141
  website.config.data.keys.select {|key| key =~ regexp}
123
142
  end
124
143
 
125
- # Create the parameter hash from +config+ which needs to be a Hash, a String or +nil+.
126
- def create_params_hash(config, node)
127
- params = tag_params_list
128
- result = case config
129
- when Hash then create_from_hash(config, params, node)
130
- when String then create_from_string(config, params, node)
131
- when NilClass then {}
132
- else
133
- log(:error) { "Invalid parameter type (#{config.class}) for tag '#{self.class.name}' in <#{node.absolute_lcn}>" }
134
- {}
135
- end
136
-
137
- unless params.all? {|k| !website.config.meta_info[k][:mandatory] || result.has_key?(k)}
138
- log(:error) { "Not all mandatory parameters for tag '#{self.class.name}' in <#{node.absolute_lcn}> set" }
139
- end
140
-
141
- result
142
- end
143
-
144
144
  # Return a valid parameter hash taking values from +config+ which has to be a Hash.
145
145
  def create_from_hash(config, params, node)
146
146
  result = {}
@@ -150,7 +150,7 @@ module Webgen::Tag::Base
150
150
  elsif params.include?(tag_config_base + '.' + key)
151
151
  result[tag_config_base + '.' + key] = value
152
152
  else
153
- log(:warn) { "Invalid parameter '#{key}' for tag '#{self.class.name}' in <#{node.absolute_lcn}>" }
153
+ log(:warn) { "Invalid parameter '#{key}' for tag '#{self.class.name}' in <#{node.alcn}>" }
154
154
  end
155
155
  end
156
156
  result
@@ -160,7 +160,7 @@ module Webgen::Tag::Base
160
160
  def create_from_string(value, params, node)
161
161
  param_name = params.find {|k| website.config.meta_info[k][:mandatory] == 'default'}
162
162
  if param_name.nil?
163
- log(:error) { "No default mandatory parameter specified for tag '#{self.class.name}' but set in <#{node.absolute_lcn}>"}
163
+ log(:error) { "No default mandatory parameter specified for tag '#{self.class.name}' but set in <#{node.alcn}>"}
164
164
  {}
165
165
  else
166
166
  {param_name => value}
@@ -16,10 +16,10 @@ module Webgen::Tag
16
16
  # Create the breadcrumb trail.
17
17
  def call(tag, body, context)
18
18
  out = breadcrumb_trail_list(context.content_node)
19
- (context.dest_node.node_info[:tag_breadcrumb_trail] ||= {})[[@params.to_a.sort, context.content_node.absolute_lcn]] = out.map {|n| n.absolute_lcn}
19
+ (context.dest_node.node_info[:tag_breadcrumb_trail] ||= {})[[@params.to_a.sort, context.content_node.alcn]] = out.map {|n| n.alcn}
20
20
  out = out.map {|n| context.dest_node.link_to(n, :lang => context.content_node.lang) }.
21
21
  join(param('tag.breadcrumbtrail.separator'))
22
- log(:debug) { "Breadcrumb trail for <#{context.content_node.absolute_lcn}>: #{out}" }
22
+ log(:debug) { "Breadcrumb trail for <#{context.content_node.alcn}>: #{out}" }
23
23
  out
24
24
  end
25
25
 
@@ -57,7 +57,7 @@ module Webgen::Tag
57
57
  list = breadcrumb_trail_list(cn)
58
58
  set_params({})
59
59
 
60
- if (list.map {|n| n.absolute_lcn} != cached_list) ||
60
+ if (list.map {|n| n.alcn} != cached_list) ||
61
61
  list.any? {|n| (r = n.routing_node(cn.lang)) && r != node && r.meta_info_changed?}
62
62
  node.flag(:dirty)
63
63
  break
@@ -11,19 +11,30 @@ module Webgen::Tag
11
11
  # Highlight the body of the block.
12
12
  def call(tag, body, context)
13
13
  require 'coderay'
14
- options = {
15
- :css => :style,
16
- :wrap => param('tag.coderay.wrap').to_sym,
17
- :line_numbers => (param('tag.coderay.line_numbers') ? :inline : nil),
18
- :line_number_start => param('tag.coderay.line_number_start'),
19
- :tab_width => param('tag.coderay.tab_width'),
20
- :bold_every => param('tag.coderay.bold_every')
21
- }
14
+
15
+ options = {}
16
+ if param('tag.coderay.css').to_s == 'other'
17
+ options[:css] = :class
18
+ elsif param('tag.coderay.css').to_s == 'class'
19
+ options[:css] = :class
20
+ default_css_style_node = context.dest_node.resolve('/stylesheets/coderay-default.css')
21
+ ((context.persistent[:cp_head] ||= {})[:css_file] ||= []) << context.dest_node.route_to(default_css_style_node)
22
+ context.dest_node.node_info[:used_meta_info_nodes] << default_css_style_node.alcn
23
+ else
24
+ options[:css] = :style
25
+ end
26
+ options.merge!(:wrap => param('tag.coderay.wrap').to_sym,
27
+ :line_numbers => (param('tag.coderay.line_numbers') ? :inline : nil),
28
+ :line_number_start => param('tag.coderay.line_number_start'),
29
+ :tab_width => param('tag.coderay.tab_width'),
30
+ :bold_every => param('tag.coderay.bold_every'))
22
31
 
23
32
  if param('tag.coderay.process_body')
24
33
  body = website.blackboard.invoke(:content_processor, 'tags').call(context.clone(:content => body)).content
25
34
  end
26
35
  CodeRay.scan(body, param('tag.coderay.lang').to_sym).html(options)
36
+ rescue LoadError
37
+ raise Webgen::LoadError.new('coderay', self.class.name, context.dest_node.alcn, 'coderay')
27
38
  end
28
39
 
29
40
  end
@@ -12,14 +12,15 @@ module Webgen::Tag
12
12
 
13
13
  include Webgen::Tag::Base
14
14
 
15
- BIT_BUCKET = (Config::CONFIG['arch'].include?('mswin32') ? "nul" : "/dev/null")
15
+ BIT_BUCKET = (Config::CONFIG['host_os'] =~ /mswin|mingw/ ? "nul" : "/dev/null")
16
16
 
17
17
  # Execute the command and return the standard output.
18
18
  def call(tag, body, context)
19
19
  command = param('tag.executecommand.command')
20
20
  output = `#{command} 2> #{BIT_BUCKET}`
21
- if ($? >> 8) != 0
22
- raise "Command '#{command}' in <#{context.ref_node.absolute_lcn}> has return value != 0: #{output}"
21
+ if $?.exitstatus != 0
22
+ raise Webgen::RenderError.new("Command '#{command}' has return value != 0: #{output}",
23
+ self.class.name, context.dest_node, context.ref_node)
23
24
  end
24
25
  output = CGI::escapeHTML(output) if param('tag.executecommand.escape_html')
25
26
  [output, param('tag.executecommand.process_output')]
@@ -15,7 +15,7 @@ module Webgen::Tag
15
15
  # Return a list of all translations of the content page.
16
16
  def call(tag, body, context)
17
17
  lang_nodes = all_lang_nodes(context.content_node)
18
- (context.dest_node.node_info[:tag_langbar_data] ||= {})[context.content_node.absolute_cn] = lang_nodes.map {|n| n.absolute_lcn}
18
+ (context.dest_node.node_info[:tag_langbar_data] ||= {})[context.content_node.acn] = lang_nodes.map {|n| n.alcn}
19
19
  result = lang_nodes.
20
20
  reject {|n| (context.content_node.lang == n.lang && !param('tag.langbar.show_own_lang'))}.
21
21
  sort {|a, b| a.lang <=> b.lang}.
@@ -31,7 +31,7 @@ module Webgen::Tag
31
31
 
32
32
  # Return all nodes with the same absolute cn as +node+.
33
33
  def all_lang_nodes(node)
34
- node.tree.node_access[:acn][node.absolute_cn]
34
+ node.tree.node_access[:acn][node.acn]
35
35
  end
36
36
 
37
37
  # Check if the langbar tag for +node+ changed.
@@ -9,16 +9,17 @@ module Webgen::Tag
9
9
 
10
10
  # Return a HTML link to the given (A)LCN.
11
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
12
+ if (dest_node = context.ref_node.resolve(param('tag.link.path').to_s, context.dest_node.lang))
13
+ context.dest_node.node_info[:used_meta_info_nodes] << dest_node.alcn
14
14
  context.dest_node.link_to(dest_node, param('tag.link.attr').merge(:lang => context.content_node.lang))
15
15
  else
16
- raise ArgumentError, 'Resolving of path failed'
16
+ log(:error) { "Could not resolve path '#{param('tag.link.path')}' in <#{context.ref_node.alcn}>" }
17
+ context.dest_node.flag(:dirty)
18
+ ''
17
19
  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
- ''
20
+ rescue URI::InvalidURIError => e
21
+ raise Webgen::RenderError.new("Error while parsing path '#{param('tag.link.path')}': #{e.message}",
22
+ self.class.name, context.dest_node, context.ref_node)
22
23
  end
23
24
 
24
25
  end
@@ -44,7 +44,7 @@ module Webgen::Tag
44
44
 
45
45
  # Return the menu tree under the node as nested list of alcn values.
46
46
  def to_lcn_list
47
- self.children.inject([]) {|temp, n| temp << n.node.absolute_lcn; temp += ((t = n.to_lcn_list).empty? ? [] : [t]) }
47
+ self.children.inject([]) {|temp, n| temp << n.node.alcn; temp += ((t = n.to_lcn_list).empty? ? [] : [t]) }
48
48
  end
49
49
 
50
50
  end
@@ -57,7 +57,7 @@ module Webgen::Tag
57
57
  def call(tag, body, context)
58
58
  tree = specific_menu_tree_for(context.content_node)
59
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)
60
+ (context.dest_node.node_info[:tag_menu_menus] ||= {})[[@params.to_a.sort, context.content_node.alcn]] = (tree ? tree.to_lcn_list : nil)
61
61
 
62
62
  if !tree || tree.children.empty?
63
63
  ''
@@ -15,7 +15,7 @@ module Webgen::Tag
15
15
  elsif context.content_node[tag]
16
16
  output = context.content_node[tag].to_s
17
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}>" }
18
+ log(:error) { "No value for meta info key '#{tag}' in <#{context.ref_node.alcn}> found in <#{context.content_node.alcn}>" }
19
19
  end
20
20
  output
21
21
  end
@@ -16,24 +16,13 @@ module Webgen::Tag
16
16
 
17
17
  # Return the relativized path for the path provided in the tag definition.
18
18
  def call(tag, body, context)
19
- uri_string = param('tag.relocatable.path')
19
+ path = param('tag.relocatable.path')
20
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
21
+ begin
22
+ result = (Webgen::Node.url(path, false).absolute? ? path : resolve_path(path, context))
23
+ rescue URI::InvalidURIError => e
24
+ raise Webgen::RenderError.new("Error while parsing path '#{path}': #{e.message}",
25
+ self.class.name, context.dest_node, context.ref_node)
37
26
  end
38
27
  result
39
28
  end
@@ -42,11 +31,18 @@ module Webgen::Tag
42
31
  private
43
32
  #######
44
33
 
45
- # Resolve the path +uri+ using the reference node and return the correct relative path from the
34
+ # Resolve the path +path+ using the reference node and return the correct relative path from the
46
35
  # 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) : '')
36
+ def resolve_path(path, context)
37
+ dest_node = context.ref_node.resolve(path, context.dest_node.lang)
38
+ if dest_node
39
+ context.dest_node.node_info[:used_meta_info_nodes] << dest_node.alcn
40
+ context.dest_node.route_to(dest_node)
41
+ else
42
+ log(:error) { "Could not resolve path '#{path}' in <#{context.ref_node.alcn}>" }
43
+ context.dest_node.flag(:dirty)
44
+ ''
45
+ end
50
46
  end
51
47
 
52
48
  end
@@ -32,16 +32,15 @@ EOF
32
32
  # Create a graphic from the commands in the body of the tag.
33
33
  def call(tag, body, context)
34
34
  path = param('tag.tikz.path')
35
- path = Webgen::Common.absolute_path(path, context.ref_node.parent.absolute_lcn)
35
+ path = Webgen::Path.make_absolute(context.ref_node.parent.alcn, path)
36
36
 
37
37
  mem_handler = website.cache.instance('Webgen::SourceHandler::Memory')
38
38
  src_path = context.ref_node.node_info[:src]
39
39
  parent = website.blackboard.invoke(:create_directories, context.ref_node.tree.root, File.dirname(path), src_path)
40
40
  params = @params
41
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|
42
+ node = website.blackboard.invoke(:create_nodes, Webgen::Path.new(path, src_path), mem_handler) do |node_path|
43
+ mem_handler.create_node(node_path, context.ref_node.alcn) do |pic_node|
45
44
  set_params(params)
46
45
  document = ERB.new(LATEX_TEMPLATE).result(binding)
47
46
  pic_path = compile(document, File.extname(path), context)
@@ -74,9 +73,8 @@ EOF
74
73
  output = `#{cmd_prefix} pdflatex --shell-escape -interaction=batchmode #{File.basename(file.path)}.tex`
75
74
  if $?.exitstatus != 0
76
75
  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
76
+ raise Webgen::RenderError.new("Error while creating a TikZ picture: #{errors}",
77
+ self.class.name, context.dest_node, context.ref_node)
80
78
  else
81
79
  cmd = cmd_prefix + "pdfcrop #{File.basename(file.path)}.pdf #{File.basename(file.path)}.pdf; "
82
80
  return unless run_command(cmd, context)
@@ -106,9 +104,8 @@ EOF
106
104
  def run_command(cmd, context)
107
105
  output = `#{cmd}`
108
106
  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
107
+ raise Webgen::RenderError.new("Error while running a command for a TikZ picture: #{output}",
108
+ self.class.name, context.dest_node, context.ref_node)
112
109
  else
113
110
  output
114
111
  end
@@ -47,12 +47,12 @@ module Webgen
47
47
 
48
48
  # A utility method called by Node#initialize. This method should not be used directly!
49
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}"
50
+ if @node_access[:alcn].has_key?(node.alcn)
51
+ raise "Can't have two nodes with same absolute lcn: #{node.alcn}"
52
52
  else
53
- @node_access[:alcn][node.absolute_lcn] = node
53
+ @node_access[:alcn][node.alcn] = node
54
54
  end
55
- (@node_access[:acn][node.absolute_cn] ||= []) << node
55
+ (@node_access[:acn][node.acn] ||= []) << node
56
56
  register_path(node)
57
57
  end
58
58
 
@@ -78,11 +78,11 @@ module Webgen
78
78
 
79
79
  website.blackboard.dispatch_msg(:before_node_deleted, n)
80
80
  n.parent.children.delete(n)
81
- @node_access[:alcn].delete(n.absolute_lcn)
82
- @node_access[:acn][n.absolute_cn].delete(n)
81
+ @node_access[:alcn].delete(n.alcn)
82
+ @node_access[:acn][n.acn].delete(n)
83
83
  @node_access[:path].delete(n.path)
84
84
 
85
- node_info.delete(n.absolute_lcn)
85
+ node_info.delete(n.alcn)
86
86
  end
87
87
 
88
88
  end
@@ -3,6 +3,6 @@
3
3
  module Webgen
4
4
 
5
5
  # The version of webgen.
6
- VERSION = '0.5.8'
6
+ VERSION = '0.5.9'
7
7
 
8
8
  end
@@ -21,6 +21,7 @@ require 'webgen/websiteaccess'
21
21
  require 'webgen/blackboard'
22
22
  require 'webgen/cache'
23
23
  require 'webgen/tree'
24
+ require 'webgen/error'
24
25
 
25
26
  # Files for autoloading
26
27
  require 'webgen/common'
@@ -35,6 +36,7 @@ require 'webgen/tag'
35
36
  require 'webgen/path'
36
37
  require 'webgen/node'
37
38
  require 'webgen/page'
39
+ require 'webgen/version'
38
40
 
39
41
  # Load deprecated classes/methods/...
40
42
  require 'webgen/deprecated'
@@ -83,6 +85,33 @@ require 'webgen/deprecated'
83
85
  # an easy way for users to include dynamic content such as automatically
84
86
  # generated menus.
85
87
  #
88
+ #
89
+ # == General information
90
+ #
91
+ # Here are some detail on the internals of webgen that will help you while developing for webgen:
92
+ #
93
+ # * webgen uses a not so complex system for determining whether a node needs to be recreated or
94
+ # re-rendered. However, for this to work correctly all extensions have to follow some rules:
95
+ #
96
+ # * It is necessary that all node alcns from which the content is used are put into the
97
+ # destination node's <tt>node_info[:used_nodes]</tt> set.
98
+ #
99
+ # * It is necessary that all other node alcns that are used for a node in any way, even if they
100
+ # are only referenced or the route to their output path used, have to be put into the node's
101
+ # <tt>node_info[:used_meta_info_nodes]</tt> set.
102
+ #
103
+ # * Any node that is created during the rendering phase, ie. via a content processor, a tag or in
104
+ # the #content method of a source handler needs to be put into the rendered node's
105
+ # <tt>node_info[:used_meta_info_nodes]</tt> or <tt>node_info[:used_nodes]</tt> set (see above for
106
+ # details)! This is especially necessary when using resolved nodes since resolved nodes can be
107
+ # created by passive sources!
108
+ #
109
+ # * webgen provides various Error classes. However, errors should only be raised if additional runs
110
+ # won't correct the problem. For example, if a path cannot be resolved, it is possible that in the
111
+ # next run a node will be created and that the path can be resolved then. This is always the case,
112
+ # for example, with fragment nodes! In such cases an error message should be written out to the
113
+ # log to inform the user that there is a potential problem.
114
+ #
86
115
  # == Blackboard services
87
116
  #
88
117
  # The Blackboard class provides an easy communication facility between objects. It implements the
@@ -104,6 +133,7 @@ require 'webgen/deprecated'
104
133
  # <tt>:create_sitemap</tt>:: Common::Sitemap#create_sitemap
105
134
  # <tt>:create_directories</tt>:: SourceHandler::Directory#create_directories
106
135
  # <tt>:create_nodes</tt>:: SourceHandler::Main#create_nodes
136
+ # <tt>:create_nodes_from_paths</tt>:: SourceHandler::Main#create_nodes_from_paths
107
137
  # <tt>:source_paths</tt>:: SourceHandler::Main#find_all_source_paths
108
138
  #
109
139
  # Following is the list of all messages that can be listened to:
@@ -242,11 +272,11 @@ module Webgen
242
272
  def render
243
273
  result = nil
244
274
  execute_in_env do
245
- init unless @config
275
+ init
246
276
 
247
277
  puts "Starting webgen..."
248
278
  shm = SourceHandler::Main.new
249
- result = shm.render(@tree)
279
+ result = shm.render
250
280
  save_tree_and_cache if result
251
281
  puts "Finished"
252
282