require 'wiki_words'
require 'chunks/chunk'
require 'cgi'
# Contains all the methods for finding and replacing wiki related
# links.
module WikiChunk
include Chunk
# A wiki link is the top-level class for anything that refers to
# another wiki page.
class WikiLink < Chunk::Abstract
# By default, no escaped text
def escaped_text() nil end
# Delimit the link text with markers to replace later unless
# the word is escaped. In that case, just return the link text
def mask(content) escaped_text || pre_mask + link_text + post_mask end
def regexp() Regexp.new(pre_mask + '(.*)?' + post_mask) end
def revert(content) content.sub!(regexp, text) end
# Do not keep this chunk if it is escaped.
# Otherwise, pass the link procedure a page_name and link_text and
# get back a string of HTML to replace the mask with.
def unmask(content)
return nil if escaped_text
return self if content.sub!(regexp) { |match| content.page_link(page_name, $1) }
end
end
# This chunk matches a WikiWord. WikiWords can be escaped
# by prepending a '\'. When this is the case, the +escaped_text+
# method will return the WikiWord instead of the usual +nil+.
# The +page_name+ method returns the matched WikiWord.
class Word < WikiLink
def self.pattern
Regexp.new('(\\\\)?(' + WikiWords::WIKI_WORD_PATTERN + ')()?', 0, "utf-8")
end # (chunk\d+chunk)?
attr_reader :page_name
def initialize(match_data, revision)
super(match_data, revision)
@escaped = match_data[1] || match_data[3]
@text.delete! '\\' if @escaped
@page_name = @link_text = match_data[2]
end
def mask(content) pre_mask + post_mask; end
def regexp() Regexp.new(pre_mask + post_mask) end
def escaped_text() (@escaped.nil? ? nil : page_name) end
def link_text() WikiWords.separate(page_name) end
end
# This chunk handles [[bracketted wiki words]] and
# [[AliasedWords|aliased wiki words]]. The first part of an
# aliased wiki word must be a WikiWord. If the WikiWord
# is aliased, the +link_text+ field will contain the
# alias, otherwise +link_text+ will contain the entire
# contents within the double brackets.
#
# NOTE: This chunk must be tested before WikiWord since
# a WikiWords can be a substring of a WikiLink.
class Link < WikiLink
def self.pattern() /\[\[([^\]]+)\]\]/ end
ALIASED_LINK_PATTERN= Regexp.new('^(.*)?\|(.*)$', 0, "utf-8")
attr_reader :page_name, :link_text
def initialize(match_data, revision)
super(match_data, revision)
# If the like is aliased, set the page name to the first bit
# and the link text to the second, otherwise set both to the
# contents of the double brackets.
if match_data[1] =~ ALIASED_LINK_PATTERN
@page_name, @link_text = $1, $2
else
@page_name, @link_text = match_data[1], match_data[1]
end
end
end
# This chunk handles [bliki[entry name]].
# This format can be easily duplicated for any other pre-configured redirection.
class BlikiLink < WikiLink
def self.pattern() /\[(\w+)\[([\w\d\s]+)\]\]/ end
attr_reader :page_name, :link_text, :entry
def initialize(match_data, revision)
super(match_data, revision)
@target, @page_name, @link_text = match_data[1], match_data[2], match_data[2]
end
def unmask(content)
return self if content.sub!(regexp) { |match|
case @target
when 'bliki'
web = revision.page.web
entry = web.bliki[page_name]
if entry.nil?
"Unknown Bliki entry: '#{page_name}'"
else
"#{entry.name}"
end
when 'c2'
"C2::#{@page_name}"
end
}
end
end
end