webgen 1.0.0.beta1 → 1.0.0.beta2

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 (62) hide show
  1. data/API.rdoc +64 -11
  2. data/ChangeLog +391 -0
  3. data/README.md +2 -2
  4. data/VERSION +1 -1
  5. data/data/webgen/passive_sources/templates/tag.template +1 -1
  6. data/data/webgen/passive_sources/templates/tikz.template +14 -0
  7. data/lib/webgen/bundle/built-in/init.rb +9 -7
  8. data/lib/webgen/bundle_loader.rb +1 -1
  9. data/lib/webgen/cli/show_command.rb +2 -0
  10. data/lib/webgen/cli/show_config_command.rb +0 -1
  11. data/lib/webgen/cli/show_dependencies_command.rb +6 -63
  12. data/lib/webgen/cli/show_tree_command.rb +85 -0
  13. data/lib/webgen/content_processor/erb.rb +1 -1
  14. data/lib/webgen/content_processor/{rdoc.rb → r_doc.rb} +0 -0
  15. data/lib/webgen/content_processor/{redcloth.rb → red_cloth.rb} +0 -0
  16. data/lib/webgen/content_processor/ruby.rb +3 -0
  17. data/lib/webgen/content_processor/sass.rb +10 -6
  18. data/lib/webgen/content_processor/tikz.rb +10 -20
  19. data/lib/webgen/context/html_head.rb +7 -0
  20. data/lib/webgen/item_tracker.rb +42 -15
  21. data/lib/webgen/item_tracker/file.rb +7 -3
  22. data/lib/webgen/item_tracker/missing_node.rb +17 -5
  23. data/lib/webgen/item_tracker/node_content.rb +7 -3
  24. data/lib/webgen/item_tracker/node_meta_info.rb +8 -3
  25. data/lib/webgen/item_tracker/nodes.rb +10 -3
  26. data/lib/webgen/node.rb +4 -29
  27. data/lib/webgen/node_finder.rb +25 -10
  28. data/lib/webgen/path.rb +2 -2
  29. data/lib/webgen/path_handler/base.rb +20 -9
  30. data/lib/webgen/path_handler/feed.rb +29 -22
  31. data/lib/webgen/path_handler/page.rb +1 -3
  32. data/lib/webgen/path_handler/page_utils.rb +114 -33
  33. data/lib/webgen/path_handler/sitemap.rb +13 -6
  34. data/lib/webgen/path_handler/template.rb +0 -70
  35. data/lib/webgen/path_handler/virtual.rb +10 -2
  36. data/lib/webgen/tag.rb +13 -13
  37. data/lib/webgen/tag/tikz.rb +2 -1
  38. data/lib/webgen/test_helper.rb +2 -11
  39. data/lib/webgen/version.rb +1 -1
  40. data/test/webgen/content_processor/test_erb.rb +4 -0
  41. data/test/webgen/content_processor/{test_rdoc.rb → test_r_doc.rb} +1 -1
  42. data/test/webgen/content_processor/{test_redcloth.rb → test_red_cloth.rb} +1 -1
  43. data/test/webgen/content_processor/test_sass.rb +2 -2
  44. data/test/webgen/content_processor/test_tikz.rb +10 -3
  45. data/test/webgen/item_tracker/test_file.rb +5 -5
  46. data/test/webgen/item_tracker/test_missing_node.rb +8 -9
  47. data/test/webgen/item_tracker/test_node_content.rb +5 -6
  48. data/test/webgen/item_tracker/test_node_meta_info.rb +6 -7
  49. data/test/webgen/item_tracker/test_nodes.rb +7 -9
  50. data/test/webgen/path_handler/test_base.rb +4 -5
  51. data/test/webgen/path_handler/test_page.rb +1 -1
  52. data/test/webgen/path_handler/test_page_utils.rb +39 -11
  53. data/test/webgen/path_handler/test_template.rb +5 -45
  54. data/test/webgen/path_handler/test_virtual.rb +21 -0
  55. data/test/webgen/tag/test_link.rb +1 -1
  56. data/test/webgen/tag/test_tikz.rb +2 -2
  57. data/test/webgen/test_context.rb +10 -0
  58. data/test/webgen/test_item_tracker.rb +7 -4
  59. data/test/webgen/test_node.rb +3 -16
  60. data/test/webgen/test_node_finder.rb +10 -6
  61. data/test/webgen/test_tag.rb +4 -4
  62. metadata +218 -216
