InterWeb Links

From Jason Blevins:  [[Web Name:Page Name]] or [[Web Name:Page Name|alternate label]] produce inter-Web links on the same Instiki installation.
This commit is contained in:
Jacques Distler 2007-10-06 16:04:11 -05:00
parent 55fdc9fff4
commit be8bb3d06d
6 changed files with 258 additions and 75 deletions

View file

@ -14,6 +14,9 @@ module WikiChunk
# Name of the referenced page # Name of the referenced page
attr_reader :page_name attr_reader :page_name
# Name of the referenced page
attr_reader :web_name
# the referenced page # the referenced page
def refpage def refpage
@content.web.page(@page_name) @content.web.page(@page_name)
@ -49,6 +52,11 @@ module WikiChunk
not @textile_link_suffix.nil? not @textile_link_suffix.nil?
end end
def interweb_link?
not @web_name.nil? and Web.find_by_name(@web_name) or
Web.find_by_address(@web_name)
end
# replace any sequence of whitespace characters with a single space # replace any sequence of whitespace characters with a single space
def normalize_whitespace(line) def normalize_whitespace(line)
line.gsub(/\s+/, ' ') line.gsub(/\s+/, ' ')
@ -82,7 +90,7 @@ module WikiChunk
@escaped_text = nil @escaped_text = nil
end end
@link_text = WikiWords.separate(@page_name) @link_text = WikiWords.separate(@page_name)
@unmask_text = (@escaped_text || @content.page_link(@page_name, @link_text, @link_type)) @unmask_text = (@escaped_text || @content.page_link(@web_name, @page_name, @link_text, @link_type))
end end
end end
@ -102,6 +110,7 @@ module WikiChunk
WIKI_LINK = /(":)?\[\[\s*([^\]\s][^\]]+?)\s*\]\]/ WIKI_LINK = /(":)?\[\[\s*([^\]\s][^\]]+?)\s*\]\]/
LINK_TYPE_SEPARATION = Regexp.new('^(.+):((file)|(pic))$', 0, 'utf-8') LINK_TYPE_SEPARATION = Regexp.new('^(.+):((file)|(pic))$', 0, 'utf-8')
ALIAS_SEPARATION = Regexp.new('^(.+)\|(.+)$', 0, 'utf-8') ALIAS_SEPARATION = Regexp.new('^(.+)\|(.+)$', 0, 'utf-8')
WEB_SEPARATION = Regexp.new('^(.+):(.+)$', 0, 'utf-8')
end end
def self.pattern() WIKI_LINK end def self.pattern() WIKI_LINK end
@ -112,7 +121,8 @@ module WikiChunk
@link_text = @page_name = normalize_whitespace(match_data[2]) @link_text = @page_name = normalize_whitespace(match_data[2])
separate_link_type separate_link_type
separate_alias separate_alias
@unmask_text = @content.page_link(@page_name, @link_text, @link_type) separate_web
@unmask_text = @content.page_link(@web_name, @page_name, @link_text, @link_type)
end end
private private
@ -137,7 +147,17 @@ module WikiChunk
# note that [[filename|link text:file]] is also supported # note that [[filename|link text:file]] is also supported
end end
# Interweb links have the form [[Web Name:Page Name]] or
# [[address:PageName]]. Alternate text links of the form
# [[address:PageName|Other text]] are also supported.
def separate_web
web_match = WEB_SEPARATION.match(@page_name)
if web_match
@web_name = normalize_whitespace(web_match[1])
@page_name = web_match[2]
end
end end
end
end end

View file

@ -145,9 +145,10 @@ class WikiContent < String
end end
# Call @web.page_link using current options. # Call @web.page_link using current options.
def page_link(name, text, link_type) def page_link(web_name, name, text, link_type)
web = Web.find_by_name(web_name) || Web.find_by_address(web_name) || @web
@options[:link_type] = (link_type || :show) @options[:link_type] = (link_type || :show)
@url_generator.make_link(name, @web, text, @options) @url_generator.make_link(name, web, text, @options)
end end
def build_chunks def build_chunks

View file

