Wiki2Go 1.14.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.
Files changed (67) hide show
  1. data/bin/Wiki2GoServer.rb +11 -0
  2. data/bin/Wiki2Go_make_site.rb +10 -0
  3. data/bin/Wiki2Go_make_wiki.rb +10 -0
  4. data/bin/Wiki2Go_update_site.rb +10 -0
  5. data/lib/Web2Go/CGIRequest.rb +99 -0
  6. data/lib/Web2Go/CGIResponse.rb +64 -0
  7. data/lib/Web2Go/ERB_Interpreter.rb +47 -0
  8. data/lib/Web2Go/MockCookie.rb +17 -0
  9. data/lib/Web2Go/MockRequest.rb +131 -0
  10. data/lib/Web2Go/MockResponse.rb +35 -0
  11. data/lib/Web2Go/Web2Go.rb +0 -0
  12. data/lib/Web2Go/WebrickRequest.rb +124 -0
  13. data/lib/Web2Go/WebrickResponse.rb +50 -0
  14. data/lib/Wiki2Go.rb +2 -0
  15. data/lib/Wiki2Go/BlackList.rb +52 -0
  16. data/lib/Wiki2Go/DotGraphics.rb +69 -0
  17. data/lib/Wiki2Go/FileStorage.rb +267 -0
  18. data/lib/Wiki2Go/GreyList.rb +88 -0
  19. data/lib/Wiki2Go/Install/config/chonqed_blacklist.txt +4743 -0
  20. data/lib/Wiki2Go/Install/config/passwords +1 -0
  21. data/lib/Wiki2Go/Install/make_site.rb +515 -0
  22. data/lib/Wiki2Go/Install/site/error.html +77 -0
  23. data/lib/Wiki2Go/Install/site/html/admin.css +135 -0
  24. data/lib/Wiki2Go/Install/site/html/xml.gif +0 -0
  25. data/lib/Wiki2Go/Install/site/robots.txt +13 -0
  26. data/lib/Wiki2Go/Install/site/style.css +135 -0
  27. data/lib/Wiki2Go/Install/templates/admin.htm +48 -0
  28. data/lib/Wiki2Go/Install/templates/admin_pages/admin.txt +1 -0
  29. data/lib/Wiki2Go/Install/templates/admin_pages/greylist.txt +72 -0
  30. data/lib/Wiki2Go/Install/templates/admin_pages/passwords.txt +67 -0
  31. data/lib/Wiki2Go/Install/templates/admin_pages/regenerate.txt +26 -0
  32. data/lib/Wiki2Go/Install/templates/admin_pages/removespam.txt +19 -0
  33. data/lib/Wiki2Go/Install/templates/admin_pages/update.txt +13 -0
  34. data/lib/Wiki2Go/Install/templates/edit.htm +74 -0
  35. data/lib/Wiki2Go/Install/templates/pagelist.htm +82 -0
  36. data/lib/Wiki2Go/Install/templates/rss.xml +11 -0
  37. data/lib/Wiki2Go/Install/templates/versionlist.htm +84 -0
  38. data/lib/Wiki2Go/Install/templates/view.htm +72 -0
  39. data/lib/Wiki2Go/Install/wiki/style.css +135 -0
  40. data/lib/Wiki2Go/Page.rb +69 -0
  41. data/lib/Wiki2Go/PrivateWikiConfig.rb +27 -0
  42. data/lib/Wiki2Go/PublicWikiConfig.rb +52 -0
  43. data/lib/Wiki2Go/ReadWriteWikiConfig.rb +23 -0
  44. data/lib/Wiki2Go/Server.rb +94 -0
  45. data/lib/Wiki2Go/SpamFilter.rb +95 -0
  46. data/lib/Wiki2Go/UrlFinder.rb +26 -0
  47. data/lib/Wiki2Go/Web.rb +185 -0
  48. data/lib/Wiki2Go/WebrickServlet.rb +211 -0
  49. data/lib/Wiki2Go/WhiteList.rb +29 -0
  50. data/lib/Wiki2Go/Wiki2Go.rb +274 -0
  51. data/lib/Wiki2Go/Wiki2GoConfig.rb +144 -0
  52. data/lib/Wiki2Go/Wiki2GoServlet.rb +197 -0
  53. data/lib/Wiki2Go/WikiFormatter.rb +597 -0
  54. data/lib/Wiki2Go/WikiLogFile.rb +43 -0
  55. data/lib/Wiki2Go/cgi/changes.rb +20 -0
  56. data/lib/Wiki2Go/cgi/display.rb +20 -0
  57. data/lib/Wiki2Go/cgi/edit.rb +20 -0
  58. data/lib/Wiki2Go/cgi/redirect.rb +20 -0
  59. data/lib/Wiki2Go/cgi/save.rb +20 -0
  60. data/lib/Wiki2Go/cgi/search.rb +20 -0
  61. data/lib/Wiki2Go/cgi/secure/admin.rb +20 -0
  62. data/lib/Wiki2Go/cgi/secure/generate_static.rb +20 -0
  63. data/lib/Wiki2Go/cgi/secure/removespam.rb +20 -0
  64. data/lib/Wiki2Go/cgi/upload.rb +20 -0
  65. data/lib/Wiki2Go/cgi/versions.rb +20 -0
  66. data/lib/Wiki2Go/cgi/view.rb +20 -0
  67. metadata +113 -0