data/README.md CHANGED
@@ -31,7 +31,7 @@ Apart from this basic functionality, webgen offers many features that
31
31
  makes authoring websites easier:
32
32
 
33
33
  * Multiple markup languages to choose from for writing HTML and CSS
34
- files (Markdown, Textile, RDoc, Haml, Sass ...)
34
+ files (Markdown, Textile, RDoc, Haml, Sass, ...)
35
35
 
36
36
  * Automatic generation of menus, breadcrumb trails, ... and more!
37
37
 
@@ -42,7 +42,7 @@ makes authoring websites easier:
42
42
  view the website *without a web server*)
43
43
 
44
44
  * Easily extendable (all major components can be extended with new
45
- functionality)
45
+ functionality or existing functionality can be replaced)
46
46
 
47
47
  * No need to know the Ruby language for basic websites
48
48
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.0.beta1
1
+ 1.0.0.beta2
@@ -1,6 +1,6 @@
1
1
  --- name:tag.langbar pipeline:ruby ------------------------------------------------------------------
2
2
  context.content = context[:nodes].map do |node|
3
- attrs = {:link_text => node.lang}
3
+ attrs = {'link_text' => node.lang}
4
4
  attrs['class'] = 'webgen-langbar-current-lang' if context.content_node.lang == node.lang
5
5
  context.dest_node.link_to(node, node.lang, attrs)
6
6
  end.join(context[:config]['tag.langbar.separator'])
@@ -0,0 +1,14 @@
1
+ --- name:content pipeline:erb
2
+ \nonstopmode
3
+ \documentclass{standalone}
4
+ \usepackage{tikz}
5
+
6
+ <% if context['content_processor.tikz.libraries'] %>
7
+ \usetikzlibrary{<%= context['content_processor.tikz.libraries'].join(',') %>}
8
+ <% end %>
9
+
10
+ \begin{document}
11
+ \begin{tikzpicture}[<%= context['content_processor.tikz.opts'] %>]
12
+ <%= context['data'] %>
13
+ \end{tikzpicture}
14
+ \end{document}
@@ -59,6 +59,8 @@ website.ext.content_processor = content_processor = Webgen::ContentProcessor.new
59
59
  content_processor.register('Blocks')
60
60
  content_processor.register('Builder')
61
61
  content_processor.register('Erb')
62
+ option('content_processor.erb.trim_mode', '',
63
+ "Specifies the ERB trim mode, can contain any combination of '%', '<' and '<>'", &is_string)
62
64
 
63
65
  content_processor.register('Erubis')
