webgen 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +340 -0
- data/ChangeLog +2172 -0
- data/README +16 -0
- data/Rakefile +283 -0
- data/TODO +133 -0
- data/VERSION +1 -0
- data/bin/webgen +5 -0
- data/doc/extension.config +55 -0
- data/doc/src/default.css +129 -0
- data/doc/src/default.template +45 -0
- data/doc/src/design.gallery +18 -0
- data/doc/src/designs/default.png +0 -0
- data/doc/src/designs/nostyle.png +0 -0
- data/doc/src/designs/old.png +0 -0
- data/doc/src/documentation/extloader.page +20 -0
- data/doc/src/documentation/filehandler/backing.page +16 -0
- data/doc/src/documentation/filehandler/copy.page +12 -0
- data/doc/src/documentation/filehandler/directory.page +15 -0
- data/doc/src/documentation/filehandler/index.page +13 -0
- data/doc/src/documentation/filehandler/page.page +122 -0
- data/doc/src/documentation/filehandler/picturegallery.page +25 -0
- data/doc/src/documentation/filehandler/template.page +21 -0
- data/doc/src/documentation/index.page +47 -0
- data/doc/src/documentation/tags/date.page +19 -0
- data/doc/src/documentation/tags/executecommand.page +19 -0
- data/doc/src/documentation/tags/includefile.page +15 -0
- data/doc/src/documentation/tags/index.page +39 -0
- data/doc/src/documentation/tags/lang.de.page +6 -0
- data/doc/src/documentation/tags/lang.page +27 -0
- data/doc/src/documentation/tags/menu.de.page +11 -0
- data/doc/src/documentation/tags/menu.page +30 -0
- data/doc/src/documentation/tags/meta.page +20 -0
- data/doc/src/documentation/tags/multilang.de.page +4 -0
- data/doc/src/documentation/tags/multilang.fr.page +4 -0
- data/doc/src/documentation/tags/multilang.page +4 -0
- data/doc/src/documentation/tags/navbar.page +19 -0
- data/doc/src/documentation/tags/relocatable.page +16 -0
- data/doc/src/documentation/tags/wikilink.page +18 -0
- data/doc/src/download.page +42 -0
- data/doc/src/features.page +14 -0
- data/doc/src/index.page +48 -0
- data/doc/src/logo.png +0 -0
- data/doc/src/meta.info +22 -0
- data/install.rb +19 -0
- data/lib/util/composite.rb +101 -0
- data/lib/util/listener.rb +105 -0
- data/lib/webgen/configuration.rb +216 -0
- data/lib/webgen/logging.rb +73 -0
- data/lib/webgen/node.rb +147 -0
- data/lib/webgen/plugins/extloader.rb +88 -0
- data/lib/webgen/plugins/filehandler/backing.rb +200 -0
- data/lib/webgen/plugins/filehandler/directory.rb +96 -0
- data/lib/webgen/plugins/filehandler/filecopy.rb +59 -0
- data/lib/webgen/plugins/filehandler/filehandler.rb +209 -0
- data/lib/webgen/plugins/filehandler/pagehandler/html.rb +43 -0
- data/lib/webgen/plugins/filehandler/pagehandler/markdown.rb +53 -0
- data/lib/webgen/plugins/filehandler/pagehandler/page.rb +205 -0
- data/lib/webgen/plugins/filehandler/pagehandler/rdoc.rb +50 -0
- data/lib/webgen/plugins/filehandler/pagehandler/textile.rb +52 -0
- data/lib/webgen/plugins/filehandler/picturegallery.rb +194 -0
- data/lib/webgen/plugins/filehandler/template.rb +98 -0
- data/lib/webgen/plugins/tags/date.rb +46 -0
- data/lib/webgen/plugins/tags/executecommand.rb +53 -0
- data/lib/webgen/plugins/tags/includefile.rb +60 -0
- data/lib/webgen/plugins/tags/lang.rb +50 -0
- data/lib/webgen/plugins/tags/menu.rb +198 -0
- data/lib/webgen/plugins/tags/meta.rb +54 -0
- data/lib/webgen/plugins/tags/navbar.rb +62 -0
- data/lib/webgen/plugins/tags/relocatable.rb +58 -0
- data/lib/webgen/plugins/tags/tags.rb +247 -0
- data/lib/webgen/plugins/tags/wikilink.rb +58 -0
- data/lib/webgen/plugins/treewalker.rb +81 -0
- data/lib/webgen/webgen.rb +155 -0
- data/setup.rb +1331 -0
- data/testsite/config.yaml +7 -0
- data/testsite/src/bluecloth.page +102 -0
- data/testsite/src/default.css +146 -0
- data/testsite/src/default.template +33 -0
- data/testsite/src/home.en.page +22 -0
- data/testsite/src/home.page +22 -0
- data/testsite/src/images/bghack.png +0 -0
- data/testsite/src/images/o.png +0 -0
- data/testsite/src/images/smagacor.png +0 -0
- data/testsite/src/images/tictactoe.png +0 -0
- data/testsite/src/images/x.png +0 -0
- data/testsite/src/index.page +21 -0
- data/testsite/src/meta.info +15 -0
- data/testsite/src/news.page +20 -0
- data/testsite/src/news_are_so-cool.de.page +19 -0
- data/testsite/src/noindex/noindex.page +20 -0
- data/testsite/src/pictures/index.page +20 -0
- data/testsite/src/projects.de.page +11 -0
- data/testsite/src/projects.es.page +11 -0
- data/testsite/src/projects.page +17 -0
- data/testsite/src/projects/00.index.de.page +10 -0
- data/testsite/src/projects/01.project2.page +20 -0
- data/testsite/src/projects/02.project1.page +20 -0
- data/testsite/src/projects/05.project3.page +22 -0
- data/testsite/src/projects/index.page +20 -0
- data/testsite/src/projects/subproj/index.page +22 -0
- data/testsite/src/projects/subproj/project3.page +21 -0
- data/testsite/src/rdoc.page +12 -0
- data/testsite/src/redcloth.page +106 -0
- data/testsite/src/test.gallery +5 -0
- metadata +155 -0
@@ -0,0 +1,59 @@
|
|
1
|
+
#
|
2
|
+
#--
|
3
|
+
#
|
4
|
+
# $Id: filecopy.rb 203 2005-02-21 18:42:04Z thomas $
|
5
|
+
#
|
6
|
+
# webgen: template based static website generator
|
7
|
+
# Copyright (C) 2004 Thomas Leitner
|
8
|
+
#
|
9
|
+
# This program is free software; you can redistribute it and/or modify it under the terms of the GNU
|
10
|
+
# General Public License as published by the Free Software Foundation; either version 2 of the
|
11
|
+
# License, or (at your option) any later version.
|
12
|
+
#
|
13
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
14
|
+
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15
|
+
# General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU General Public License along with this program; if not,
|
18
|
+
# write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
19
|
+
#
|
20
|
+
#++
|
21
|
+
#
|
22
|
+
|
23
|
+
require 'fileutils'
|
24
|
+
require 'webgen/plugins/filehandler/filehandler'
|
25
|
+
|
26
|
+
module FileHandlers
|
27
|
+
|
28
|
+
# A simple file handler which copies files with a specific extension from the source to the output
|
29
|
+
# directory. The extensions of the files to copy are customizable.
|
30
|
+
class FileCopyHandler < DefaultHandler
|
31
|
+
|
32
|
+
summary "Copies files from source to destination without modification"
|
33
|
+
add_param 'types', ['css', 'jpg', 'png', 'gif'], \
|
34
|
+
'The extension that will be registered by this handler. All files with ' \
|
35
|
+
'these extensions will be copied from the source to the destination folder.'
|
36
|
+
depends_on 'FileHandler'
|
37
|
+
|
38
|
+
def initialize
|
39
|
+
super
|
40
|
+
get_param( 'types' ).each do |type|
|
41
|
+
extension( type )
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def create_node( srcName, parent )
|
46
|
+
node = Node.new( parent )
|
47
|
+
node['dest'] = node['src'] = node['title'] = File.basename( srcName )
|
48
|
+
node['processor'] = self
|
49
|
+
node
|
50
|
+
end
|
51
|
+
|
52
|
+
# Copy the file to the destination directory if it has been modified.
|
53
|
+
def write_node( node )
|
54
|
+
FileUtils.cp( node.recursive_value( 'src' ), node.recursive_value( 'dest' ) ) if Webgen::Plugin['FileHandler'].file_modified?( node )
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
@@ -0,0 +1,209 @@
|
|
1
|
+
#
|
2
|
+
#--
|
3
|
+
#
|
4
|
+
# $Id: filehandler.rb 203 2005-02-21 18:42:04Z thomas $
|
5
|
+
#
|
6
|
+
# webgen: template based static website generator
|
7
|
+
# Copyright (C) 2004 Thomas Leitner
|
8
|
+
#
|
9
|
+
# This program is free software; you can redistribute it and/or modify it under the terms of the GNU
|
10
|
+
# General Public License as published by the Free Software Foundation; either version 2 of the
|
11
|
+
# License, or (at your option) any later version.
|
12
|
+
#
|
13
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
14
|
+
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15
|
+
# General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU General Public License along with this program; if not,
|
18
|
+
# write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
19
|
+
#
|
20
|
+
#++
|
21
|
+
#
|
22
|
+
|
23
|
+
require 'util/listener'
|
24
|
+
|
25
|
+
module FileHandlers
|
26
|
+
|
27
|
+
# Super plugin for handling files. File handler plugins can register themselves by adding a new
|
28
|
+
# key:value pair to +extensions+. The key has to be the extension in lowercase and the value is
|
29
|
+
# the plugin object itself.
|
30
|
+
class FileHandler < Webgen::Plugin
|
31
|
+
|
32
|
+
summary "Super plugin for handling files"
|
33
|
+
description "Provides interface on file level. The FileHandler goes through the source
|
34
|
+
directory, reads in all files for which approriate plugins exist and
|
35
|
+
builds the tree. When all approriate transformations on the tree have
|
36
|
+
been performed the FileHandler is used to write the output files.
|
37
|
+
".gsub( /^\s+/, '' ).gsub( /\n/, ' ' )
|
38
|
+
|
39
|
+
add_param 'ignored', ['.svn', 'CVS'], 'Specifies path names via regular expresssions which should be ignored.'
|
40
|
+
|
41
|
+
|
42
|
+
include Listener
|
43
|
+
|
44
|
+
attr_reader :extensions
|
45
|
+
|
46
|
+
def initialize
|
47
|
+
@extensions = Hash.new
|
48
|
+
|
49
|
+
add_msg_name( :DIR_NODE_CREATED )
|
50
|
+
add_msg_name( :FILE_NODE_CREATED )
|
51
|
+
add_msg_name( :AFTER_DIR_READ )
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
# Recursively builds the tree with all the nodes and returns it.
|
56
|
+
def build_tree
|
57
|
+
root = build_entry( Webgen::Plugin['Configuration']['srcDirectory'], nil )
|
58
|
+
unless root.nil?
|
59
|
+
root['title'] = '/'
|
60
|
+
root['dest'] = Webgen::Plugin['Configuration']['outDirectory'] + '/'
|
61
|
+
root['src'] = Webgen::Plugin['Configuration']['srcDirectory'] + '/'
|
62
|
+
end
|
63
|
+
root
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
# Recursively writes out the tree specified by +node+.
|
68
|
+
def write_tree( node )
|
69
|
+
self.logger.info { "Writing <#{node.recursive_value('dest')}>" }
|
70
|
+
|
71
|
+
node['processor'].write_node( node )
|
72
|
+
|
73
|
+
node.each do |child|
|
74
|
+
write_tree child
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
# Returns true if the source file specified by +node+ has been modified since the last execution
|
80
|
+
# of webgen. The +mtime+ values for the source and destination files are used to find this out.
|
81
|
+
def file_modified?( node )
|
82
|
+
src = node.recursive_value( 'src' )
|
83
|
+
dest = node.recursive_value( 'dest' )
|
84
|
+
if File.exists?( dest ) && ( File.mtime( src ) < File.mtime( dest ) )
|
85
|
+
self.logger.info { "File is up to date: <#{dest}>" }
|
86
|
+
return false
|
87
|
+
else
|
88
|
+
return true
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
#######
|
94
|
+
private
|
95
|
+
#######
|
96
|
+
|
97
|
+
def build_entry( path, parent )
|
98
|
+
self.logger.info { "Processing <#{path}> ..." }
|
99
|
+
|
100
|
+
if FileTest.file?( path )
|
101
|
+
node = handle_file( path, parent )
|
102
|
+
elsif FileTest.directory?( path )
|
103
|
+
node = handle_directory( path, parent )
|
104
|
+
else
|
105
|
+
type = File.lstat( path ).ftype if File.exists?( path )
|
106
|
+
self.logger.warn { "Path <#{path}> (type: #{type || 'non existing file/dir'}) cannot be handled as it is neither a file nor a directory" }
|
107
|
+
node = nil
|
108
|
+
end
|
109
|
+
|
110
|
+
return node
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
def handle_file( path, parent )
|
115
|
+
extension = File.extname( path ).sub( /^./, '' )
|
116
|
+
|
117
|
+
if @extensions.has_key?( extension )
|
118
|
+
node = @extensions[extension].create_node( path, parent )
|
119
|
+
dispatch_msg( :FILE_NODE_CREATED, node ) unless node.nil?
|
120
|
+
else
|
121
|
+
self.logger.warn { "No plugin for <#{path}> (extension: #{extension}) -> ignored" }
|
122
|
+
end
|
123
|
+
|
124
|
+
return node
|
125
|
+
end
|
126
|
+
|
127
|
+
|
128
|
+
def handle_directory( path, parent )
|
129
|
+
node = nil
|
130
|
+
|
131
|
+
if @extensions.has_key?( :dir )
|
132
|
+
node = @extensions[:dir].create_node( path, parent )
|
133
|
+
node['processor'] = @extensions[:dir]
|
134
|
+
|
135
|
+
dispatch_msg( :DIR_NODE_CREATED, node )
|
136
|
+
|
137
|
+
Dir[path + File::SEPARATOR + '{.*,*}'].delete_if do |name|
|
138
|
+
name =~ /#{File::SEPARATOR}.{1,2}$/ || \
|
139
|
+
File.basename( name ) =~ Regexp.new( get_param( 'ignored' ).join( '|' ) )
|
140
|
+
end.sort! do |a, b|
|
141
|
+
if File.file?( a ) && File.directory?( b )
|
142
|
+
-1
|
143
|
+
elsif ( File.file?( a ) && File.file?( b ) ) || ( File.directory?( a ) && File.directory?( b ) )
|
144
|
+
a <=> b
|
145
|
+
else
|
146
|
+
1
|
147
|
+
end
|
148
|
+
end.each do |filename|
|
149
|
+
child = build_entry( filename, node )
|
150
|
+
node.add_child( child ) unless child.nil?
|
151
|
+
end
|
152
|
+
|
153
|
+
dispatch_msg( :AFTER_DIR_READ, node )
|
154
|
+
end
|
155
|
+
|
156
|
+
return node
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|
160
|
+
|
161
|
+
# The default handler which is the super class of all file handlers.
|
162
|
+
class DefaultHandler < Webgen::Plugin
|
163
|
+
|
164
|
+
VIRTUAL = true
|
165
|
+
|
166
|
+
summary "Base class of all file handler plugins"
|
167
|
+
|
168
|
+
def initialize
|
169
|
+
extension( Webgen::Plugin.config[self.class.name].extension ) if Webgen::Plugin.config[self.class.name].extension
|
170
|
+
end
|
171
|
+
|
172
|
+
# Register the file extension specified by a subclass.
|
173
|
+
def extension( ext )
|
174
|
+
self.logger.info { "Registering file handler #{self.class.name} (#{self.object_id}) with extension '#{ext}'" }
|
175
|
+
Webgen::Plugin['FileHandler'].extensions[ext] = self
|
176
|
+
end
|
177
|
+
|
178
|
+
# Supplies the +path+ to a file and the +parent+ node sothat the plugin can create a node for this
|
179
|
+
# path. Should return the node for the path or nil if the node could not be created.
|
180
|
+
#
|
181
|
+
# Has to be overridden by the subclass!!!
|
182
|
+
def create_node( path, parent )
|
183
|
+
raise "Not implemented"
|
184
|
+
end
|
185
|
+
|
186
|
+
# Asks the plugin to write out the node.
|
187
|
+
#
|
188
|
+
# Has to be overridden by the subclass!!!
|
189
|
+
def write_node( node )
|
190
|
+
raise "Not implemented"
|
191
|
+
end
|
192
|
+
|
193
|
+
# Returns the language node for the given +node+. The default implementation returns the node
|
194
|
+
# itself. You can optionally specify the language of the node which should be returned. If not
|
195
|
+
# specified the language of the node is used.
|
196
|
+
def get_lang_node( node, lang = node['lang'] )
|
197
|
+
node
|
198
|
+
end
|
199
|
+
|
200
|
+
# Returns a HTML link for the given +node+ relative to +refNode+. You can optionally specify the
|
201
|
+
# title for the link. If not specified, the title of the node is used.
|
202
|
+
def get_html_link( node, refNode, title = node['title'] )
|
203
|
+
url = refNode.relpath_to_node( node )
|
204
|
+
"<a href=\"#{url}\">#{title}</a>"
|
205
|
+
end
|
206
|
+
|
207
|
+
end
|
208
|
+
|
209
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
#
|
2
|
+
#--
|
3
|
+
#
|
4
|
+
# $Id: html.rb 203 2005-02-21 18:42:04Z thomas $
|
5
|
+
#
|
6
|
+
# webgen: template based static website generator
|
7
|
+
# Copyright (C) 2004 Thomas Leitner
|
8
|
+
#
|
9
|
+
# This program is free software; you can redistribute it and/or modify it under the terms of the GNU
|
10
|
+
# General Public License as published by the Free Software Foundation; either version 2 of the
|
11
|
+
# License, or (at your option) any later version.
|
12
|
+
#
|
13
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
14
|
+
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15
|
+
# General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU General Public License along with this program; if not,
|
18
|
+
# write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
19
|
+
#
|
20
|
+
#++
|
21
|
+
#
|
22
|
+
|
23
|
+
require 'webgen/plugins/filehandler/pagehandler/page'
|
24
|
+
|
25
|
+
module ContentHandlers
|
26
|
+
|
27
|
+
# Handles HTML content. Assumes that the content is already valid HTML.
|
28
|
+
class HTMLHandler < ContentHandler
|
29
|
+
|
30
|
+
summary "Handles HTML formatted content"
|
31
|
+
depends_on "PageHandler"
|
32
|
+
|
33
|
+
def initialize
|
34
|
+
register_format( 'html' )
|
35
|
+
end
|
36
|
+
|
37
|
+
def format_content( txt )
|
38
|
+
txt
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
#
|
2
|
+
#--
|
3
|
+
#
|
4
|
+
# $Id: markdown.rb 203 2005-02-21 18:42:04Z thomas $
|
5
|
+
#
|
6
|
+
# webgen: template based static website generator
|
7
|
+
# Copyright (C) 2004 Thomas Leitner
|
8
|
+
#
|
9
|
+
# This program is free software; you can redistribute it and/or modify it under the terms of the GNU
|
10
|
+
# General Public License as published by the Free Software Foundation; either version 2 of the
|
11
|
+
# License, or (at your option) any later version.
|
12
|
+
#
|
13
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
14
|
+
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15
|
+
# General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU General Public License along with this program; if not,
|
18
|
+
# write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
19
|
+
#
|
20
|
+
#++
|
21
|
+
#
|
22
|
+
|
23
|
+
|
24
|
+
begin
|
25
|
+
require 'bluecloth'
|
26
|
+
require 'webgen/plugins/filehandler/pagehandler/page'
|
27
|
+
|
28
|
+
module ContentHandlers
|
29
|
+
|
30
|
+
# Handles text formatted in Markdown format using BlueCloth.
|
31
|
+
class MarkdownHandler < ContentHandler
|
32
|
+
|
33
|
+
summary "Handles content formatted in Markdown format using BlueCloth"
|
34
|
+
depends_on "PageHandler"
|
35
|
+
|
36
|
+
def initialize
|
37
|
+
register_format( 'markdown' )
|
38
|
+
end
|
39
|
+
|
40
|
+
def format_content( txt )
|
41
|
+
BlueCloth.new( txt ).to_html
|
42
|
+
rescue
|
43
|
+
self.logger.error { "Error converting Markdown text to HTML" }
|
44
|
+
''
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
rescue LoadError => e
|
52
|
+
self.logger.warn { "Markdown not available as content format as BlueCloth could not be loaded: #{e.message}" }
|
53
|
+
end
|
@@ -0,0 +1,205 @@
|
|
1
|
+
#
|
2
|
+
#--
|
3
|
+
#
|
4
|
+
# $Id: page.rb 203 2005-02-21 18:42:04Z thomas $
|
5
|
+
#
|
6
|
+
# webgen: template based static website generator
|
7
|
+
# Copyright (C) 2004 Thomas Leitner
|
8
|
+
#
|
9
|
+
# This program is free software; you can redistribute it and/or modify it under the terms of the GNU
|
10
|
+
# General Public License as published by the Free Software Foundation; either version 2 of the
|
11
|
+
# License, or (at your option) any later version.
|
12
|
+
#
|
13
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
14
|
+
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15
|
+
# General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU General Public License along with this program; if not,
|
18
|
+
# write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
19
|
+
#
|
20
|
+
#++
|
21
|
+
#
|
22
|
+
|
23
|
+
require 'webgen/plugins/filehandler/filehandler'
|
24
|
+
require 'yaml'
|
25
|
+
|
26
|
+
module FileHandlers
|
27
|
+
|
28
|
+
# Super class for all page description files. Provides helper methods so that writing new plugins
|
29
|
+
# for page description files is easy.
|
30
|
+
class PageHandler < DefaultHandler
|
31
|
+
|
32
|
+
# Specialized node describing a page. A page node itself is virtual, it has sub nodes which
|
33
|
+
# describe the page files in all available languages.
|
34
|
+
class PageNode < Node
|
35
|
+
|
36
|
+
def initialize( parent, basename )
|
37
|
+
super( parent )
|
38
|
+
self['page:basename'] = self['title'] = basename
|
39
|
+
self['src'] = self['dest'] = basename
|
40
|
+
self['virtual'] = true
|
41
|
+
self['processor'] = Webgen::Plugin['PageHandler']
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
summary "Class for processing page files"
|
47
|
+
extension 'page'
|
48
|
+
add_param 'defaultLangInFilename', false, \
|
49
|
+
'If true, the output files for the default language will have the ' \
|
50
|
+
'language in the file name like all other page files. If false, they won''t.'
|
51
|
+
add_param 'defaultContentFormat', 'textile', 'The default content format used in page files'
|
52
|
+
depends_on 'FileHandler'
|
53
|
+
|
54
|
+
attr_reader :formats
|
55
|
+
|
56
|
+
def initialize
|
57
|
+
super
|
58
|
+
@formats = Hash.new( ContentHandlers::ContentHandler.new )
|
59
|
+
end
|
60
|
+
|
61
|
+
def create_node( srcName, parent )
|
62
|
+
create_node_internally( parse_data( File.read( srcName ), srcName ), analyse_file_name( File.basename( srcName ) ), parent )
|
63
|
+
end
|
64
|
+
|
65
|
+
def create_node_from_data( data, srcName, parent )
|
66
|
+
create_node_internally( parse_data( data, srcName ), analyse_file_name( File.basename( srcName ) ), parent )
|
67
|
+
end
|
68
|
+
|
69
|
+
def write_node( node )
|
70
|
+
# do nothing if page base node
|
71
|
+
return unless node['virtual'].nil?
|
72
|
+
templateNode = Webgen::Plugin['TemplateFileHandler'].get_template_for_node( node )
|
73
|
+
|
74
|
+
outstring = templateNode['content'].dup
|
75
|
+
|
76
|
+
Webgen::Plugin['Tags'].substitute_tags( outstring, node, templateNode )
|
77
|
+
|
78
|
+
File.open( node.recursive_value( 'dest' ), File::CREAT|File::TRUNC|File::RDWR ) do |file|
|
79
|
+
file.write( outstring )
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def page_node_exists?( basename, dirNode )
|
84
|
+
dirNode.find {|node| node['page:basename'] == basename}
|
85
|
+
end
|
86
|
+
alias :get_page_node :page_node_exists?
|
87
|
+
|
88
|
+
def lang_node_exists?( pageNode, lang )
|
89
|
+
langNode = pageNode.find {|child| child['lang'] == lang }
|
90
|
+
return !langNode.nil?
|
91
|
+
end
|
92
|
+
|
93
|
+
def get_lang_node( node, lang = node['lang'] )
|
94
|
+
node = node.parent unless node['page:basename']
|
95
|
+
langNode = node.find {|child| child['lang'] == lang} ||
|
96
|
+
node.find {|child| child['lang'] == Webgen::Plugin['Configuration']['lang']}
|
97
|
+
if langNode.nil?
|
98
|
+
langNode = node.children[0]
|
99
|
+
self.logger.warn do
|
100
|
+
"No input file in language '#{lang}' nor the default language (#{Webgen::Plugin['Configuration']['lang']}) found," +
|
101
|
+
"using first available input file for <#{node['title']}>"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
langNode
|
105
|
+
end
|
106
|
+
|
107
|
+
#######
|
108
|
+
private
|
109
|
+
#######
|
110
|
+
|
111
|
+
def create_node_internally( data, analysed, parent )
|
112
|
+
pageNodeExisted = get_page_node( analysed.baseName, parent )
|
113
|
+
pageNode = pageNodeExisted || PageNode.new( parent, analysed.baseName )
|
114
|
+
|
115
|
+
lang = data['lang'] || analysed.lang
|
116
|
+
|
117
|
+
if lang_node_exists?( pageNode, lang )
|
118
|
+
pageNodeExisted = false
|
119
|
+
logger.warn do
|
120
|
+
"Two input files in the same language for one page, " + \
|
121
|
+
"using <#{get_lang_node( pageNode, lang ).recursive_value( 'src' )}> " + \
|
122
|
+
"instead of <#{analysed.srcName}>"
|
123
|
+
end
|
124
|
+
else
|
125
|
+
node = Node.new( pageNode )
|
126
|
+
node.metainfo = data
|
127
|
+
node['src'] = analysed.srcName
|
128
|
+
node['dest'] = analysed.urlName
|
129
|
+
node['lang'] ||= analysed.lang
|
130
|
+
node['title'] ||= analysed.title
|
131
|
+
node['menuOrder'] ||= analysed.menuOrder
|
132
|
+
node['processor'] = self
|
133
|
+
pageNode.add_child( node )
|
134
|
+
end
|
135
|
+
|
136
|
+
return ( pageNodeExisted ? nil : pageNode )
|
137
|
+
end
|
138
|
+
|
139
|
+
def parse_data( data, srcName )
|
140
|
+
options = {}
|
141
|
+
blocks = data.split( /^---\s*$/ )
|
142
|
+
if blocks.length > 0
|
143
|
+
if blocks[0] == ''
|
144
|
+
begin
|
145
|
+
options = YAML::load( blocks[1] )
|
146
|
+
rescue ArgumentError => x
|
147
|
+
self.logger.error { "Error parsing options for file <#{srcName}>: #{x.message}" }
|
148
|
+
end
|
149
|
+
blocks[0..1] = []
|
150
|
+
end
|
151
|
+
blocks.each {|b| b.gsub!( /^(\\+)(---\s*)$/ ) {|m| "\\" * ($1.length / 2) + $2 } }
|
152
|
+
(options['blocks'] ||= [{'name'=>'content', 'format'=>get_param( 'defaultContentFormat' )}]).each do |blockdata|
|
153
|
+
self.logger.debug { "Block '#{blockdata['name']}' formatted using '#{blockdata['format']}'" }
|
154
|
+
options[blockdata['name']] = @formats[blockdata['format']].format_content( blocks.shift || '' )
|
155
|
+
end
|
156
|
+
end
|
157
|
+
options
|
158
|
+
end
|
159
|
+
|
160
|
+
def analyse_file_name( srcName )
|
161
|
+
matchData = /^(?:(\d+)\.)?([^.]*?)(?:\.(\w\w))?\.(.*)$/.match( srcName )
|
162
|
+
analysed = OpenStruct.new
|
163
|
+
|
164
|
+
self.logger.info { "Using default language for file <#{srcName}>" } if matchData[3].nil?
|
165
|
+
analysed.lang = matchData[3] || Webgen::Plugin['Configuration']['lang']
|
166
|
+
analysed.baseName = matchData[2] + '.html'
|
167
|
+
analysed.srcName = srcName
|
168
|
+
langPart = ( !get_param( 'defaultLangInFilename' ) && Webgen::Plugin['Configuration']['lang'] == analysed.lang ? '' : '.' + analysed.lang )
|
169
|
+
analysed.urlName = matchData[2] + langPart + '.html'
|
170
|
+
analysed.menuOrder = matchData[1].to_i
|
171
|
+
analysed.title = matchData[2].tr('_-', ' ').capitalize
|
172
|
+
|
173
|
+
self.logger.debug { analysed.inspect }
|
174
|
+
|
175
|
+
analysed
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
179
|
+
|
180
|
+
end
|
181
|
+
|
182
|
+
|
183
|
+
module ContentHandlers
|
184
|
+
|
185
|
+
class ContentHandler < Webgen::Plugin
|
186
|
+
|
187
|
+
VIRTUAL = true
|
188
|
+
|
189
|
+
summary "Base class for all page file content handlers"
|
190
|
+
|
191
|
+
# Register the format specified by a subclass.
|
192
|
+
def register_format( fmt )
|
193
|
+
self.logger.info { "Registering class #{self.class.name} for formatting '#{fmt}'" }
|
194
|
+
Webgen::Plugin['PageHandler'].formats[fmt] = self
|
195
|
+
end
|
196
|
+
|
197
|
+
# Format the given +content+. Should be overridden in subclass!
|
198
|
+
def format_content( content )
|
199
|
+
self.logger.error { "Invalid content format specified, copying source verbatim!" }
|
200
|
+
content
|
201
|
+
end
|
202
|
+
|
203
|
+
end
|
204
|
+
|
205
|
+
end
|