instiki 0.9.2 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +165 -0
- data/README +68 -172
- data/app/controllers/admin_controller.rb +94 -0
- data/app/controllers/application.rb +131 -0
- data/app/controllers/file_controller.rb +129 -0
- data/app/controllers/wiki_controller.rb +354 -0
- data/{libraries/view_helper.rb → app/helpers/application_helper.rb} +68 -33
- data/app/models/author.rb +3 -3
- data/app/models/chunks/category.rb +33 -31
- data/app/models/chunks/chunk.rb +86 -20
- data/app/models/chunks/engines.rb +54 -38
- data/app/models/chunks/include.rb +41 -29
- data/app/models/chunks/literal.rb +31 -19
- data/app/models/chunks/nowiki.rb +28 -31
- data/app/models/chunks/test.rb +18 -18
- data/app/models/chunks/uri.rb +182 -97
- data/app/models/chunks/wiki.rb +141 -82
- data/app/models/file_yard.rb +58 -0
- data/app/models/page.rb +112 -86
- data/app/models/page_lock.rb +22 -23
- data/app/models/page_set.rb +89 -64
- data/app/models/revision.rb +123 -90
- data/app/models/web.rb +176 -89
- data/app/models/wiki_content.rb +207 -105
- data/app/models/wiki_service.rb +233 -83
- data/app/models/wiki_words.rb +23 -25
- data/app/views/{wiki/new_system.rhtml → admin/create_system.rhtml} +83 -78
- data/app/views/{wiki/new_web.rhtml → admin/create_web.rhtml} +69 -64
- data/app/views/admin/edit_web.rhtml +136 -0
- data/app/views/file/file.rhtml +19 -0
- data/app/views/file/import.rhtml +23 -0
- data/app/views/layouts/default.rhtml +85 -0
- data/app/views/markdown_help.rhtml +12 -16
- data/app/views/mixed_help.rhtml +7 -0
- data/app/views/navigation.rhtml +30 -19
- data/app/views/rdoc_help.rhtml +12 -16
- data/app/views/textile_help.rhtml +24 -28
- data/app/views/wiki/authors.rhtml +11 -13
- data/app/views/wiki/edit.rhtml +39 -31
- data/app/views/wiki/export.rhtml +12 -14
- data/app/views/wiki/feeds.rhtml +14 -10
- data/app/views/wiki/list.rhtml +64 -57
- data/app/views/wiki/locked.rhtml +23 -14
- data/app/views/wiki/login.rhtml +14 -11
- data/app/views/wiki/new.rhtml +31 -27
- data/app/views/wiki/page.rhtml +115 -81
- data/app/views/wiki/print.rhtml +14 -16
- data/app/views/wiki/published.rhtml +9 -10
- data/app/views/wiki/recently_revised.rhtml +27 -30
- data/app/views/wiki/revision.rhtml +103 -81
- data/app/views/wiki/rollback.rhtml +14 -9
- data/app/views/wiki/rss_feed.rhtml +22 -22
- data/app/views/wiki/search.rhtml +38 -15
- data/app/views/wiki/tex.rhtml +22 -22
- data/app/views/wiki/tex_web.rhtml +34 -34
- data/app/views/wiki/web_list.rhtml +18 -13
- data/app/views/wiki_words_help.rhtml +9 -8
- data/config/environment.rb +82 -0
- data/config/environments/development.rb +5 -0
- data/config/environments/production.rb +4 -0
- data/config/environments/test.rb +17 -0
- data/config/routes.rb +18 -0
- data/instiki +6 -67
- data/instiki.rb +3 -0
- data/lib/active_record_stub.rb +31 -0
- data/{libraries/diff → lib}/diff.rb +444 -475
- data/lib/instiki_errors.rb +15 -0
- data/{libraries → lib}/rdocsupport.rb +151 -155
- data/lib/redcloth_for_tex.rb +736 -0
- data/natives/osx/desktop_launcher/AppDelegate.h +18 -0
- data/natives/osx/desktop_launcher/AppDelegate.mm +109 -0
- data/natives/osx/desktop_launcher/Credits.html +16 -0
- data/natives/osx/desktop_launcher/English.lproj/InfoPlist.strings +0 -0
- data/natives/osx/desktop_launcher/English.lproj/MainMenu.nib/classes.nib +13 -0
- data/natives/osx/desktop_launcher/English.lproj/MainMenu.nib/info.nib +24 -0
- data/natives/osx/desktop_launcher/English.lproj/MainMenu.nib/objects.nib +0 -0
- data/natives/osx/desktop_launcher/Info.plist +13 -0
- data/natives/osx/desktop_launcher/Instiki.xcode/project.pbxproj +592 -0
- data/natives/osx/desktop_launcher/Instiki_Prefix.pch +7 -0
- data/natives/osx/desktop_launcher/MakeDMG.sh +9 -0
- data/natives/osx/desktop_launcher/main.mm +14 -0
- data/natives/osx/desktop_launcher/version.plist +16 -0
- data/public/404.html +6 -0
- data/public/500.html +6 -0
- data/public/dispatch.rb +10 -0
- data/public/favicon.ico +0 -0
- data/public/javascripts/edit_web.js +52 -0
- data/public/javascripts/prototype.js +336 -0
- data/{app/views/static_style_sheet.rhtml → public/stylesheets/instiki.css} +221 -198
- data/script/breakpointer +4 -0
- data/script/server +93 -0
- metadata +59 -32
- data/app/controllers/wiki.rb +0 -389
- data/app/models/chunks/match.rb +0 -19
- data/app/views/bottom.rhtml +0 -4
- data/app/views/top.rhtml +0 -49
- data/app/views/wiki/edit_web.rhtml +0 -138
- data/libraries/action_controller_servlet.rb +0 -177
- data/libraries/erb.rb +0 -490
- data/libraries/madeleine_service.rb +0 -68
- data/libraries/redcloth_for_tex.rb +0 -869
- data/libraries/web_controller_server.rb +0 -81
data/app/models/chunks/nowiki.rb
CHANGED
@@ -1,31 +1,28 @@
|
|
1
|
-
require 'chunks/chunk'
|
2
|
-
|
3
|
-
# This chunks allows certain parts of a wiki page to be hidden from the
|
4
|
-
# rest of the rendering pipeline. It should be run at the beginning
|
5
|
-
# of the pipeline in `wiki_content.rb`.
|
6
|
-
#
|
7
|
-
# An example use of this chunk is to markup double brackets or
|
8
|
-
# auto URI links:
|
9
|
-
# <nowiki>Here are [[double brackets]] and a URI: www.uri.org</nowiki>
|
10
|
-
#
|
11
|
-
# The contents of the chunks will not be processed by any other chunk
|
12
|
-
# so the `www.uri.org` and the double brackets will appear verbatim.
|
13
|
-
#
|
14
|
-
# Author: Mark Reid <mark at threewordslong dot com>
|
15
|
-
# Created: 8th June 2004
|
16
|
-
class NoWiki < Chunk::Abstract
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
def unmask(content) nil end
|
30
|
-
def revert(content) content.sub!( Regexp.new(mask(content)), plain_text ) end
|
31
|
-
end
|
1
|
+
require 'chunks/chunk'
|
2
|
+
|
3
|
+
# This chunks allows certain parts of a wiki page to be hidden from the
|
4
|
+
# rest of the rendering pipeline. It should be run at the beginning
|
5
|
+
# of the pipeline in `wiki_content.rb`.
|
6
|
+
#
|
7
|
+
# An example use of this chunk is to markup double brackets or
|
8
|
+
# auto URI links:
|
9
|
+
# <nowiki>Here are [[double brackets]] and a URI: www.uri.org</nowiki>
|
10
|
+
#
|
11
|
+
# The contents of the chunks will not be processed by any other chunk
|
12
|
+
# so the `www.uri.org` and the double brackets will appear verbatim.
|
13
|
+
#
|
14
|
+
# Author: Mark Reid <mark at threewordslong dot com>
|
15
|
+
# Created: 8th June 2004
|
16
|
+
class NoWiki < Chunk::Abstract
|
17
|
+
|
18
|
+
NOWIKI_PATTERN = Regexp.new('<nowiki>(.*?)</nowiki>')
|
19
|
+
def self.pattern() NOWIKI_PATTERN end
|
20
|
+
|
21
|
+
attr_reader :plain_text
|
22
|
+
|
23
|
+
def initialize(match_data, content)
|
24
|
+
super
|
25
|
+
@plain_text = @unmask_text = match_data[1]
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
data/app/models/chunks/test.rb
CHANGED
@@ -1,18 +1,18 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
|
3
|
-
class ChunkTest < Test::Unit::TestCase
|
4
|
-
|
5
|
-
# Asserts a number of tests for the given type and text.
|
6
|
-
def match(type, test_text, expected)
|
7
|
-
pattern = type.pattern
|
8
|
-
assert_match(pattern, test_text)
|
9
|
-
pattern =~ test_text # Previous assertion guarantees match
|
10
|
-
chunk = type.new($~)
|
11
|
-
|
12
|
-
# Test if requested parts are correct.
|
13
|
-
for method_sym, value in expected do
|
14
|
-
assert_respond_to(chunk, method_sym)
|
15
|
-
assert_equal(value, chunk.method(method_sym).call, "Checking value of '#{method_sym}'")
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
class ChunkTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
# Asserts a number of tests for the given type and text.
|
6
|
+
def match(type, test_text, expected)
|
7
|
+
pattern = type.pattern
|
8
|
+
assert_match(pattern, test_text)
|
9
|
+
pattern =~ test_text # Previous assertion guarantees match
|
10
|
+
chunk = type.new($~)
|
11
|
+
|
12
|
+
# Test if requested parts are correct.
|
13
|
+
for method_sym, value in expected do
|
14
|
+
assert_respond_to(chunk, method_sym)
|
15
|
+
assert_equal(value, chunk.method(method_sym).call, "Checking value of '#{method_sym}'")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/app/models/chunks/uri.rb
CHANGED
@@ -1,97 +1,182 @@
|
|
1
|
-
require 'chunks/chunk'
|
2
|
-
|
3
|
-
# This wiki chunk matches arbitrary URIs, using patterns from the Ruby URI modules.
|
4
|
-
# It parses out a variety of fields that could be used by renderers to format
|
5
|
-
# the links in various ways (shortening domain names, hiding email addresses)
|
6
|
-
# It matches email addresses and host.com.au domains without schemes (http://)
|
7
|
-
# but adds these on as required.
|
8
|
-
#
|
9
|
-
# The heuristic used to match a URI is designed to err on the side of caution.
|
10
|
-
# That is, it is more likely to not autolink a URI than it is to accidently
|
11
|
-
# autolink something that is not a URI. The reason behind this is it is easier
|
12
|
-
# to force a URI link by prefixing 'http://' to it than it is to escape and
|
13
|
-
# incorrectly marked up non-URI.
|
14
|
-
#
|
15
|
-
# I'm using a part of the [ISO 3166-1 Standard][iso3166] for country name suffixes.
|
16
|
-
# The generic names are from www.bnoack.com/data/countrycode2.html)
|
17
|
-
# [iso3166]: http://geotags.com/iso3166/
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
#
|
48
|
-
#
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
#
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
end
|
1
|
+
require 'chunks/chunk'
|
2
|
+
|
3
|
+
# This wiki chunk matches arbitrary URIs, using patterns from the Ruby URI modules.
|
4
|
+
# It parses out a variety of fields that could be used by renderers to format
|
5
|
+
# the links in various ways (shortening domain names, hiding email addresses)
|
6
|
+
# It matches email addresses and host.com.au domains without schemes (http://)
|
7
|
+
# but adds these on as required.
|
8
|
+
#
|
9
|
+
# The heuristic used to match a URI is designed to err on the side of caution.
|
10
|
+
# That is, it is more likely to not autolink a URI than it is to accidently
|
11
|
+
# autolink something that is not a URI. The reason behind this is it is easier
|
12
|
+
# to force a URI link by prefixing 'http://' to it than it is to escape and
|
13
|
+
# incorrectly marked up non-URI.
|
14
|
+
#
|
15
|
+
# I'm using a part of the [ISO 3166-1 Standard][iso3166] for country name suffixes.
|
16
|
+
# The generic names are from www.bnoack.com/data/countrycode2.html)
|
17
|
+
# [iso3166]: http://geotags.com/iso3166/
|
18
|
+
|
19
|
+
class URIChunk < Chunk::Abstract
|
20
|
+
include URI::REGEXP::PATTERN
|
21
|
+
|
22
|
+
# this condition is to get rid of pesky warnings in tests
|
23
|
+
unless defined? URIChunk::INTERNET_URI_REGEXP
|
24
|
+
|
25
|
+
GENERIC = 'aero|biz|com|coop|edu|gov|info|int|mil|museum|name|net|org'
|
26
|
+
|
27
|
+
COUNTRY = 'ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|az|ba|bb|bd|be|' +
|
28
|
+
'bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cf|cd|cg|ch|ci|ck|cl|' +
|
29
|
+
'cm|cn|co|cr|cs|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|fi|' +
|
30
|
+
'fj|fk|fm|fo|fr|fx|ga|gb|gd|ge|gf|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|' +
|
31
|
+
'hk|hm|hn|hr|ht|hu|id|ie|il|in|io|iq|ir|is|it|jm|jo|jp|ke|kg|kh|ki|km|kn|' +
|
32
|
+
'kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|mg|mh|mk|ml|mm|' +
|
33
|
+
'mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nt|' +
|
34
|
+
'nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|pt|pw|py|qa|re|ro|ru|rw|sa|sb|sc|' +
|
35
|
+
'sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|' +
|
36
|
+
'tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|' +
|
37
|
+
'ws|ye|yt|yu|za|zm|zr|zw'
|
38
|
+
# These are needed otherwise HOST will match almost anything
|
39
|
+
TLDS = "(?:#{GENERIC}|#{COUNTRY})"
|
40
|
+
|
41
|
+
# Redefine USERINFO so that it must have non-zero length
|
42
|
+
USERINFO = "(?:[#{UNRESERVED};:&=+$,]|#{ESCAPED})+"
|
43
|
+
|
44
|
+
# unreserved_no_ending = alphanum | mark, but URI_ENDING [)!] excluded
|
45
|
+
UNRESERVED_NO_ENDING = "-_.~*'(#{ALNUM}"
|
46
|
+
|
47
|
+
# this ensures that query or fragment do not end with URI_ENDING
|
48
|
+
# and enable us to use a much simpler self.pattern Regexp
|
49
|
+
|
50
|
+
# uric_no_ending = reserved | unreserved_no_ending | escaped
|
51
|
+
URIC_NO_ENDING = "(?:[#{UNRESERVED_NO_ENDING}#{RESERVED}]|#{ESCAPED})"
|
52
|
+
# query = *uric
|
53
|
+
QUERY = "#{URIC_NO_ENDING}*"
|
54
|
+
# fragment = *uric
|
55
|
+
FRAGMENT = "#{URIC_NO_ENDING}*"
|
56
|
+
|
57
|
+
# DOMLABEL is defined in the ruby uri library, TLDS is defined above
|
58
|
+
INTERNET_HOSTNAME = "(?:#{DOMLABEL}\\.)+#{TLDS}"
|
59
|
+
|
60
|
+
# Correct a typo bug in ruby 1.8.x lib/uri/common.rb
|
61
|
+
PORT = '\\d*'
|
62
|
+
|
63
|
+
INTERNET_URI =
|
64
|
+
"(?:(#{SCHEME}):/{0,2})?" + # Optional scheme: (\1)
|
65
|
+
"(?:(#{USERINFO})@)?" + # Optional userinfo@ (\2)
|
66
|
+
"(#{INTERNET_HOSTNAME})" + # Mandatory hostname (\3)
|
67
|
+
"(?::(#{PORT}))?" + # Optional :port (\4)
|
68
|
+
"(#{ABS_PATH})?" + # Optional absolute path (\5)
|
69
|
+
"(?:\\?(#{QUERY}))?" + # Optional ?query (\6)
|
70
|
+
"(?:\\#(#{FRAGMENT}))?" + # Optional #fragment (\7)
|
71
|
+
'(?=\.?(?:\s|\)|\z))' # ends only with optional dot + space or ")"
|
72
|
+
# or end of the string
|
73
|
+
|
74
|
+
SUSPICIOUS_PRECEDING_CHARACTER = '(!|\"\:|\"|\\\')?' # any of !, ":, ", '
|
75
|
+
|
76
|
+
INTERNET_URI_REGEXP =
|
77
|
+
Regexp.new(SUSPICIOUS_PRECEDING_CHARACTER + INTERNET_URI, Regexp::EXTENDED, 'N')
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
def URIChunk.pattern
|
82
|
+
INTERNET_URI_REGEXP
|
83
|
+
end
|
84
|
+
|
85
|
+
attr_reader :user, :host, :port, :path, :query, :fragment, :link_text
|
86
|
+
|
87
|
+
def self.apply_to(content)
|
88
|
+
content.gsub!( self.pattern ) do |matched_text|
|
89
|
+
chunk = self.new($~, content)
|
90
|
+
if chunk.avoid_autolinking?
|
91
|
+
# do not substitute nor register the chunk
|
92
|
+
matched_text
|
93
|
+
else
|
94
|
+
content.add_chunk(chunk)
|
95
|
+
chunk.mask
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def initialize(match_data, content)
|
101
|
+
super
|
102
|
+
@link_text = match_data[0]
|
103
|
+
@suspicious_preceding_character = match_data[1]
|
104
|
+
@original_scheme, @user, @host, @port, @path, @query, @fragment = match_data[2..-1]
|
105
|
+
treat_trailing_character
|
106
|
+
@unmask_text = "<a href=\"#{uri}\">#{link_text}</a>"
|
107
|
+
end
|
108
|
+
|
109
|
+
def avoid_autolinking?
|
110
|
+
not @suspicious_preceding_character.nil?
|
111
|
+
end
|
112
|
+
|
113
|
+
def treat_trailing_character
|
114
|
+
# If the last character matched by URI pattern is in ! or ), this may be part of the markup,
|
115
|
+
# not a URL. We should handle it as such. It is possible to do it by a regexp, but
|
116
|
+
# much easier to do programmatically
|
117
|
+
last_char = @link_text[-1..-1]
|
118
|
+
if last_char == ')' or last_char == '!'
|
119
|
+
@trailing_punctuation = last_char
|
120
|
+
@link_text.chop!
|
121
|
+
[@original_scheme, @user, @host, @port, @path, @query, @fragment].compact.last.chop!
|
122
|
+
else
|
123
|
+
@trailing_punctuation = nil
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def scheme
|
128
|
+
@original_scheme or (@user ? 'mailto' : 'http')
|
129
|
+
end
|
130
|
+
|
131
|
+
def scheme_delimiter
|
132
|
+
scheme == 'mailto' ? ':' : '://'
|
133
|
+
end
|
134
|
+
|
135
|
+
def user_delimiter
|
136
|
+
'@' unless @user.nil?
|
137
|
+
end
|
138
|
+
|
139
|
+
def port_delimiter
|
140
|
+
':' unless @port.nil?
|
141
|
+
end
|
142
|
+
|
143
|
+
def query_delimiter
|
144
|
+
'?' unless @query.nil?
|
145
|
+
end
|
146
|
+
|
147
|
+
def uri
|
148
|
+
[scheme, scheme_delimiter, user, user_delimiter, host, port_delimiter, port, path,
|
149
|
+
query_delimiter, query].compact.join
|
150
|
+
end
|
151
|
+
|
152
|
+
end
|
153
|
+
|
154
|
+
# uri with mandatory scheme but less restrictive hostname, like
|
155
|
+
# http://localhost:2500/blah.html
|
156
|
+
class LocalURIChunk < URIChunk
|
157
|
+
|
158
|
+
unless defined? LocalURIChunk::LOCAL_URI_REGEXP
|
159
|
+
# hostname can be just a simple word like 'localhost'
|
160
|
+
ANY_HOSTNAME = "(?:#{DOMLABEL}\\.)*#{TOPLABEL}\\.?"
|
161
|
+
|
162
|
+
# The basic URI expression as a string
|
163
|
+
# Scheme and hostname are mandatory
|
164
|
+
LOCAL_URI =
|
165
|
+
"(?:(#{SCHEME})://)+" + # Mandatory scheme:// (\1)
|
166
|
+
"(?:(#{USERINFO})@)?" + # Optional userinfo@ (\2)
|
167
|
+
"(#{ANY_HOSTNAME})" + # Mandatory hostname (\3)
|
168
|
+
"(?::(#{PORT}))?" + # Optional :port (\4)
|
169
|
+
"(#{ABS_PATH})?" + # Optional absolute path (\5)
|
170
|
+
"(?:\\?(#{QUERY}))?" + # Optional ?query (\6)
|
171
|
+
"(?:\\#(#{FRAGMENT}))?" + # Optional #fragment (\7)
|
172
|
+
'(?=\.?(?:\s|\)|\z))' # ends only with optional dot + space or ")"
|
173
|
+
# or end of the string
|
174
|
+
|
175
|
+
LOCAL_URI_REGEXP = Regexp.new(SUSPICIOUS_PRECEDING_CHARACTER + LOCAL_URI, Regexp::EXTENDED, 'N')
|
176
|
+
end
|
177
|
+
|
178
|
+
def LocalURIChunk.pattern
|
179
|
+
LOCAL_URI_REGEXP
|
180
|
+
end
|
181
|
+
|
182
|
+
end
|
data/app/models/chunks/wiki.rb
CHANGED
@@ -1,82 +1,141 @@
|
|
1
|
-
require 'wiki_words'
|
2
|
-
require 'chunks/chunk'
|
3
|
-
require '
|
4
|
-
|
5
|
-
|
6
|
-
# links.
|
7
|
-
module WikiChunk
|
8
|
-
include Chunk
|
9
|
-
|
10
|
-
# A wiki
|
11
|
-
# another wiki page.
|
12
|
-
class
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
# the
|
18
|
-
def
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
#
|
60
|
-
#
|
61
|
-
#
|
62
|
-
#
|
63
|
-
class
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
1
|
+
require 'wiki_words'
|
2
|
+
require 'chunks/chunk'
|
3
|
+
require 'chunks/wiki'
|
4
|
+
require 'cgi'
|
5
|
+
|
6
|
+
# Contains all the methods for finding and replacing wiki related links.
|
7
|
+
module WikiChunk
|
8
|
+
include Chunk
|
9
|
+
|
10
|
+
# A wiki reference is the top-level class for anything that refers to
|
11
|
+
# another wiki page.
|
12
|
+
class WikiReference < Chunk::Abstract
|
13
|
+
|
14
|
+
# Name of the referenced page
|
15
|
+
attr_reader :page_name
|
16
|
+
|
17
|
+
# the referenced page
|
18
|
+
def refpage
|
19
|
+
@content.web.pages[@page_name]
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
# A wiki link is the top-level class for links that refers to
|
25
|
+
# another wiki page.
|
26
|
+
class WikiLink < WikiReference
|
27
|
+
|
28
|
+
attr_reader :link_text, :link_type
|
29
|
+
|
30
|
+
def initialize(match_data, content)
|
31
|
+
super
|
32
|
+
@link_type = :show
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.apply_to(content)
|
36
|
+
content.gsub!( self.pattern ) do |matched_text|
|
37
|
+
chunk = self.new($~, content)
|
38
|
+
if chunk.textile_url?
|
39
|
+
# do not substitute
|
40
|
+
matched_text
|
41
|
+
else
|
42
|
+
content.add_chunk(chunk)
|
43
|
+
chunk.mask
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# the referenced page
|
49
|
+
def refpage
|
50
|
+
@content.web.pages[@page_name]
|
51
|
+
end
|
52
|
+
|
53
|
+
def textile_url?
|
54
|
+
not @textile_link_suffix.nil?
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
# This chunk matches a WikiWord. WikiWords can be escaped
|
60
|
+
# by prepending a '\'. When this is the case, the +escaped_text+
|
61
|
+
# method will return the WikiWord instead of the usual +nil+.
|
62
|
+
# The +page_name+ method returns the matched WikiWord.
|
63
|
+
class Word < WikiLink
|
64
|
+
|
65
|
+
attr_reader :escaped_text
|
66
|
+
|
67
|
+
unless defined? WIKI_WORD
|
68
|
+
WIKI_WORD = Regexp.new('(":)?(\\\\)?(' + WikiWords::WIKI_WORD_PATTERN + ')\b', 0, "utf-8")
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.pattern
|
72
|
+
WIKI_WORD
|
73
|
+
end
|
74
|
+
|
75
|
+
def initialize(match_data, content)
|
76
|
+
super
|
77
|
+
@textile_link_suffix, @escape, @page_name = match_data[1..3]
|
78
|
+
if @escape
|
79
|
+
@unmask_mode = :escape
|
80
|
+
@escaped_text = @page_name
|
81
|
+
else
|
82
|
+
@escaped_text = nil
|
83
|
+
end
|
84
|
+
@link_text = WikiWords.separate(@page_name)
|
85
|
+
@unmask_text = (@escaped_text || @content.page_link(@page_name, @link_text, @link_type))
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
# This chunk handles [[bracketted wiki words]] and
|
91
|
+
# [[AliasedWords|aliased wiki words]]. The first part of an
|
92
|
+
# aliased wiki word must be a WikiWord. If the WikiWord
|
93
|
+
# is aliased, the +link_text+ field will contain the
|
94
|
+
# alias, otherwise +link_text+ will contain the entire
|
95
|
+
# contents within the double brackets.
|
96
|
+
#
|
97
|
+
# NOTE: This chunk must be tested before WikiWord since
|
98
|
+
# a WikiWords can be a substring of a WikiLink.
|
99
|
+
class Link < WikiLink
|
100
|
+
|
101
|
+
unless defined? WIKI_LINK
|
102
|
+
WIKI_LINK = /(":)?\[\[([^\]]+)\]\]/
|
103
|
+
LINK_TYPE_SEPARATION = Regexp.new('^(.+):((file)|(pic))$', 0, 'utf-8')
|
104
|
+
ALIAS_SEPARATION = Regexp.new('^(.+)\|(.+)$', 0, 'utf-8')
|
105
|
+
end
|
106
|
+
|
107
|
+
def self.pattern() WIKI_LINK end
|
108
|
+
|
109
|
+
def initialize(match_data, content)
|
110
|
+
super
|
111
|
+
@textile_link_suffix, @page_name = match_data[1..2]
|
112
|
+
@link_text = @page_name
|
113
|
+
separate_link_type
|
114
|
+
separate_alias
|
115
|
+
@unmask_text = @content.page_link(@page_name, @link_text, @link_type)
|
116
|
+
end
|
117
|
+
|
118
|
+
private
|
119
|
+
|
120
|
+
# if link wihin the brackets has a form of [[filename:file]] or [[filename:pic]],
|
121
|
+
# this means a link to a picture or a file
|
122
|
+
def separate_link_type
|
123
|
+
link_type_match = LINK_TYPE_SEPARATION.match(@page_name)
|
124
|
+
if link_type_match
|
125
|
+
@link_text = @page_name = link_type_match[1]
|
126
|
+
@link_type = link_type_match[2..3].compact[0].to_sym
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# link text may be different from page name. this will look like [[actual page|link text]]
|
131
|
+
def separate_alias
|
132
|
+
alias_match = ALIAS_SEPARATION.match(@page_name)
|
133
|
+
if alias_match
|
134
|
+
@page_name, @link_text = alias_match[1..2]
|
135
|
+
end
|
136
|
+
# note that [[filename|link text:file]] is also supported
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|