project = options[:project] || @project
- # turn wiki links into html links
- # example:
+ # Wiki links
+ #
+ # Examples:
# [[mypage]]
# [[mypage|mytext]]
# wiki links can refer other project wikis, using project name or identifier:
# [[project:|mytext]]
# [[project:mypage]]
# [[project:mypage|mytext]]
- text = text.gsub(/\[\[([^\]\|]+)(\|([^\]\|]+))?\]\]/) do |m|
+ text = text.gsub(/(!)?(\[\[([^\]\|]+)(\|([^\]\|]+))?\]\])/) do |m|
link_project = project
- page = $1
- title = $3
- if page =~ /^([^\:]+)\:(.*)$/
- link_project = Project.find_by_name($1) || Project.find_by_identifier($1)
- page = title || $2
- title = $1 if page.blank?
- end
-
- if link_project && link_project.wiki
- # check if page exists
- wiki_page = link_project.wiki.find_page(page)
- link_to((title || page), format_wiki_link.call(link_project, Wiki.titleize(page)),
- :class => ('wiki-page' + (wiki_page ? '' : ' new')))
+ esc, all, page, title = $1, $2, $3, $5
+ if esc.nil?
+ if page =~ /^([^\:]+)\:(.*)$/
+ link_project = Project.find_by_name($1) || Project.find_by_identifier($1)
+ page = $2
+ title ||= $1 if page.blank?
+ end
+
+ if link_project && link_project.wiki
+ # check if page exists
+ wiki_page = link_project.wiki.find_page(page)
+ link_to((title || page), format_wiki_link.call(link_project, Wiki.titleize(page)),
+ :class => ('wiki-page' + (wiki_page ? '' : ' new')))
+ else
+ # project or wiki doesn't exist
+ title || page
+ end
else
- # project or wiki doesn't exist
- title || page
+ all
end
end
- # turn issue and revision ids into links
- # example:
- # #52 -> <a href="/issues/show/52">#52</a>
- # r52 -> <a href="/repositories/revision/6?rev=52">r52</a> (project.id is 6)
- text = text.gsub(%r{([\s\(,-^])(#|r)(\d+)(?=[[:punct:]]|\s|<|$)}) do |m|
- leading, otype, oid = $1, $2, $3
+ # Redmine links
+ #
+ # Examples:
+ # Issues:
+ # #52 -> Link to issue #52
+ # Changesets:
+ # r52 -> Link to revision 52
+ # Documents:
+ # document#17 -> Link to document with id 17
+ # document:Greetings -> Link to the document with title "Greetings"
+ # document:"Some document" -> Link to the document with title "Some document"
+ # Versions:
+ # version#3 -> Link to version with id 3
+ # version:1.0.0 -> Link to version named "1.0.0"
+ # version:"1.0 beta 2" -> Link to version named "1.0 beta 2"
+ # Attachments:
+ # attachment:file.zip -> Link to the attachment of the current object named file.zip
+ text = text.gsub(%r{([\s\(,-^])(!)?(attachment|document|version)?((#|r)(\d+)|(:)([^"][^\s<>]+|"[^"]+"))(?=[[:punct:]]|\s|<|$)}) do |m|
+ leading, esc, prefix, sep, oid = $1, $2, $3, $5 || $7, $6 || $8
link = nil
- if otype == 'r'
- if project && (changeset = project.changesets.find_by_revision(oid))
- link = link_to("r#{oid}", {:controller => 'repositories', :action => 'revision', :id => project.id, :rev => oid}, :class => 'changeset',
- :title => truncate(changeset.comments, 100))
- end
- else
- if issue = Issue.find_by_id(oid.to_i, :include => [:project, :status], :conditions => Project.visible_by(User.current))
- link = link_to("##{oid}", {:controller => 'issues', :action => 'show', :id => oid}, :class => 'issue',
- :title => "#{truncate(issue.subject, 100)} (#{issue.status.name})")
- link = content_tag('del', link) if issue.closed?
+ if esc.nil?
+ if prefix.nil? && sep == 'r'
+ if project && (changeset = project.changesets.find_by_revision(oid))
+ link = link_to("r#{oid}", {:controller => 'repositories', :action => 'revision', :id => project.id, :rev => oid}, :class => 'changeset',
+ :title => truncate(changeset.comments, 100))
+ end
+ elsif sep == '#'
+ oid = oid.to_i
+ case prefix
+ when nil
+ if issue = Issue.find_by_id(oid, :include => [:project, :status], :conditions => Project.visible_by(User.current))
+ link = link_to("##{oid}", {:controller => 'issues', :action => 'show', :id => oid}, :class => 'issue',
+ :title => "#{truncate(issue.subject, 100)} (#{issue.status.name})")
+ link = content_tag('del', link) if issue.closed?
+ end
+ when 'document'
+ if document = Document.find_by_id(oid, :include => [:project], :conditions => Project.visible_by(User.current))
+ link = link_to h(document.title), {:controller => 'documents', :action => 'show', :id => document}, :class => 'document'
+ end
+ when 'version'
+ if version = Version.find_by_id(oid, :include => [:project], :conditions => Project.visible_by(User.current))
+ link = link_to h(version.name), {:controller => 'versions', :action => 'show', :id => version}, :class => 'version'
+ end
+ end
+ elsif sep == ':'
+ # removes the double quotes if any
+ name = oid.gsub(%r{^"(.*)"$}, "\\1")
+ case prefix
+ when 'document'
+ if project && document = project.documents.find_by_title(name)
+ link = link_to h(document.title), {:controller => 'documents', :action => 'show', :id => document}, :class => 'document'
+ end
+ when 'version'
+ if project && version = project.versions.find_by_name(name)
+ link = link_to h(version.name), {:controller => 'versions', :action => 'show', :id => version}, :class => 'version'
+ end
+ when 'attachment'
+ if attachments && attachment = attachments.detect {|a| a.filename == name }
+ link = link_to h(attachment.filename), {:controller => 'attachments', :action => 'download', :id => attachment}, :class => 'attachment'
+ end
+ end
end
end
- leading + (link || "#{otype}#{oid}")
+ leading + (link || "#{prefix}#{sep}#{oid}")
end
text
# Elements to handle
GLYPHS = [
# [ /([^\s\[{(>])?\'([dmst]\b|ll\b|ve\b|\s|:|$)/, '\1’\2' ], # single closing
- [ /([^\s\[{(>#{PUNCT_Q}][#{PUNCT_Q}]*)\'/, '\1’' ], # single closing
- [ /\'(?=[#{PUNCT_Q}]*(s\b|[\s#{PUNCT_NOQ}]))/, '’' ], # single closing
- [ /\'/, '‘' ], # single opening
+ # [ /([^\s\[{(>#{PUNCT_Q}][#{PUNCT_Q}]*)\'/, '\1’' ], # single closing
+ # [ /\'(?=[#{PUNCT_Q}]*(s\b|[\s#{PUNCT_NOQ}]))/, '’' ], # single closing
+ # [ /\'/, '‘' ], # single opening
[ /</, '<' ], # less-than
[ />/, '>' ], # greater-than
# [ /([^\s\[{(])?"(\s|:|$)/, '\1”\2' ], # double closing
- [ /([^\s\[{(>#{PUNCT_Q}][#{PUNCT_Q}]*)"/, '\1”' ], # double closing
- [ /"(?=[#{PUNCT_Q}]*[\s#{PUNCT_NOQ}])/, '”' ], # double closing
- [ /"/, '“' ], # double opening
+ # [ /([^\s\[{(>#{PUNCT_Q}][#{PUNCT_Q}]*)"/, '\1”' ], # double closing
+ # [ /"(?=[#{PUNCT_Q}]*[\s#{PUNCT_NOQ}])/, '”' ], # double closing
+ # [ /"/, '“' ], # double opening
[ /\b( )?\.{3}/, '\1…' ], # ellipsis
[ /\b([A-Z][A-Z0-9]{2,})\b(?:[(]([^)]*)[)])/, '<acronym title="\2">\1</acronym>' ], # 3+ uppercase acronym
[ /(^|[^"][>\s])([A-Z][A-Z0-9 ]+[A-Z0-9])([^<A-Za-z0-9]|$)/, '\1<span class="caps">\2</span>\3', :no_span_caps ], # 3+ uppercase caps
class ApplicationHelperTest < HelperTestCase
include ApplicationHelper
include ActionView::Helpers::TextHelper
- fixtures :projects, :repositories, :changesets, :trackers, :issue_statuses, :issues
+ fixtures :projects, :repositories, :changesets, :trackers, :issue_statuses, :issues, :documents, :versions, :wikis, :wiki_pages, :wiki_contents
def setup
super
def test_redmine_links
issue_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3},
:class => 'issue', :title => 'Error 281 when updating a recipe (New)')
+
changeset_link = link_to('r1', {:controller => 'repositories', :action => 'revision', :id => 1, :rev => 1},
:class => 'changeset', :title => 'My very first commit')
+ document_link = link_to('Test document', {:controller => 'documents', :action => 'show', :id => 1},
+ :class => 'document')
+
+ version_link = link_to('1.0', {:controller => 'versions', :action => 'show', :id => 2},
+ :class => 'version')
+
to_test = {
'#3, #3 and #3.' => "#{issue_link}, #{issue_link} and #{issue_link}.",
- 'r1' => changeset_link
+ 'r1' => changeset_link,
+ 'document#1' => document_link,
+ 'document:"Test document"' => document_link,
+ 'version#2' => version_link,
+ 'version:1.0' => version_link,
+ 'version:"1.0"' => version_link,
+ # escaping
+ '!#3.' => '#3.',
+ '!r1' => 'r1',
+ '!document#1' => 'document#1',
+ '!document:"Test document"' => 'document:"Test document"',
+ '!version#2' => 'version#2',
+ '!version:1.0' => 'version:1.0',
+ '!version:"1.0"' => 'version:"1.0"',
+ }
+ @project = Project.find(1)
+ to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
+ end
+
+ def test_wiki_links
+ to_test = {
+ '[[CookBook documentation]]' => '<a href="/wiki/ecookbook/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
+ '[[Another page|Page]]' => '<a href="/wiki/ecookbook/Another_page" class="wiki-page">Page</a>',
+ # page that doesn't exist
+ '[[Unknown page]]' => '<a href="/wiki/ecookbook/Unknown_page" class="wiki-page new">Unknown page</a>',
+ '[[Unknown page|404]]' => '<a href="/wiki/ecookbook/Unknown_page" class="wiki-page new">404</a>',
+ # link to another project wiki
+ '[[onlinestore:]]' => '<a href="/wiki/onlinestore/" class="wiki-page">onlinestore</a>',
+ '[[onlinestore:|Wiki]]' => '<a href="/wiki/onlinestore/" class="wiki-page">Wiki</a>',
+ '[[onlinestore:Start page]]' => '<a href="/wiki/onlinestore/Start_page" class="wiki-page">Start page</a>',
+ '[[onlinestore:Start page|Text]]' => '<a href="/wiki/onlinestore/Start_page" class="wiki-page">Text</a>',
+ '[[onlinestore:Unknown page]]' => '<a href="/wiki/onlinestore/Unknown_page" class="wiki-page new">Unknown page</a>',
+ # escaping
+ '![[Another page|Page]]' => '[[Another page|Page]]',
}
@project = Project.find(1)
to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }