84 lines
2.7 KiB
Ruby
84 lines
2.7 KiB
Ruby
|
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 + ')\b', 0, "utf-8")
|
||
|
end
|
||
|
|
||
|
attr_reader :page_name
|
||
|
|
||
|
def initialize(match_data)
|
||
|
super(match_data)
|
||
|
@escape = match_data[1]
|
||
|
@page_name = match_data[2]
|
||
|
end
|
||
|
|
||
|
def escaped_text() (@escape.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)
|
||
|
super(match_data)
|
||
|
|
||
|
# 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
|
||
|
end
|