webgen 0.3.0
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 +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
|