@@ -0,0 +1,597 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'erb'
4
+ require 'cgi'
5
+ require 'English'
6
+
7
+ module Wiki2Go
8
+
9
+ class PageContext
10
+ attr_reader :format
11
+ attr_reader :web
12
+ attr_reader :page
13
+ attr_reader :text
14
+ attr_reader :pages
15
+ attr_reader :searchtopic
16
+ attr_reader :config
17
+ attr_accessor :title
18
+
19
+ def initialize(config,formatter,text,page,web,pages,searchtopic,title)
20
+ @config = config
21
+ @format = formatter
22
+ @web = web
23
+ @page = page
24
+ @text = text
25
+ @pages = pages
26
+ @searchtopic = searchtopic
27
+ @title = title
28
+ end
29
+ end
30
+
31
+ class Formatter
32
+
33
+ def initialize(web,storage,config,generate_html,editable)
34
+ @web = web
35
+ @storage = storage
36
+ @config = config
37
+ @in_table = false
38
+ @bullets = Array.new
39
+ @pre_line = ""
40
+ @post_line = ""
41
+ @generate_html = generate_html
42
+ @editable = editable
43
+ end
44
+
45
+ public
46
+
47
+ def format_page_in_template(template,page)
48
+ formatted_page = format_page(page.content)
49
+ template = splice_variable_values(template,page,formatted_page)
50
+ erb = ERB.new(template)
51
+ context = PageContext.new(@config,self,formatted_page,page,@web,nil,nil,nil)
52
+ template = evaluate(erb,context)
53
+ return template
54
+ end
55
+
56
+ def format_pagelist_in_template(template,pages,searchtopic,title)
57
+ template = splice_web_values(template)
58
+ erb = ERB.new(template)
59
+ context = PageContext.new(@config,self,nil,nil,@web,pages,searchtopic,title)
60
+ template = evaluate(erb,context)
61
+ return template
62
+ end
63
+
64
+ def put_page_in_template(template,page)
65
+ formatted_page = page_text(page).gsub(/&/n, '&amp;').gsub(/\"/n, '&quot;').gsub(/>/n, '&gt;').gsub(/</n, '&lt;')
66
+
67
+ template = splice_variable_values(template,page,formatted_page)
68
+ erb = ERB.new(template)
69
+ context = PageContext.new(@config,self,formatted_page,page,@web,nil,nil,nil)
70
+ template = evaluate(erb,context)
71
+ return template
72
+ end
73
+
74
+ def format_page(content)
75
+ result = format_page_content(content)
76
+ emit_bullets
77
+ result += @pre_line
78
+ return format_empty_lines(result)
79
+ end
80
+
81
+ def format_line(line)
82
+ @added_bullets = false
83
+ line = format_wiki_markup(line)
84
+ if !@added_bullets then
85
+ emit_bullets
86
+ end
87
+
88
+ return formatted_output(line)
89
+ end
90
+
91
+ def generate_rss(template,changes)
92
+
93
+ template_after_items = <<-END_OF_AFTER_ITEMS_XML
94
+ </channel>
95
+ </rss>
96
+ END_OF_AFTER_ITEMS_XML
97
+
98
+ items = ""
99
+
100
+ changes.each do |page|
101
+ items = items + <<-END_OF_ITEMS
102
+ <item>
103
+ <title>#{page.name}</title>
104
+ <author>#{page.alias}</author>
105
+ <pubDate>#{page.lastmodified.strftime("%d %B %Y %H:%M GMT")}</pubDate>
106
+ <link>#{absolute_url_of_topic(page.title)}</link>
107
+ <guid isPermaLink="true">#{@web.name}/#{page.title}</guid>
108
+ <description><![CDATA[#{format_page(page.content).strip}]]></description>
109
+ </item>
110
+ END_OF_ITEMS
111
+ end
112
+
113
+ template = template + items + template_after_items
114
+
115
+ # We're using hard coded GMT, because %Z returns something strange
116
+ time = Time.new.gmtime.strftime("%d %B %Y %H:%M GMT")
117
+ template.gsub!(/\$DATE\$/, time)
118
+ template = splice_web_values(template)
119
+ return template
120
+ end
121
+
122
+ def absolute_url
123
+ return @web.base_url + view_url(@web.name,@web.current_page)
124
+ end
125
+
126
+ def absolute_url_of_topic(topic)
127
+ return @web.base_url + view_url(@web.name,topic)
128
+ end
129
+
130
+ def edit_link(subwiki,page,name)
131
+ if @editable then
132
+ return name + edit_this_link(subwiki,page,"?")
133
+ else
134
+ return name
135
+ end
136
+ end
137
+
138
+ def edit_this_link(subwiki,page,name)
139
+ if @editable then
140
+ return "<a href=\"#{join(@web.script_prefix,"edit"+@web.script_extension,subwiki,page)}\">#{name}</a>"
141
+ else
142
+ return ""
143
+ end
144
+ end
145
+
146
+ def save_this_link(subwiki,page)
147
+ if @editable then
148
+ return join(@web.script_prefix,"save"+@web.script_extension,subwiki,page)
149
+ else
150
+ return page
151
+ end
152
+ end
153
+
154
+ def verb_url(verb)
155
+ return join(@web.script_prefix,verb+@web.script_extension,@web.name,@web.current_page)
156
+ end
157
+
158
+ def removespam_url(user)
159
+ return join(@web.script_prefix,'removespam'+@web.script_extension,@web.name,'') + '?user=' + user
160
+ end
161
+
162
+ def version_url(page)
163
+ return join(@web.script_prefix,'versions'+@web.script_extension,@web.name,page)
164
+ end
165
+
166
+ def save_url
167
+ verb_url('save')
168
+ end
169
+
170
+ def search_link(desc)
171
+ return "<a href=\"#{search_url + "?text="+desc}\">#{desc}</a>"
172
+ end
173
+
174
+ def search_link2(desc,name)
175
+ return "<a href=\"#{search_url + "?text="+desc}\">#{name}</a>"
176
+ end
177
+
178
+ def search_url
179
+ return join(@web.script_prefix,'search'+@web.script_extension,@web.name)
180
+ end
181
+
182
+ def changes_url
183
+ return join(@web.script_prefix,'changes'+@web.script_extension,@web.name)
184
+ end
185
+
186
+ def changes_link(desc)
187
+ return "<a href=\"#{changes_url}\">#{desc}</a>"
188
+ end
189
+
190
+ def view_link(subwiki,page,name)
191
+ if subwiki == @web.name then
192
+ return "<a href=\"#{view_url(subwiki,page)}\">#{name}</a>"
193
+ else
194
+ return "<a href=\"#{view_url(subwiki,page)}\">#{subwiki}:#{name}</a>"
195
+ end
196
+ end
197
+
198
+ def view_version_link(subwiki,page,name,parameters=nil)
199
+ return "<a href=\"#{view_version_url(subwiki,page)+query_string(parameters)}\">#{name}</a>"
200
+ end
201
+
202
+ def view_version_url(subwiki,page)
203
+ return join(@web.script_prefix,"view" + @web.script_extension,subwiki,page)
204
+ end
205
+
206
+ def query_string(parameters)
207
+ return "" if parameters.nil?
208
+ return "?" + parameters.collect { |key,value| key + '=' + value}.sort.join('&')
209
+ end
210
+
211
+ def version_link(page,name)
212
+ return "<a href=\"#{version_url(page)}\">#{name}</a>"
213
+ end
214
+
215
+ def admin_link(page,name)
216
+ return "<a href=\"#{join(@web.script_prefix,'admin' + @web.script_extension,page)}\">#{name}</a>"
217
+ end
218
+
219
+
220
+ def redirect_url(url)
221
+ if @config.redirect_url?(@web,url) then
222
+ redirected_url = join(@web.script_prefix,"redirect",@web.name + "?url=" + CGI::escape(url) )
223
+ return redirected_url
224
+ else
225
+ return url
226
+ end
227
+ end
228
+
229
+ def redirect_link(label,url)
230
+ if @config.redirect_url?(@web,url) then
231
+ redirected_url = redirect_url(url)
232
+ return "<a href=\"#{redirected_url}\" rel=\"nofollow\" target=\"_blank\">#{label}</a>"
233
+ else
234
+ return "<a href=\"#{url}\" target=\"_blank\">#{label}</a>"
235
+ end
236
+
237
+ end
238
+
239
+ def view_url(subwiki,page)
240
+ if @generate_html then
241
+ return join(subwiki,page + ".html")
242
+ else
243
+ return join(@web.script_prefix,"view" + @web.script_extension,subwiki,page)
244
+ end
245
+ end
246
+
247
+ def resource_url(name)
248
+ File.join('html',@web.name,name)
249
+ end
250
+
251
+ def encode_mail_to(addr)
252
+
253
+ addr =~ /(.*)@(.*)/ ;
254
+ name = $1 ;
255
+ site = $2 ;
256
+
257
+ return "<a href=\"#{view_url(@web.name,"MailFormattingRules")}\" onmouseover=\"this.href='mai' + 'lto:' + '#{name}' + '&#64;' + '#{site}'\">#{name}</a>"
258
+ end
259
+
260
+ alias :encodeMailTo :encode_mail_to
261
+
262
+ private
263
+
264
+ def evaluate(erb,current)
265
+ Wiki2Go.module_eval{
266
+ erb.result(binding)
267
+ }
268
+ end
269
+
270
+ def format_empty_lines(content)
271
+ lines = content.split($/)
272
+ paragraph = ''
273
+ result = ''
274
+ lines.each do |line|
275
+ if line.strip.length == 0 then
276
+ paragraph = "<p>" + $/
277
+ else
278
+ result += $/ if result.length > 0
279
+ result += paragraph
280
+ paragraph = ''
281
+ result += line
282
+ end
283
+ end
284
+ result
285
+ end
286
+
287
+ def format_page_content(content)
288
+ if content.length == 0 then
289
+ return ''
290
+ elsif content =~ /^(.*)(<!--(.*)-->\n?)(.*)$/m then
291
+ before,match,after = $1,$2,$4
292
+ return append(format_page_content(before),format_comment(match),format_page_content(after))
293
+ elsif content =~ /^(.*)(<pre>(.*)<\/pre>)(.*)$/im then
294
+ before,match,after = $1,$2,$4
295
+ return append(format_page_content(before),match,format_page_content(after))
296
+ else
297
+ result = ''
298
+ lines = content.split($/)
299
+ if lines.length > 1 then
300
+ lines.each do |line|
301
+ result += format_line(line) + $/
302
+ end
303
+ else
304
+ result = format_line(content)
305
+ end
306
+ return result
307
+ end
308
+
309
+ end
310
+
311
+ def append(before,match,after)
312
+ result = ''
313
+ result += before if !before.nil?
314
+ result += match if !match.nil?
315
+ result += after if !after.nil?
316
+ result
317
+ end
318
+
319
+ def format_comment(text)
320
+ @config.preprocess(@web,text)
321
+ end
322
+
323
+ def format_tag(text)
324
+ text = text.gsub(/"((http|ftp|gopher|news|https)\:[^"]*)"/) { externalUrl($1) }
325
+
326
+ return '<' + text + '>'
327
+ end
328
+
329
+ def splice_variable_values(template, page, formatted_page)
330
+ template.gsub!(/\$TEXT\$/,formatted_page)
331
+ template.gsub!(/\$TOPIC\$/,page.title)
332
+ template.gsub!(/\$AUTHOR\$/,page.author)
333
+ template.gsub!(/\$LASTMODIFIED\$/,page.lastmodified.strftime("%d/%m/%Y"))
334
+ template.gsub!(/\$MESSAGE\$/,"")
335
+ template = splice_web_values(template)
336
+ return template
337
+ end
338
+
339
+ def splice_web_values(template)
340
+ template.gsub!(/\$WEB\$/,@web.name)
341
+ template.gsub!(/\$BASEURL\$/,@web.base_url)
342
+ template.gsub!(/\$HTMLURL\$/,@web.base_url)
343
+ template.gsub!(/\$SCRIPTURL\$/,@web.script_prefix)
344
+ template.gsub!(/\$MESSAGE\$/,"")
345
+ template.gsub!(/\$EXT\$/,@web.script_extension)
346
+ template = remove_markers(template)
347
+ return template
348
+ end
349
+
350
+ def format_wiki_markup(line)
351
+ if line =~ /^(.*)<(\S.*)\>(.*)$/ then
352
+ before,match,after = $1,$2,$3
353
+ return append(format_wiki_markup(before),format_tag(match),format_wiki_markup(after))
354
+ else
355
+ line = escape_wiki_markers(line)
356
+
357
+ if line =~ /^(.*)\{([^\}]*)\}(.*)$/ then
358
+ before,match,after = $1,$2,$3
359
+ line = append(format_wiki_markup(before),format_forced_link(match),format_wiki_markup(after))
360
+ elsif line =~ /^(.*)\%([^\%]*)\%(.*)$/ then
361
+ before,match,after = $1,$2,$3
362
+ line = append(format_wiki_markup(before),format_forced_link(match),format_wiki_markup(after))
363
+ elsif line =~ /^(.*)((http|ftp|gopher|news|https)\:(\w|\/|\.|_|-|\?|\=|&|;|\~|#|,)+)(.*)$/ then
364
+ before,match,after = $1,$2,$5
365
+ line = append(format_wiki_markup(before),external_link(match),format_wiki_markup(after))
366
+ elsif line =~ /^(.*)mailto\:([a-zA-Z0-9\-\_\.]+@[a-zA-Z0-9\-\_\.]+)(.*)$/ then
367
+ before,match,after = $1,$2,$3
368
+ line = append(format_wiki_markup(before),encode_mail_to(match),format_wiki_markup(after))
369
+ else
370
+ line = format_brackets(line)
371
+ line = format_entities(line)
372
+ line = format_bullets(line)
373
+ line = formatMarkup(line)
374
+ line = format_table(line)
375
+ line = recognize_wiki_words(line)
376
+ end
377
+ line = remove_markers(line)
378
+ return line
379
+ end
380
+ end
381
+
382
+ def formatted_output(line)
383
+ output = @pre_line + line + @post_line
384
+ @pre_line = ""
385
+ @post_line = ""
386
+ return output
387
+ end
388
+
389
+
390
+ def page_text(page)
391
+ result = ""
392
+ page.lines.each do |line|
393
+ result = result + line
394
+ end
395
+ return result
396
+ end
397
+
398
+ def escape_wiki_markers(line)
399
+ line = line.gsub(/%%/,"&percent;")
400
+ line = line.gsub(/\{\{/,"&openingbrace;")
401
+ line = line.gsub(/\}\}/,"&closingbrace;")
402
+ end
403
+
404
+ def remove_markers(line)
405
+ line = line.gsub(/&percent;/,"%")
406
+ line = line.gsub(/&openingbrace;/,"{")
407
+ line = line.gsub(/&closingbrace;/,"}")
408
+ line = line.gsub(/&tilde;/,"~")
409
+ line = line.gsub(/&asterisk;/,"*")
410
+ line = line.gsub(/&underscore;/,"_")
411
+ return line
412
+ end
413
+
414
+
415
+ def format_brackets(line)
416
+ line = line.gsub(/</,"&lt\;") ;
417
+ line = line.gsub(/>/,"&gt\;") ;
418
+ return line
419
+ end
420
+
421
+ def format_entities(line)
422
+ line = line.gsub(/\~/,"&tilde;") ;
423
+ line = line.gsub(/&(\w+)\;/,"~\\1\;") ;
424
+ line = line.gsub(/&(#\d+)\;/,"~\\1\;") ;
425
+ line = line.gsub(/&/,"&amp\;") ;
426
+ line = line.gsub(/~/,"&") ;
427
+ line = line.gsub(/\t/," ") ;
428
+ return line
429
+ end
430
+
431
+ def formatMarkup(line)
432
+ line = line.gsub(/\*\*([^\*]*)\*\*/,"<h2>\\1<\/h2>")
433
+ line = line.gsub(/\*([^\*]+)\*/,"<STRONG>\\1<\/STRONG>")
434
+ line = line.gsub(/\b_([^_]*)_/,"<EM>\\1<\/EM>")
435
+ line = line.gsub(/^---+/,"<hr>")
436
+ # line = line.gsub(/^\s*$/,"\n<p>")
437
+ return line
438
+ end
439
+
440
+ def format_bullets(line)
441
+ line = line.gsub(/^([\s]{3,99})\*(.*)$/) { add_bullet($1,$2,'u') }
442
+ line = line.gsub(/^([\s]{3,99})(\d)+\.?(.*)$/) { add_bullet($1,$3,'o') }
443
+ return line
444
+ end
445
+
446
+ def format_table(line)
447
+ if @in_table then
448
+ replacement = "</table>"
449
+ else
450
+ replacement = '<table class="wikitable" >'
451
+ end
452
+ if line.gsub!(/^(\|-+\|)/,replacement) then
453
+ @in_table = ! @in_table
454
+ elsif line.gsub!(/^\|\((.+)\)-+\|/,'<table class="\1" >') then
455
+ @in_table = true
456
+ end
457
+ if @in_table then
458
+ line = line.gsub(/^\|/,"<tr><td>")
459
+ line = line.gsub(/\|\s*$/,"<\/td><\/tr>")
460
+ line = line.gsub(/\|/,"<\/td><td>")
461
+ end
462
+ return line
463
+
464
+ end
465
+
466
+ def recognize_wiki_words(line)
467
+ line = line.gsub(/(^|[^\w\.])([A-Z]+[a-z0-9]+[A-Z]+[a-zA-Z0-9]*)/) { $1 + internalLink($2) }
468
+
469
+ end
470
+
471
+ def external_link(url)
472
+ if url =~ /([^\/]+)\.(gif|jpg|jpeg|png)$/i then
473
+ alt = $1
474
+ return "<img src=\"#{url}\" alt=\"#{alt}\">"
475
+ else
476
+ return redirect_link(url,url)
477
+ end
478
+ end
479
+
480
+ def externalUrl(url)
481
+ return '"' + redirect_url(url) + (@config.redirect_url?(@web,url) ? '" rel="nofollow"' : '"') +' target="_blank"'
482
+ end
483
+
484
+ def format_forced_link(link)
485
+ if ! link.gsub!(/^([^%@]+)@(http[^%]+)$/) { labelLink($1,$2) } then
486
+ link.gsub!(/^(([^\%@]+)@)?(([^\%:]+):)?([^%]+)$/) { mega_link($2,$4,$5,@web.name) }
487
+ end
488
+ link
489
+ end
490
+
491
+ def labelLink(label,url)
492
+ return redirect_link(label,url)
493
+ end
494
+
495
+ def internalLink(page)
496
+ return internalSubwikiNamedLink(@web.name,page,page)
497
+ end
498
+
499
+ def mega_link(name,subwiki,page,default_wiki)
500
+ name = page if name.nil? || name.empty?
501
+ subwiki = default_wiki if subwiki.nil? || subwiki.empty?
502
+ internalSubwikiNamedLink(subwiki,page,name)
503
+ end
504
+
505
+ def internalSubwikiNamedLink(subwiki,page,name)
506
+ if subwiki == "xpnl" then
507
+ return "<a href=\"http://www.xpnl.org/Wiki/#{page}\" target=\"_blank\">xpnl:#{page}</a>"
508
+ elsif subwiki == 'xpbe' then
509
+ return "<a href=\"http://wiki.xp.be/Xpbe/#{page}.html\" target=\"_blank\">xpbe:#{page}</a>"
510
+ elsif subwiki == "wiki" then
511
+ return "<a href=\"http://c2.com/cgi/wiki?#{page}\" target=\"_blank\">wiki:#{page}</a>"
512
+ elsif subwiki == "book" then
513
+ return "<a href=\"http://bookshelved.org/cgi-bin/wiki.pl?#{page}\" target=\"_blank\">book:#{page}</a>"
514
+ elsif subwiki == "wiki2go" then
515
+ return "<a href=\"http://wiki2go.nayima.be/Wiki2Go/#{page}.html\" target=\"_blank\">wiki2go:#{page}</a>"
516
+ elsif subwiki =~ /^isbn$/i then
517
+ name = "ISBN " + page if page == name
518
+ return "<a href=\"http://www.amazon.co.uk/exec/obidos/ASIN/#{page}/agilesystems-21\" target=\"_blank\">#{name}</a>"
519
+ elsif page =~ /^isbn(.+)$/i then
520
+ name = "ISBN " + $1 if page == name
521
+ return "<a href=\"http://www.amazon.co.uk/exec/obidos/ASIN/#{$1}/agilesystems-21\" target=\"_blank\">#{name}</a>"
522
+ elsif page =~ /\./ then
523
+ return resource_link(subwiki,page,name)
524
+ elsif @storage.exists(File.join(subwiki,page)) then
525
+ return view_link(subwiki,page,name)
526
+ else
527
+ return edit_link(subwiki,page,name)
528
+ end
529
+ end
530
+
531
+ def resource_link(subwiki,page,name)
532
+ if page =~ /^(.*)\.(gif|jpg|jpeg|png)$/i then
533
+ filename = $1
534
+ alt_label = name
535
+ if page == name || url?(name) then
536
+ alt_label = filename
537
+ end
538
+ image_link = "<img src=\"html/#{subwiki}/#{page}\" border=0 alt=\"#{alt_label}\" >"
539
+ if url?(name) then
540
+ return redirect_link(image_link,name)
541
+ else
542
+ return image_link
543
+ end
544
+ else
545
+ return "<a href=\"html/#{subwiki}/#{page}\" target=\"_blank\">#{name}</a>"
546
+ end
547
+ end
548
+
549
+ def add_bullet(prefix,text,code)
550
+ @added_bullets = true
551
+ depth = prefix.length / 3
552
+ result = ""
553
+ bullet_depth = @bullets.length
554
+ if depth > bullet_depth then
555
+ bullet_depth.upto(depth-1) do
556
+ result += "<#{code}l>"
557
+ @bullets.push(code)
558
+ end
559
+ elsif depth < bullet_depth then
560
+ bullet_depth.downto(depth+1) do
561
+ bullet = @bullets.pop
562
+ result += "</#{bullet}l>"
563
+ end
564
+ elsif @bullets.last != code then
565
+ bullet = @bullets.pop
566
+ result += "</#{bullet}l>"
567
+ result += "<#{code}l>"
568
+ @bullets.push(code)
569
+ end
570
+ return result + "<li>#{text}"
571
+ end
572
+
573
+ def emit_bullets
574
+ while ! @bullets.empty?
575
+ bullet = @bullets.pop
576
+ @pre_line += "</#{bullet}l>"
577
+ end
578
+ end
579
+
580
+ def join(*dirs)
581
+ result = ""
582
+ dirs.each do |name|
583
+ if !name.nil? and name.length > 0 then
584
+ result += '/' unless result.length == 0
585
+ result += name
586
+ end
587
+ end
588
+ return result.squeeze('/')
589
+ end
590
+
591
+ def url?(name)
592
+ name =~ /(http|ftp|gopher|news|https)\:(\w|\/|\.|_|-|\?|\=|&|;|\~|#|,)+/
593
+ end
594
+
595
+ end
596
+
597
+ end