Pimki 1.0.092
Sign up to get free protection for your applications and to get access to all the features.
- data/README +158 -0
- data/README-PIMKI +87 -0
- data/app/controllers/wiki.rb +563 -0
- data/app/models/author.rb +4 -0
- data/app/models/chunks/category.rb +31 -0
- data/app/models/chunks/category_test.rb +21 -0
- data/app/models/chunks/chunk.rb +20 -0
- data/app/models/chunks/engines.rb +34 -0
- data/app/models/chunks/include.rb +29 -0
- data/app/models/chunks/literal.rb +19 -0
- data/app/models/chunks/match.rb +19 -0
- data/app/models/chunks/nowiki.rb +31 -0
- data/app/models/chunks/nowiki_test.rb +14 -0
- data/app/models/chunks/test.rb +18 -0
- data/app/models/chunks/todo.rb +22 -0
- data/app/models/chunks/uri.rb +97 -0
- data/app/models/chunks/uri_test.rb +92 -0
- data/app/models/chunks/wiki.rb +82 -0
- data/app/models/chunks/wiki_test.rb +36 -0
- data/app/models/page.rb +91 -0
- data/app/models/page_lock.rb +24 -0
- data/app/models/page_set.rb +73 -0
- data/app/models/page_test.rb +76 -0
- data/app/models/revision.rb +91 -0
- data/app/models/revision_test.rb +252 -0
- data/app/models/web.rb +277 -0
- data/app/models/web_test.rb +53 -0
- data/app/models/wiki_content.rb +113 -0
- data/app/models/wiki_service.rb +137 -0
- data/app/models/wiki_service_test.rb +15 -0
- data/app/models/wiki_words.rb +26 -0
- data/app/models/wiki_words_test.rb +12 -0
- data/app/views/bottom.rhtml +4 -0
- data/app/views/markdown_help.rhtml +16 -0
- data/app/views/menu.rhtml +20 -0
- data/app/views/navigation.rhtml +26 -0
- data/app/views/rdoc_help.rhtml +16 -0
- data/app/views/static_style_sheet.rhtml +231 -0
- data/app/views/style.rhtml +179 -0
- data/app/views/textile_help.rhtml +28 -0
- data/app/views/top.rhtml +52 -0
- data/app/views/wiki/authors.rhtml +15 -0
- data/app/views/wiki/bliki.rhtml +101 -0
- data/app/views/wiki/bliki_edit.rhtml +33 -0
- data/app/views/wiki/bliki_new.rhtml +61 -0
- data/app/views/wiki/bliki_revision.rhtml +51 -0
- data/app/views/wiki/edit.rhtml +34 -0
- data/app/views/wiki/edit_menu.rhtml +27 -0
- data/app/views/wiki/edit_web.rhtml +139 -0
- data/app/views/wiki/export.rhtml +14 -0
- data/app/views/wiki/feeds.rhtml +10 -0
- data/app/views/wiki/list.rhtml +164 -0
- data/app/views/wiki/locked.rhtml +14 -0
- data/app/views/wiki/login.rhtml +11 -0
- data/app/views/wiki/mind.rhtml +39 -0
- data/app/views/wiki/new.rhtml +27 -0
- data/app/views/wiki/new_system.rhtml +78 -0
- data/app/views/wiki/new_web.rhtml +64 -0
- data/app/views/wiki/page.rhtml +84 -0
- data/app/views/wiki/print.rhtml +16 -0
- data/app/views/wiki/published.rhtml +10 -0
- data/app/views/wiki/recently_revised.rhtml +31 -0
- data/app/views/wiki/revision.rhtml +87 -0
- data/app/views/wiki/rss_feed.rhtml +22 -0
- data/app/views/wiki/search.rhtml +26 -0
- data/app/views/wiki/tex.rhtml +23 -0
- data/app/views/wiki/tex_web.rhtml +35 -0
- data/app/views/wiki/todo.rhtml +39 -0
- data/app/views/wiki/web_list.rhtml +13 -0
- data/app/views/wiki_words_help.rhtml +8 -0
- data/libraries/action_controller_servlet.rb +177 -0
- data/libraries/bluecloth.rb +1127 -0
- data/libraries/diff/diff.rb +475 -0
- data/libraries/diff/diff_test.rb +80 -0
- data/libraries/erb.rb +490 -0
- data/libraries/madeleine/automatic.rb +357 -0
- data/libraries/madeleine/clock.rb +94 -0
- data/libraries/madeleine_service.rb +69 -0
- data/libraries/rdocsupport.rb +156 -0
- data/libraries/redcloth_for_tex.rb +869 -0
- data/libraries/redcloth_for_tex_test.rb +41 -0
- data/libraries/view_helper.rb +33 -0
- data/libraries/web_controller_server.rb +95 -0
- data/pimki.rb +97 -0
- metadata +169 -0
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'chunks/chunk'
|
2
|
+
|
3
|
+
# The category chunk looks for "category: news" on a line by
|
4
|
+
# itself and parses the terms after the ':' as categories.
|
5
|
+
# Other classes can search for Category chunks within
|
6
|
+
# rendered content to find out what categories this page
|
7
|
+
# should be in.
|
8
|
+
#
|
9
|
+
# Category lines can be hidden using ':category: news', for example
|
10
|
+
class Category < Chunk::Abstract
|
11
|
+
def self.pattern() return /^(:)?category\s*:(.*)$/i end
|
12
|
+
|
13
|
+
attr_reader :hidden, :list
|
14
|
+
|
15
|
+
def initialize(match_data)
|
16
|
+
super(match_data)
|
17
|
+
@hidden = match_data[1]
|
18
|
+
@list = match_data[2].split(',').map { |c| c.strip }
|
19
|
+
end
|
20
|
+
|
21
|
+
# Mark this chunk's start and end points but allow the terms
|
22
|
+
# after the ':' to be marked up.
|
23
|
+
def mask(content) pre_mask + list.join(', ') + post_mask end
|
24
|
+
|
25
|
+
# If the chunk is hidden, erase the mask and return this chunk
|
26
|
+
# otherwise, surround it with a 'div' block.
|
27
|
+
def unmask(content)
|
28
|
+
replacement = ( hidden ? '' : '<div class="property">category:\1</div>' )
|
29
|
+
self if content.sub!( Regexp.new( pre_mask+'(.*)?'+post_mask ), replacement )
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'chunks/category'
|
2
|
+
require 'chunks/match'
|
3
|
+
require 'test/unit'
|
4
|
+
|
5
|
+
class CategoryTest < Test::Unit::TestCase
|
6
|
+
include ChunkMatch
|
7
|
+
|
8
|
+
def test_single_category
|
9
|
+
match(Category, 'category: test', :list => ['test'], :hidden => nil)
|
10
|
+
match(Category, 'category : chunk test ', :list => ['chunk test'], :hidden => nil)
|
11
|
+
match(Category, ':category: test', :list => ['test'], :hidden => ':')
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_multiple_categories
|
15
|
+
match(Category, 'category: test, multiple', :list => ['test', 'multiple'], :hidden => nil)
|
16
|
+
match(Category, 'category : chunk test , multi category,regression test case ',
|
17
|
+
:list => ['chunk test','multi category','regression test case'], :hidden => nil
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
require 'uri/common'
|
3
|
+
|
4
|
+
# A chunk is a pattern of text that can be protected
|
5
|
+
# and interrogated by a renderer. Each Chunk class has a
|
6
|
+
# +pattern+ that states what sort of text it matches.
|
7
|
+
# Chunks are initalized by passing in the result of a
|
8
|
+
# match by its pattern.
|
9
|
+
module Chunk
|
10
|
+
class Abstract
|
11
|
+
attr_reader :text
|
12
|
+
|
13
|
+
def initialize(match_data) @text = match_data[0] end
|
14
|
+
def pre_mask() "chunk#{self.id}start " end
|
15
|
+
def post_mask() " chunk#{self.id}end" end
|
16
|
+
def mask(content) "chunk#{self.id}chunk" end
|
17
|
+
def revert(content) content.sub!( Regexp.new(mask(content)), text ) end
|
18
|
+
def unmask(content) self if revert(content) end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'rdocsupport'
|
2
|
+
require 'chunks/chunk'
|
3
|
+
|
4
|
+
# The markup engines are Chunks that call the one of RedCloth, BlueCloth
|
5
|
+
# or RDoc to convert text. This markup occurs when the chunk is required
|
6
|
+
# to mask itself.
|
7
|
+
module Engines
|
8
|
+
class Textile < Chunk::Abstract
|
9
|
+
def self.pattern() /^(.*)$/m end
|
10
|
+
def mask(content)
|
11
|
+
RedCloth.new(text,content.options[:engine_opts]).to_html
|
12
|
+
end
|
13
|
+
def unmask(content) self end
|
14
|
+
end
|
15
|
+
|
16
|
+
class Markdown < Chunk::Abstract
|
17
|
+
def self.pattern() /^(.*)$/m end
|
18
|
+
def mask(content)
|
19
|
+
BlueCloth.new(text,content.options[:engine_opts]).to_html
|
20
|
+
end
|
21
|
+
def unmask(content) self end
|
22
|
+
end
|
23
|
+
|
24
|
+
class RDoc < Chunk::Abstract
|
25
|
+
def self.pattern() /^(.*)$/m end
|
26
|
+
def mask(content)
|
27
|
+
RDocSupport::RDocFormatter.new(text).to_html
|
28
|
+
end
|
29
|
+
def unmask(content) self end
|
30
|
+
end
|
31
|
+
|
32
|
+
MAP = { :textile => Textile, :markdown => Markdown, :rdoc => RDoc }
|
33
|
+
end
|
34
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'chunks/wiki'
|
2
|
+
|
3
|
+
# Includes the contents of another page for rendering.
|
4
|
+
# The include command looks like this: "[[!include PageName]]".
|
5
|
+
# It is a WikiLink since it refers to another page (PageName)
|
6
|
+
# and the wiki content using this command must be notified
|
7
|
+
# of changes to that page.
|
8
|
+
# If the included page could not be found, a warning is displayed.
|
9
|
+
class Include < WikiChunk::WikiLink
|
10
|
+
def self.pattern() /^\[\[!include(.*)\]\]\s*$/i end
|
11
|
+
|
12
|
+
attr_reader :page_name
|
13
|
+
|
14
|
+
def initialize(match_data)
|
15
|
+
super(match_data)
|
16
|
+
@page_name = match_data[1].strip
|
17
|
+
end
|
18
|
+
|
19
|
+
# This replaces the [[!include PageName]] text with
|
20
|
+
# the contents of PageName if it exists. Otherwise
|
21
|
+
# a warning is displayed.
|
22
|
+
def mask(content)
|
23
|
+
page = content.web.pages[page_name]
|
24
|
+
(page ? page.content : "<em>Could not include #{page_name}</em>")
|
25
|
+
end
|
26
|
+
|
27
|
+
# Keep this chunk regardless of what happens.
|
28
|
+
def unmask(content) self end
|
29
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'chunks/chunk'
|
2
|
+
|
3
|
+
# These are basic chunks that have a pattern and can be protected.
|
4
|
+
# They are used by rendering process to prevent wiki rendering
|
5
|
+
# occuring within literal areas such as <code> and <pre> blocks
|
6
|
+
# and within HTML tags.
|
7
|
+
module Literal
|
8
|
+
# A literal chunk that protects 'code' and 'pre' tags from wiki rendering.
|
9
|
+
class Pre < Chunk::Abstract
|
10
|
+
PRE_BLOCKS = "a|pre|code"
|
11
|
+
def self.pattern() Regexp.new('<('+PRE_BLOCKS+')\b[^>]*?>.*?</\1>', Regexp::MULTILINE) end
|
12
|
+
end
|
13
|
+
|
14
|
+
# A literal chunk that protects HTML tags from wiki rendering.
|
15
|
+
class Tags < Chunk::Abstract
|
16
|
+
TAGS = "a|img|em|strong|div|span|table|td|th|ul|ol|li|dl|dt|dd"
|
17
|
+
def self.pattern() Regexp.new('<(?:'+TAGS+')[^>]*?>', Regexp::MULTILINE) end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# This module is to be included in unit tests that involve matching chunks.
|
2
|
+
# It provides a easy way to test whether a chunk matches a particular string
|
3
|
+
# and any the values of any fields that should be set after a match.
|
4
|
+
module ChunkMatch
|
5
|
+
|
6
|
+
# Asserts a number of tests for the given type and text.
|
7
|
+
def match(type, test_text, expected)
|
8
|
+
pattern = type.pattern
|
9
|
+
assert_match(pattern, test_text)
|
10
|
+
pattern =~ test_text # Previous assertion guarantees match
|
11
|
+
chunk = type.new($~)
|
12
|
+
|
13
|
+
# Test if requested parts are correct.
|
14
|
+
for method_sym, value in expected do
|
15
|
+
assert_respond_to(chunk, method_sym)
|
16
|
+
assert_equal(value, chunk.method(method_sym).call, "Checking value of '#{method_sym}'")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,31 @@
|
|
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
|
+
def self.pattern() Regexp.new('<nowiki>(.*?)</nowiki>') end
|
19
|
+
|
20
|
+
attr_reader :plain_text
|
21
|
+
|
22
|
+
def initialize(match_data)
|
23
|
+
super(match_data)
|
24
|
+
@plain_text = match_data[1]
|
25
|
+
end
|
26
|
+
|
27
|
+
# The nowiki content is not unmasked. This means the chunk will be reverted
|
28
|
+
# using the plain text.
|
29
|
+
def unmask(content) nil end
|
30
|
+
def revert(content) content.sub!( Regexp.new(mask(content)), plain_text ) end
|
31
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'chunks/nowiki'
|
2
|
+
require 'chunks/match'
|
3
|
+
require 'test/unit'
|
4
|
+
|
5
|
+
class NoWikiTest < Test::Unit::TestCase
|
6
|
+
include ChunkMatch
|
7
|
+
|
8
|
+
def test_simple_nowiki
|
9
|
+
match(NoWiki, 'This sentence contains <nowiki>[[raw text]]</nowiki>. Do not touch!',
|
10
|
+
:plain_text => '[[raw text]]'
|
11
|
+
)
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +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
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'chunks/wiki'
|
2
|
+
require 'date'
|
3
|
+
require 'parsedate'
|
4
|
+
|
5
|
+
# ToDo items.
|
6
|
+
class Todo < Chunk::Abstract
|
7
|
+
def self.pattern() /todo: ([^\n]+)/i end
|
8
|
+
|
9
|
+
def initialize(match_data)
|
10
|
+
super(match_data)
|
11
|
+
end
|
12
|
+
|
13
|
+
def escaped_text() nil end
|
14
|
+
|
15
|
+
def unmask(content)
|
16
|
+
return self if content.gsub!( Regexp.new(mask(content)),
|
17
|
+
# the style 'todo' is bright-red to be eye catching. It is not expected that
|
18
|
+
# there will be too many items on one page, but each is supposed to stand out.
|
19
|
+
# The ToDo special page differentiates between the 'todo' and 'todoFuture' styles.
|
20
|
+
"<span class=\"todo\"><strong>TODO:</strong> #{@text.gsub(/todo:\s*/, '')}</span>" )
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,97 @@
|
|
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
|
+
class URIChunk < Chunk::Abstract
|
19
|
+
include URI::REGEXP::PATTERN
|
20
|
+
|
21
|
+
GENERIC = '(?:aero|biz|com|coop|edu|gov|info|int|mil|museum|name|net|org)'
|
22
|
+
COUNTRY = '(?:au|at|be|ca|ch|de|dk|fr|hk|in|ir|it|jp|nl|no|pt|ru|se|sw|tv|tw|uk|us)'
|
23
|
+
|
24
|
+
# These are needed otherwise HOST will match almost anything
|
25
|
+
TLDS = "\\.(?:#{GENERIC}|#{COUNTRY})"
|
26
|
+
|
27
|
+
# Redefine USERINFO so that it must have non-zero length
|
28
|
+
USERINFO = "(?:[#{UNRESERVED};:&=+$,]|#{ESCAPED})+"
|
29
|
+
|
30
|
+
# Pattern of legal URI endings to stop interference with some Textile
|
31
|
+
# markup. (Images: !URI!) and other punctuation eg, (http://wiki.com/)
|
32
|
+
URI_ENDING = '[)!]'
|
33
|
+
|
34
|
+
# The basic URI expression as a string
|
35
|
+
URI_PATTERN =
|
36
|
+
"(?:(#{SCHEME})://)?" + # Optional scheme:// (\1|\8)
|
37
|
+
"(?:(#{USERINFO})@)?" + # Optional userinfo@ (\2|\9)
|
38
|
+
"(#{HOSTNAME}#{TLDS})" + # Mandatory host eg, HOST.com.au (\3|\10)
|
39
|
+
"(?::(#{PORT}))?" + # Optional :port (\4|\11)
|
40
|
+
"(#{ABS_PATH})?" + # Optional absolute path (\5|\12)
|
41
|
+
"(?:\\?(#{QUERY}))?" + # Optional ?query (\6|\13)
|
42
|
+
"(?:\\#(#{FRAGMENT}))?" # Optional #fragment (\7|\14)
|
43
|
+
|
44
|
+
def self.pattern()
|
45
|
+
# This pattern first tries to match the URI_PATTERN that ends with
|
46
|
+
# punctuation that is a valid URI character (eg, ')', '!'). If
|
47
|
+
# such a match occurs, there should be no backtracking (hence the ?> ).
|
48
|
+
# If the string cannot match a URI ending with URI_ENDING, then a second
|
49
|
+
# attempt is tried.
|
50
|
+
Regexp.new("(?>#{URI_PATTERN}(?=#{URI_ENDING}))|#{URI_PATTERN}", Regexp::EXTENDED, 'N')
|
51
|
+
end
|
52
|
+
|
53
|
+
attr_reader :uri, :scheme, :user, :host, :port, :path, :query, :fragment, :link_text
|
54
|
+
|
55
|
+
def initialize(match_data)
|
56
|
+
super(match_data)
|
57
|
+
# Since the URI_PATTERN is tried twice, there are two sets of
|
58
|
+
# groups, one from \1 to \7 and the second from \8 to \14.
|
59
|
+
# The fields are set by which ever group matches.
|
60
|
+
@scheme = match_data[1] || match_data[8]
|
61
|
+
@user = match_data[2] || match_data[9]
|
62
|
+
@host = match_data[3] || match_data[10]
|
63
|
+
@port = match_data[4] || match_data[11]
|
64
|
+
@path = match_data[5] || match_data[12]
|
65
|
+
@query = match_data[6] || match_data[13]
|
66
|
+
@fragment = match_data[7] || match_data[14]
|
67
|
+
|
68
|
+
# If there is no scheme, add an appropriate one, otherwise
|
69
|
+
# set the URI to the matched text.
|
70
|
+
@text_scheme = scheme
|
71
|
+
@uri = (scheme ? match_data[0] : nil )
|
72
|
+
@scheme = scheme || ( user ? 'mailto' : 'http' )
|
73
|
+
@delimiter = ( scheme == 'mailto' ? ':' : '://' )
|
74
|
+
@uri ||= scheme + @delimiter + match_data[0]
|
75
|
+
|
76
|
+
# Build up the link text. Schemes are omitted unless explicitly given.
|
77
|
+
@link_text = ''
|
78
|
+
@link_text << "#{@scheme}#{@delimiter}" if @text_scheme
|
79
|
+
@link_text << "#{@user}@" if @user
|
80
|
+
@link_text << "#{@host}" if @host
|
81
|
+
@link_text << ":#{@port}" if @port
|
82
|
+
@link_text << "#{@path}" if @path
|
83
|
+
@link_text << "?#{@query}" if @query
|
84
|
+
end
|
85
|
+
|
86
|
+
# If the text should be escaped then don't keep this chunk.
|
87
|
+
# Otherwise only keep this chunk if it was substituted back into the
|
88
|
+
# content.
|
89
|
+
def unmask(content)
|
90
|
+
return nil if escaped_text
|
91
|
+
return self if content.sub!( Regexp.new(mask(content)), "<a href=\"#{uri}\">#{link_text}</a>" )
|
92
|
+
end
|
93
|
+
|
94
|
+
# If there is no hostname in the URI, do not render it
|
95
|
+
# It's probably only contains the scheme, eg 'something:'
|
96
|
+
def escaped_text() ( host.nil? ? @uri : nil ) end
|
97
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'chunks/uri'
|
2
|
+
require 'chunks/match'
|
3
|
+
require 'test/unit'
|
4
|
+
|
5
|
+
class URITest < Test::Unit::TestCase
|
6
|
+
include ChunkMatch
|
7
|
+
|
8
|
+
def test_non_matches
|
9
|
+
assert_no_match(URIChunk.pattern, 'There is no URI here')
|
10
|
+
assert_no_match(URIChunk.pattern, 'One gemstone is the garnet:reddish in colour, like ruby')
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_simple_uri
|
14
|
+
match(URIChunk, 'http://www.example.com',
|
15
|
+
:scheme =>'http', :host =>'www.example.com', :path => nil,
|
16
|
+
:link_text => 'http://www.example.com'
|
17
|
+
)
|
18
|
+
match(URIChunk, 'http://www.example.com/',
|
19
|
+
:scheme =>'http', :host =>'www.example.com', :path => '/',
|
20
|
+
:link_text => 'http://www.example.com/'
|
21
|
+
)
|
22
|
+
match(URIChunk, 'www.example.com',
|
23
|
+
:scheme =>'http', :host =>'www.example.com', :link_text => 'www.example.com'
|
24
|
+
)
|
25
|
+
match(URIChunk, 'example.com',
|
26
|
+
:scheme =>'http',:host =>'example.com', :link_text => 'example.com'
|
27
|
+
)
|
28
|
+
match(URIChunk, 'http://example.com.au/',
|
29
|
+
:scheme =>'http', :host =>'example.com.au', :link_text => 'http://example.com.au/'
|
30
|
+
)
|
31
|
+
match(URIChunk, 'example.com.au',
|
32
|
+
:scheme =>'http', :host =>'example.com.au', :link_text => 'example.com.au'
|
33
|
+
)
|
34
|
+
match(URIChunk, 'http://www.example.co.uk/',
|
35
|
+
:scheme =>'http', :host =>'www.example.co.uk',
|
36
|
+
:link_text => 'http://www.example.co.uk/'
|
37
|
+
)
|
38
|
+
match(URIChunk, 'example.co.uk',
|
39
|
+
:scheme =>'http', :host =>'example.co.uk', :link_text => 'example.co.uk'
|
40
|
+
)
|
41
|
+
match(URIChunk, 'http://moinmoin.wikiwikiweb.de/HelpOnNavigation',
|
42
|
+
:scheme => 'http', :host => 'moinmoin.wikiwikiweb.de', :path => '/HelpOnNavigation',
|
43
|
+
:link_text => 'http://moinmoin.wikiwikiweb.de/HelpOnNavigation'
|
44
|
+
)
|
45
|
+
match(URIChunk, 'moinmoin.wikiwikiweb.de/HelpOnNavigation',
|
46
|
+
:scheme => 'http', :host => 'moinmoin.wikiwikiweb.de', :path => '/HelpOnNavigation',
|
47
|
+
:link_text => 'moinmoin.wikiwikiweb.de/HelpOnNavigation'
|
48
|
+
)
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_email_uri
|
52
|
+
match(URIChunk, 'mail@example.com',
|
53
|
+
:user => 'mail', :host => 'example.com', :link_text => 'mail@example.com'
|
54
|
+
)
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_non_email
|
58
|
+
# The @ is part of the normal text, but 'example.com' is marked up.
|
59
|
+
match(URIChunk, 'Not an email: @example.com', :user => nil, :uri => 'http://example.com')
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_non_uri
|
63
|
+
assert_no_match(URIChunk.pattern, 'httpd.conf')
|
64
|
+
assert_no_match(URIChunk.pattern, 'libproxy.so')
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_uri_in_text
|
68
|
+
match(URIChunk, 'Go to: http://www.example.com/', :host => 'www.example.com', :path =>'/')
|
69
|
+
match(URIChunk, 'http://www.example.com/ is a link.', :host => 'www.example.com')
|
70
|
+
match(URIChunk,
|
71
|
+
'Email david@loudthinking.com',
|
72
|
+
:scheme =>'mailto', :user =>'david', :host =>'loudthinking.com'
|
73
|
+
)
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_uri_in_parentheses
|
77
|
+
match(URIChunk, 'URI (http://brackets.com.de) in brackets', :host => 'brackets.com.de')
|
78
|
+
match(URIChunk, 'because (as shown at research.net) the results', :host => 'research.net')
|
79
|
+
match(URIChunk,
|
80
|
+
'A wiki (http://wiki.org/wiki.cgi?WhatIsWiki) page',
|
81
|
+
:scheme => 'http', :host => 'wiki.org', :path => '/wiki.cgi', :query => 'WhatIsWiki'
|
82
|
+
)
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_uri_list_item
|
86
|
+
match(
|
87
|
+
URIChunk,
|
88
|
+
'* http://www.btinternet.com/~mail2minh/SonyEricssonP80xPlatform.sis',
|
89
|
+
:path => '/~mail2minh/SonyEricssonP80xPlatform.sis'
|
90
|
+
)
|
91
|
+
end
|
92
|
+
end
|