64
66
  option('content_processor.erubis.use_pi', false,
@@ -112,6 +114,8 @@ option('content_processor.tikz.resolution', '72 72',
112
114
  end
113
115
  option('content_processor.tikz.transparent', false,
114
116
  'Specifies whether the generated image should be transparent (only if the extension is png)', &true_or_false)
117
+ option('content_processor.tikz.template', '/templates/tikz.template',
118
+ 'Specifies the template with the LaTeX framework that should be used for rendering', &is_string)
115
119
 
116
120
  content_processor.register('Xmllint')
117
121
  option('content_processor.xmllint.options', "--catalogs --noout --valid",
@@ -196,6 +200,8 @@ option('path_handler.version_in_dest_path', 'except_default',
196
200
  raise "The value has to be 'true', 'false' or 'except_default'"
197
201
  end
198
202
  end
203
+ option('path_handler.default_template', 'default.template',
204
+ 'The name of the default template file')
199
205
 
200
206
  website.ext.path_handler = path_handler = Webgen::PathHandler.new(website)
201
207
 
@@ -203,11 +209,7 @@ website.ext.path_handler = path_handler = Webgen::PathHandler.new(website)
203
209
 
204
210
  path_handler.register('Directory')
205
211
  path_handler.register('MetaInfo', :patterns => ['/**/metainfo', '/**/*.metainfo'])
206
-
207
212
  path_handler.register('Template')
208
- option('path_handler.template.default_template', 'default.template',
209
- 'The name of the default template file')
210
-
211
213
  path_handler.register('Page')
212
214
  path_handler.register('Copy')
213
215
  path_handler.register('Feed')
@@ -255,7 +257,7 @@ tag.register('Date')
255
257
  option('tag.date.format', '%Y-%m-%d %H:%M:%S',
256
258
  'The format of the date (same options as Ruby\'s Time#strftime)', &is_string)
257
259
 
258
- tag.register('MetaInfo', :names => :default)
260
+ tag.register('MetaInfo', :names => ['meta_info', :default])
259
261
  option('tag.meta_info.escape_html', true,
260
262
  'Special HTML characters in the output will be escaped if true', &true_or_false)
261
263
 
@@ -271,7 +273,7 @@ option('tag.link.path', nil,
271
273
  option('tag.link.attr', {},
272
274
  'A hash of additional HTML attributes that should be set on the link', &is_hash)
273
275
 
274
- tag.register('ExecuteCommand', :names => 'execute_cmd', :mandatory => ['command'])
276
+ tag.register('ExecuteCommand', :mandatory => ['command'])
275
277
  option('tag.execute_command.command', nil,
276
278
  'The command which should be executed', &is_string)
277
279
  option('tag.execute_command.process_output', true,
@@ -293,7 +295,7 @@ option('tag.coderay.lang', 'ruby',
293
295
  option('tag.coderay.process_body', true,
294
296
  'The tag body will be scanned for tags before highlighting if true', &true_or_false)
295
297
  option('tag.coderay.wrap', :div,
296
- 'Specifies how the code should be wrapped, either "div" or "span"') do |val|
298
+ "Specifies how the code should be wrapped, either 'div' or 'span'") do |val|
297
299
  val = val.to_s.intern
298
300
  raise "The value has to be either div or span" unless val == :div || val == :span
299
301
  val
@@ -54,7 +54,7 @@ module Webgen
54
54
 
55
55
  info_file = File.join(File.dirname(file), 'info.yaml')
56
56
  next unless File.file?(info_file)
57
- next unless YAML.load(File.read(info_file))['autoload']
57
+ next unless (begin YAML.load(File.read(info_file))['autoload']; rescue Exception; false end)
58
58
 
59
59
  load(bundle_name)
60
60
  end
@@ -4,6 +4,7 @@ require 'webgen/cli/utils'
4
4
  require 'webgen/cli/show_extensions_command'
5
5
  require 'webgen/cli/show_config_command'
6
6
  require 'webgen/cli/show_dependencies_command'
7
+ require 'webgen/cli/show_tree_command'
7
8
 
8
9
  module Webgen
9
10
  module CLI
@@ -22,6 +23,7 @@ DESC
22
23
  add_command(ShowConfigCommand.new)
23
24
  add_command(ShowExtensionsCommand.new)
24
25
  add_command(ShowDependenciesCommand.new)
26
+ add_command(ShowTreeCommand.new)
25
27
  end
26
28
 
27
29
  end
@@ -33,7 +33,6 @@ DESC
33
33
  end
34
34
  end
35
35
  @modified = false
36
- @unknown = true
37
36
  end
38
37
 
39
38
  def execute(args) # :nodoc:
@@ -24,79 +24,22 @@ DESC
24
24
  end
25
25
 
26
26
  def execute(args) # :nodoc:
27
- cache = commandparser.website.cache[:item_tracker_data]
28
- if cache.nil?
27
+ data = commandparser.website.ext.item_tracker.cached_items(commandparser.verbose)
28
+ if data.empty?
29
29
  puts "No data available, you need to generate the website first!"
30
30
  return
31
31
  end
32
32
  arg = args.shift
33
33
 
34
- data = cache[:node_dependencies]
35
- data = data.select {|alcn, _| alcn.include?(arg) } if arg
36
- data.sort.each do |alcn, deps|
37
- deps = deps.sort {|a,b| a.first <=> b.first }.map do |uid|
38
- method = "format_#{uid.first}"
39
- if respond_to?(method, true)
40
- send(method, alcn, uid, cache[:item_data][uid])
41
- else
42
- unknown_uid(uid)
43
- end
44
- end.compact
45
-
46
- if deps.length > 0 || commandparser.verbose
34
+ data.select! {|alcn, _| alcn.include?(arg) } if arg
35
+ data.sort.each do |alcn, items|
36
+ if items.length > 0 || commandparser.verbose
47
37
  puts("#{Utils.light(Utils.blue(alcn))}: ")
48
- deps.each {|d| puts(" #{[d].flatten.join("\n ")}")}
38
+ items.each {|d| puts(" #{[d].flatten.join("\n ")}")}
49
39
  end
50
40
  end
51
41
  end
52
42
 
53
- def unknown_uid(uid)
54
- uid.first.to_s
55
- end
56
- private :unknown_uid
57
-
58
- def format_node_meta_info(alcn, uid, data)
59
- dep_alcn, key = *uid.last
60
- return if alcn == dep_alcn && !commandparser.verbose
61
-
62
- if key.nil?
63
- "Any meta info from <#{dep_alcn}>"
64
- else
65
- "Meta info key '#{key}' from <#{dep_alcn}>"
66
- end
67
- end
68
- private :format_node_meta_info
69
-
70
- def format_node_content(alcn, uid, data)
71
- dep_alcn = uid.last
72
- return if alcn == dep_alcn && !commandparser.verbose
73
-
74
- "Content from node <#{dep_alcn}>"
75
- end
76
- private :format_node_content
77
-
78
- def format_file(alcn, uid, data)
79
- "Content from file '#{uid.last}'"
80
- end
81
- private :format_file
82
-
83
- def format_missing_node(alcn, uid, data)
84
- path, lang = *uid.last
85
-
86
- "Missing acn, alcn or dest path <#{path}>" << (lang.nil? ? '' : " in language '#{lang}'")
87
- end
88
- private :format_missing_node
89
-
90
- def format_nodes(alcn, uid, data)
91
- method, _, type = *uid.last
92
-
93
- res = [(type == :content ? "Content" : "Meta info") + " from these nodes"]
94
- res.first << " (result of #{[method].flatten.join('.')})" if commandparser.verbose
95
- res.first << ":"
96
- res += data.flatten
97
- end
98
- private :format_nodes
99
-
100
43
  end
101
44
 
102
45
  end
@@ -0,0 +1,85 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'webgen/cli/utils'
4
+
5
+ module Webgen
6
+ module CLI
7
+
8
+ # The CLI command for showing the node tree.
9
+ class ShowTreeCommand < CmdParse::Command
10
+
11
+ def initialize # :nodoc:
12
+ super('tree', false, false, true)
13
+ self.short_desc = 'Show the node tree'
14
+ self.description = Utils.format_command_desc(<<DESC)
15
+ Shows the internal representation of all destination paths that have been created
16
+ from the source paths. Additionally, the meta information associated with each
17
+ node can be shown as well.
18
+
19
+ This command can be used before or after the website has been generated. Note,
20
+ however, that nodes that are created during generation like fragment nodes can
21
+ only be shown if the website has been generated.
22
+
23
+ If an argument is given, only those nodes that have the argument in their LCN
24
+ are displayed.
25
+
26
+ Hint: The global verbosity option enables additional output.
27
+ DESC
28
+ self.options = CmdParse::OptionParserWrapper.new do |opts|
29
+ opts.separator "Options:"
30
+ opts.on("-a", "--alcn",
31
+ *Utils.format_option_desc("Use ALCN insted of LCN for paths")) do |v|
32
+ @use_alcn = true
33
+ end
34
+ opts.on("-f", "--[no-]fragments",
35
+ *Utils.format_option_desc("Show fragment nodes (default: no)")) do |v|
36
+ @show_fragments = v
37
+ end
38
+ opts.on("-m", "--[no-]meta-info",
39
+ *Utils.format_option_desc("Show meta information (default: no)")) do |v|
40
+ @meta_info = v
41
+ end
42
+ end
43
+ @meta_info = false
44
+ @use_alcn = false
45
+ @show_fragments = false
46
+ end
47
+
48
+ def execute(args) # :nodoc:
49
+ selector = args.shift
50
+ commandparser.website.ext.path_handler.populate_tree
51
+ data = collect_data(commandparser.website.tree.dummy_root.children, selector)
52
+ print_tree(data, selector)
53
+ end
54
+
55
+ def collect_data(children, selector)
56
+ children.sort {|a,b| a.alcn <=> b.alcn}.map do |node|
57
+ sub = collect_data(node.children, selector)
58
+ if sub.length > 0 ||
59
+ ((selector.nil? || node.lcn.include?(selector)) &&
60
+ ((!node.is_fragment? || @show_fragments) &&
61
+ (!node['passive'] || commandparser.website.ext.item_tracker.node_referenced?(node))))
62
+ data = [@use_alcn ? node.alcn : node.lcn]
63
+ data << (@meta_info ? node.meta_info.map {|k,v| "#{k}: #{v.inspect}"} : [])
64
+ data << sub
65
+ data
66
+ else
67
+ nil
68
+ end
69
+ end.compact
70
+ end
71
+ private :collect_data
72
+
73
+ def print_tree(data, indent = '', selector)
74
+ data.each do |name, info, children|
75
+ puts("#{indent}#{Utils.light(Utils.blue(name))}")
76
+ info.each {|i| puts("#{indent} #{i}")} if info.length > 0 && (selector.nil? || name.include?(selector))
77
+ print_tree(children, indent + ' ', selector)
78
+ end
79
+ end
80
+ private :print_tree
81
+
82
+ end
83
+
84
+ end
85
+ end
@@ -13,7 +13,7 @@ module Webgen
13
13
 
14
14
  # Process the Ruby statements embedded in the content of +context+.
15
15
  def self.call(context)
16
- erb = ERB.new(context.content)
16
+ erb = ERB.new(context.content, nil, context.website.config['content_processor.erb.trim_mode'])
17
17
  erb.filename = context.ref_node.alcn
18
18
  context.content = erb.result(binding)
19
19
  context
File without changes
@@ -1,6 +1,7 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
 
3
3
  require 'webgen/content_processor'
4
+ require 'erb'
4
5
 
5
6
  module Webgen
6
7
  class ContentProcessor
@@ -8,6 +9,8 @@ module Webgen
8
9
  # Processes the content that is valid Ruby to generate new content.
9
10
  module Ruby
10
11
 
12
+ extend ERB::Util
13
+
11
14
  # Process the content of +context+ which needs to be valid Ruby code.
12
15
  def self.call(context)
13
16
  eval(context.content, binding, context.ref_node.alcn)
@@ -105,14 +105,18 @@ module Webgen
105
105
  context = options[:webgen_context]
106
106
  path = path.value
107
107
 
108
- dest_node = context.website.tree[options[:filename]].resolve(path, context.dest_node.lang, true)
109
- if dest_node
110
- context.website.ext.item_tracker.add(context.dest_node, :node_meta_info, dest_node.alcn)
111
- result = context.dest_node.route_to(dest_node)
108
+ ref_node = context.website.tree[options[:filename]]
109
+ ref_node = context.website.tree.root if ref_node.nil? && path[0] == ?/
110
+
111
+ if ref_node
112
+ if dest_node = ref_node.resolve(path, context.dest_node.lang, true)
113
+ context.website.ext.item_tracker.add(context.dest_node, :node_meta_info, dest_node.alcn)
114
+ path = context.dest_node.route_to(dest_node)
115
+ end
112
116
  else
113
- result = path
117
+ context.website.logger.warn { "Couldn't determine reference node for resolving node in Sass file." }
114
118
  end
115
- ::Sass::Script::String.new("url(\"#{result}\")")
119
+ ::Sass::Script::String.new(path, :string)
116
120
  end
117
121
  declare :relocatable, [:string]
118
122
 
@@ -18,22 +18,11 @@ module Webgen
18
18
  # Uses LaTeX and the TikZ library for creating images from LaTeX code.
19
19
  module Tikz
20
20
 
21
- LATEX_TEMPLATE = <<EOF
22
- \\nonstopmode \\documentclass{article} \\usepackage{tikz} \\pagestyle{empty}
23
- <% if context['content_processor.tikz.libraries'] %>
24
- \\usetikzlibrary{<%= context['content_processor.tikz.libraries'].join(',') %>}
25
- <% end %>
26
- \\begin{document}
27
- \\begin{tikzpicture}[<%= context['content_processor.tikz.opts'] %>]
28
- <%= context.content %>
29
- \\end{tikzpicture}
30
- \\end{document}
31
- EOF
32
-
33
21
  # Process the content with LaTeX to generate a TikZ image.
34
22
  def self.call(context)
35
23
  prepare_options(context)
36
- context.content = ERB.new(LATEX_TEMPLATE).result(binding)
24
+ context.content = context.render_block(:name => 'content',
25
+ :chain => [context.website.tree[context['content_processor.tikz.template']]])
37
26
  context.content = File.binread(compile(context))
38
27
  context
39
28
  end
@@ -41,9 +30,11 @@ EOF
41
30
  # Collect the necessary options and save them in the context object.
42
31
  def self.prepare_options(context)
43
32
  %w[content_processor.tikz.resolution content_processor.tikz.transparent
44
- content_processor.tikz.libraries content_processor.tikz.opts].each do |opt|
33
+ content_processor.tikz.libraries content_processor.tikz.opts
34
+ content_processor.tikz.template].each do |opt|
45
35
  context[opt] = context.content_node[opt] || context.website.config[opt]
46
36
  end
37
+ context['data'] = context.content
47
38
  end
48
39
  private_class_method :prepare_options
49
40
 
@@ -54,17 +45,16 @@ EOF
54
45
  # Returns the path to the created image.
55
46
  def self.compile(context)
56
47
  cwd = context.website.tmpdir('content_processor.tikz')
48
+ tex_file = File.join(cwd, context.dest_node.dest_path.tr('/', '_').sub(/\..*?$/, '.tex'))
57
49
  FileUtils.mkdir_p(cwd)
58
- tempfile = Tempfile.open(['webgen-tikz', '.tex'], cwd)
59
- tempfile.write(context.content)
60
- tempfile.close
50
+ File.write(tex_file, context.content)
61
51
 
62
- file = File.basename(tempfile.path, '.tex')
52
+ file = File.basename(tex_file, '.tex')
63
53
  ext = File.extname(context.dest_node.dest_path)
64
54
  render_res, output_res = context['content_processor.tikz.resolution'].split(' ')
65
55
 
66
- execute("pdflatex --shell-escape -interaction=batchmode #{file}.tex", cwd, context) do |status, stdout, stderr|
67
- errors = stderr.scan(/^!(.*\n.*)/).join("\n")
56
+ execute("pdflatex -shell-escape -interaction=nonstopmode -halt-on-error #{file}.tex", cwd, context) do |status, stdout, stderr|
57
+ errors = (stdout+stderr).scan(/^!(.*\n.*)/).join("\n")
68
58
  raise Webgen::RenderError.new("Error while parsing TikZ picture commands with PDFLaTeX: #{errors}",
69
59
  self.name, context.dest_node, context.ref_node)
70
60
  end
@@ -16,6 +16,13 @@ module Webgen
16
16
  @context = context
17
17
  end
18
18
 
19
+ # Set the meta tag to the provided value.
20
+ #
21
+ # Note that some meta information keys may not be specified multiple times!
22
+ def meta(name, content)
23
+ (cp_hash[:meta] ||= {})[name] = content
24
+ end
25
+
19
26
  # Add a link to the given file in the HTML head section.
20
27
  #
21
28
  # The type can either be :css for CSS files or :js for javascript files. The path to the