Wiki2Go 1.15.1 → 1.16.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/DebugWiki2GoServer.rb +10 -0
- data/bin/{Wiki2Go_make_repository.rb → Wiki2Go_make_cvs_repository.rb} +1 -1
- data/lib/Web2Go/WebrickRequest.rb +1 -1
- data/lib/Web2Go/WebrickResponse.rb +3 -3
- data/lib/Wiki2Go/BlackList.rb +24 -11
- data/lib/Wiki2Go/DotGraphics.rb +45 -5
- data/lib/Wiki2Go/FileStorage.rb +8 -2
- data/lib/Wiki2Go/GreyList.rb +38 -22
- data/lib/Wiki2Go/Install/make_repository.rb +351 -36
- data/lib/Wiki2Go/Install/make_site.rb +17 -8
- data/lib/Wiki2Go/Install/site/ruby.css +18 -0
- data/lib/Wiki2Go/Install/templates/admin.htm +11 -0
- data/lib/Wiki2Go/Install/templates/admin_pages/commit_site.txt +21 -0
- data/lib/Wiki2Go/Install/templates/admin_pages/edit.txt +33 -0
- data/lib/Wiki2Go/Install/templates/admin_pages/editfiles.txt +33 -0
- data/lib/Wiki2Go/Install/templates/admin_pages/greylist.txt +19 -37
- data/lib/Wiki2Go/Install/templates/admin_pages/show_log.txt +21 -0
- data/lib/Wiki2Go/Install/templates/admin_pages/update_conflicts.txt +38 -0
- data/lib/Wiki2Go/Install/templates/admin_pages/update_site.txt +49 -0
- data/lib/Wiki2Go/Install/wiki/ruby.css +18 -0
- data/lib/Wiki2Go/LineFormatter.rb +504 -0
- data/lib/Wiki2Go/Page.rb +50 -18
- data/lib/Wiki2Go/PublicWikiConfig.rb +34 -11
- data/lib/Wiki2Go/Server.rb +13 -2
- data/lib/Wiki2Go/SpamFilter.rb +27 -8
- data/lib/Wiki2Go/SyntaxHighlighter.rb +41 -0
- data/lib/Wiki2Go/Web.rb +0 -3
- data/lib/Wiki2Go/WebrickServlet.rb +2 -0
- data/lib/Wiki2Go/Wiki2Go.rb +19 -8
- data/lib/Wiki2Go/Wiki2GoConfig.rb +125 -18
- data/lib/Wiki2Go/Wiki2GoServlet.rb +32 -21
- data/lib/Wiki2Go/WikiFormatter.rb +55 -468
- data/lib/Wiki2Go/cgi/secure/log_rss +21 -0
- data/test/All.rb +21 -0
- data/test/TestBlackList.rb +82 -0
- data/test/TestConfig.rb +205 -0
- data/test/TestDot.rb +109 -0
- data/test/TestFormatter.rb +491 -0
- data/test/TestInstall.rb +120 -0
- data/test/TestLineFormatter.rb +553 -0
- data/test/TestMail.rb +29 -0
- data/test/TestRSS.rb +183 -0
- data/test/TestRepositoryMaker.rb +101 -0
- data/test/TestServer.rb +65 -0
- data/test/TestSpamFilter.rb +130 -0
- data/test/TestStorage.rb +212 -0
- data/test/TestSyntaxHighlighter.rb +41 -0
- data/test/TestUnitTestFiles.rb +27 -0
- data/test/TestUrlFinder.rb +39 -0
- data/test/TestWeb.rb +197 -0
- data/test/TestWeb2Go.rb +90 -0
- data/test/TestWiki2Go.rb +184 -0
- data/test/TestWiki2GoServlet.rb +747 -0
- data/test/UnitTestFiles.rb +102 -0
- data/test/Wiki2GoConfigForTest.rb +93 -0
- data/test/checksite.rb +56 -0
- data/test/testdata/changes.txt +4 -0
- data/test/testdata/expected_changes.html +93 -0
- data/test/testdata/expected_edit.html +105 -0
- data/test/testdata/expected_full_rss.xml +29 -0
- data/test/testdata/expected_header_rss.xml +13 -0
- data/test/testdata/expected_out.html +97 -0
- data/test/testdata/expected_put.html +99 -0
- data/test/testdata/expected_save.html +66 -0
- data/test/testdata/expected_savehtml.html +66 -0
- data/test/testdata/expected_search.html +67 -0
- data/test/testdata/expected_upload.html +69 -0
- data/test/testdata/expected_versions.html +85 -0
- data/test/testdata/expected_view.html +97 -0
- data/test/testdata/site/html/Xpday/rss.xml +103 -0
- data/test/testdata/templates/Test/child.htm +2 -0
- data/test/testdata/templates/Test/grandchild.htm +1 -0
- data/test/testdata/templates/Test/master.htm +3 -0
- data/test/testdata/texts/Test/FrontPage.txt +7 -0
- data/test/testdata/texts/Test/NewPage.txt +3 -0
- data/test/testdata/texts/Test/Subdir/Subpage.txt +1 -0
- data/test/testdata/texts/Test/empty.txt +3 -0
- data/test/testdata/texts/Test/test.txt +3 -0
- data/test/testdata/texts/Xpday/FrontPage.txt +36 -0
- data/test/testdata/texts/Xpday/Page.txt +3 -0
- data/test/testdata/texts/Xpday/VersionedPage.log +14 -0
- data/test/testdata/texts/Xpday/VersionedPage.txt +3 -0
- data/test/testdata/texts/Xpday/empty.log +3482 -0
- data/test/testdata/texts/Xpday/empty.txt +4 -0
- data/test/testdata/texts/Xpday/test.log +9425 -0
- data/test/testdata/texts/Xpday/test.txt +5 -0
- data/test/testdata/texts/whitelist.txt +1 -0
- metadata +85 -5
- data/lib/Wiki2Go/Install/templates/admin_pages/update.txt +0 -13
@@ -6,7 +6,7 @@ require 'optparse'
|
|
6
6
|
require "uri"
|
7
7
|
|
8
8
|
require 'rubygems'
|
9
|
-
WIKI2GO_VERSION = '1.
|
9
|
+
WIKI2GO_VERSION = '1.16.0'
|
10
10
|
require_gem "Wiki2Go","~>#{WIKI2GO_VERSION}"
|
11
11
|
|
12
12
|
require 'Wiki2Go/PublicWikiConfig'
|
@@ -115,7 +115,7 @@ module Wiki2Go
|
|
115
115
|
set_owner(configuration.directory,configuration.user)
|
116
116
|
File.umask(oldmask)
|
117
117
|
puts "Installed."
|
118
|
-
puts "Include #{configuration.directory}/config/site.conf in your Apache configuration"
|
118
|
+
puts "Include '#{configuration.directory}/config/site.conf' in your Apache configuration"
|
119
119
|
puts " and restart Apache to activate your wiki."
|
120
120
|
end
|
121
121
|
end
|
@@ -316,14 +316,11 @@ module Wiki2Go
|
|
316
316
|
template = <<-TEMPLATE_END
|
317
317
|
#!/usr/bin/env ruby
|
318
318
|
|
319
|
-
#
|
319
|
+
# Select which version of Wiki2Go is used.
|
320
320
|
require 'rubygems'
|
321
321
|
require_gem "Wiki2Go","~>#{WIKI2GO_VERSION}"
|
322
322
|
require "Wiki2Go/#{baseconfig}"
|
323
323
|
|
324
|
-
# Uncomment if you want to add 'dot' graphics to your page (see http://www.graphviz.org)
|
325
|
-
# require 'Wiki2Go/DotGraphics'
|
326
|
-
|
327
324
|
class CgiOptions < Wiki2Go::#{baseconfig}
|
328
325
|
|
329
326
|
def initialize
|
@@ -353,8 +350,19 @@ class CgiOptions < Wiki2Go::#{baseconfig}
|
|
353
350
|
@subsite = '#{config.subsite}'
|
354
351
|
|
355
352
|
# Uncomment if you want to add 'dot' graphics to your page (see http://www.graphviz.org)
|
356
|
-
# The path must point to the 'dot'
|
357
|
-
#
|
353
|
+
# The path must point to the 'dot' executable
|
354
|
+
# enable_dot_graphics('/usr/bin/')
|
355
|
+
|
356
|
+
# Uncomment if you want to add Ruby syntax highlighting
|
357
|
+
# You also need to include the html/ruby.css stylesheet in your template
|
358
|
+
# enable_syntax_highlighting
|
359
|
+
|
360
|
+
# If you want to enable CVS commit/update support for your wiki, uncomment the following line
|
361
|
+
# and fill in the CVSROOT and the name of the module as parameters
|
362
|
+
# The CVS repository and module must exist and the webserver user must have commit access to it
|
363
|
+
# You need to have the rscm 0.3 gem installed
|
364
|
+
# use_repository('MYCVSROOT','mymodule')
|
365
|
+
|
358
366
|
end
|
359
367
|
|
360
368
|
end
|
@@ -393,6 +401,7 @@ TEMPLATE_END
|
|
393
401
|
mkdir_p(File.join(dest,'html'),{ :mode => 0775})
|
394
402
|
source = File.join(config.source_dir,'site','.')
|
395
403
|
cp_r source,dest
|
404
|
+
Dir["#{dest}/**/CVS"].each { |name| rm_r name }
|
396
405
|
end
|
397
406
|
|
398
407
|
def Install.do_make_wiki(config)
|
@@ -0,0 +1,18 @@
|
|
1
|
+
.ruby .normal {}
|
2
|
+
.ruby .comment { color: #005; font-style: italic; }
|
3
|
+
.ruby .keyword { color: #A00; font-weight: bold; }
|
4
|
+
.ruby .method { color: #077; }
|
5
|
+
.ruby .class { color: #074; }
|
6
|
+
.ruby .module { color: #050; }
|
7
|
+
.ruby .punct { color: #447; font-weight: bold; }
|
8
|
+
.ruby .symbol { color: #099; }
|
9
|
+
.ruby .string { color: #944; background: #FFE; }
|
10
|
+
.ruby .char { color: #F07; }
|
11
|
+
.ruby .ident { color: #004; }
|
12
|
+
.ruby .constant { color: #07F; }
|
13
|
+
.ruby .regex { color: #B66; background: #FEF; }
|
14
|
+
.ruby .number { color: #F99; }
|
15
|
+
.ruby .attribute { color: #7BB; }
|
16
|
+
.ruby .global { color: #7FB; }
|
17
|
+
.ruby .expr { color: #227; }
|
18
|
+
.ruby .escape { color: #277; }
|
@@ -32,6 +32,7 @@
|
|
32
32
|
<div class="menuheading"><%= formatter.admin_link("","Home")%></div>
|
33
33
|
<ul>
|
34
34
|
<li><%= formatter.admin_link("regenerate","Regenerate HTML")%></li>
|
35
|
+
<li><%= formatter.admin_link("editfiles","Edit Files")%></li>
|
35
36
|
<li><%= formatter.admin_link("passwords","Passwords")%></li>
|
36
37
|
</ul>
|
37
38
|
<div class="menuheading">SPAM filter</div>
|
@@ -39,6 +40,16 @@
|
|
39
40
|
<li><%= formatter.admin_link("greylist","Greylist")%></li>
|
40
41
|
<li><%= formatter.admin_link("update_blacklist","Update Blacklist")%></li>
|
41
42
|
</ul>
|
43
|
+
<div class="menuheading">Repository</div>
|
44
|
+
<ul>
|
45
|
+
<li><%= formatter.admin_link("update_site","Update Site")%></li>
|
46
|
+
<li><%= formatter.admin_link("commit_site","Commit Site")%></li>
|
47
|
+
<li><%= formatter.admin_link("update_conflicts","Update Conflicts")%></li>
|
48
|
+
</ul>
|
49
|
+
<div class="menuheading">Logs</div>
|
50
|
+
<ul>
|
51
|
+
<li><%= formatter.admin_link("show_log","Show Log")%></li>
|
52
|
+
</ul>
|
42
53
|
</TD>
|
43
54
|
<TD width="100%" valign="top">$BODY$</TD>
|
44
55
|
</TR>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<%
|
2
|
+
output = ''
|
3
|
+
|
4
|
+
doit = @request.parameter('update',nil)
|
5
|
+
comment = @request.parameter('comment','no comment')
|
6
|
+
|
7
|
+
if doit then
|
8
|
+
commit_log = @config.commit_to_repository(comment)
|
9
|
+
commit_log = commit_log.collect { |line| CGI::escapeHTML(line) }
|
10
|
+
output = commit_log.join("<br>#{$/}")
|
11
|
+
end
|
12
|
+
%>
|
13
|
+
|
14
|
+
<h3>Commit Site</h3>
|
15
|
+
<form action="<%= File.join(@web.script_prefix,'admin','commit_site')%>" method="get">
|
16
|
+
Comment: <input name="comment" value="">
|
17
|
+
<button type="submit" name="update" value="update">
|
18
|
+
Commit site changes to repository
|
19
|
+
</button>
|
20
|
+
</form>
|
21
|
+
<%= output %>
|
@@ -0,0 +1,33 @@
|
|
1
|
+
<%
|
2
|
+
|
3
|
+
file = @request.parameter('file',nil)
|
4
|
+
|
5
|
+
content = 'EMPTY'
|
6
|
+
if !file.nil? then
|
7
|
+
filename = File.join(@config.root_directory,file)
|
8
|
+
if File.exists?(filename)
|
9
|
+
content = IO::read(filename)
|
10
|
+
end
|
11
|
+
|
12
|
+
doit = @request.parameter('update',nil)
|
13
|
+
if !doit.nil? then
|
14
|
+
content = @request.parameter('text',nil)
|
15
|
+
if !content.nil? then
|
16
|
+
File::open(filename,File::CREAT|File::WRONLY) do |f|
|
17
|
+
f.puts content
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
%>
|
24
|
+
<h3>Edit File</h3>
|
25
|
+
<form action="<%= File.join(@web.script_prefix,'admin','edit')%>" method="post">
|
26
|
+
<input type="hidden" name="file" value="<%= file %>">
|
27
|
+
<textarea name="text" rows="35" cols="96"><%= content %></textarea><br>
|
28
|
+
<button type="submit" name="update" value="update">
|
29
|
+
Save file
|
30
|
+
</button> <input type="reset" value=" Undo changes ">
|
31
|
+
</form>
|
32
|
+
|
33
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
<%
|
2
|
+
|
3
|
+
def edit_file(filename)
|
4
|
+
"<a href=\"#{ File.join(@web.script_prefix,'admin','edit')}?file=#{CGI::escape(filename)}\">#{filename}</a>"
|
5
|
+
end
|
6
|
+
%>
|
7
|
+
|
8
|
+
<%
|
9
|
+
all_files = []
|
10
|
+
|
11
|
+
Dir.chdir(@config.root_directory)
|
12
|
+
files = Dir.glob('**/*')
|
13
|
+
|
14
|
+
all_files = files.find_all { |name| File.file?(File.join(@config.root_directory,name)) && name !~ /CVS/ }.sort
|
15
|
+
all_files = all_files.reject do |name|
|
16
|
+
name =~ /\.png$/ || name =~ /\.jpg$/ || name =~ /\.gif$/ || name =~ /\.pdf$/ || name =~ /\.xls$/
|
17
|
+
end
|
18
|
+
|
19
|
+
odd = false
|
20
|
+
%>
|
21
|
+
|
22
|
+
<h3>Site files</h3>
|
23
|
+
|
24
|
+
<% if all_files.length > 0 then %>
|
25
|
+
<table class="topiclist">
|
26
|
+
<% all_files.each do |file|
|
27
|
+
style = (odd ? "odd" : "even")
|
28
|
+
odd = !odd
|
29
|
+
%>
|
30
|
+
<tr class="<%= style%>"><td><%= edit_file(file) %></td></tr>
|
31
|
+
<% end %>
|
32
|
+
</table>
|
33
|
+
<% end %>
|
@@ -1,44 +1,24 @@
|
|
1
1
|
<%
|
2
|
+
require 'Wiki2Go/SpamFilter'
|
2
3
|
|
3
|
-
|
4
|
-
exists = File.exists?(greylist)
|
4
|
+
spamfilter = Wiki2Go::SpamFilter.new(@config)
|
5
5
|
|
6
|
-
|
6
|
+
author = @request.parameter('author','').strip
|
7
|
+
url = @request.parameter('url','').strip
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
lines = f.readlines
|
12
|
-
end
|
9
|
+
if !@request.parameter('accept').nil? && !author.empty? then
|
10
|
+
@config.log("Accept #{author} and url '#{url}'")
|
11
|
+
spamfilter.remove_from_greylist(author,url)
|
13
12
|
end
|
14
13
|
|
15
|
-
if
|
16
|
-
@config.
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
nil
|
21
|
-
else
|
22
|
-
line
|
23
|
-
end
|
24
|
-
}
|
25
|
-
lines = lines.compact
|
26
|
-
pwdfile = File.open(greylist,'w') do |f|
|
27
|
-
f.puts lines
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
if !@request.parameter('blacklist').nil? && !selected_line.empty? then
|
32
|
-
user , url = selected_line.split(' ')
|
33
|
-
blacklist = @config.storage.load_blacklist('user')
|
34
|
-
blacklist.add(user)
|
35
|
-
@config.storage.save_list(blacklist)
|
36
|
-
|
37
|
-
blacklist = @config.storage.load_blacklist('url')
|
38
|
-
blacklist.add(url.gsub(/\\\./,'.'))
|
39
|
-
@config.storage.save_list(blacklist)
|
14
|
+
if !@request.parameter('blacklist').nil? && !author.empty? then
|
15
|
+
@config.errorlog("Blacklist user '#{author}' and URL '#{url}'")
|
16
|
+
spamfilter.remove_from_greylist(author,url)
|
17
|
+
spamfilter.blacklist_user(author)
|
18
|
+
spamfilter.blacklist_url(url)
|
40
19
|
end
|
41
20
|
|
21
|
+
supects = spamfilter.greylist_suspects
|
42
22
|
|
43
23
|
%>
|
44
24
|
<h3>Manage greylist</h3>
|
@@ -46,10 +26,10 @@ end
|
|
46
26
|
<tr><th>Name</th><th>URL</th><th> </th><th> </th></tr>
|
47
27
|
<%
|
48
28
|
odd = false
|
49
|
-
|
29
|
+
supects.each do |suspect|
|
50
30
|
style = (odd ? "odd" : "even")
|
51
31
|
odd = !odd
|
52
|
-
name,url =
|
32
|
+
name,url = suspect.user,suspect.url
|
53
33
|
clean_url = 'http' + url.gsub(/\\\./,'.')
|
54
34
|
%>
|
55
35
|
<tr class="<%= style%>">
|
@@ -58,12 +38,14 @@ end
|
|
58
38
|
<td>
|
59
39
|
<form action="<%= File.join(@web.script_prefix,'admin','greylist')%>" method="GET">
|
60
40
|
<input type="submit" name="accept" value="Accept">
|
61
|
-
<input type="hidden" name="
|
41
|
+
<input type="hidden" name="author" value="<%= name %>">
|
42
|
+
<input type="hidden" name="url" value="<%= clean_url %>">
|
62
43
|
</form>
|
63
44
|
</td>
|
64
45
|
<td>
|
65
46
|
<form action="<%= File.join(@web.script_prefix,'admin','greylist')%>" method="GET">
|
66
|
-
<input type="hidden" name="
|
47
|
+
<input type="hidden" name="author" value="<%= name %>">
|
48
|
+
<input type="hidden" name="url" value="<%= clean_url %>">
|
67
49
|
<input type="submit" name="blacklist" value="Blacklist">
|
68
50
|
</form>
|
69
51
|
</td>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<%
|
2
|
+
output = ''
|
3
|
+
|
4
|
+
doit = @request.parameter('show',nil)
|
5
|
+
|
6
|
+
if doit then
|
7
|
+
logfile = @config.logfile
|
8
|
+
File.open(logfile,File::RDONLY) do |f|
|
9
|
+
output = f.read
|
10
|
+
end
|
11
|
+
end
|
12
|
+
%>
|
13
|
+
|
14
|
+
<h3>View log</h3>
|
15
|
+
<form action="<%= File.join(@web.script_prefix,'admin','show_log')%>" method="get">
|
16
|
+
<button type="submit" name="show" value="show">
|
17
|
+
Show logfile
|
18
|
+
</button>
|
19
|
+
</form>
|
20
|
+
<%= CGI::escapeHTML(output).gsub(/\n/,"<br>\n") %>
|
21
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
<%
|
2
|
+
|
3
|
+
def edit_file(filename)
|
4
|
+
"<a href=\"#{ File.join(@web.script_prefix,'admin','edit')}?file=#{CGI::escape(filename)}\">#{filename}</a>"
|
5
|
+
end
|
6
|
+
|
7
|
+
def contains_conflict_marker(name)
|
8
|
+
content = IO::read(File.join(@config.root_directory,name))
|
9
|
+
return content =~ /<{7,7}/ && content =~ />{7,7}/ && content =~ /={7,7}/
|
10
|
+
end
|
11
|
+
%>
|
12
|
+
|
13
|
+
<%
|
14
|
+
clashed = []
|
15
|
+
|
16
|
+
Dir.chdir(@config.root_directory)
|
17
|
+
files = Dir.glob('**/*')
|
18
|
+
|
19
|
+
all_files = files.find_all { |name| File.file?(File.join(@config.root_directory,name)) && name !~ /CVS/ }
|
20
|
+
|
21
|
+
|
22
|
+
clashed = all_files.find_all {|name| contains_conflict_marker(name) }.sort
|
23
|
+
odd = false
|
24
|
+
%>
|
25
|
+
|
26
|
+
<h3>Update Conflicts</h3>
|
27
|
+
|
28
|
+
<% if clashed.length > 0 then %>
|
29
|
+
<hr>
|
30
|
+
<table class="topiclist"><caption>Clashed</caption>
|
31
|
+
<% clashed.each do |file|
|
32
|
+
style = (odd ? "odd" : "even")
|
33
|
+
odd = !odd
|
34
|
+
%>
|
35
|
+
<tr class="<%= style%>"><td><%= edit_file(file) %></td></tr>
|
36
|
+
<% end %>
|
37
|
+
</table>
|
38
|
+
<% end %>
|
@@ -0,0 +1,49 @@
|
|
1
|
+
<%
|
2
|
+
output = ''
|
3
|
+
|
4
|
+
doit = @request.parameter('update',nil)
|
5
|
+
|
6
|
+
updated = []
|
7
|
+
clashed = []
|
8
|
+
if doit then
|
9
|
+
updated,clashed = @config.update_from_repository
|
10
|
+
end
|
11
|
+
|
12
|
+
def edit_file(filename)
|
13
|
+
"<a href=\"#{ File.join(@web.script_prefix,'admin','edit')}?file=#{CGI::escape(filename)}\">#{filename}</a>"
|
14
|
+
end
|
15
|
+
|
16
|
+
odd = false
|
17
|
+
|
18
|
+
%>
|
19
|
+
|
20
|
+
<h3>Update Site</h3>
|
21
|
+
<form action="<%= File.join(@web.script_prefix,'admin','update_site')%>" method="get">
|
22
|
+
<button type="submit" name="update" value="update">
|
23
|
+
Update the site from repository
|
24
|
+
</button>
|
25
|
+
</form>
|
26
|
+
|
27
|
+
<% if updated.length > 0 then %>
|
28
|
+
<hr>
|
29
|
+
<table class="topiclist"><caption>Updated</caption>
|
30
|
+
<% updated.each do |file|
|
31
|
+
style = (odd ? "odd" : "even")
|
32
|
+
odd = !odd
|
33
|
+
%>
|
34
|
+
<tr class="<%= style %>"><td><%= edit_file(file) %></td></tr>
|
35
|
+
<% end %>
|
36
|
+
</table>
|
37
|
+
<% end %>
|
38
|
+
|
39
|
+
<% if clashed.length > 0 then %>
|
40
|
+
<hr>
|
41
|
+
<table class="topiclist"><caption>Clashed</caption>
|
42
|
+
<% clashed.each do |file|
|
43
|
+
style = (odd ? "odd" : "even")
|
44
|
+
odd = !odd
|
45
|
+
%>
|
46
|
+
<tr class="<%= style%>"><td><%= edit_file(file) %></td></tr>
|
47
|
+
<% end %>
|
48
|
+
</table>
|
49
|
+
<% end %>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
.ruby .normal {}
|
2
|
+
.ruby .comment { color: #005; font-style: italic; }
|
3
|
+
.ruby .keyword { color: #A00; font-weight: bold; }
|
4
|
+
.ruby .method { color: #077; }
|
5
|
+
.ruby .class { color: #074; }
|
6
|
+
.ruby .module { color: #050; }
|
7
|
+
.ruby .punct { color: #447; font-weight: bold; }
|
8
|
+
.ruby .symbol { color: #099; }
|
9
|
+
.ruby .string { color: #944; background: #FFE; }
|
10
|
+
.ruby .char { color: #F07; }
|
11
|
+
.ruby .ident { color: #004; }
|
12
|
+
.ruby .constant { color: #07F; }
|
13
|
+
.ruby .regex { color: #B66; background: #FEF; }
|
14
|
+
.ruby .number { color: #F99; }
|
15
|
+
.ruby .attribute { color: #7BB; }
|
16
|
+
.ruby .global { color: #7FB; }
|
17
|
+
.ruby .expr { color: #227; }
|
18
|
+
.ruby .escape { color: #277; }
|
@@ -0,0 +1,504 @@
|
|
1
|
+
|
2
|
+
#!/usr/bin/ruby
|
3
|
+
|
4
|
+
require 'erb'
|
5
|
+
require 'cgi'
|
6
|
+
require 'English'
|
7
|
+
|
8
|
+
module Wiki2Go
|
9
|
+
|
10
|
+
class LineFormatter
|
11
|
+
|
12
|
+
attr_reader :config
|
13
|
+
|
14
|
+
def initialize(web,storage,config,generate_html,editable)
|
15
|
+
@web = web
|
16
|
+
@storage = storage
|
17
|
+
@config = config
|
18
|
+
@in_table = false
|
19
|
+
@bullets = Array.new
|
20
|
+
@pre_line = ""
|
21
|
+
@post_line = ""
|
22
|
+
@generate_html = generate_html
|
23
|
+
@editable = editable
|
24
|
+
@absolute_urls = false
|
25
|
+
end
|
26
|
+
|
27
|
+
public
|
28
|
+
|
29
|
+
def format_line(line)
|
30
|
+
@added_bullets = false
|
31
|
+
line = escape_wiki_markers(line)
|
32
|
+
line = format_wiki_markup(line)
|
33
|
+
line = format_table(line)
|
34
|
+
line = remove_markers(line)
|
35
|
+
if !@added_bullets then
|
36
|
+
emit_bullets
|
37
|
+
end
|
38
|
+
|
39
|
+
return formatted_output(line)
|
40
|
+
end
|
41
|
+
|
42
|
+
def formatting_done
|
43
|
+
emit_bullets
|
44
|
+
@pre_line
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
def absolute_url
|
49
|
+
return @web.base_url + view_page_url(@web.name,@web.current_page)
|
50
|
+
end
|
51
|
+
|
52
|
+
def absolute_url_of_topic(topic)
|
53
|
+
return @web.base_url + view_page_url(@web.name,topic)
|
54
|
+
end
|
55
|
+
|
56
|
+
def edit_link(subwiki,page,name)
|
57
|
+
if @editable then
|
58
|
+
return name + edit_this_link(subwiki,page,"?")
|
59
|
+
else
|
60
|
+
return name
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def edit_this_link(subwiki,page,name)
|
65
|
+
if @editable then
|
66
|
+
return "<a href=\"#{join(@web.script_prefix,"edit"+@web.script_extension,subwiki,page)}\">#{name}</a>"
|
67
|
+
else
|
68
|
+
return ""
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def save_this_link(subwiki,page)
|
73
|
+
if @editable then
|
74
|
+
return join(@web.script_prefix,"save"+@web.script_extension,subwiki,page)
|
75
|
+
else
|
76
|
+
return page
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def verb_url(verb)
|
81
|
+
return join(@web.script_prefix,verb+@web.script_extension,@web.name,@web.current_page)
|
82
|
+
end
|
83
|
+
|
84
|
+
def removespam_url(user)
|
85
|
+
return join(@web.script_prefix,'removespam'+@web.script_extension,@web.name,'') + '?user=' + user
|
86
|
+
end
|
87
|
+
|
88
|
+
def version_url(page)
|
89
|
+
return join(@web.script_prefix,'versions'+@web.script_extension,@web.name,page)
|
90
|
+
end
|
91
|
+
|
92
|
+
def save_url
|
93
|
+
verb_url('save')
|
94
|
+
end
|
95
|
+
|
96
|
+
def search_link(desc)
|
97
|
+
return "<a href=\"#{search_url + "?text="+desc}\">#{desc}</a>"
|
98
|
+
end
|
99
|
+
|
100
|
+
def search_link2(desc,name)
|
101
|
+
return "<a href=\"#{search_url + "?text="+desc}\">#{name}</a>"
|
102
|
+
end
|
103
|
+
|
104
|
+
def search_url
|
105
|
+
return join(@web.script_prefix,'search'+@web.script_extension,@web.name)
|
106
|
+
end
|
107
|
+
|
108
|
+
def changes_url
|
109
|
+
if @generate_html then
|
110
|
+
return join(@web.name,'recent_changes.html')
|
111
|
+
else
|
112
|
+
return join(@web.script_prefix,'changes'+@web.script_extension,@web.name)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def changes_link(desc)
|
117
|
+
return "<a href=\"#{changes_url}\">#{desc}</a>"
|
118
|
+
end
|
119
|
+
|
120
|
+
def view_page_url(subwiki,page)
|
121
|
+
if @generate_html then
|
122
|
+
return join(subwiki,page + ".html")
|
123
|
+
else
|
124
|
+
return join(@web.script_prefix,"view" + @web.script_extension,subwiki,page)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def view_url(subwiki,page)
|
129
|
+
if @absolute_urls then
|
130
|
+
return File.join(@web.base_url,view_page_url(subwiki,page))
|
131
|
+
else
|
132
|
+
return view_page_url(subwiki,page)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
|
137
|
+
|
138
|
+
def view_link(subwiki,page,name)
|
139
|
+
if subwiki == @web.name then
|
140
|
+
return "<a href=\"#{view_url(subwiki,page)}\">#{name}</a>"
|
141
|
+
else
|
142
|
+
return "<a href=\"#{view_url(subwiki,page)}\">#{subwiki}:#{name}</a>"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def perform_link(subwiki,page,name)
|
147
|
+
if @storage.exists?(File.join(subwiki,page)) then
|
148
|
+
url = join(@web.script_prefix,"view" + @web.script_extension,subwiki,page)
|
149
|
+
if subwiki == @web.name then
|
150
|
+
return "<a href=\"#{url}\">#{name}</a>"
|
151
|
+
else
|
152
|
+
return "<a href=\"#{url}\">#{subwiki}:#{name}</a>"
|
153
|
+
end
|
154
|
+
else
|
155
|
+
return edit_link(subwiki,page,name)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def view_version_link(subwiki,page,name,parameters=nil)
|
160
|
+
return "<a href=\"#{view_version_url(subwiki,page)+query_string(parameters)}\">#{name}</a>"
|
161
|
+
end
|
162
|
+
|
163
|
+
def view_version_url(subwiki,page)
|
164
|
+
return join(@web.script_prefix,"view" + @web.script_extension,subwiki,page)
|
165
|
+
end
|
166
|
+
|
167
|
+
def query_string(parameters)
|
168
|
+
return "" if parameters.nil?
|
169
|
+
return "?" + parameters.collect { |key,value| key + '=' + value}.sort.join('&')
|
170
|
+
end
|
171
|
+
|
172
|
+
def version_link(page,name)
|
173
|
+
return "<a href=\"#{version_url(page)}\">#{name}</a>"
|
174
|
+
end
|
175
|
+
|
176
|
+
def admin_link(page,name)
|
177
|
+
return "<a href=\"#{join(@web.script_prefix,'admin' + @web.script_extension,page)}\">#{name}</a>"
|
178
|
+
end
|
179
|
+
|
180
|
+
|
181
|
+
def redirect_url(url)
|
182
|
+
if @config.redirect_url?(@web,url) then
|
183
|
+
redirected_url = join(@web.script_prefix,"redirect",@web.name + "?url=" + CGI::escape(url) )
|
184
|
+
return redirected_url
|
185
|
+
else
|
186
|
+
return url
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def redirect_link(label,url)
|
191
|
+
if @config.redirect_url?(@web,url) then
|
192
|
+
redirected_url = redirect_url(url)
|
193
|
+
return "<a href=\"#{redirected_url}\" rel=\"nofollow\" target=\"_blank\">#{label}</a>"
|
194
|
+
else
|
195
|
+
return "<a href=\"#{url}\" target=\"_blank\">#{label}</a>"
|
196
|
+
end
|
197
|
+
|
198
|
+
end
|
199
|
+
|
200
|
+
|
201
|
+
def resource_url(name)
|
202
|
+
if @absolute_urls then
|
203
|
+
File.join(@web.base_url,'html',@web.name,name)
|
204
|
+
else
|
205
|
+
File.join('html',@web.name,name)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def encode_mail_to(addr)
|
210
|
+
|
211
|
+
addr =~ /(.*)@(.*)/ ;
|
212
|
+
name = $1 ;
|
213
|
+
site = $2 ;
|
214
|
+
|
215
|
+
return "<a href=\"#{view_url(@web.name,"MailFormattingRules")}\" onmouseover=\"this.href='mai' + 'lto:' + '#{name}' + '@' + '#{site}'\">#{name}</a>"
|
216
|
+
end
|
217
|
+
|
218
|
+
alias :encodeMailTo :encode_mail_to
|
219
|
+
|
220
|
+
private
|
221
|
+
|
222
|
+
|
223
|
+
def append(before,match,after)
|
224
|
+
result = ''
|
225
|
+
result += before if !before.nil?
|
226
|
+
result += match if !match.nil?
|
227
|
+
result += after if !after.nil?
|
228
|
+
result
|
229
|
+
end
|
230
|
+
|
231
|
+
def format_tag(text)
|
232
|
+
text = text.gsub(/"((http|ftp|gopher|news|https)\:[^"]*)"/) { externalUrl($1) }
|
233
|
+
|
234
|
+
return '<' + text + '>'
|
235
|
+
end
|
236
|
+
|
237
|
+
|
238
|
+
def format_wiki_markup(line)
|
239
|
+
if line =~ /^(.*)\{\!(.*)\!\}(.*)$/im then
|
240
|
+
before,match,after = $1,$2,$3
|
241
|
+
return append(format_wiki_markup(before),match,format_wiki_markup(after))
|
242
|
+
elsif line =~ /^(.*)<(\S.*)\>(.*)$/ then
|
243
|
+
before,match,after = $1,$2,$3
|
244
|
+
line = append(format_wiki_markup(before),escape_url_markers(format_tag(match)),format_wiki_markup(after))
|
245
|
+
elsif line =~ /^(.*)\{\%([^\}]*)\%\}(.*)$/ then
|
246
|
+
before,match,after = $1,$2,$3
|
247
|
+
line = append(format_wiki_markup(before),escape_url_markers(format_dynamic_link(match)),format_wiki_markup(after))
|
248
|
+
elsif line =~ /^(.*)\{([^\}]*)\}(.*)$/ then
|
249
|
+
before,match,after = $1,$2,$3
|
250
|
+
line = append(format_wiki_markup(before),escape_url_markers(format_forced_link(match)),format_wiki_markup(after))
|
251
|
+
elsif line =~ /^(.*)\%([^\%]*)\%(.*)$/ then
|
252
|
+
before,match,after = $1,$2,$3
|
253
|
+
line = append(format_wiki_markup(before),escape_url_markers(format_forced_link(match)),format_wiki_markup(after))
|
254
|
+
elsif line =~ /^(.*)((http|ftp|gopher|news|https)\:\/\/(\w|\/|\.|_|-|\?|\=|&|;|\~|#|,)+)(.*)$/ then
|
255
|
+
before,match,after = $1,$2,$5
|
256
|
+
line = append(format_wiki_markup(before),escape_url_markers(external_link(match)),format_wiki_markup(after))
|
257
|
+
elsif line =~ /^(.*)mailto\:([a-zA-Z0-9\-\_\.]+@[a-zA-Z0-9\-\_\.]+)(.*)$/ then
|
258
|
+
before,match,after = $1,$2,$3
|
259
|
+
line = append(format_wiki_markup(before),escape_url_markers(encode_mail_to(match)),format_wiki_markup(after))
|
260
|
+
else
|
261
|
+
line = format_brackets(line)
|
262
|
+
line = format_entities(line)
|
263
|
+
line = recognize_wiki_words(line)
|
264
|
+
end
|
265
|
+
line = format_bullets(line)
|
266
|
+
line = format_markup(line)
|
267
|
+
return line
|
268
|
+
end
|
269
|
+
|
270
|
+
def formatted_output(line)
|
271
|
+
output = @pre_line + line + @post_line
|
272
|
+
@pre_line = ""
|
273
|
+
@post_line = ""
|
274
|
+
return output
|
275
|
+
end
|
276
|
+
|
277
|
+
|
278
|
+
def escape_wiki_markers(line)
|
279
|
+
line = line.gsub(/%%/,"&percent;")
|
280
|
+
line = line.gsub(/\{\{/,"&openingbrace;")
|
281
|
+
line = line.gsub(/\}\}/,"&closingbrace;")
|
282
|
+
end
|
283
|
+
|
284
|
+
def escape_url_markers(line)
|
285
|
+
line = line.gsub(/%/ ,'&percent;')
|
286
|
+
line = line.gsub(/\{/,'&openingbrace;')
|
287
|
+
line = line.gsub(/\}/,'&closingbrace;')
|
288
|
+
line = line.gsub(/~/ ,'˜')
|
289
|
+
line = line.gsub(/\*/,'&asterisk;')
|
290
|
+
line = line.gsub(/_/ ,'&underscore;')
|
291
|
+
return line
|
292
|
+
end
|
293
|
+
|
294
|
+
def remove_markers(line)
|
295
|
+
line = line.gsub(/&percent;/,"%")
|
296
|
+
line = line.gsub(/&openingbrace;/,"{")
|
297
|
+
line = line.gsub(/&closingbrace;/,"}")
|
298
|
+
line = line.gsub(/˜/,"~")
|
299
|
+
line = line.gsub(/&asterisk;/,"*")
|
300
|
+
line = line.gsub(/&underscore;/,"_")
|
301
|
+
return line
|
302
|
+
end
|
303
|
+
|
304
|
+
|
305
|
+
def format_brackets(line)
|
306
|
+
line = line.gsub(/</,"<\;") ;
|
307
|
+
line = line.gsub(/>/,">\;") ;
|
308
|
+
return line
|
309
|
+
end
|
310
|
+
|
311
|
+
def format_entities(line)
|
312
|
+
line = line.gsub(/\~/,"˜") ;
|
313
|
+
line = line.gsub(/&(\w+)\;/,"~\\1\;") ;
|
314
|
+
line = line.gsub(/&(#\d+)\;/,"~\\1\;") ;
|
315
|
+
line = line.gsub(/&/,"&\;") ;
|
316
|
+
line = line.gsub(/~/,"&") ;
|
317
|
+
line = line.gsub(/\t/," ") ;
|
318
|
+
return line
|
319
|
+
end
|
320
|
+
|
321
|
+
def format_markup(line)
|
322
|
+
line = line.gsub(/\*\*([^\*]*)\*\*/,"<h2>\\1<\/h2>")
|
323
|
+
line = line.gsub(/\*([^\*]+)\*/,"<STRONG>\\1<\/STRONG>")
|
324
|
+
line = line.gsub(/\b_([^_]*)_/,"<EM>\\1<\/EM>")
|
325
|
+
line = line.gsub(/^---+/,"<hr>")
|
326
|
+
return line
|
327
|
+
end
|
328
|
+
|
329
|
+
def format_bullets(line)
|
330
|
+
line = line.gsub(/^([\s]{3,99})\*(.*)$/) { add_bullet($1,$2,'u') }
|
331
|
+
line = line.gsub(/^([\s]{3,99})(\d)+\.?(.*)$/) { add_bullet($1,$3,'o') }
|
332
|
+
return line
|
333
|
+
end
|
334
|
+
|
335
|
+
def format_table(line)
|
336
|
+
if @in_table then
|
337
|
+
replacement = "</table>"
|
338
|
+
else
|
339
|
+
replacement = '<table class="wikitable" >'
|
340
|
+
end
|
341
|
+
if line.gsub!(/^(\|-+\|)/,replacement) then
|
342
|
+
@in_table = ! @in_table
|
343
|
+
elsif line.gsub!(/^\|\((.+)\)-+\|/,'<table class="\1" >') then
|
344
|
+
@in_table = true
|
345
|
+
end
|
346
|
+
if @in_table then
|
347
|
+
line = line.gsub(/^\|/,"<tr><td>")
|
348
|
+
line = line.gsub(/\|\s*$/,"<\/td><\/tr>")
|
349
|
+
line = line.gsub(/\|/,"<\/td><td>")
|
350
|
+
end
|
351
|
+
return line
|
352
|
+
|
353
|
+
end
|
354
|
+
|
355
|
+
def recognize_wiki_words(line)
|
356
|
+
line = line.gsub(/(^|[^\w\.])([A-Z]+[a-z0-9]+[A-Z]+[a-zA-Z0-9]*)/) { $1 + internalLink($2) }
|
357
|
+
|
358
|
+
end
|
359
|
+
|
360
|
+
def external_link(url)
|
361
|
+
if url =~ /([^\/]+)\.(gif|jpg|jpeg|png)$/i then
|
362
|
+
alt = $1
|
363
|
+
return "<img src=\"#{url}\" alt=\"#{alt}\">"
|
364
|
+
else
|
365
|
+
return redirect_link(url,url)
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
def externalUrl(url)
|
370
|
+
return '"' + redirect_url(url) + (@config.redirect_url?(@web,url) ? '" rel="nofollow"' : '"') +' target="_blank"'
|
371
|
+
end
|
372
|
+
|
373
|
+
def format_forced_link(link)
|
374
|
+
if ! link.gsub!(/^([^%@]+)@(http[^%]+)$/) { labelLink($1,$2) } then
|
375
|
+
link.gsub!(/^(([^\%@]+)@)?(([^\%:]+):)?([^%]+)$/) { mega_link($2,$4,$5,@web.name) }
|
376
|
+
end
|
377
|
+
link
|
378
|
+
end
|
379
|
+
|
380
|
+
def format_dynamic_link(link)
|
381
|
+
return link.gsub(/^(([^\%@]+)@)?(([^\%:]+):)?([^%]+)$/) { dynamic_link($2,$4,$5,@web.name) }
|
382
|
+
end
|
383
|
+
|
384
|
+
def labelLink(label,url)
|
385
|
+
return redirect_link(label,url)
|
386
|
+
end
|
387
|
+
|
388
|
+
def internalLink(page)
|
389
|
+
return internalSubwikiNamedLink(@web.name,page,page)
|
390
|
+
end
|
391
|
+
|
392
|
+
def mega_link(name,subwiki,page,default_wiki)
|
393
|
+
name = page if name.nil? || name.empty?
|
394
|
+
subwiki = default_wiki if subwiki.nil? || subwiki.empty?
|
395
|
+
internalSubwikiNamedLink(subwiki,page,name)
|
396
|
+
end
|
397
|
+
|
398
|
+
def dynamic_link(name,subwiki,page,default_wiki)
|
399
|
+
name = page if name.nil? || name.empty?
|
400
|
+
subwiki = default_wiki if subwiki.nil? || subwiki.empty?
|
401
|
+
perform_link(subwiki,page+'.rbl',name)
|
402
|
+
end
|
403
|
+
|
404
|
+
def internalSubwikiNamedLink(subwiki,page,name)
|
405
|
+
if subwiki == "xpnl" then
|
406
|
+
return "<a href=\"http://www.xpnl.org/Wiki/#{page}\" target=\"_blank\">xpnl:#{page}</a>"
|
407
|
+
elsif subwiki == 'xpbe' then
|
408
|
+
return "<a href=\"http://wiki.xp.be/Xpbe/#{page}.html\" target=\"_blank\">xpbe:#{page}</a>"
|
409
|
+
elsif subwiki == "wiki" then
|
410
|
+
return "<a href=\"http://c2.com/cgi/wiki?#{page}\" target=\"_blank\">wiki:#{page}</a>"
|
411
|
+
elsif subwiki == "book" then
|
412
|
+
return "<a href=\"http://bookshelved.org/cgi-bin/wiki.pl?#{page}\" target=\"_blank\">book:#{page}</a>"
|
413
|
+
elsif subwiki == "wiki2go" then
|
414
|
+
return "<a href=\"http://wiki2go.nayima.be/Wiki2Go/#{page}.html\" target=\"_blank\">wiki2go:#{page}</a>"
|
415
|
+
elsif subwiki =~ /^isbn$/i then
|
416
|
+
name = "ISBN " + page if page == name
|
417
|
+
return "<a href=\"http://www.amazon.co.uk/exec/obidos/ASIN/#{page}/#{@config.amazon_affiliate}\" target=\"_blank\">#{name}</a>"
|
418
|
+
elsif page =~ /^isbn(.+)$/i then
|
419
|
+
name = "ISBN " + $1 if page == name
|
420
|
+
return "<a href=\"http://www.amazon.co.uk/exec/obidos/ASIN/#{$1}/#{@config.amazon_affiliate}\" target=\"_blank\">#{name}</a>"
|
421
|
+
elsif page =~ /\./ then
|
422
|
+
return resource_link(subwiki,page,name)
|
423
|
+
elsif @storage.exists?(File.join(subwiki,page)) then
|
424
|
+
return view_link(subwiki,page,name)
|
425
|
+
else
|
426
|
+
return edit_link(subwiki,page,name)
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
430
|
+
def resource_link(subwiki,page,name)
|
431
|
+
if page =~ /^(.+)\.(gif|jpg|jpeg|png)$/i then
|
432
|
+
filename = $1
|
433
|
+
alt_label = name
|
434
|
+
if page == name || url?(name) then
|
435
|
+
alt_label = filename
|
436
|
+
end
|
437
|
+
image_link = "<img src=\"#{resource_url(page)}\" border=0 alt=\"#{alt_label}\" >"
|
438
|
+
if url?(name) then
|
439
|
+
return redirect_link(image_link,name)
|
440
|
+
else
|
441
|
+
return image_link
|
442
|
+
end
|
443
|
+
elsif page =~ /^(.*)\.rbl$/i then
|
444
|
+
page_name = $1
|
445
|
+
if page == name then
|
446
|
+
name = page_name
|
447
|
+
end
|
448
|
+
return perform_link(subwiki,page,name)
|
449
|
+
elsif page =~ /^(.+)\.html?$/i then
|
450
|
+
return "<a href=\"#{resource_url(page)}\">#{name}</a>"
|
451
|
+
else
|
452
|
+
return "<a href=\"#{resource_url(page)}\" target=\"_blank\">#{name}</a>"
|
453
|
+
end
|
454
|
+
end
|
455
|
+
|
456
|
+
def add_bullet(prefix,text,code)
|
457
|
+
@added_bullets = true
|
458
|
+
depth = prefix.length / 3
|
459
|
+
result = ""
|
460
|
+
bullet_depth = @bullets.length
|
461
|
+
if depth > bullet_depth then
|
462
|
+
bullet_depth.upto(depth-1) do
|
463
|
+
result += "<#{code}l>"
|
464
|
+
@bullets.push(code)
|
465
|
+
end
|
466
|
+
elsif depth < bullet_depth then
|
467
|
+
bullet_depth.downto(depth+1) do
|
468
|
+
bullet = @bullets.pop
|
469
|
+
result += "</#{bullet}l>"
|
470
|
+
end
|
471
|
+
elsif @bullets.last != code then
|
472
|
+
bullet = @bullets.pop
|
473
|
+
result += "</#{bullet}l>"
|
474
|
+
result += "<#{code}l>"
|
475
|
+
@bullets.push(code)
|
476
|
+
end
|
477
|
+
return result + "<li>#{text}"
|
478
|
+
end
|
479
|
+
|
480
|
+
def emit_bullets
|
481
|
+
while ! @bullets.empty?
|
482
|
+
bullet = @bullets.pop
|
483
|
+
@pre_line += "</#{bullet}l>"
|
484
|
+
end
|
485
|
+
end
|
486
|
+
|
487
|
+
def join(*dirs)
|
488
|
+
result = ""
|
489
|
+
dirs.each do |name|
|
490
|
+
if !name.nil? and name.length > 0 then
|
491
|
+
result += '/' unless result.length == 0
|
492
|
+
result += name
|
493
|
+
end
|
494
|
+
end
|
495
|
+
return result.squeeze('/')
|
496
|
+
end
|
497
|
+
|
498
|
+
def url?(name)
|
499
|
+
name =~ /(http|ftp|gopher|news|https)\:(\w|\/|\.|_|-|\?|\=|&|;|\~|#|,)+/
|
500
|
+
end
|
501
|
+
|
502
|
+
end
|
503
|
+
|
504
|
+
end
|