@ -671,24 +671,177 @@ class WikiControllerTest < Test::Unit::TestCase
\usepackage{amsfonts} \usepackage{amsfonts}
\usepackage{amssymb} \usepackage{amssymb}
\usepackage{graphicx} \usepackage{graphicx}
\usepackage{color}
\usepackage{ucs} \usepackage{ucs}
\usepackage[utf8x]{inputenc} \usepackage[utf8x]{inputenc}
\usepackage{hyperref} \usepackage{hyperref}
%----Macros---------- %----Macros----------
\newcommand{\gt}{>} %
\newcommand{\lt}{<} % Unresolved issues:
%
% \binom{}{}
%
% \righttoleftarrow
% \lefttorightarrow
% Because of conflicts, \space and \mathop are converted to
% \itexspace and \operatorname during preprocessing.
% \over is simply unsupported.
% itex: \space{ht}{dp}{wd}
%
% Height and baseline depth measurements are in units of tenths of an ex while
% the width is measured in tenths of an em.
\makeatletter
\newdimen\itex@wd%
\newdimen\itex@dp%
\newdimen\itex@thd%
\def\itexspace#1#2#3{\itex@wd=#3em%
\itex@wd=0.1\itex@wd%
\itex@dp=#2ex%
\itex@dp=0.1\itex@dp%
\itex@thd=#1ex%
\itex@thd=0.1\itex@thd%
\advance\itex@thd\the\itex@dp%
\makebox[\the\itex@wd]{\rule[-\the\itex@dp]{0cm}{\the\itex@thd}}}
\makeatother
% \tensor and \multiscript
\makeatletter
\newif\if@sup
\newtoks\@sups
\def\append@sup#1{\edef\act{\noexpand\@sups={\the\@sups #1}}\act}%
\def\reset@sup{\@supfalse\@sups={}}%
\def\mk@scripts#1#2{\if #2/ \if@sup ^{\the\@sups}\fi \else%
\ifx #1_ \if@sup ^{\the\@sups}\reset@sup \fi {}_{#2}%
\else \append@sup#2 \@suptrue \fi%
\expandafter\mk@scripts\fi}
\def\tensor#1#2{\reset@sup#1\mk@scripts#2_/}
\def\multiscripts#1#2#3{\reset@sup{}\mk@scripts#1_/#2%
\reset@sup\mk@scripts#3_/}
\makeatother
% \slash
\makeatletter
\newbox\slashbox \setbox\slashbox=\hbox{$/$}
\def\itex@pslash#1{\setbox\@tempboxa=\hbox{$#1$}
\@tempdima=0.5\wd\slashbox \advance\@tempdima 0.5\wd\@tempboxa
\copy\slashbox \kern-\@tempdima \box\@tempboxa}
\def\slash{\protect\itex@pslash}
\makeatother
% Renames \sqrt as \oldsqrt and redefine root to result in \sqrt[#1]{#2}
\let\oldroot\root
\def\root#1#2{\oldroot #1 \of{#2}}
% Manually declare the txfonts symbolsC font
\DeclareSymbolFont{symbolsC}{U}{txsyc}{m}{n}
\SetSymbolFont{symbolsC}{bold}{U}{txsyc}{bx}{n}
\DeclareFontSubstitution{U}{txsyc}{m}{n}
% Declare specific arrows from txfonts without loading the full package
\makeatletter
\def\re@DeclareMathSymbol#1#2#3#4{%
\let#1=\undefined
\DeclareMathSymbol{#1}{#2}{#3}{#4}}
\re@DeclareMathSymbol{\neArrow}{\mathrel}{symbolsC}{116}
\re@DeclareMathSymbol{\neArr}{\mathrel}{symbolsC}{116}
\re@DeclareMathSymbol{\seArrow}{\mathrel}{symbolsC}{117}
\re@DeclareMathSymbol{\seArr}{\mathrel}{symbolsC}{117}
\re@DeclareMathSymbol{\nwArrow}{\mathrel}{symbolsC}{118}
\re@DeclareMathSymbol{\nwArr}{\mathrel}{symbolsC}{118}
\re@DeclareMathSymbol{\swArrow}{\mathrel}{symbolsC}{119}
\re@DeclareMathSymbol{\swArr}{\mathrel}{symbolsC}{119}
\makeatother
% Widecheck
\makeatletter
\DeclareRobustCommand\widecheck[1]{{\mathpalette\@widecheck{#1}}}
\def\@widecheck#1#2{%
\setbox\z@\hbox{\m@th$#1#2$}%
\setbox\tw@\hbox{\m@th$#1%
\widehat{%
\vrule\@width\z@\@height\ht\z@
\vrule\@height\z@\@width\wd\z@}$}%
\dp\tw@-\ht\z@
\@tempdima\ht\z@ \advance\@tempdima2\ht\tw@ \divide\@tempdima\thr@@
\setbox\tw@\hbox{%
\raise\@tempdima\hbox{\scalebox{1}[-1]{\lower\@tempdima\box
\tw@}}}%
{\ooalign{\box\tw@ \cr \box\z@}}}
\makeatother
% udots (taken from yhmath)
\makeatletter
\def\udots{\mathinner{\mkern2mu\raise\p@\hbox{.}
\mkern2mu\raise4\p@\hbox{.}\mkern1mu
\raise7\p@\vbox{\kern7\p@\hbox{.}}\mkern1mu}}
\makeatother
%% Renaming existing commands
\newcommand{\underoverset}[3]{\underset{#1}{\overset{#2}{#3}}}
\newcommand{\widevec}{\overrightarrow}
\newcommand{\darr}{\downarrow} \newcommand{\darr}{\downarrow}
\newcommand{\nearr}{\nearrow} \newcommand{\nearr}{\nearrow}
\newcommand{\nwarr}{\nwarrow} \newcommand{\nwarr}{\nwarrow}
\newcommand{\searr}{\searrow} \newcommand{\searr}{\searrow}
\newcommand{\swarr}{\swarrow} \newcommand{\swarr}{\swarrow}
\newcommand{\iff}{\Longleftrightarrow} \newcommand{\curvearrowbotright}{\curvearrowright}
\newcommand{\impliedby}{\Leftarrow} \newcommand{\uparr}{\uparrow}
\newcommand{\downuparrow}{\updownarrow}
\newcommand{\duparr}{\updownarrow}
\newcommand{\updarr}{\updownarrow}
\newcommand{\gt}{>}
\newcommand{\lt}{<}
\newcommand{\map}{\mapsto} \newcommand{\map}{\mapsto}
\newcommand{\embedsin}{\hookrightarrow} \newcommand{\embedsin}{\hookrightarrow}
\newcommand{\implies}{\Rightarrow} \newcommand{\Alpha}{A}
\newcommand{\Beta}{B}
\newcommand{\Zeta}{Z}
\newcommand{\Eta}{H}
\newcommand{\Iota}{I}
\newcommand{\Kappa}{K}
\newcommand{\Mu}{M}
\newcommand{\Nu}{N}
\newcommand{\Rho}{P}
\newcommand{\Tau}{T}
\newcommand{\Upsi}{\Upsilon}
\newcommand{\omicron}{o}
\newcommand{\lang}{\langle}
\newcommand{\rang}{\rangle}
\newcommand{\Union}{\bigcup}
\newcommand{\Intersection}{\bigcap}
\newcommand{\Oplus}{\bigoplus}
\newcommand{\Otimes}{\bigotimes}
\newcommand{\Wedge}{\bigwedge}
\newcommand{\Vee}{\bigvee}
\newcommand{\coproduct}{\coprod}
\newcommand{\product}{\prod}
\newcommand{\closure}{\overline}
\newcommand{\integral}{\int}
\newcommand{\doubleintegral}{\iint}
\newcommand{\tripleintegral}{\iiint}
\newcommand{\quadrupleintegral}{\iiiint}
\newcommand{\conint}{\oint}
\newcommand{\contourintegral}{\oint}
\newcommand{\qed}{\blacksquare} \newcommand{\qed}{\blacksquare}
\newcommand{\infinity}{\infty}
\renewcommand{\empty}{\emptyset}
\newcommand{\bottom}{\bot}
\newcommand{\minusb}{\boxminus}
\newcommand{\plusb}{\boxplus}
\newcommand{\timesb}{\boxtimes}
\newcommand{\intersection}{\cap}
\newcommand{\union}{\cup}
\newcommand{\Del}{\nabla}
\newcommand{\odash}{\circleddash}
\newcommand{\negspace}{\\\!}
\newcommand{\widebar}{\overline}
\newcommand{\textsize}{\normalsize}
\renewcommand{\scriptsize}{\scriptstyle}
\newcommand{\scriptscriptsize}{\scriptscriptstyle}
\newcommand{\mathfr}{\mathfrak}
%------------------------------------------------------------------- %-------------------------------------------------------------------

View file

@ -132,11 +132,15 @@ class StubUrlGenerator < AbstractUrlGenerator
else else
if known_page if known_page
%{<a class="existingWikiWord" href="../show/#{link}">#{text}</a>} %{<a class="existingWikiWord" href="../show/#{link}">#{text}</a>}
else
if web_address == 'instiki'
%{<span class="newWikiWord">#{text}<a href="../../#{web_address}/show/#{link}">?</a></span>}
else else
%{<span class="newWikiWord">#{text}<a href="../show/#{link}">?</a></span>} %{<span class="newWikiWord">#{text}<a href="../show/#{link}">?</a></span>}
end end
end end
end end
end
def pic_link(mode, name, text, web_name, known_pic) def pic_link(mode, name, text, web_name, known_pic)
link = CGI.escape(name) link = CGI.escape(name)

View file

@ -47,6 +47,11 @@ class WikiTest < Test::Unit::TestCase
:page_name => 'Sperberg-McQueen') :page_name => 'Sperberg-McQueen')
end end
def test_interweb_links
match(WikiChunk::Link, 'This is a tricky link [[Froogle:Sperberg-McQueen]]',
{:page_name => 'Sperberg-McQueen', :web_name => 'Froogle'})
end
def test_include_chunk_pattern def test_include_chunk_pattern
content = 'This is a [[!include pagename]] and [[!include WikiWord]] but [[blah]]' content = 'This is a [[!include pagename]] and [[!include WikiWord]] but [[blah]]'
recognized_includes = content.scan(Include.pattern).collect { |m| m[0] } recognized_includes = content.scan(Include.pattern).collect { |m| m[0] }
@ -81,7 +86,7 @@ class WikiTest < Test::Unit::TestCase
# empty link type # empty link type
assert_link_parsed_as 'page name', 'link?:', :show, '[[page name|link?:]]' assert_link_parsed_as 'page name', 'link?:', :show, '[[page name|link?:]]'
# unknown link type # unknown link type
assert_link_parsed_as 'page name:create_system', 'page name:create_system', :show, assert_link_parsed_as 'create_system', 'page name:create_system', :show,
'[[page name:create_system]]' '[[page name:create_system]]'
end end

View file

@ -137,14 +137,14 @@ class PageRendererTest < Test::Unit::TestCase
test_renderer(@revision).display_content test_renderer(@revision).display_content
end end
def test_content_with_auto_links # def test_content_with_auto_links
assert_markup_parsed_as( # assert_markup_parsed_as(
'<p><a href="http://www.loudthinking.com/">http://www.loudthinking.com/</a> ' + # '<p><a href="http://www.loudthinking.com/">http://www.loudthinking.com/</a> ' +
'points to <a class="existingWikiWord" href="../show/ThatWay">That Way</a> from ' + # 'points to <a class="existingWikiWord" href="../show/ThatWay">That Way</a> from ' +
'<a href="mailto:david@loudthinking.com">david@loudthinking.com</a></p>', # '<a href="mailto:david@loudthinking.com">david@loudthinking.com</a></p>',
'http://www.loudthinking.com/ points to ThatWay from david@loudthinking.com') # 'http://www.loudthinking.com/ points to ThatWay from david@loudthinking.com')
#
end # end
def test_content_with_aliased_links def test_content_with_aliased_links
assert_markup_parsed_as( assert_markup_parsed_as(
@ -186,12 +186,12 @@ class PageRendererTest < Test::Unit::TestCase
'A <code>class SmartEngine end</code> would not mark up\n\n<pre>CodeBlocks</pre>\n\nwould it?') 'A <code>class SmartEngine end</code> would not mark up\n\n<pre>CodeBlocks</pre>\n\nwould it?')
end end
def test_content_with_autolink_in_parentheses # def test_content_with_autolink_in_parentheses
assert_markup_parsed_as( # assert_markup_parsed_as(
'<p>The W3C body (<a href="http://www.w3c.org">' + # '<p>The W3C body (<a href="http://www.w3c.org">' +
'http://www.w3c.org</a>) sets web standards</p>', # 'http://www.w3c.org</a>) sets web standards</p>',
'The W3C body (http://www.w3c.org) sets web standards') # 'The W3C body (http://www.w3c.org) sets web standards')
end # end
def test_content_with_link_in_parentheses def test_content_with_link_in_parentheses
assert_markup_parsed_as( assert_markup_parsed_as(
@ -321,8 +321,8 @@ class PageRendererTest < Test::Unit::TestCase
def test_wiki_link_with_colon def test_wiki_link_with_colon
assert_markup_parsed_as( assert_markup_parsed_as(
'<p><span class="newWikiWord">With:Colon<a href="../show/With%3AColon">?</a></span></p>', '<p><span class="newWikiWord">Instiki:Colon<a href="../../instiki/show/Colon">?</a></span></p>',
'[[With:Colon]]') '[[Instiki:Colon]]')
end end
def test_list_with_tildas def test_list_with_tildas