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,247 @@
|
|
|
1
|
+
#
|
|
2
|
+
#--
|
|
3
|
+
#
|
|
4
|
+
# $Id: tags.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 'yaml'
|
|
24
|
+
|
|
25
|
+
module Tags
|
|
26
|
+
|
|
27
|
+
# This is the main class for tags. Tag plugins can register themselves by adding a new key:value
|
|
28
|
+
# pair to +tags+. The key has to be the name of the tag as specified in the page description files
|
|
29
|
+
# and the value is the plugin object itself. When the content is parsed and a tag is
|
|
30
|
+
# encountered, the registered plugin for the tag is called. If no plugin for a tag is registered
|
|
31
|
+
# but a default plugin is, the default plugin is called. Otherwise an error is raised.
|
|
32
|
+
#
|
|
33
|
+
# The default plugin can be registered by using the special key <tt>:default</tt>.
|
|
34
|
+
class Tags < Webgen::Plugin
|
|
35
|
+
|
|
36
|
+
summary "Super plugin for handling tags"
|
|
37
|
+
|
|
38
|
+
# Tag plugins should add an entry to this hash.
|
|
39
|
+
attr_reader :tags
|
|
40
|
+
|
|
41
|
+
def initialize
|
|
42
|
+
@tags = Hash.new
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Substitutes all references to tags in the string +content+. The +node+ parameter specifies the
|
|
46
|
+
# tree node the content of which is used. The +refNode+ parameter specifies relative to which
|
|
47
|
+
# all references should be resolved.
|
|
48
|
+
def substitute_tags( content, node, refNode )
|
|
49
|
+
if !content.kind_of?( String )
|
|
50
|
+
self.logger.error { "The content in <#{refNode.recursive_value( 'src' )}> is not a string, but a #{content.class.name}" }
|
|
51
|
+
content = content.to_s
|
|
52
|
+
end
|
|
53
|
+
return replace_tags( content ) do |tag, data|
|
|
54
|
+
self.logger.info { "Replacing tag #{tag} with data '#{data}' in <#{node.recursive_value( 'dest' )}>" }
|
|
55
|
+
processor = get_tag_processor( tag )
|
|
56
|
+
begin
|
|
57
|
+
processor.set_tag_config( YAML::load( "--- #{data}" ), refNode )
|
|
58
|
+
rescue ArgumentError => e
|
|
59
|
+
self.logger.error { "Could parse the data '#{data}' for tag #{tag} in <#{node.recursive_value( 'dest' )}>: #{e.message}" }
|
|
60
|
+
end
|
|
61
|
+
output = processor.process_tag( tag, node, refNode )
|
|
62
|
+
processor.reset_tag_config
|
|
63
|
+
output = substitute_tags( output, node, node ) if processor.processOutput
|
|
64
|
+
output
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
#######
|
|
69
|
+
private
|
|
70
|
+
#######
|
|
71
|
+
|
|
72
|
+
# Scans the +content+ for tags. If a tag is found, the block is called which needs to return the
|
|
73
|
+
# value for the given tag. The changed content is returned.
|
|
74
|
+
def replace_tags( content ) # :yields: tag, data
|
|
75
|
+
offset = 0;
|
|
76
|
+
while index = content.index( /(\\*)\{(\w+):/, offset )
|
|
77
|
+
bracketCount = 1;
|
|
78
|
+
length = $1.length + 1;
|
|
79
|
+
tag = $2
|
|
80
|
+
content[(index + length)..-1].each_byte do |char|
|
|
81
|
+
length += 1
|
|
82
|
+
bracketCount += 1 if char == ?{
|
|
83
|
+
bracketCount -= 1 if char == ?}
|
|
84
|
+
break if bracketCount == 0
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
if bracketCount > 0
|
|
88
|
+
self.logger.error { "Unbalanced curly brackets!!!" }
|
|
89
|
+
newContent = content[index, length]
|
|
90
|
+
else
|
|
91
|
+
newContent = "\\"* ( $1.length / 2 )
|
|
92
|
+
if $1.length % 2 == 1
|
|
93
|
+
newContent += content[index + $1.length, length - $1.length]
|
|
94
|
+
else
|
|
95
|
+
tagHeaderLength = $1.length + tag.length + 2
|
|
96
|
+
realContent = content[index + tagHeaderLength, length - tagHeaderLength - 1]
|
|
97
|
+
newContent += yield( tag, realContent )
|
|
98
|
+
end
|
|
99
|
+
content[index, length] = newContent
|
|
100
|
+
end
|
|
101
|
+
offset = index + newContent.length
|
|
102
|
+
end
|
|
103
|
+
content
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
# Returns the tag processor for +tag+ or throws an error if +tag+ is unkown.
|
|
108
|
+
def get_tag_processor( tag )
|
|
109
|
+
if @tags.has_key?( tag )
|
|
110
|
+
return @tags[tag]
|
|
111
|
+
elsif @tags.has_key?( :default )
|
|
112
|
+
return @tags[:default]
|
|
113
|
+
else
|
|
114
|
+
self.logger.error { "No tag processor for tag '#{tag}' found" }
|
|
115
|
+
return DefaultTag.new
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
# Base class for all tag plugins. The base class provides a default mechanism for retrieving
|
|
123
|
+
# configuration data from either the configuration file or the tag itself.
|
|
124
|
+
class DefaultTag < Webgen::Plugin
|
|
125
|
+
|
|
126
|
+
VIRTUAL = true
|
|
127
|
+
|
|
128
|
+
summary "Base class for all tag plugins"
|
|
129
|
+
depends_on "Tags"
|
|
130
|
+
|
|
131
|
+
# +true+, if the output should be processed again
|
|
132
|
+
attr_reader :processOutput
|
|
133
|
+
|
|
134
|
+
def initialize
|
|
135
|
+
@processOutput = true
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# Set the parameter +param+ as mandatory. The parameter +default+ specifies, if this parameter
|
|
139
|
+
# should be the default mandatory parameter. If only a String is supplied in a tag, its value
|
|
140
|
+
# will be assigned to the default mandatory parameter. There *should* be only one default
|
|
141
|
+
# mandatory parameter.
|
|
142
|
+
def self.set_mandatory( param, default = false )
|
|
143
|
+
if Webgen::Plugin.config[self.name].params.nil? || !Webgen::Plugin.config[self.name].params.has_key?( param )
|
|
144
|
+
self.logger.error { "Cannot set parameter #{param} as mandatory as this parameter does not exist for #{self.name}" }
|
|
145
|
+
else
|
|
146
|
+
Webgen::Plugin.config[self.name].params[param].mandatory = true
|
|
147
|
+
Webgen::Plugin.config[self.name].params[param].mandatoryDefault = default
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# Register +tag+ at the Tags plugin.
|
|
152
|
+
def register_tag( tag )
|
|
153
|
+
Webgen::Plugin['Tags'].tags[tag] = self
|
|
154
|
+
Webgen::Plugin.config[self.class.name].tag = tag
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Set the configuration parameters for the next #process_tag call. The configuration, if
|
|
158
|
+
# specified, is taken from the tag itself.
|
|
159
|
+
def set_tag_config( config, node )
|
|
160
|
+
@curConfig = {}
|
|
161
|
+
case config
|
|
162
|
+
when Hash
|
|
163
|
+
set_cur_config( config, node )
|
|
164
|
+
|
|
165
|
+
when String
|
|
166
|
+
set_default_mandatory_param( config )
|
|
167
|
+
|
|
168
|
+
when NilClass
|
|
169
|
+
if has_mandatory_params?
|
|
170
|
+
self.logger.error { "Mandatory parameters for tag '#{self.class.name}' in <#{node.recursive_value( 'src' )}> not specified" }
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
else
|
|
174
|
+
self.logger.error { "Invalid parameter for tag '#{self.class.name}' in <#{node.recursive_value( 'src' )}>" }
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
unless all_mandatory_params_set?
|
|
178
|
+
self.logger.error { "Not all mandatory parameters for tag '#{self.class.name}' in <#{node.recursive_value( 'src' )}> set" }
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
# Resets the tag configuration data.
|
|
184
|
+
def reset_tag_config
|
|
185
|
+
@curConfig = {}
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
# Default implementation for processing a tag.
|
|
190
|
+
#
|
|
191
|
+
# Has to be overridden by the subclass!!!
|
|
192
|
+
def process_tag( tag, node, refNode )
|
|
193
|
+
''
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
#######
|
|
197
|
+
private
|
|
198
|
+
#######
|
|
199
|
+
|
|
200
|
+
# Set the current configuration taking values from +config+ which has to be a Hash.
|
|
201
|
+
def set_cur_config( config, node )
|
|
202
|
+
config.each do |key, value|
|
|
203
|
+
if has_param?( key )
|
|
204
|
+
@curConfig[key] = value
|
|
205
|
+
self.logger.debug { "Setting parameter '#{key}' for tag '#{self.class.name}' in <#{node.recursive_value( 'src' )}>" }
|
|
206
|
+
else
|
|
207
|
+
self.logger.warn { "Invalid parameter '#{key}' for tag '#{self.class.name}' in <#{node.recursive_value( 'src' )}>" }
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
# Set the default mandatory parameter.
|
|
213
|
+
def set_default_mandatory_param( value )
|
|
214
|
+
data = Webgen::Plugin.config[self.class.name]
|
|
215
|
+
key = data.params.detect {|k,v| v.mandatoryDefault} unless data.params.nil?
|
|
216
|
+
if key.nil?
|
|
217
|
+
self.logger.error { "Default mandatory parameter not specified for tag '#{self.class.name}'"}
|
|
218
|
+
else
|
|
219
|
+
@curConfig[key[0]] = value
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
# Check if this tag has mandatory parameters.
|
|
224
|
+
def has_mandatory_params?
|
|
225
|
+
data = Webgen::Plugin.config[self.class.name]
|
|
226
|
+
!data.params.nil? && data.params.any? {|k,v| v.mandatory }
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
# Check if all mandatory parameters have been set
|
|
230
|
+
def all_mandatory_params_set?
|
|
231
|
+
params = Webgen::Plugin.config[self.class.name].params
|
|
232
|
+
( params.nil? ? true : params.all? { |k,v| !v.mandatory || @curConfig.has_key?( k ) } )
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
# Retrieves the parameter value for +name+. The value is taken from the current tag if the
|
|
236
|
+
# parameter is specified there or the default value set in #register_config_value is used.
|
|
237
|
+
def get_param( name )
|
|
238
|
+
if !@curConfig.nil? && @curConfig.has_key?( name )
|
|
239
|
+
return @curConfig[name]
|
|
240
|
+
else
|
|
241
|
+
super( name )
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#
|
|
2
|
+
#--
|
|
3
|
+
#
|
|
4
|
+
# $Id: wikilink.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/tags/tags'
|
|
24
|
+
|
|
25
|
+
module Tags
|
|
26
|
+
|
|
27
|
+
class WikiLinkTag < DefaultTag
|
|
28
|
+
|
|
29
|
+
summary 'Adds a link to wiki page'
|
|
30
|
+
depends_on 'Tags'
|
|
31
|
+
add_param 'title', nil, 'The title of the link. If it is not specified, the title of the current page is used.'
|
|
32
|
+
add_param 'rootURL', '/wiki/wiki.pl?', 'The root URL for the wiki link, ie. the path to the wiki CGI.'
|
|
33
|
+
add_param 'relURL', nil, 'The relativ URL for the wiki link (the varying part that is appended to rootURL). ' \
|
|
34
|
+
'If it is not specified, the title of the current page is used.'
|
|
35
|
+
add_param 'convertSpaces', true, 'True if spaces in the relative URL should be converted to underscores.'
|
|
36
|
+
|
|
37
|
+
def initialize
|
|
38
|
+
super
|
|
39
|
+
register_tag( 'wikilink' )
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def process_tag( tag, node, refNode )
|
|
43
|
+
"<a href=\"#{get_link( node )}\">#{get_param( 'title' ) || node['title']}</a>"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
#######
|
|
47
|
+
private
|
|
48
|
+
#######
|
|
49
|
+
|
|
50
|
+
def get_link( node )
|
|
51
|
+
link = get_param( 'rootURL' )
|
|
52
|
+
relURL = get_param( 'relURL' ) || node['title']
|
|
53
|
+
link + (get_param( 'convertSpaces' ) ? relURL.tr( ' ', '_' ) : relURL )
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#
|
|
2
|
+
#--
|
|
3
|
+
#
|
|
4
|
+
# $Id: treewalker.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
|
+
# All plugins which count as "tree walkers" should be put into this module.
|
|
25
|
+
module TreeWalkers
|
|
26
|
+
|
|
27
|
+
# This is the main class for tree walkers. A tree walker plugin can register itself with this class
|
|
28
|
+
# so that it is called when the main class' #execute method is called.
|
|
29
|
+
class TreeWalker < Webgen::Plugin
|
|
30
|
+
|
|
31
|
+
summary "Super plugin for transforming the data tree"
|
|
32
|
+
|
|
33
|
+
attr_reader :walkers
|
|
34
|
+
|
|
35
|
+
def initialize
|
|
36
|
+
@walkers = []
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Uses either all registered walkers or the specified +walker+. Walks the +tree+ for each walker
|
|
40
|
+
# separately.
|
|
41
|
+
def execute( tree, walker = nil )
|
|
42
|
+
walkers = ( walker.nil? ? @walkers : [walker] )
|
|
43
|
+
walkers.each do |walker|
|
|
44
|
+
walk_tree( tree, walker, 0 )
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
#######
|
|
49
|
+
private
|
|
50
|
+
#######
|
|
51
|
+
|
|
52
|
+
# Walks the tree and calls the plugin +walker+ for each and every node.
|
|
53
|
+
def walk_tree( node, walker, level )
|
|
54
|
+
walker.handle_node( node, level )
|
|
55
|
+
node.each do |child|
|
|
56
|
+
walk_tree( child, walker, level + 1 )
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
# Prints the whole tree of read files if the log level is at least DEBUG.
|
|
64
|
+
class DebugTreePrinter < Webgen::Plugin
|
|
65
|
+
|
|
66
|
+
summary "Prints out the information in the tree for debug purposes."
|
|
67
|
+
depends_on 'TreeWalker'
|
|
68
|
+
|
|
69
|
+
def initialize
|
|
70
|
+
Webgen::Plugin['TreeWalker'].walkers << self
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def handle_node( node, level )
|
|
74
|
+
self.logger.debug do
|
|
75
|
+
" "*level << "\\_ "*(level > 0 ? 1 : 0) << (node['virtual'] ? "[V]" : "") << "#{node['title']}: #{node['src']} -> #{node['dest']}"
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
end
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
#
|
|
2
|
+
#--
|
|
3
|
+
#
|
|
4
|
+
# $Id: webgen.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 'optparse'
|
|
24
|
+
require 'webgen/configuration'
|
|
25
|
+
|
|
26
|
+
module Webgen
|
|
27
|
+
|
|
28
|
+
class Color
|
|
29
|
+
|
|
30
|
+
@@colors = {:bold => [0, 1], :green => [0, 32], :lblue => [1, 34], :lred => [1, 31], :reset => [0, 0]}
|
|
31
|
+
|
|
32
|
+
def Color.colorify
|
|
33
|
+
@@colors.each do |color, values|
|
|
34
|
+
module_eval <<-EOF
|
|
35
|
+
def Color.#{color.to_s}
|
|
36
|
+
"\e[#{values[0]};#{values[1]}m"
|
|
37
|
+
end
|
|
38
|
+
EOF
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def Color.method_missing( id )
|
|
43
|
+
''
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
class WebgenMain
|
|
49
|
+
|
|
50
|
+
def main( cmdOptions )
|
|
51
|
+
Color.colorify if $stdout.isatty
|
|
52
|
+
main, data = parse_options( cmdOptions )
|
|
53
|
+
|
|
54
|
+
Plugin['Configuration'].init_all( data )
|
|
55
|
+
main.call
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def parse_options( cmdOptions )
|
|
60
|
+
config = Plugin['Configuration']
|
|
61
|
+
data = {}
|
|
62
|
+
main = method( :runMain )
|
|
63
|
+
|
|
64
|
+
opts = OptionParser.new do |opts|
|
|
65
|
+
opts.summary_width = 25
|
|
66
|
+
opts.summary_indent = ' '
|
|
67
|
+
|
|
68
|
+
opts.banner = "Usage: webgen [options]\n#{Webgen::SUMMARY}"
|
|
69
|
+
|
|
70
|
+
opts.separator ""
|
|
71
|
+
opts.separator "Configuration options:"
|
|
72
|
+
|
|
73
|
+
opts.on( "--config-file FILE", "-C", String, "The configuration file which should be used" ) { |data['configfile']| }
|
|
74
|
+
opts.on( "--source-dir DIR", "-S", String, "The directory from where the files are read" ) { |data['srcDirectory']| }
|
|
75
|
+
opts.on( "--output-dir DIR", "-O", String, "The directory where the output should go" ) { |data['outDirectory']| }
|
|
76
|
+
opts.on( "--verbosity LEVEL", "-V", Integer, "The verbosity level" ) { |data['verbosityLevel']| }
|
|
77
|
+
opts.on( "--[no-]logfile", "-L", "Log to file webgen.log" ) { |logfile| config.set_log_dev_to_logfile if logfile }
|
|
78
|
+
|
|
79
|
+
opts.separator ""
|
|
80
|
+
opts.separator "Other options:"
|
|
81
|
+
|
|
82
|
+
opts.on( "--list-plugins", "-p", "List all the plugins and information about them" ) { main = method( :runListPlugins ) }
|
|
83
|
+
opts.on( "--list-configuration", "-c", "List all plugin configuration parameters" ) { main = method( :runListConfiguration ) }
|
|
84
|
+
opts.on_tail( "--help", "Display this help screen" ) { puts opts; exit }
|
|
85
|
+
opts.on_tail( "--version", "-v", "Show version" ) do
|
|
86
|
+
puts "Webgen #{Webgen::VERSION}"
|
|
87
|
+
exit
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
begin
|
|
92
|
+
opts.parse!( cmdOptions )
|
|
93
|
+
rescue RuntimeError => e
|
|
94
|
+
print "Error:\n" << e.reason << ": " << e.args.join(", ") << "\n\n"
|
|
95
|
+
puts opts
|
|
96
|
+
exit
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
[main, data]
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def runMain
|
|
104
|
+
logger.info "Starting Webgen..."
|
|
105
|
+
|
|
106
|
+
# load all the files in src dir and build tree
|
|
107
|
+
tree = Plugin['FileHandler'].build_tree
|
|
108
|
+
|
|
109
|
+
# execute tree transformer plugins
|
|
110
|
+
Plugin['TreeWalker'].execute( tree ) unless tree.nil?
|
|
111
|
+
|
|
112
|
+
# generate output files
|
|
113
|
+
Plugin['FileHandler'].write_tree( tree ) unless tree.nil?
|
|
114
|
+
|
|
115
|
+
logger.info "Webgen finished"
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def runListPlugins
|
|
120
|
+
print "List of loaded plugins:\n"
|
|
121
|
+
|
|
122
|
+
headers = Hash.new {|h,k| h[k] = k.gsub(/([A-Z])/, ' \1').strip}
|
|
123
|
+
|
|
124
|
+
ljustlength = 30 + Color.green.length + Color.reset.length
|
|
125
|
+
header = ''
|
|
126
|
+
Plugin.config.sort { |a, b| a[0] <=> b[0] }.each do |classname, data|
|
|
127
|
+
newHeader = headers[classname[/^.*?(?=::)/]]
|
|
128
|
+
unless newHeader == header
|
|
129
|
+
print "\n #{Color.bold}#{newHeader}#{Color.reset}:\n";
|
|
130
|
+
header = newHeader
|
|
131
|
+
end
|
|
132
|
+
print " - #{Color.green}#{data.plugin}#{Color.reset}:".ljust(ljustlength) +"#{data.summary}\n"
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def runListConfiguration
|
|
138
|
+
print "List of configuration parameters:\n\n"
|
|
139
|
+
ljustlength = 20 + Color.green.length + Color.reset.length
|
|
140
|
+
Plugin.config.sort.each do |classname, data|
|
|
141
|
+
next if data.params.nil?
|
|
142
|
+
print " #{Color.bold}#{data.plugin}#{Color.reset}:\n"
|
|
143
|
+
data.params.sort.each do |key, item|
|
|
144
|
+
print " #{Color.green}Parameter:#{Color.reset}".ljust(ljustlength)
|
|
145
|
+
puts Color.lred + item.name + Color.reset + " = " + Color.lblue + item.value.inspect + Color.reset + " (" + item.default.inspect + ")"
|
|
146
|
+
puts " #{Color.green}Description:#{Color.reset}".ljust(ljustlength) + item.description
|
|
147
|
+
print "\n"
|
|
148
|
+
end
|
|
149
|
+
print "\n"
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
end
|