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.
- data/COPYING +4 -0
- data/ChangeLog +1037 -0
- data/Rakefile +5 -6
- data/THANKS +1 -0
- data/VERSION +1 -1
- data/bin/webgen +1 -1
- data/data/webgen/passive_sources/images/generated_by_webgen.png +0 -0
- data/data/webgen/passive_sources/images/webgen_logo.png +0 -0
- data/data/webgen/passive_sources/stylesheets/coderay-default.css +129 -0
- data/data/webgen/passive_sources/templates/atom_feed.template +38 -0
- data/data/webgen/passive_sources/templates/rss_feed.template +28 -0
- data/data/webgen/passive_sources/templates/sitemap.template +21 -0
- data/data/webgen/resources.yaml +2 -1
- data/data/webgen/website_skeleton/Rakefile +5 -1
- data/doc/contentprocessor/builder.page +2 -2
- data/doc/contentprocessor/erb.page +5 -2
- data/doc/contentprocessor/erubis.page +2 -2
- data/doc/contentprocessor/head.page +21 -0
- data/doc/contentprocessor/tidy.page +14 -0
- data/doc/extensions.page +1 -1
- data/doc/faq.page +2 -2
- data/doc/manual.page +108 -43
- data/doc/reference_configuration.page +83 -5
- data/doc/reference_metainfo.page +24 -4
- data/doc/reference_website_styles.page +2 -2
- data/doc/sourcehandler/feed.page +11 -13
- data/doc/sourcehandler/metainfo.page +10 -3
- data/doc/sourcehandler/page.page +4 -4
- data/doc/sourcehandler/sitemap.page +8 -7
- data/doc/tag/coderay.page +6 -2
- data/doc/tag/includefile.page +1 -1
- data/doc/tag/menu.page +3 -0
- data/lib/webgen/cli/apply_command.rb +1 -1
- data/lib/webgen/cli/utils.rb +2 -2
- data/lib/webgen/common.rb +0 -9
- data/lib/webgen/contentprocessor.rb +18 -3
- data/lib/webgen/contentprocessor/blocks.rb +67 -36
- data/lib/webgen/contentprocessor/builder.rb +5 -2
- data/lib/webgen/contentprocessor/erb.rb +4 -2
- data/lib/webgen/contentprocessor/erubis.rb +5 -2
- data/lib/webgen/contentprocessor/haml.rb +6 -2
- data/lib/webgen/contentprocessor/head.rb +64 -0
- data/lib/webgen/contentprocessor/maruku.rb +3 -1
- data/lib/webgen/contentprocessor/rdiscount.rb +2 -0
- data/lib/webgen/contentprocessor/rdoc.rb +2 -0
- data/lib/webgen/contentprocessor/redcloth.rb +2 -0
- data/lib/webgen/contentprocessor/sass.rb +5 -3
- data/lib/webgen/contentprocessor/tags.rb +40 -24
- data/lib/webgen/contentprocessor/tidy.rb +38 -0
- data/lib/webgen/context.rb +13 -4
- data/lib/webgen/context/render.rb +32 -0
- data/lib/webgen/context/tags.rb +20 -0
- data/lib/webgen/default_config.rb +15 -4
- data/lib/webgen/deprecated.rb +38 -4
- data/lib/webgen/error.rb +135 -0
- data/lib/webgen/node.rb +48 -40
- data/lib/webgen/output.rb +5 -3
- data/lib/webgen/output/filesystem.rb +4 -4
- data/lib/webgen/page.rb +4 -4
- data/lib/webgen/path.rb +161 -58
- data/lib/webgen/source.rb +9 -6
- data/lib/webgen/source/filesystem.rb +1 -1
- data/lib/webgen/source/stacked.rb +13 -5
- data/lib/webgen/source/tararchive.rb +6 -2
- data/lib/webgen/sourcehandler.rb +100 -54
- data/lib/webgen/sourcehandler/base.rb +58 -24
- data/lib/webgen/sourcehandler/copy.rb +6 -5
- data/lib/webgen/sourcehandler/directory.rb +3 -9
- data/lib/webgen/sourcehandler/feed.rb +25 -50
- data/lib/webgen/sourcehandler/fragment.rb +10 -8
- data/lib/webgen/sourcehandler/memory.rb +9 -10
- data/lib/webgen/sourcehandler/metainfo.rb +9 -9
- data/lib/webgen/sourcehandler/page.rb +6 -5
- data/lib/webgen/sourcehandler/sitemap.rb +22 -22
- data/lib/webgen/sourcehandler/template.rb +6 -6
- data/lib/webgen/sourcehandler/virtual.rb +19 -17
- data/lib/webgen/tag/base.rb +27 -27
- data/lib/webgen/tag/breadcrumbtrail.rb +3 -3
- data/lib/webgen/tag/coderay.rb +19 -8
- data/lib/webgen/tag/executecommand.rb +4 -3
- data/lib/webgen/tag/langbar.rb +2 -2
- data/lib/webgen/tag/link.rb +8 -7
- data/lib/webgen/tag/menu.rb +2 -2
- data/lib/webgen/tag/metainfo.rb +1 -1
- data/lib/webgen/tag/relocatable.rb +17 -21
- data/lib/webgen/tag/tikz.rb +7 -10
- data/lib/webgen/tree.rb +7 -7
- data/lib/webgen/version.rb +1 -1
- data/lib/webgen/website.rb +32 -2
- data/misc/default.css +8 -2
- data/misc/default.template +2 -2
- data/misc/logo.svg +313 -0
- data/misc/style.page +1 -1
- data/test/helper.rb +18 -2
- data/test/test_cli.rb +104 -0
- data/test/test_common_sitemap.rb +1 -1
- data/test/test_contentprocessor.rb +8 -2
- data/test/test_contentprocessor_blocks.rb +17 -8
- data/test/test_contentprocessor_builder.rb +13 -2
- data/test/test_contentprocessor_erb.rb +9 -3
- data/test/test_contentprocessor_erubis.rb +9 -3
- data/test/test_contentprocessor_fragments.rb +12 -11
- data/test/test_contentprocessor_haml.rb +11 -2
- data/test/test_contentprocessor_head.rb +44 -0
- data/test/test_contentprocessor_maruku.rb +5 -1
- data/test/test_contentprocessor_rdiscount.rb +4 -0
- data/test/test_contentprocessor_rdoc.rb +4 -0
- data/test/test_contentprocessor_redcloth.rb +5 -1
- data/test/test_contentprocessor_sass.rb +8 -2
- data/test/test_contentprocessor_tags.rb +22 -7
- data/test/test_contentprocessor_tidy.rb +34 -0
- data/test/test_context.rb +39 -0
- data/test/test_error.rb +85 -0
- data/test/test_node.rb +57 -21
- data/test/test_page.rb +23 -5
- data/test/test_path.rb +120 -64
- data/test/test_source_filesystem.rb +1 -1
- data/test/test_source_stacked.rb +19 -6
- data/test/test_sourcehandler_base.rb +63 -50
- data/test/test_sourcehandler_copy.rb +6 -6
- data/test/test_sourcehandler_directory.rb +8 -12
- data/test/test_sourcehandler_feed.rb +15 -7
- data/test/test_sourcehandler_fragment.rb +6 -5
- data/test/test_sourcehandler_main.rb +39 -0
- data/test/test_sourcehandler_memory.rb +4 -4
- data/test/test_sourcehandler_metainfo.rb +20 -11
- data/test/test_sourcehandler_page.rb +10 -10
- data/test/test_sourcehandler_sitemap.rb +24 -5
- data/test/test_sourcehandler_template.rb +18 -15
- data/test/test_sourcehandler_virtual.rb +9 -5
- data/test/test_tag_base.rb +6 -29
- data/test/test_tag_coderay.rb +16 -3
- data/test/test_tag_executecommand.rb +2 -2
- data/test/test_tag_link.rb +5 -4
- data/test/test_tag_menu.rb +15 -15
- data/test/test_tag_metainfo.rb +1 -0
- data/test/test_tag_relocatable.rb +3 -2
- data/test/test_tag_tikz.rb +5 -5
- data/test/test_tree.rb +8 -8
- data/test/test_website.rb +15 -0
- metadata +21 -14
- data/test/test_common.rb +0 -18
data/lib/webgen/output.rb
CHANGED
|
@@ -18,8 +18,10 @@ module Webgen
|
|
|
18
18
|
# Write the +data+ to the given output +path+. The parameter +data+ is either a String with the
|
|
19
19
|
# content or a Webgen::Path::SourceIO object. The parameter +type+ specifies the type of the to
|
|
20
20
|
# be written path: <tt>:file</tt> or <tt>:directory</tt>.
|
|
21
|
-
# [<tt>read(path)</tt>]
|
|
22
|
-
# Return the content of the given path if it exists or raise an error otherwise.
|
|
21
|
+
# [<tt>read(path, mode = 'rb')</tt>]
|
|
22
|
+
# Return the content of the given path if it exists or raise an error otherwise. The parameter
|
|
23
|
+
# +mode+ specifies the mode in which the path should be opened and defaults to reading in binary
|
|
24
|
+
# mode.
|
|
23
25
|
#
|
|
24
26
|
# It seems a bit odd that an output instance has to implement reading functionality. However,
|
|
25
27
|
# consider the case where you want webgen to render a website programmatically and *use* the
|
|
@@ -52,7 +54,7 @@ module Webgen
|
|
|
52
54
|
# @data[path] = [(io.kind_of?(String) ? io : io.data), type]
|
|
53
55
|
# end
|
|
54
56
|
#
|
|
55
|
-
# def read(path)
|
|
57
|
+
# def read(path, mode = 'rb')
|
|
56
58
|
# path = File.join('/', path)
|
|
57
59
|
# raise "No such file #{path}" unless @data[path] && @data[path].last == :file
|
|
58
60
|
# @data[path].first
|
|
@@ -50,7 +50,7 @@ module Webgen::Output
|
|
|
50
50
|
if data.kind_of?(String)
|
|
51
51
|
File.open(dest, 'wb') {|f| f.write(data) }
|
|
52
52
|
else
|
|
53
|
-
data.stream do |source|
|
|
53
|
+
data.stream('rb') do |source|
|
|
54
54
|
File.open(dest, 'wb') {|f| FileUtils.copy_stream(source, f) }
|
|
55
55
|
end
|
|
56
56
|
end
|
|
@@ -59,9 +59,9 @@ module Webgen::Output
|
|
|
59
59
|
end
|
|
60
60
|
end
|
|
61
61
|
|
|
62
|
-
# Return the content of the given +path+.
|
|
63
|
-
def read(path)
|
|
64
|
-
File.open(File.join(@root, path),
|
|
62
|
+
# Return the content of the given +path+ which is opened in +mode+.
|
|
63
|
+
def read(path, mode = 'rb')
|
|
64
|
+
File.open(File.join(@root, path), mode) {|f| f.read}
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
end
|
data/lib/webgen/page.rb
CHANGED
|
@@ -49,7 +49,7 @@ module Webgen
|
|
|
49
49
|
|
|
50
50
|
|
|
51
51
|
# Raised during parsing of data in Webgen Page Format if the data is invalid.
|
|
52
|
-
class FormatError <
|
|
52
|
+
class FormatError < StandardError; end
|
|
53
53
|
|
|
54
54
|
|
|
55
55
|
# :stopdoc:
|
|
@@ -57,7 +57,7 @@ module Webgen
|
|
|
57
57
|
RE_META_INFO = /\A---\s*(?:\n|\r|\r\n).*?(?:\n|\r|\r\n)(?=---.*?(?:\n|\r|\r\n)|\Z)/m
|
|
58
58
|
RE_BLOCKS_OPTIONS = /^--- *?(?: *((?:\w+:[^\s]* *)*))?$|^$/
|
|
59
59
|
RE_BLOCKS_START = /^--- .*?$|^--- *$/
|
|
60
|
-
RE_BLOCKS = /(?:(#{RE_BLOCKS_START})|\A)(.*?)(?:(?=#{RE_BLOCKS_START})|\
|
|
60
|
+
RE_BLOCKS = /(?:(#{RE_BLOCKS_START})|\A)\n?(.*?)(?:(?=#{RE_BLOCKS_START})|\z)/m
|
|
61
61
|
# :startdoc:
|
|
62
62
|
|
|
63
63
|
class << self
|
|
@@ -100,7 +100,7 @@ module Webgen
|
|
|
100
100
|
raise FormatError, "Invalid structure of meta information block: expected YAML hash but found #{meta_info.class}"
|
|
101
101
|
end
|
|
102
102
|
rescue ArgumentError => e
|
|
103
|
-
raise FormatError, e.message
|
|
103
|
+
raise FormatError, "Invalid YAML syntax in meta information block: #{e.message}"
|
|
104
104
|
end
|
|
105
105
|
meta_info
|
|
106
106
|
end
|
|
@@ -126,7 +126,7 @@ module Webgen
|
|
|
126
126
|
raise(FormatError, "Previously used name '#{name}' also used for block #{index+1}") if blocks.has_key?(name)
|
|
127
127
|
content ||= ''
|
|
128
128
|
content.gsub!(/^(\\+)(---.*?)$/) {|m| "\\" * ($1.length / 2) + $2}
|
|
129
|
-
content.
|
|
129
|
+
content.chomp!("\n") unless index + 1 == scanned.length
|
|
130
130
|
blocks[name] = blocks[index+1] = Block.new(name, content, options)
|
|
131
131
|
end
|
|
132
132
|
meta_info.delete('blocks')
|
data/lib/webgen/path.rb
CHANGED
|
@@ -1,11 +1,33 @@
|
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
|
2
2
|
|
|
3
|
+
require 'pathname'
|
|
3
4
|
require 'webgen/languages'
|
|
4
5
|
|
|
5
6
|
module Webgen
|
|
6
7
|
|
|
7
|
-
#
|
|
8
|
-
#
|
|
8
|
+
# == General Information
|
|
9
|
+
#
|
|
10
|
+
# A Path object provides information about a path that is used to create one or more nodes as well
|
|
11
|
+
# as methods for accessing the path's content. So a Path object always refers to a source path. In
|
|
12
|
+
# contrast, output paths are always strings and just specify the location where a specific node
|
|
13
|
+
# should be written to.
|
|
14
|
+
#
|
|
15
|
+
# Note the +path+ and +source_path+ attributes of a Path object:
|
|
16
|
+
#
|
|
17
|
+
# * The +source_path+ specifies a path string that was directly created by a Source object. Each
|
|
18
|
+
# Path object must have such a valid source path sothat webgen can infer the Path the lead to
|
|
19
|
+
# the creation of a Node object later.
|
|
20
|
+
#
|
|
21
|
+
# * In contrast, the +path+ attribute specifies the path that is used to create the canonical name
|
|
22
|
+
# (and by default the output path) of a Node object. Normally it is the same as the
|
|
23
|
+
# +source_path+ but can differ (e.g. when fragment nodes are created for page file nodes).
|
|
24
|
+
#
|
|
25
|
+
# A Path object can represent one of three different things: a directory, a file or a fragment. If
|
|
26
|
+
# the +path+ ends with a slash character, then the path object represents a directory, if the path
|
|
27
|
+
# contains a hash character anywhere, then the path object represents a fragment and else it
|
|
28
|
+
# represents a file. Have a look at the webgen manual to see the exact format of a path!
|
|
29
|
+
#
|
|
30
|
+
# == Relation to Source classes
|
|
9
31
|
#
|
|
10
32
|
# A webgen source class needs to derive a specialized path class from this class and implement an
|
|
11
33
|
# approriate #changed? method that returns +true+ if the path's content has changed since the last
|
|
@@ -13,30 +35,48 @@ module Webgen
|
|
|
13
35
|
class Path
|
|
14
36
|
|
|
15
37
|
# Helper class for easy access to the content of a path.
|
|
38
|
+
#
|
|
39
|
+
# This class is used sothat the creation of the real IO object for #stream can be delayed till
|
|
40
|
+
# it is actually needed. This is done by not directly requiring the user of this class to supply
|
|
41
|
+
# the IO object, but by requiring a block that creates the real IO object.
|
|
16
42
|
class SourceIO
|
|
17
43
|
|
|
18
|
-
# Create a new SourceIO object. A block has to be specified that returns
|
|
44
|
+
# Create a new SourceIO object. A block has to be specified that returns the to-be-wrapped IO
|
|
45
|
+
# object.
|
|
19
46
|
def initialize(&block)
|
|
20
47
|
@block = block
|
|
21
|
-
raise ArgumentError, '
|
|
48
|
+
raise ArgumentError, 'You need to provide a block which returns an IO object' if @block.nil?
|
|
22
49
|
end
|
|
23
50
|
|
|
24
|
-
# Provide direct access to the wrapped IO object.
|
|
25
|
-
|
|
26
|
-
|
|
51
|
+
# Provide direct access to the wrapped IO object by yielding it. After the method block
|
|
52
|
+
# returns the IO object is automatically closed.
|
|
53
|
+
#
|
|
54
|
+
# The parameter +mode+ specifies the mode in which the wrapped IO object should be opened.
|
|
55
|
+
# This can be used, for example, to open a file in binary mode (or specify a certain input
|
|
56
|
+
# encoding under Ruby 1.9).
|
|
57
|
+
def stream(mode = 'r')
|
|
58
|
+
io = @block.call(mode)
|
|
27
59
|
yield(io)
|
|
28
60
|
ensure
|
|
29
61
|
io.close
|
|
30
62
|
end
|
|
31
63
|
|
|
32
|
-
# Return the content of the wrapped IO object as string.
|
|
33
|
-
|
|
34
|
-
|
|
64
|
+
# Return the whole content of the wrapped IO object as string. For a description of the
|
|
65
|
+
# parameter +mode+ see #stream.
|
|
66
|
+
def data(mode = 'r')
|
|
67
|
+
stream(mode) {|io| io.read}
|
|
35
68
|
end
|
|
36
69
|
|
|
37
70
|
end
|
|
38
71
|
|
|
39
72
|
|
|
73
|
+
# Make the given +path+ absolute by prepending the absolute directory path +base+ if necessary.
|
|
74
|
+
# Also resolves all '..' and '.' references in +path+.
|
|
75
|
+
def self.make_absolute(base, path)
|
|
76
|
+
raise(ArgumentError, 'base has to be an absolute path, ie. needs to start with a slash') unless base =~ /\//
|
|
77
|
+
Pathname.new(path =~ /^\// ? path : File.join(base, path)).cleanpath.to_s
|
|
78
|
+
end
|
|
79
|
+
|
|
40
80
|
# Return +true+ if the given +path+ matches the given +pattern+ (trailing slashes of directories
|
|
41
81
|
# are not respected). For information on which patterns are supported, have a look at the
|
|
42
82
|
# documentation of File.fnmatch.
|
|
@@ -49,66 +89,86 @@ module Webgen
|
|
|
49
89
|
|
|
50
90
|
include Comparable
|
|
51
91
|
|
|
52
|
-
# The full path.
|
|
53
|
-
|
|
92
|
+
# The full path for which this Path object was created.
|
|
93
|
+
attr_reader :path
|
|
54
94
|
|
|
55
|
-
#
|
|
56
|
-
|
|
95
|
+
# A string specifying the path that lead to the creation of this path.
|
|
96
|
+
attr_reader :source_path
|
|
57
97
|
|
|
58
|
-
# The
|
|
59
|
-
|
|
98
|
+
# The string specifying the parent path
|
|
99
|
+
attr_reader :parent_path
|
|
60
100
|
|
|
61
|
-
# The
|
|
62
|
-
attr_accessor :
|
|
63
|
-
|
|
64
|
-
# The canonical name without the extension.
|
|
65
|
-
attr_accessor :cnbase
|
|
101
|
+
# The canonical name of the path without the extension.
|
|
102
|
+
attr_accessor :basename
|
|
66
103
|
|
|
67
|
-
# The extension
|
|
104
|
+
# The extension of the +path+.
|
|
68
105
|
attr_accessor :ext
|
|
69
106
|
|
|
70
107
|
# Extracted meta information for the path.
|
|
71
108
|
attr_accessor :meta_info
|
|
72
109
|
|
|
110
|
+
# Specifies whether this path should be used during the "tree update" phase of a webgen run or
|
|
111
|
+
# only later during node resolution.
|
|
112
|
+
attr_writer :passive
|
|
113
|
+
|
|
114
|
+
# Is this path only used later during node resolution? Defaults to +false+, i.e. used during the
|
|
115
|
+
# "tree update" phase.
|
|
116
|
+
def passive?; @passive; end
|
|
117
|
+
|
|
118
|
+
|
|
73
119
|
# Create a new Path object for +path+. The optional +source_path+ parameter specifies the path
|
|
74
|
-
# that lead to the creation of this path. The optional block needs to return an IO object
|
|
75
|
-
# the content of the path.
|
|
120
|
+
# string that lead to the creation of this path. The optional block needs to return an IO object
|
|
121
|
+
# for getting the content of the path.
|
|
122
|
+
#
|
|
123
|
+
# The +path+ needs to be in a well defined format which can be looked up in the webgen manual.
|
|
76
124
|
def initialize(path, source_path = path, &ioblock)
|
|
77
125
|
@meta_info = {}
|
|
78
126
|
@io = block_given? ? SourceIO.new(&ioblock) : nil
|
|
79
127
|
@source_path = source_path
|
|
128
|
+
@passive = false
|
|
80
129
|
analyse(path)
|
|
81
130
|
end
|
|
82
131
|
|
|
83
|
-
# Mount this path at the mount point +mp
|
|
84
|
-
# the new path object.
|
|
132
|
+
# Mount this path at the mount point +mp+, optionally stripping +prefix+ from the parent path,
|
|
133
|
+
# and return the new path object.
|
|
134
|
+
#
|
|
135
|
+
# The parameters +mp+ and +prefix+ have to be absolute directory paths, ie. they have to start
|
|
136
|
+
# and end with a slash and must not contain any hash characters!
|
|
137
|
+
#
|
|
138
|
+
#--
|
|
139
|
+
# Can't use self.class.new(...) here because the semantics of the sub constructors is not know
|
|
140
|
+
#++
|
|
85
141
|
def mount_at(mp, prefix = nil)
|
|
142
|
+
raise(ArgumentError, "The mount point (#{mp}) must be a valid directory path") if mp =~ /^[^\/]|#|[^\/]$/
|
|
143
|
+
raise(ArgumentError, "The strip prefix (#{prefix}) must be a valid directory path") if !prefix.nil? && prefix =~ /^[^\/]|#|[^\/]$/
|
|
144
|
+
|
|
86
145
|
temp = dup
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
temp.
|
|
146
|
+
strip_re = /^#{Regexp.escape(prefix.to_s)}/
|
|
147
|
+
temp.instance_variable_set(:@path, temp.path.sub(strip_re, ''))
|
|
148
|
+
reanalyse = (@path == '/' || temp.path == '')
|
|
149
|
+
temp.instance_variable_set(:@path, File.join(mp, temp.path))
|
|
150
|
+
temp.instance_variable_set(:@source_path, temp.path) if @path == @source_path
|
|
91
151
|
if reanalyse
|
|
92
152
|
temp.send(:analyse, temp.path)
|
|
93
153
|
else
|
|
94
|
-
temp.
|
|
154
|
+
temp.instance_variable_set(:@parent_path, File.join(mp, temp.parent_path.sub(strip_re, '')))
|
|
95
155
|
end
|
|
96
156
|
temp
|
|
97
157
|
end
|
|
98
158
|
|
|
99
|
-
# Has the content of this path changed since the last webgen run? This default implementation
|
|
100
|
-
# always returns +true+, a specialized sub class needs to override this behaviour!
|
|
101
|
-
def changed?
|
|
102
|
-
true
|
|
103
|
-
end
|
|
104
|
-
|
|
105
159
|
# Duplicate the path object.
|
|
106
160
|
def dup
|
|
107
161
|
temp = super
|
|
108
|
-
temp.meta_info
|
|
162
|
+
temp.instance_variable_set(:@meta_info, @meta_info.dup)
|
|
109
163
|
temp
|
|
110
164
|
end
|
|
111
165
|
|
|
166
|
+
# Has the content of this path changed since the last webgen run? This default implementation
|
|
167
|
+
# always returns +true+, a specialized sub class needs to override this behaviour!
|
|
168
|
+
def changed?
|
|
169
|
+
true
|
|
170
|
+
end
|
|
171
|
+
|
|
112
172
|
# The SourceIO object associated with the path.
|
|
113
173
|
def io
|
|
114
174
|
if @io
|
|
@@ -118,26 +178,45 @@ module Webgen
|
|
|
118
178
|
end
|
|
119
179
|
end
|
|
120
180
|
|
|
121
|
-
# The canonical name created from the
|
|
181
|
+
# The canonical name created from the +path+ (namely from the parts +basename+ and +extension+).
|
|
122
182
|
def cn
|
|
123
|
-
@
|
|
183
|
+
@basename + (@ext.length > 0 ? '.' + @ext : '') + (@basename != '/' && @path =~ /.\/$/ ? '/' : '')
|
|
124
184
|
end
|
|
125
185
|
|
|
126
|
-
# Utility method for creating the lcn from +cn+ and the language +lang+.
|
|
186
|
+
# Utility method for creating the lcn from the +cn+ and the language +lang+.
|
|
127
187
|
def self.lcn(cn, lang)
|
|
128
188
|
if lang.nil?
|
|
129
189
|
cn
|
|
130
190
|
else
|
|
131
|
-
cn.split('.').insert(1, lang.to_s).join('.')
|
|
191
|
+
cn.split('.').insert((cn =~ /^\./ ? 2 : 1), lang.to_s).join('.')
|
|
132
192
|
end
|
|
133
193
|
end
|
|
134
194
|
|
|
135
|
-
# The localized canonical name created from the
|
|
195
|
+
# The localized canonical name created from the +path+.
|
|
136
196
|
def lcn
|
|
137
197
|
self.class.lcn(cn, @meta_info['lang'])
|
|
138
198
|
end
|
|
139
199
|
|
|
140
|
-
#
|
|
200
|
+
# The absolute canonical name of this path.
|
|
201
|
+
def acn
|
|
202
|
+
if @path =~ /#/
|
|
203
|
+
self.class.new(@parent_path).acn + cn
|
|
204
|
+
else
|
|
205
|
+
@parent_path + cn
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# The absolute localized canonical name of this path.
|
|
210
|
+
def alcn
|
|
211
|
+
if @path =~ /#/
|
|
212
|
+
self.class.new(@parent_path).alcn + lcn
|
|
213
|
+
else
|
|
214
|
+
@parent_path + lcn
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# Equality -- Return +true+ if +other+ is a Path object with the same #path or if +other+ is a
|
|
219
|
+
# String equal to the #path. Else return +false+.
|
|
141
220
|
def ==(other)
|
|
142
221
|
if other.kind_of?(Path)
|
|
143
222
|
other.path == @path
|
|
@@ -149,13 +228,12 @@ module Webgen
|
|
|
149
228
|
end
|
|
150
229
|
alias_method(:eql?, :==)
|
|
151
230
|
|
|
152
|
-
#
|
|
231
|
+
# Compare the #path of this object to <tt>other.path</tt>
|
|
153
232
|
def <=>(other)
|
|
154
|
-
@path <=> other.
|
|
233
|
+
@path <=> other.path
|
|
155
234
|
end
|
|
156
235
|
|
|
157
|
-
|
|
158
|
-
def hash
|
|
236
|
+
def hash #:nodoc:
|
|
159
237
|
@path.hash
|
|
160
238
|
end
|
|
161
239
|
|
|
@@ -172,21 +250,46 @@ module Webgen
|
|
|
172
250
|
private
|
|
173
251
|
#######
|
|
174
252
|
|
|
175
|
-
FILENAME_RE = /^(?:(\d+)\.)?([^.]*?)(?:\.(\w\w\w?)(?=.))?(?:\.(.*))?$/
|
|
176
|
-
|
|
177
253
|
# Analyse the +path+ and fill the object with the extracted information.
|
|
178
254
|
def analyse(path)
|
|
179
255
|
@path = path
|
|
180
|
-
@
|
|
181
|
-
|
|
182
|
-
|
|
256
|
+
if @path =~ /#/
|
|
257
|
+
analyse_fragment
|
|
258
|
+
elsif @path =~ /\/$/
|
|
259
|
+
analyse_directory
|
|
260
|
+
else
|
|
261
|
+
analyse_file
|
|
262
|
+
end
|
|
263
|
+
@meta_info['title'] = @basename.tr('_-', ' ').capitalize
|
|
264
|
+
@ext ||= ''
|
|
265
|
+
raise "The basename of a path may not be empty: #{@path}" if @basename.empty? || @basename == '#'
|
|
266
|
+
raise "The parent path must start with a slash: #{@path}" if @path !~ /^\// && @path != '/'
|
|
267
|
+
end
|
|
183
268
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
@
|
|
187
|
-
@
|
|
269
|
+
# Analyse the path assuming it is a directory.
|
|
270
|
+
def analyse_directory
|
|
271
|
+
@parent_path = (@path == '/' ? '' : File.join(File.dirname(@path), '/'))
|
|
272
|
+
@basename = File.basename(@path)
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
FILENAME_RE = /^(?:(\d+)\.)?(\.?[^.]*?)(?:\.(\w\w\w?)(?=\.))?(?:\.(.*))?$/
|
|
276
|
+
|
|
277
|
+
# Analyse the path assuming it is a file.
|
|
278
|
+
def analyse_file
|
|
279
|
+
@parent_path = File.join(File.dirname(@path), '/')
|
|
280
|
+
match_data = FILENAME_RE.match(File.basename(@path))
|
|
281
|
+
|
|
282
|
+
@meta_info['sort_info'] = (match_data[1].nil? ? nil : match_data[1].to_i)
|
|
283
|
+
@basename = match_data[2]
|
|
284
|
+
@meta_info['lang'] = Webgen::LanguageManager.language_for_code(match_data[3])
|
|
285
|
+
@ext = (@meta_info['lang'].nil? && !match_data[3].nil? ? match_data[3].to_s : '') + match_data[4].to_s
|
|
286
|
+
end
|
|
188
287
|
|
|
189
|
-
|
|
288
|
+
# Analyse the path assuming it is a fragment.
|
|
289
|
+
def analyse_fragment
|
|
290
|
+
@parent_path, @basename = @path.scan(/^(.*?)(#.*?)$/).first
|
|
291
|
+
raise "The parent path of a fragment path must be a file path and not a directory path: #{@path}" if @parent_path =~ /\/$/
|
|
292
|
+
raise "A fragment path must only contain one hash character: #{path}" if @path.count("#") > 1
|
|
190
293
|
end
|
|
191
294
|
|
|
192
295
|
end
|
data/lib/webgen/source.rb
CHANGED
|
@@ -10,9 +10,13 @@ module Webgen
|
|
|
10
10
|
#
|
|
11
11
|
# A source class only needs to respond to the method +paths+ which needs to return a set of paths
|
|
12
12
|
# for the source. The returned paths must respond to the method <tt>changed?</tt> (has to return
|
|
13
|
-
# +true+ if the paths has changed since the last webgen run).
|
|
14
|
-
#
|
|
15
|
-
# singleton methods on each path
|
|
13
|
+
# +true+ if the paths has changed since the last webgen run). If a path represents a directory, it
|
|
14
|
+
# needs to have a trailing slash! The default implementation in the Path class just returns
|
|
15
|
+
# +true+. One can either derive a specialized path class or define singleton methods on each path
|
|
16
|
+
# object.
|
|
17
|
+
#
|
|
18
|
+
# Also note that the returned Path objects should have the meta information <tt>modified_at</tt>
|
|
19
|
+
# set to the correct last modification time of the path, ie. the value has to be a Time object!
|
|
16
20
|
#
|
|
17
21
|
# == Sample Source Class
|
|
18
22
|
#
|
|
@@ -36,10 +40,9 @@ module Webgen
|
|
|
36
40
|
# end
|
|
37
41
|
#
|
|
38
42
|
# You can use this source class in your website (after placing the code in, for example,
|
|
39
|
-
# <tt>ext/init.rb</tt>) by updating the <tt>sources</tt> configuration option
|
|
40
|
-
# has to be placed after the definition of the +MemorySource+ class):
|
|
43
|
+
# <tt>ext/init.rb</tt>) by updating the <tt>sources</tt> configuration option:
|
|
41
44
|
#
|
|
42
|
-
# WebsiteAccess.website.config['sources'] << ['/', MemorySource]
|
|
45
|
+
# WebsiteAccess.website.config['sources'] << ['/', 'MemorySource']
|
|
43
46
|
#
|
|
44
47
|
module Source
|
|
45
48
|
|
|
@@ -14,7 +14,7 @@ module Webgen
|
|
|
14
14
|
|
|
15
15
|
# Create a new object with absolute path +path+ for the file system path +fs_path+.
|
|
16
16
|
def initialize(path, fs_path)
|
|
17
|
-
super(path) { File.open(fs_path,
|
|
17
|
+
super(path) {|mode| File.open(fs_path, mode) }
|
|
18
18
|
@fs_path = fs_path
|
|
19
19
|
WebsiteAccess.website.cache[[:fs_path, @fs_path]] = File.mtime(@fs_path)
|
|
20
20
|
@meta_info['modified_at'] = File.mtime(@fs_path)
|