Wiki link (square brackets) now knows its type (show, file or pic),
and does not mess up with Textile link hyperlink syntax
This commit is contained in:
parent
87ab5d00ae
commit
92404470e8
|
@ -3,14 +3,31 @@ require 'chunks/chunk'
|
||||||
require 'chunks/wiki'
|
require 'chunks/wiki'
|
||||||
require 'cgi'
|
require 'cgi'
|
||||||
|
|
||||||
# Contains all the methods for finding and replacing wiki related
|
# Contains all the methods for finding and replacing wiki related links.
|
||||||
# links.
|
|
||||||
module WikiChunk
|
module WikiChunk
|
||||||
include Chunk
|
include Chunk
|
||||||
|
|
||||||
# A wiki link is the top-level class for anything that refers to
|
# A wiki link is the top-level class for anything that refers to
|
||||||
# another wiki page.
|
# another wiki page.
|
||||||
class WikiLink < Chunk::Abstract
|
class WikiLink < Chunk::Abstract
|
||||||
|
|
||||||
|
def self.apply_to(content)
|
||||||
|
content.gsub!( self.pattern ) do |matched_text|
|
||||||
|
chunk = self.new($~)
|
||||||
|
if chunk.textile_url?
|
||||||
|
# do not substitute
|
||||||
|
matched_text
|
||||||
|
else
|
||||||
|
content.chunks << chunk
|
||||||
|
chunk.mask(content)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def textile_url?
|
||||||
|
not @textile_link_suffix.nil?
|
||||||
|
end
|
||||||
|
|
||||||
# By default, no escaped text
|
# By default, no escaped text
|
||||||
def escaped_text() nil end
|
def escaped_text() nil end
|
||||||
|
|
||||||
|
@ -31,6 +48,7 @@ module WikiChunk
|
||||||
content.page_link(page_name, $1)
|
content.page_link(page_name, $1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# This chunk matches a WikiWord. WikiWords can be escaped
|
# This chunk matches a WikiWord. WikiWords can be escaped
|
||||||
|
@ -39,9 +57,9 @@ module WikiChunk
|
||||||
# The +page_name+ method returns the matched WikiWord.
|
# The +page_name+ method returns the matched WikiWord.
|
||||||
class Word < WikiLink
|
class Word < WikiLink
|
||||||
unless defined? WIKI_LINK
|
unless defined? WIKI_LINK
|
||||||
WIKI_WORD = Regexp.new('(\\\\)?(' + WikiWords::WIKI_WORD_PATTERN + ')\b', 0, "utf-8")
|
WIKI_WORD = Regexp.new('(":)?(\\\\)?(' + WikiWords::WIKI_WORD_PATTERN + ')\b', 0, "utf-8")
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.pattern
|
def self.pattern
|
||||||
WIKI_WORD
|
WIKI_WORD
|
||||||
end
|
end
|
||||||
|
@ -50,8 +68,7 @@ module WikiChunk
|
||||||
|
|
||||||
def initialize(match_data)
|
def initialize(match_data)
|
||||||
super(match_data)
|
super(match_data)
|
||||||
@escape = match_data[1]
|
@textile_link_suffix, @escape, @page_name = match_data[1..3]
|
||||||
@page_name = match_data[2]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def escaped_text() (@escape.nil? ? nil : page_name) end
|
def escaped_text() (@escape.nil? ? nil : page_name) end
|
||||||
|
@ -69,25 +86,41 @@ module WikiChunk
|
||||||
# a WikiWords can be a substring of a WikiLink.
|
# a WikiWords can be a substring of a WikiLink.
|
||||||
class Link < WikiLink
|
class Link < WikiLink
|
||||||
|
|
||||||
WIKI_LINK = /\[\[([^\]]+)\]\]/ unless defined? WIKI_LINK
|
unless defined? WIKI_LINK
|
||||||
ALIASED_LINK_PATTERN =
|
WIKI_LINK = /(":)?\[\[([^\]]+)\]\]/
|
||||||
Regexp.new('^(.*)?\|(.*)$', 0, 'utf-8') unless defined? ALIASED_LINK_PATTERN
|
LINK_TYPE_SEPARATION = Regexp.new('^(.+):((file)|(pic))$', 0, 'utf-8')
|
||||||
|
ALIAS_SEPARATION = Regexp.new('^(.+)\|(.+)$', 0, 'utf-8')
|
||||||
|
end
|
||||||
|
|
||||||
def self.pattern() WIKI_LINK end
|
def self.pattern() WIKI_LINK end
|
||||||
|
|
||||||
attr_reader :page_name, :link_text
|
|
||||||
|
attr_reader :page_name, :link_text, :link_type
|
||||||
|
|
||||||
def initialize(match_data)
|
def initialize(match_data)
|
||||||
super(match_data)
|
super(match_data)
|
||||||
|
|
||||||
# If the like is aliased, set the page name to the first bit
|
@textile_link_suffix, @page_name = match_data[1..2]
|
||||||
# and the link text to the second, otherwise set both to the
|
|
||||||
# contents of the double brackets.
|
# defaults
|
||||||
if match_data[1] =~ ALIASED_LINK_PATTERN
|
@link_type = 'show'
|
||||||
@page_name, @link_text = $1, $2
|
@link_text = @page_name
|
||||||
else
|
|
||||||
@page_name, @link_text = match_data[1], match_data[1]
|
# if link wihin the brackets has a form of [[filename:file]] or [[filename:pic]],
|
||||||
|
# this means a link to a picture or a file
|
||||||
|
link_type_match = LINK_TYPE_SEPARATION.match(@page_name)
|
||||||
|
if link_type_match
|
||||||
|
@link_text = @page_name = link_type_match[1]
|
||||||
|
@link_type = link_type_match[2..3].compact[0]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# link text may be different from page name. this will look like [[actual page|link text]]
|
||||||
|
alias_match = ALIAS_SEPARATION.match(@page_name)
|
||||||
|
if alias_match
|
||||||
|
@page_name, @link_text = alias_match[1..2]
|
||||||
|
end
|
||||||
|
# note that [[filename|link text:file]] is also supported
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,9 +2,15 @@
|
||||||
|
|
||||||
require File.dirname(__FILE__) + '/../../test_helper'
|
require File.dirname(__FILE__) + '/../../test_helper'
|
||||||
require 'chunks/wiki'
|
require 'chunks/wiki'
|
||||||
require 'chunks/match'
|
|
||||||
|
|
||||||
class WikiTest < Test::Unit::TestCase
|
class WikiTest < Test::Unit::TestCase
|
||||||
|
|
||||||
|
class ContentStub < String
|
||||||
|
def chunks
|
||||||
|
@chunks ||= []
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
include ChunkMatch
|
include ChunkMatch
|
||||||
|
|
||||||
def test_simple
|
def test_simple
|
||||||
|
@ -30,7 +36,46 @@ class WikiTest < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_textile_link
|
def test_textile_link
|
||||||
assert_no_match(WikiChunk::Word.pattern, '"Here is a special link":SpecialLink')
|
textile_link = ContentStub.new('"Here is a special link":SpecialLink')
|
||||||
|
WikiChunk::Word.apply_to(textile_link)
|
||||||
|
assert_equal '"Here is a special link":SpecialLink', textile_link
|
||||||
|
assert textile_link.chunks.empty?
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_file_types
|
||||||
|
# only link
|
||||||
|
assert_link_parsed_as 'only text', 'only text', 'show', '[[only text]]'
|
||||||
|
# link and text
|
||||||
|
assert_link_parsed_as 'page name', 'link text', 'show', '[[page name|link text]]'
|
||||||
|
# link and type (file)
|
||||||
|
assert_link_parsed_as 'foo.tar.gz', 'foo.tar.gz', 'file', '[[foo.tar.gz:file]]'
|
||||||
|
# link and type (pic)
|
||||||
|
assert_link_parsed_as 'foo.tar.gz', 'foo.tar.gz', 'pic', '[[foo.tar.gz:pic]]'
|
||||||
|
# link, text and type
|
||||||
|
assert_link_parsed_as 'foo.tar.gz', 'FooTar', 'file', '[[foo.tar.gz|FooTar:file]]'
|
||||||
|
|
||||||
|
# NEGATIVE TEST CASES
|
||||||
|
|
||||||
|
# empty page name
|
||||||
|
assert_link_parsed_as '|link text?', '|link text?', 'file', '[[|link text?:file]]'
|
||||||
|
# empty link text
|
||||||
|
assert_link_parsed_as 'page name?|', 'page name?|', 'file', '[[page name?|:file]]'
|
||||||
|
# empty link type
|
||||||
|
assert_link_parsed_as 'page name', 'link?:', 'show', '[[page name|link?:]]'
|
||||||
|
# unknown link type
|
||||||
|
assert_link_parsed_as 'page name:create_system', 'page name:create_system', 'show',
|
||||||
|
'[[page name:create_system]]'
|
||||||
|
end
|
||||||
|
|
||||||
|
def assert_link_parsed_as(expected_page_name, expected_link_text, expected_link_type, link)
|
||||||
|
link_to_file = ContentStub.new(link)
|
||||||
|
WikiChunk::Link.apply_to(link_to_file)
|
||||||
|
chunk = link_to_file.chunks.last
|
||||||
|
assert chunk
|
||||||
|
assert_equal expected_page_name, chunk.page_name
|
||||||
|
assert_equal expected_link_text, chunk.link_text
|
||||||
|
assert_equal expected_link_type, chunk.link_type
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue