Soks 0.0.4 → 0.0.5
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/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
|