Soks 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.txt +22 -20
- data/bin/soks-create-wiki.rb +11 -2
- data/contrib/{redcloth-3.0.1.rb → redcloth-3.0.3.rb} +161 -66
- data/lib/authenticators.rb +2 -2
- data/lib/helpers/mail2wiki-helper.rb +101 -0
- data/lib/helpers/rss2wiki-helper.rb +48 -0
- data/lib/soks-model.rb +7 -5
- data/lib/soks-servlet.rb +8 -19
- data/lib/soks-view.rb +70 -162
- data/lib/soks.rb +20 -2
- data/templates/default/attachment/favicon.ico +0 -0
- data/templates/default/attachment/logo_thumb.bmp +0 -0
- data/templates/default/attachment/robots.txt +5 -0
- data/templates/default/attachment/stylesheet.css +1 -0
- data/templates/default/content/Attached%20ruby%20logo.textile +1 -0
- data/templates/default/content/Attached%20test%20thing.textile +1 -0
- data/templates/default/content/Automatic%20Summaries.textile +1 -1
- data/templates/default/content/Bug%3A%20%5BFATAL%5D%20When%20renaming%20upload%20%2F%20picture%2.textile +1 -0
- data/templates/default/content/Bug%3A%20Duplicate%20links%2Dto%20a%20page%20sometimes%20appear.textile +1 -1
- data/templates/default/content/Bug%3A%20External%20links%20incorrectly%20include%20trailing%20pu.textile +1 -1
- data/templates/default/content/Bug%3A%20No%20robots%2Etxt%20or%20favicon%2Eico.textile +1 -1
- data/templates/default/content/Bug%3A%20Page%20titles%20cannot%20have%20html%20tags%20in%20them.textile +1 -1
- data/templates/default/content/Bug%3A%20Punctuation%20in%20page%20titles%20still%20problematic.textile +7 -0
- data/templates/default/content/Bug%3A%20Search%20includes%20leading%20and%20trailing%20spaces.textile +1 -0
- data/templates/default/content/Bug%3A%20Search%20inluced%20leading%20and%20trailing%20spaces.textile +1 -0
- data/templates/default/content/Bug%3A%20no%20superclass%20method%20%60%5Fdeprecated%5Fbase64.textile +1 -0
- data/templates/default/content/Bug%3A%20notextile%20does%20not%20prevent%20page%20inserts.textile +1 -0
- data/templates/default/content/Fixed%20Bug%3A%20%5BFATAL%5D%20When%20renaming%20upload%20%2F%20p.textile +34 -0
- data/templates/default/content/Fixed%20Bug%3A%20Duplicate%20links%2Dto%20a%20page%20sometimes%20.textile +3 -0
- data/templates/default/content/Fixed%20Bug%3A%20External%20links%20incorrectly%20include%20trail.textile +3 -0
- data/templates/default/content/Fixed%20Bug%3A%20No%20robots%2Etxt%20or%20favicon%2Eico.textile +4 -0
- data/templates/default/content/Fixed%20Bug%3A%20Search%20includes%20leading%20and%20trailing%20s.textile +3 -0
- data/templates/default/content/Fixed%20Bug%3A%20no%20superclass%20method%20%60%5Fdeprecated%5Fba.textile +3 -0
- data/templates/default/content/Home%20Page.textile +2 -2
- data/templates/default/content/How%20to%20administrate%20this%20wiki.textile +1 -1
- data/templates/default/content/How%20to%20report%20a%20bug.textile +8 -0
- data/templates/default/content/Instructions%20and%20Howtos.textile +1 -0
- data/templates/default/content/Known%20bugs.textile +4 -5
- data/templates/default/content/List%20of%20changes.textile +32 -0
- data/templates/default/content/Picture%20of%20a%20logo%20for%20the%20ruby%20language.textile +1 -0
- data/templates/default/content/Picture%20of%20powered%20by%20ruby%20logo.textile +1 -0
- data/templates/default/content/Planned%20Features.textile +19 -0
- data/templates/default/content/README.textile +22 -20
- data/templates/default/content/Recent%20Changes%20to%20This%20Site.textile +123 -8
- data/templates/default/content/SOKS%20features.textile +5 -1
- data/templates/default/content/Site%20Index.textile +11 -6
- data/templates/default/start.rb +17 -6
- data/templates/default/version.txt +1 -1
- data/templates/default/views/Page_edit.rhtml +7 -6
- data/templates/default/views/Page_meta.rhtml +5 -5
- data/templates/default/views/Page_revisions.rhtml +4 -3
- data/templates/default/views/Page_search_results.rhtml +3 -3
- data/templates/default/views/Page_view.rhtml +2 -2
- data/templates/default/views/UploadPage_edit.rhtml +6 -6
- data/templates/default/views/frame.rhtml +15 -14
- data/templates/instiki/content/Attached%20ruby%20logo.textile +1 -0
- data/templates/instiki/content/Attached%20test%20thing.textile +1 -0
- data/templates/instiki/content/Automatic%20Summaries.textile +1 -1
- data/templates/instiki/content/Bug%3A%20%5BFATAL%5D%20When%20renaming%20upload%20%2F%20picture%2.textile +1 -0
- data/templates/instiki/content/Bug%3A%20Duplicate%20links%2Dto%20a%20page%20sometimes%20appear.textile +1 -1
- data/templates/instiki/content/Bug%3A%20External%20links%20incorrectly%20include%20trailing%20pu.textile +1 -1
- data/templates/instiki/content/Bug%3A%20No%20robots%2Etxt%20or%20favicon%2Eico.textile +1 -1
- data/templates/instiki/content/Bug%3A%20Page%20titles%20cannot%20have%20html%20tags%20in%20them.textile +1 -1
- data/templates/instiki/content/Bug%3A%20Punctuation%20in%20page%20titles%20still%20problematic.textile +7 -0
- data/templates/instiki/content/Bug%3A%20Search%20includes%20leading%20and%20trailing%20spaces.textile +1 -0
- data/templates/instiki/content/Bug%3A%20Search%20inluced%20leading%20and%20trailing%20spaces.textile +1 -0
- data/templates/instiki/content/Bug%3A%20no%20superclass%20method%20%60%5Fdeprecated%5Fbase64.textile +1 -0
- data/templates/instiki/content/Bug%3A%20notextile%20does%20not%20prevent%20page%20inserts.textile +1 -0
- data/templates/instiki/content/Fixed%20Bug%3A%20%5BFATAL%5D%20When%20renaming%20upload%20%2F%20p.textile +34 -0
- data/templates/instiki/content/Fixed%20Bug%3A%20Duplicate%20links%2Dto%20a%20page%20sometimes%20.textile +3 -0
- data/templates/instiki/content/Fixed%20Bug%3A%20External%20links%20incorrectly%20include%20trail.textile +3 -0
- data/templates/instiki/content/Fixed%20Bug%3A%20No%20robots%2Etxt%20or%20favicon%2Eico.textile +4 -0
- data/templates/instiki/content/Fixed%20Bug%3A%20Search%20includes%20leading%20and%20trailing%20s.textile +3 -0
- data/templates/instiki/content/Fixed%20Bug%3A%20no%20superclass%20method%20%60%5Fdeprecated%5Fba.textile +3 -0
- data/templates/instiki/content/Home%20Page.textile +2 -2
- data/templates/instiki/content/How%20to%20administrate%20this%20wiki.textile +1 -1
- data/templates/instiki/content/How%20to%20report%20a%20bug.textile +8 -0
- data/templates/instiki/content/Instructions%20and%20Howtos.textile +1 -0
- data/templates/instiki/content/Known%20bugs.textile +4 -5
- data/templates/instiki/content/List%20of%20changes.textile +32 -0
- data/templates/instiki/content/Picture%20of%20a%20logo%20for%20the%20ruby%20language.textile +1 -0
- data/templates/instiki/content/Picture%20of%20powered%20by%20ruby%20logo.textile +1 -0
- data/templates/instiki/content/Planned%20Features.textile +19 -0
- data/templates/instiki/content/README.textile +22 -20
- data/templates/instiki/content/Recent%20Changes%20to%20This%20Site.textile +123 -8
- data/templates/instiki/content/SOKS%20features.textile +5 -1
- data/templates/instiki/content/Site%20Index.textile +11 -6
- data/templates/instiki/version.txt +1 -1
- data/templates/rails/content/Attached%20ruby%20logo.textile +1 -0
- data/templates/rails/content/Attached%20test%20thing.textile +1 -0
- data/templates/rails/content/Automatic%20Summaries.textile +1 -1
- data/templates/rails/content/Bug%3A%20%5BFATAL%5D%20When%20renaming%20upload%20%2F%20picture%2.textile +1 -0
- data/templates/rails/content/Bug%3A%20Duplicate%20links%2Dto%20a%20page%20sometimes%20appear.textile +1 -1
- data/templates/rails/content/Bug%3A%20External%20links%20incorrectly%20include%20trailing%20pu.textile +1 -1
- data/templates/rails/content/Bug%3A%20No%20robots%2Etxt%20or%20favicon%2Eico.textile +1 -1
- data/templates/rails/content/Bug%3A%20Page%20titles%20cannot%20have%20html%20tags%20in%20them.textile +1 -1
- data/templates/rails/content/Bug%3A%20Punctuation%20in%20page%20titles%20still%20problematic.textile +7 -0
- data/templates/rails/content/Bug%3A%20Search%20includes%20leading%20and%20trailing%20spaces.textile +1 -0
- data/templates/rails/content/Bug%3A%20Search%20inluced%20leading%20and%20trailing%20spaces.textile +1 -0
- data/templates/rails/content/Bug%3A%20no%20superclass%20method%20%60%5Fdeprecated%5Fbase64.textile +1 -0
- data/templates/rails/content/Bug%3A%20notextile%20does%20not%20prevent%20page%20inserts.textile +1 -0
- data/templates/rails/content/Fixed%20Bug%3A%20%5BFATAL%5D%20When%20renaming%20upload%20%2F%20p.textile +34 -0
- data/templates/rails/content/Fixed%20Bug%3A%20Duplicate%20links%2Dto%20a%20page%20sometimes%20.textile +3 -0
- data/templates/rails/content/Fixed%20Bug%3A%20External%20links%20incorrectly%20include%20trail.textile +3 -0
- data/templates/rails/content/Fixed%20Bug%3A%20No%20robots%2Etxt%20or%20favicon%2Eico.textile +4 -0
- data/templates/rails/content/Fixed%20Bug%3A%20Search%20includes%20leading%20and%20trailing%20s.textile +3 -0
- data/templates/rails/content/Fixed%20Bug%3A%20no%20superclass%20method%20%60%5Fdeprecated%5Fba.textile +3 -0
- data/templates/rails/content/Home%20Page.textile +2 -2
- data/templates/rails/content/How%20to%20administrate%20this%20wiki.textile +1 -1
- data/templates/rails/content/How%20to%20report%20a%20bug.textile +8 -0
- data/templates/rails/content/Instructions%20and%20Howtos.textile +1 -0
- data/templates/rails/content/Known%20bugs.textile +4 -5
- data/templates/rails/content/List%20of%20changes.textile +32 -0
- data/templates/rails/content/Picture%20of%20a%20logo%20for%20the%20ruby%20language.textile +1 -0
- data/templates/rails/content/Picture%20of%20powered%20by%20ruby%20logo.textile +1 -0
- data/templates/rails/content/Planned%20Features.textile +19 -0
- data/templates/rails/content/README.textile +22 -20
- data/templates/rails/content/Recent%20Changes%20to%20This%20Site.textile +123 -8
- data/templates/rails/content/SOKS%20features.textile +5 -1
- data/templates/rails/content/Site%20Index.textile +11 -6
- data/templates/rails/version.txt +1 -1
- metadata +64 -5
- data/contrib/redcloth-2.0.11.rb +0 -896
- /data/lib/{soks-helpers.rb → helpers/default-helpers.rb} +0 -0
data/README.txt
CHANGED
@@ -4,9 +4,9 @@ h1. SOKS: Another Ruby Wiki
|
|
4
4
|
* The project has been kindly hosted at http://rubyforge.org/projects/soks/
|
5
5
|
|
6
6
|
Quickstart:
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
# gem install Soks
|
8
|
+
# soks-create-wiki.rb
|
9
|
+
# http://localhost:8000
|
10
10
|
|
11
11
|
h2. REQUIRES
|
12
12
|
|
@@ -21,13 +21,13 @@ h2. AUTHOR
|
|
21
21
|
h2. INSTALL
|
22
22
|
|
23
23
|
Preferably:
|
24
|
-
|
25
|
-
|
24
|
+
# Install rubygems from http://rubyforge.org/projects/rubygems/
|
25
|
+
# gem install Soks (you may need to be root first)
|
26
26
|
|
27
27
|
Alternatively
|
28
|
-
|
29
|
-
|
30
|
-
|
28
|
+
# Download the tar or zip file from http://rubyforge.org/projects/soks/
|
29
|
+
# Unzip or untar it
|
30
|
+
# Change into the soks directory
|
31
31
|
|
32
32
|
h2. USE
|
33
33
|
|
@@ -40,22 +40,24 @@ To change the settings (url, port, etc) edit the start.rb file in the soks-wiki
|
|
40
40
|
|
41
41
|
h2. FEATURES
|
42
42
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
43
|
+
# Runs on its own webrick server (no independent web server required)
|
44
|
+
# Uses textile as its text coding (a proto-standard)
|
45
|
+
# Uses a combination of flat and yaml files for storage (no database, and page content human readable outside of soks)
|
46
|
+
# Allows uploads
|
47
|
+
# Allows authentication
|
48
|
+
# Automatically links pages within the wiki
|
49
|
+
# Pages can be deleted and moved easily (and these can be undone)
|
50
|
+
# Has a mechanism for external classes to manipulate the wiki to provide, for instance, automatic calendar pages, or automatic summaries or blog like pages.
|
51
51
|
|
52
52
|
h2. BUGS
|
53
53
|
|
54
54
|
I suspect there are many, as befits its version number. In particular it has:
|
55
|
-
*
|
56
|
-
*
|
55
|
+
* No authentication on pictures and attachments
|
56
|
+
* Punctuation in page titles problematic. ? <> and [] cause problems. : and / are ok.
|
57
|
+
* Insert page commands are not inhibited by notextile, pre or code tags
|
57
58
|
|
58
59
|
h2. RELEASES
|
59
60
|
|
60
|
-
2005
|
61
|
-
2005 Jan
|
61
|
+
# 2005 Feb 12 - soks-0.0.5 - Third public release (alpha)
|
62
|
+
# 2005 Jan 24 - soks-0.0.4 - Second public release (alpha)
|
63
|
+
# 2005 Jan 11 - soks-0.0.2 - First public release (alpha)
|
data/bin/soks-create-wiki.rb
CHANGED
@@ -38,11 +38,20 @@ def backup_directory( directory )
|
|
38
38
|
backup_dir
|
39
39
|
end
|
40
40
|
|
41
|
+
# Used to remove the content of a directory (FileUtils.rm_r seems to fail for me?)
|
42
|
+
def remove_directory( directory )
|
43
|
+
Dir.entries(directory).each do |file|
|
44
|
+
next if File.directory?( file )
|
45
|
+
File.delete( File.join( directory, file ) )
|
46
|
+
end
|
47
|
+
Dir.rmdir( directory )
|
48
|
+
end
|
49
|
+
|
41
50
|
#Find where we are
|
42
51
|
$SOKS_APPLICATION_DIRECTORY, this_script = File.split(File.expand_path(File.dirname(__FILE__)))
|
43
52
|
|
44
53
|
#Make sure we can find our libraries
|
45
|
-
soks_library = [ File.join( $SOKS_APPLICATION_DIRECTORY,'lib') , File.join( $SOKS_APPLICATION_DIRECTORY,'/contrib' ) ]
|
54
|
+
soks_library = [ File.join( $SOKS_APPLICATION_DIRECTORY,'lib') , File.join( $SOKS_APPLICATION_DIRECTORY,'lib','helpers'), File.join( $SOKS_APPLICATION_DIRECTORY,'/contrib' ) ]
|
46
55
|
$:.push( *soks_library )
|
47
56
|
|
48
57
|
require 'easyprompt'
|
@@ -114,7 +123,7 @@ if upgrade
|
|
114
123
|
puts "Copied #{source} to #{destination}"
|
115
124
|
|
116
125
|
if keep_content
|
117
|
-
|
126
|
+
remove_directory( File.join( destination, 'content' ) )
|
118
127
|
FileUtils.cp_r( File.join( old_wiki, 'content'), destination )
|
119
128
|
puts "Copied content from #{old_wiki} to #{destination}"
|
120
129
|
if wiki_version == '0.0.2'
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# NOTE THERE ARE SLIGHT TWEAKS TO THIS VERSION MADE BY TAMC
|
1
2
|
# vim:ts=4:sw=4:
|
2
3
|
# = RedCloth - Textile and Markdown Hybrid for Ruby
|
3
4
|
#
|
@@ -166,7 +167,8 @@
|
|
166
167
|
|
167
168
|
class RedCloth < String
|
168
169
|
|
169
|
-
VERSION = '3.0.
|
170
|
+
VERSION = '3.0.3'
|
171
|
+
DEFAULT_RULES = [:textile, :markdown]
|
170
172
|
|
171
173
|
#
|
172
174
|
# Two accessor for setting security restrictions.
|
@@ -192,6 +194,16 @@ class RedCloth < String
|
|
192
194
|
#
|
193
195
|
attr_accessor :hard_breaks
|
194
196
|
|
197
|
+
#
|
198
|
+
# Accessor for toggling span caps.
|
199
|
+
#
|
200
|
+
# Textile places `span' tags around capitalized
|
201
|
+
# words by default, but this wreaks havoc on Wikis.
|
202
|
+
# If +:no_span_caps+ is set, this will be
|
203
|
+
# suppressed.
|
204
|
+
#
|
205
|
+
attr_accessor :no_span_caps
|
206
|
+
|
195
207
|
#
|
196
208
|
# Establishes the markup predence. Available rules include:
|
197
209
|
#
|
@@ -230,7 +242,6 @@ class RedCloth < String
|
|
230
242
|
#
|
231
243
|
def initialize( string, restrictions = [] )
|
232
244
|
restrictions.each { |r| method( "#{ r }=" ).call( true ) }
|
233
|
-
@rules = [:textile, :markdown]
|
234
245
|
super( string )
|
235
246
|
end
|
236
247
|
|
@@ -242,7 +253,7 @@ class RedCloth < String
|
|
242
253
|
# #=>"And then? She <strong>fell</strong>!"
|
243
254
|
#
|
244
255
|
def to_html( *rules )
|
245
|
-
rules =
|
256
|
+
rules = DEFAULT_RULES if rules.empty?
|
246
257
|
# make our working copy
|
247
258
|
text = self.dup
|
248
259
|
|
@@ -268,18 +279,22 @@ class RedCloth < String
|
|
268
279
|
# standard clean up
|
269
280
|
incoming_entities text
|
270
281
|
clean_white_space text
|
282
|
+
no_textile text
|
271
283
|
|
272
284
|
# start processor
|
273
|
-
pre_list =
|
285
|
+
@pre_list = []
|
286
|
+
rip_offtags text
|
287
|
+
hard_break text
|
274
288
|
refs text
|
275
289
|
blocks text
|
276
290
|
inline text
|
277
|
-
smooth_offtags text
|
291
|
+
smooth_offtags text
|
278
292
|
|
279
293
|
retrieve text
|
280
294
|
|
281
295
|
text.gsub!( /<\/?notextile>/, '' )
|
282
296
|
text.gsub!( /x%x%/, '&' )
|
297
|
+
clean_html text if filter_html
|
283
298
|
text.strip!
|
284
299
|
text
|
285
300
|
|
@@ -340,7 +355,7 @@ class RedCloth < String
|
|
340
355
|
[ /"/, '“' ], # double opening
|
341
356
|
[ /\b( )?\.{3}/, '\1…' ], # ellipsis
|
342
357
|
[ /\b([A-Z][A-Z0-9]{2,})\b(?:[(]([^)]*)[)])/, '<acronym title="\2">\1</acronym>' ], # 3+ uppercase acronym
|
343
|
-
[ /(^|[^"][>\s])([A-Z][A-Z0-9 ]{2,})([^<a-z0-9]|$)/, '\1<span class="caps">\2</span>\3' ], # 3+ uppercase caps
|
358
|
+
[ /(^|[^"][>\s])([A-Z][A-Z0-9 ]{2,})([^<a-z0-9]|$)/, '\1<span class="caps">\2</span>\3', :no_span_caps ], # 3+ uppercase caps
|
344
359
|
[ /(\.\s)?\s?--\s?/, '\1—' ], # em dash
|
345
360
|
[ /\s->\s/, ' → ' ], # right arrow
|
346
361
|
[ /\s-\s/, ' – ' ], # en dash
|
@@ -366,20 +381,36 @@ class RedCloth < String
|
|
366
381
|
QTAGS = [
|
367
382
|
['**', 'b'],
|
368
383
|
['*', 'strong'],
|
369
|
-
['??', 'cite'],
|
370
|
-
['-', 'del'],
|
384
|
+
['??', 'cite', :limit],
|
385
|
+
['-', 'del', :limit],
|
371
386
|
['__', 'i'],
|
372
|
-
['_', 'em'],
|
373
|
-
['%', 'span'],
|
374
|
-
['+', 'ins'],
|
387
|
+
['_', 'em', :limit],
|
388
|
+
['%', 'span', :limit],
|
389
|
+
['+', 'ins', :limit],
|
375
390
|
['^', 'sup'],
|
376
391
|
['~', 'sub']
|
377
392
|
]
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
393
|
+
QTAGS.collect! do |rc, ht, rtype|
|
394
|
+
rcq = Regexp::quote rc
|
395
|
+
re =
|
396
|
+
case rtype
|
397
|
+
when :limit
|
398
|
+
/(\W)
|
399
|
+
(#{rcq})
|
400
|
+
(#{C})
|
401
|
+
(?::(\S+?))?
|
402
|
+
(.+?)
|
403
|
+
#{rcq}
|
404
|
+
(?=\W)/x
|
405
|
+
else
|
406
|
+
/(#{rcq})
|
407
|
+
(#{C})
|
408
|
+
(?::(\S+?))?
|
409
|
+
(.+?)
|
410
|
+
#{rcq}/xm
|
411
|
+
end
|
412
|
+
[rc, ht, re, rtype]
|
413
|
+
end
|
383
414
|
|
384
415
|
#
|
385
416
|
# Flexible HTML escaping
|
@@ -394,7 +425,8 @@ class RedCloth < String
|
|
394
425
|
|
395
426
|
# Search and replace for Textile glyphs (quotes, dashes, other symbols)
|
396
427
|
def pgl( text )
|
397
|
-
GLYPHS.each do |re, resub|
|
428
|
+
GLYPHS.each do |re, resub, tog|
|
429
|
+
next if tog and method( tog ).call
|
398
430
|
text.gsub! re, resub
|
399
431
|
end
|
400
432
|
end
|
@@ -412,7 +444,7 @@ class RedCloth < String
|
|
412
444
|
style << "vertical-align:#{ v_align( $& ) };" if text =~ A_VLGN
|
413
445
|
end
|
414
446
|
|
415
|
-
style << "#{ $1 };" if not
|
447
|
+
style << "#{ $1 };" if not filter_styles and
|
416
448
|
text.sub!( /\{([^}]*)\}/, '' )
|
417
449
|
|
418
450
|
lang = $1 if
|
@@ -526,20 +558,18 @@ class RedCloth < String
|
|
526
558
|
end
|
527
559
|
end
|
528
560
|
|
529
|
-
CODE_RE = /
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
(?=[\s\]}\)<#{PUNCT}]|$) # 4 closing bracket?
|
536
|
-
/x
|
561
|
+
CODE_RE = /(\W)
|
562
|
+
@
|
563
|
+
(?:\|(\w+?)\|)?
|
564
|
+
(.+?)
|
565
|
+
@
|
566
|
+
(?=\W)/x
|
537
567
|
|
538
568
|
def inline_textile_code( text )
|
539
569
|
text.gsub!( CODE_RE ) do |m|
|
540
570
|
before,lang,code,after = $~[1..4]
|
541
571
|
lang = " lang=\"#{ lang }\"" if lang
|
542
|
-
"#{ before }<code#{ lang }>#{ code }</code>#{ after }"
|
572
|
+
rip_offtags( "#{ before }<code#{ lang }>#{ code }</code>#{ after }" )
|
543
573
|
end
|
544
574
|
end
|
545
575
|
|
@@ -548,14 +578,14 @@ class RedCloth < String
|
|
548
578
|
end
|
549
579
|
|
550
580
|
def hard_break( text )
|
551
|
-
text.gsub!( /(.)\n(?! *[#*\s|])/, "\\1<br />" ) if
|
581
|
+
text.gsub!( /(.)\n(?! *[#*\s|]|$)/, "\\1<br />" ) if hard_breaks
|
552
582
|
end
|
553
583
|
|
554
|
-
BLOCKS_GROUP_RE =
|
584
|
+
BLOCKS_GROUP_RE = /\n{2,}(?! )/m
|
555
585
|
|
556
586
|
def blocks( text, deep_code = false )
|
557
|
-
text.
|
558
|
-
plain =
|
587
|
+
text.replace( text.split( BLOCKS_GROUP_RE ).collect do |blk|
|
588
|
+
plain = blk !~ /\A[#*> ]/
|
559
589
|
|
560
590
|
# skip blocks that are complex HTML
|
561
591
|
if blk =~ /^<\/?(\w+).*>/ and not SIMPLE_HTML_TAGS.include? $1
|
@@ -578,11 +608,11 @@ class RedCloth < String
|
|
578
608
|
end
|
579
609
|
end
|
580
610
|
|
581
|
-
block_applied =
|
611
|
+
block_applied = 0
|
582
612
|
@rules.each do |rule_name|
|
583
|
-
|
613
|
+
block_applied += 1 if ( rule_name.to_s.match /^block_/ and method( rule_name ).call( blk ) )
|
584
614
|
end
|
585
|
-
|
615
|
+
if block_applied.zero?
|
586
616
|
if deep_code
|
587
617
|
blk = "\t<pre><code>#{ blk }</code></pre>"
|
588
618
|
else
|
@@ -594,7 +624,7 @@ class RedCloth < String
|
|
594
624
|
end
|
595
625
|
end
|
596
626
|
|
597
|
-
end
|
627
|
+
end.join( "\n\n" ) )
|
598
628
|
end
|
599
629
|
|
600
630
|
def textile_bq( tag, atts, cite, content )
|
@@ -694,16 +724,23 @@ class RedCloth < String
|
|
694
724
|
end
|
695
725
|
|
696
726
|
def inline_textile_span( text )
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
727
|
+
QTAGS.each do |qtag_rc, ht, qtag_re, rtype|
|
728
|
+
text.gsub!( qtag_re ) do |m|
|
729
|
+
|
730
|
+
case rtype
|
731
|
+
when :limit
|
732
|
+
sta,qtag,atts,cite,content = $~[1..5]
|
733
|
+
else
|
734
|
+
qtag,atts,cite,content = $~[1..4]
|
735
|
+
sta = ''
|
736
|
+
end
|
737
|
+
atts = pba( atts )
|
738
|
+
atts << " cite=\"#{ cite }\"" if cite
|
739
|
+
atts = shelve( atts ) if atts
|
704
740
|
|
705
|
-
|
741
|
+
"#{ sta }<#{ ht }#{ atts }>#{ content }</#{ ht }>"
|
706
742
|
|
743
|
+
end
|
707
744
|
end
|
708
745
|
end
|
709
746
|
|
@@ -865,14 +902,14 @@ class RedCloth < String
|
|
865
902
|
end
|
866
903
|
end
|
867
904
|
|
868
|
-
def shelve( val )
|
869
|
-
|
870
|
-
|
905
|
+
def shelve( val )
|
906
|
+
@shelf << val
|
907
|
+
"<#{ @shelf.length }>"
|
871
908
|
end
|
872
909
|
|
873
910
|
def retrieve( text )
|
874
911
|
@shelf.each_with_index do |r, i|
|
875
|
-
text.gsub!( "
|
912
|
+
text.gsub!( "<#{ i + 1 }>", r )
|
876
913
|
end
|
877
914
|
end
|
878
915
|
|
@@ -885,9 +922,9 @@ class RedCloth < String
|
|
885
922
|
end
|
886
923
|
|
887
924
|
def no_textile( text )
|
888
|
-
text.gsub!( /(^|\s)==(
|
925
|
+
text.gsub!( /(^|\s)==([^=]+.*?)==(\s|$)?/,
|
889
926
|
'\1<notextile>\2</notextile>\3' )
|
890
|
-
text.gsub!( /^ *==(
|
927
|
+
text.gsub!( /^ *==([^=]+.*?)==/m,
|
891
928
|
'\1<notextile>\2</notextile>\3' )
|
892
929
|
end
|
893
930
|
|
@@ -907,11 +944,13 @@ class RedCloth < String
|
|
907
944
|
|
908
945
|
def flush_left( text )
|
909
946
|
indt = 0
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
947
|
+
if text =~ /^ /
|
948
|
+
while text !~ /^ {#{indt}}\S/
|
949
|
+
indt += 1
|
950
|
+
end unless text.empty?
|
951
|
+
if indt.nonzero?
|
952
|
+
text.gsub!( /^ {#{indt}}/, '' )
|
953
|
+
end
|
915
954
|
end
|
916
955
|
end
|
917
956
|
|
@@ -936,9 +975,7 @@ class RedCloth < String
|
|
936
975
|
text.gsub!( ALLTAG_MATCH ) do |line|
|
937
976
|
## matches are off if we're between <code>, <pre> etc.
|
938
977
|
if $1
|
939
|
-
if
|
940
|
-
htmlesc( line, :NoQuotes )
|
941
|
-
elsif line =~ OFFTAG_OPEN
|
978
|
+
if line =~ OFFTAG_OPEN
|
942
979
|
codepre += 1
|
943
980
|
elsif line =~ OFFTAG_CLOSE
|
944
981
|
codepre -= 1
|
@@ -957,7 +994,6 @@ class RedCloth < String
|
|
957
994
|
end
|
958
995
|
|
959
996
|
def rip_offtags( text )
|
960
|
-
pre_list = []
|
961
997
|
if text =~ /<.*>/
|
962
998
|
## strip and encode <pre> content
|
963
999
|
codepre, used_offtags = 0, {}
|
@@ -968,17 +1004,17 @@ class RedCloth < String
|
|
968
1004
|
used_offtags[offtag] = true
|
969
1005
|
if codepre - used_offtags.length > 0
|
970
1006
|
htmlesc( line, :NoQuotes ) unless used_offtags['notextile']
|
971
|
-
pre_list.last << line
|
1007
|
+
@pre_list.last << line
|
972
1008
|
line = ""
|
973
1009
|
else
|
974
1010
|
htmlesc( aftertag, :NoQuotes ) if aftertag and not used_offtags['notextile']
|
975
|
-
line = "<redpre##{ pre_list.length }>"
|
976
|
-
pre_list << "#{ $3 }#{ aftertag }"
|
1011
|
+
line = "<redpre##{ @pre_list.length }>"
|
1012
|
+
@pre_list << "#{ $3 }#{ aftertag }"
|
977
1013
|
end
|
978
1014
|
elsif $1 and codepre > 0
|
979
1015
|
if codepre - used_offtags.length > 0
|
980
1016
|
htmlesc( line, :NoQuotes ) unless used_offtags['notextile']
|
981
|
-
pre_list.last << line
|
1017
|
+
@pre_list.last << line
|
982
1018
|
line = ""
|
983
1019
|
end
|
984
1020
|
codepre -= 1 unless codepre.zero?
|
@@ -987,13 +1023,13 @@ class RedCloth < String
|
|
987
1023
|
line
|
988
1024
|
end
|
989
1025
|
end
|
990
|
-
|
1026
|
+
text
|
991
1027
|
end
|
992
1028
|
|
993
|
-
def smooth_offtags( text
|
994
|
-
unless pre_list.empty?
|
1029
|
+
def smooth_offtags( text )
|
1030
|
+
unless @pre_list.empty?
|
995
1031
|
## replace <pre> content
|
996
|
-
text.gsub!( /<redpre#(\d+)>/ ) { pre_list[$1.to_i] }
|
1032
|
+
text.gsub!( /<redpre#(\d+)>/ ) { @pre_list[$1.to_i] }
|
997
1033
|
end
|
998
1034
|
end
|
999
1035
|
|
@@ -1015,5 +1051,64 @@ class RedCloth < String
|
|
1015
1051
|
' <a target="_blank" href="http://hobix.com/textile/#' + helpvar + '" onclick="window.open(this.href, \'popupwindow\', \'width=' + windowW + ',height=' + windowH + ',scrollbars,resizable\'); return false;">' + name + '</a><br />'
|
1016
1052
|
end
|
1017
1053
|
|
1054
|
+
# HTML cleansing stuff
|
1055
|
+
BASIC_TAGS = {
|
1056
|
+
'a' => ['href', 'title'],
|
1057
|
+
'img' => ['src', 'alt', 'title'],
|
1058
|
+
'br' => [],
|
1059
|
+
'i' => nil,
|
1060
|
+
'u' => nil,
|
1061
|
+
'b' => nil,
|
1062
|
+
'pre' => nil,
|
1063
|
+
'kbd' => nil,
|
1064
|
+
'code' => ['lang'],
|
1065
|
+
'cite' => nil,
|
1066
|
+
'strong' => nil,
|
1067
|
+
'em' => nil,
|
1068
|
+
'ins' => nil,
|
1069
|
+
'sup' => nil,
|
1070
|
+
'sub' => nil,
|
1071
|
+
'del' => nil,
|
1072
|
+
'table' => nil,
|
1073
|
+
'tr' => nil,
|
1074
|
+
'td' => ['colspan', 'rowspan'],
|
1075
|
+
'th' => nil,
|
1076
|
+
'ol' => nil,
|
1077
|
+
'ul' => nil,
|
1078
|
+
'li' => nil,
|
1079
|
+
'p' => nil,
|
1080
|
+
'h1' => nil,
|
1081
|
+
'h2' => nil,
|
1082
|
+
'h3' => nil,
|
1083
|
+
'h4' => nil,
|
1084
|
+
'h5' => nil,
|
1085
|
+
'h6' => nil,
|
1086
|
+
'blockquote' => ['cite']
|
1087
|
+
}
|
1088
|
+
|
1089
|
+
def clean_html( text, tags = BASIC_TAGS )
|
1090
|
+
text.gsub!( /<!\[CDATA\[/, '' )
|
1091
|
+
text.gsub!( /<(\/?)(\w+)(.*?)(\/?)>/ ) do
|
1092
|
+
raw = $~
|
1093
|
+
tag = raw[2].downcase
|
1094
|
+
if tags.has_key? tag
|
1095
|
+
pcs = [tag]
|
1096
|
+
tags[tag].each do |prop|
|
1097
|
+
['"', "'", ''].each do |q|
|
1098
|
+
q2 = ( q != '' ? q : '\s' )
|
1099
|
+
if raw[3] =~ /#{prop}\s*=\s*#{q}([^#{q2}]+)#{q}/i
|
1100
|
+
attrv = $1
|
1101
|
+
next if prop == 'src' and attrv !~ /^http/
|
1102
|
+
pcs << "#{prop}=\"#{attrv.gsub('"', '\\"')}\""
|
1103
|
+
break
|
1104
|
+
end
|
1105
|
+
end
|
1106
|
+
end if tags[tag]
|
1107
|
+
"<#{raw[1]}#{pcs.join " "}#{raw[4]}>"
|
1108
|
+
else
|
1109
|
+
" "
|
1110
|
+
end
|
1111
|
+
end
|
1112
|
+
end
|
1018
1113
|
end
|
1019
1114
|
|
data/lib/authenticators.rb
CHANGED
@@ -37,7 +37,7 @@ module WEBrick
|
|
37
37
|
unless basic_credentials = check_scheme(req)
|
38
38
|
challenge(req, res)
|
39
39
|
end
|
40
|
-
userid, password = decode64(basic_credentials).split(":", 2)
|
40
|
+
userid, password = Base64.decode64(basic_credentials).split(":", 2)
|
41
41
|
if userid.empty?
|
42
42
|
error("user id was not given.")
|
43
43
|
challenge(req, res)
|
@@ -70,7 +70,7 @@ module WEBrick
|
|
70
70
|
unless basic_credentials = check_scheme(req)
|
71
71
|
challenge(req, res)
|
72
72
|
end
|
73
|
-
userid, password = decode64(basic_credentials).split(":", 2)
|
73
|
+
userid, password = Base64.decode64(basic_credentials).split(":", 2)
|
74
74
|
password ||= ""
|
75
75
|
if userid.empty?
|
76
76
|
error("user id was not given.")
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'net/imap'
|
2
|
+
|
3
|
+
class Message
|
4
|
+
|
5
|
+
attr_reader :message_id, :subject, :sender_name, :sender_email, :date, :text
|
6
|
+
|
7
|
+
def initialize( imap, message_id )
|
8
|
+
@imap, @message_id = imap, message_id
|
9
|
+
envelope = @imap.fetch( @message_id, 'ENVELOPE' ).first.attr['ENVELOPE']
|
10
|
+
@subject = envelope['subject']
|
11
|
+
@sender_name = envelope['from'].first['name']
|
12
|
+
@sender_email = envelope['from'].first['mailbox'] + '@' + envelope['from'].first['host']
|
13
|
+
@text = plain_text_content_from_message( message_id )
|
14
|
+
end
|
15
|
+
|
16
|
+
def plain_text_content_from_message( id )
|
17
|
+
text = @imap.fetch( id, 'BODY[1]' ).first.attr['BODY[1]']
|
18
|
+
text.gsub!(/\r\n/,"\n")
|
19
|
+
text.gsub!(/\r/,"\n")
|
20
|
+
text.gsub!(/=\n/,'')
|
21
|
+
text.gsub!(/((?:=[0-9a-fA-F]{2})+)/n) { [$1.delete('=')].pack('H*') }
|
22
|
+
text
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
class Mail2WikiHelper
|
28
|
+
|
29
|
+
DEFAULT_SETTINGS = {
|
30
|
+
:server => 'imap.hermes.cam.ac.uk',
|
31
|
+
:username => 'tamc2',
|
32
|
+
:password => '',
|
33
|
+
:mailbox => 'mcr notices',
|
34
|
+
:check_frequency => 600, # Seconds
|
35
|
+
:subject_regexp => /.*/,
|
36
|
+
}
|
37
|
+
|
38
|
+
def initialize( wiki, settings = {} )
|
39
|
+
@settings = DEFAULT_SETTINGS.merge( settings )
|
40
|
+
@wiki = wiki
|
41
|
+
check_mailbox
|
42
|
+
Thread.new do
|
43
|
+
loop do
|
44
|
+
sleep @settings[:check_frequency ]
|
45
|
+
check_mailbox
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def check_mailbox
|
53
|
+
login
|
54
|
+
select_mailbox
|
55
|
+
p "Checking for emails in #{@settings[:server]}"
|
56
|
+
new_messages_for_wiki do |message_id|
|
57
|
+
this_message = Message.new( @imap, message_id )
|
58
|
+
if this_message.subject =~ @settings[:subject_regexp]
|
59
|
+
add_message_to_wiki( this_message )
|
60
|
+
mark_as_added( message_id )
|
61
|
+
end
|
62
|
+
end
|
63
|
+
logout
|
64
|
+
end
|
65
|
+
|
66
|
+
def add_message_to_wiki( message )
|
67
|
+
current_page = @wiki.page( message.subject )
|
68
|
+
if current_page.empty?
|
69
|
+
text = "h1. #{message.subject}"
|
70
|
+
else
|
71
|
+
text = current_page.textile
|
72
|
+
end
|
73
|
+
text << "\n\n----\n\n"
|
74
|
+
text << "#{message.date} from #{message.sender_name} #{message.sender_email}\n"
|
75
|
+
text << message.text.gsub(/[\*-]{2,}/,'').gsub(/\n\s+/,"\n").gsub(/\n/,"\n\n")
|
76
|
+
@wiki.revise(message.subject, text, message.sender_name )
|
77
|
+
end
|
78
|
+
|
79
|
+
def login
|
80
|
+
@imap = Net::IMAP.new(@settings[:server])
|
81
|
+
@imap.login( @settings[:username], @settings[:password] )
|
82
|
+
end
|
83
|
+
|
84
|
+
def logout
|
85
|
+
@imap.logout
|
86
|
+
@imap.disconnect
|
87
|
+
end
|
88
|
+
|
89
|
+
def select_mailbox
|
90
|
+
@imap.select @settings[:mailbox]
|
91
|
+
end
|
92
|
+
|
93
|
+
def new_messages_for_wiki
|
94
|
+
@imap.search('UNKEYWORD PutInWiki').each { |id| yield id }
|
95
|
+
end
|
96
|
+
|
97
|
+
def mark_as_added( id )
|
98
|
+
# @imap.store( id, '+FLAGS', ['PutInWiki'] )
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'rss/1.0'
|
2
|
+
require 'rss/2.0'
|
3
|
+
require 'open-uri'
|
4
|
+
|
5
|
+
class RSS2WikiHelper
|
6
|
+
|
7
|
+
DEFAULT_SETTINGS = {
|
8
|
+
:url => 'http://localhost:8000/rss/recent%20changes%20to%20this%20site',
|
9
|
+
:pagename => nil, # If nil, uses channel title,
|
10
|
+
:check_frequency => 1200,
|
11
|
+
:author => 'AutomaticRSS2Wiki',
|
12
|
+
}
|
13
|
+
|
14
|
+
def initialize( wiki, settings = {} )
|
15
|
+
@settings = DEFAULT_SETTINGS.merge( settings )
|
16
|
+
@wiki = wiki
|
17
|
+
Thread.new do
|
18
|
+
loop do
|
19
|
+
update_rss
|
20
|
+
update_wiki
|
21
|
+
sleep @settings[ :check_frequency ]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def update_wiki
|
27
|
+
@wiki.revise( @settings[:pagename] || @rss.channel.title, render, @rss.items.first.respond_to?('author') ? @rss.items.first.author : "AutomaticRSS" )
|
28
|
+
end
|
29
|
+
|
30
|
+
def render
|
31
|
+
content = "h1. #{@rss.channel.title}\n\n"
|
32
|
+
@rss.items.each do |item|
|
33
|
+
content << "# [[ #{escape(item.title)} => #{item.link} ]]\n"
|
34
|
+
end
|
35
|
+
content
|
36
|
+
end
|
37
|
+
|
38
|
+
def update_rss
|
39
|
+
$stderr.puts "Updating feed"
|
40
|
+
open(@settings[:url]) do |http|
|
41
|
+
@rss = RSS::Parser.parse( http.read , false)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def escape( string )
|
46
|
+
string.tr('[]=>','')
|
47
|
+
end
|
48
|
+
end
|