@@ -220,8 +220,9 module ApplicationHelper | |||
|
220 | 220 | |
|
221 | 221 | project = options[:project] || @project |
|
222 | 222 | |
|
223 | # turn wiki links into html links | |
|
224 |
# |
|
|
223 | # Wiki links | |
|
224 | # | |
|
225 | # Examples: | |
|
225 | 226 | # [[mypage]] |
|
226 | 227 | # [[mypage|mytext]] |
|
227 | 228 | # wiki links can refer other project wikis, using project name or identifier: |
@@ -229,47 +230,94 module ApplicationHelper | |||
|
229 | 230 | # [[project:|mytext]] |
|
230 | 231 | # [[project:mypage]] |
|
231 | 232 | # [[project:mypage|mytext]] |
|
232 | text = text.gsub(/\[\[([^\]\|]+)(\|([^\]\|]+))?\]\]/) do |m| | |
|
233 | text = text.gsub(/(!)?(\[\[([^\]\|]+)(\|([^\]\|]+))?\]\])/) do |m| | |
|
233 | 234 | link_project = project |
|
234 | page = $1 | |
|
235 | title = $3 | |
|
236 | if page =~ /^([^\:]+)\:(.*)$/ | |
|
237 | link_project = Project.find_by_name($1) || Project.find_by_identifier($1) | |
|
238 |
page = |
|
|
239 | title = $1 if page.blank? | |
|
240 | end | |
|
241 | ||
|
242 | if link_project && link_project.wiki | |
|
243 | # check if page exists | |
|
244 | wiki_page = link_project.wiki.find_page(page) | |
|
245 | link_to((title || page), format_wiki_link.call(link_project, Wiki.titleize(page)), | |
|
246 | :class => ('wiki-page' + (wiki_page ? '' : ' new'))) | |
|
235 | esc, all, page, title = $1, $2, $3, $5 | |
|
236 | if esc.nil? | |
|
237 | if page =~ /^([^\:]+)\:(.*)$/ | |
|
238 | link_project = Project.find_by_name($1) || Project.find_by_identifier($1) | |
|
239 | page = $2 | |
|
240 | title ||= $1 if page.blank? | |
|
241 | end | |
|
242 | ||
|
243 | if link_project && link_project.wiki | |
|
244 | # check if page exists | |
|
245 | wiki_page = link_project.wiki.find_page(page) | |
|
246 | link_to((title || page), format_wiki_link.call(link_project, Wiki.titleize(page)), | |
|
247 | :class => ('wiki-page' + (wiki_page ? '' : ' new'))) | |
|
248 | else | |
|
249 | # project or wiki doesn't exist | |
|
250 | title || page | |
|
251 | end | |
|
247 | 252 | else |
|
248 | # project or wiki doesn't exist | |
|
249 | title || page | |
|
253 | all | |
|
250 | 254 | end |
|
251 | 255 | end |
|
252 | 256 | |
|
253 | # turn issue and revision ids into links | |
|
254 |
# |
|
|
255 | # #52 -> <a href="/issues/show/52">#52</a> | |
|
256 | # r52 -> <a href="/repositories/revision/6?rev=52">r52</a> (project.id is 6) | |
|
257 | text = text.gsub(%r{([\s\(,-^])(#|r)(\d+)(?=[[:punct:]]|\s|<|$)}) do |m| | |
|
258 | leading, otype, oid = $1, $2, $3 | |
|
257 | # Redmine links | |
|
258 | # | |
|
259 | # Examples: | |
|
260 | # Issues: | |
|
261 | # #52 -> Link to issue #52 | |
|
262 | # Changesets: | |
|
263 | # r52 -> Link to revision 52 | |
|
264 | # Documents: | |
|
265 | # document#17 -> Link to document with id 17 | |
|
266 | # document:Greetings -> Link to the document with title "Greetings" | |
|
267 | # document:"Some document" -> Link to the document with title "Some document" | |
|
268 | # Versions: | |
|
269 | # version#3 -> Link to version with id 3 | |
|
270 | # version:1.0.0 -> Link to version named "1.0.0" | |
|
271 | # version:"1.0 beta 2" -> Link to version named "1.0 beta 2" | |
|
272 | # Attachments: | |
|
273 | # attachment:file.zip -> Link to the attachment of the current object named file.zip | |
|
274 | text = text.gsub(%r{([\s\(,-^])(!)?(attachment|document|version)?((#|r)(\d+)|(:)([^"][^\s<>]+|"[^"]+"))(?=[[:punct:]]|\s|<|$)}) do |m| | |
|
275 | leading, esc, prefix, sep, oid = $1, $2, $3, $5 || $7, $6 || $8 | |
|
259 | 276 | link = nil |
|
260 | if otype == 'r' | |
|
261 | if project && (changeset = project.changesets.find_by_revision(oid)) | |
|
262 | link = link_to("r#{oid}", {:controller => 'repositories', :action => 'revision', :id => project.id, :rev => oid}, :class => 'changeset', | |
|
263 | :title => truncate(changeset.comments, 100)) | |
|
264 | end | |
|
265 |
|
|
|
266 | if issue = Issue.find_by_id(oid.to_i, :include => [:project, :status], :conditions => Project.visible_by(User.current)) | |
|
267 | link = link_to("##{oid}", {:controller => 'issues', :action => 'show', :id => oid}, :class => 'issue', | |
|
268 | :title => "#{truncate(issue.subject, 100)} (#{issue.status.name})") | |
|
269 | link = content_tag('del', link) if issue.closed? | |
|
277 | if esc.nil? | |
|
278 | if prefix.nil? && sep == 'r' | |
|
279 | if project && (changeset = project.changesets.find_by_revision(oid)) | |
|
280 | link = link_to("r#{oid}", {:controller => 'repositories', :action => 'revision', :id => project.id, :rev => oid}, :class => 'changeset', | |
|
281 | :title => truncate(changeset.comments, 100)) | |
|
282 | end | |
|
283 | elsif sep == '#' | |
|
284 | oid = oid.to_i | |
|
285 | case prefix | |
|
286 | when nil | |
|
287 | if issue = Issue.find_by_id(oid, :include => [:project, :status], :conditions => Project.visible_by(User.current)) | |
|
288 | link = link_to("##{oid}", {:controller => 'issues', :action => 'show', :id => oid}, :class => 'issue', | |
|
289 | :title => "#{truncate(issue.subject, 100)} (#{issue.status.name})") | |
|
290 | link = content_tag('del', link) if issue.closed? | |
|
291 | end | |
|
292 | when 'document' | |
|
293 | if document = Document.find_by_id(oid, :include => [:project], :conditions => Project.visible_by(User.current)) | |
|
294 | link = link_to h(document.title), {:controller => 'documents', :action => 'show', :id => document}, :class => 'document' | |
|
295 | end | |
|
296 | when 'version' | |
|
297 | if version = Version.find_by_id(oid, :include => [:project], :conditions => Project.visible_by(User.current)) | |
|
298 | link = link_to h(version.name), {:controller => 'versions', :action => 'show', :id => version}, :class => 'version' | |
|
299 | end | |
|
300 | end | |
|
301 | elsif sep == ':' | |
|
302 | # removes the double quotes if any | |
|
303 | name = oid.gsub(%r{^"(.*)"$}, "\\1") | |
|
304 | case prefix | |
|
305 | when 'document' | |
|
306 | if project && document = project.documents.find_by_title(name) | |
|
307 | link = link_to h(document.title), {:controller => 'documents', :action => 'show', :id => document}, :class => 'document' | |
|
308 | end | |
|
309 | when 'version' | |
|
310 | if project && version = project.versions.find_by_name(name) | |
|
311 | link = link_to h(version.name), {:controller => 'versions', :action => 'show', :id => version}, :class => 'version' | |
|
312 | end | |
|
313 | when 'attachment' | |
|
314 | if attachments && attachment = attachments.detect {|a| a.filename == name } | |
|
315 | link = link_to h(attachment.filename), {:controller => 'attachments', :action => 'download', :id => attachment}, :class => 'attachment' | |
|
316 | end | |
|
317 | end | |
|
270 | 318 | end |
|
271 | 319 | end |
|
272 |
leading + (link || "#{ |
|
|
320 | leading + (link || "#{prefix}#{sep}#{oid}") | |
|
273 | 321 | end |
|
274 | 322 | |
|
275 | 323 | text |
@@ -395,15 +395,15 class RedCloth < String | |||
|
395 | 395 | # Elements to handle |
|
396 | 396 | GLYPHS = [ |
|
397 | 397 | # [ /([^\s\[{(>])?\'([dmst]\b|ll\b|ve\b|\s|:|$)/, '\1’\2' ], # single closing |
|
398 |
|
|
|
399 |
|
|
|
400 |
|
|
|
398 | # [ /([^\s\[{(>#{PUNCT_Q}][#{PUNCT_Q}]*)\'/, '\1’' ], # single closing | |
|
399 | # [ /\'(?=[#{PUNCT_Q}]*(s\b|[\s#{PUNCT_NOQ}]))/, '’' ], # single closing | |
|
400 | # [ /\'/, '‘' ], # single opening | |
|
401 | 401 | [ /</, '<' ], # less-than |
|
402 | 402 | [ />/, '>' ], # greater-than |
|
403 | 403 | # [ /([^\s\[{(])?"(\s|:|$)/, '\1”\2' ], # double closing |
|
404 |
|
|
|
405 |
|
|
|
406 |
|
|
|
404 | # [ /([^\s\[{(>#{PUNCT_Q}][#{PUNCT_Q}]*)"/, '\1”' ], # double closing | |
|
405 | # [ /"(?=[#{PUNCT_Q}]*[\s#{PUNCT_NOQ}])/, '”' ], # double closing | |
|
406 | # [ /"/, '“' ], # double opening | |
|
407 | 407 | [ /\b( )?\.{3}/, '\1…' ], # ellipsis |
|
408 | 408 | [ /\b([A-Z][A-Z0-9]{2,})\b(?:[(]([^)]*)[)])/, '<acronym title="\2">\1</acronym>' ], # 3+ uppercase acronym |
|
409 | 409 | [ /(^|[^"][>\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 |
@@ -21,4 +21,14 wiki_contents_002: | |||
|
21 | 21 | page_id: 2 |
|
22 | 22 | id: 2 |
|
23 | 23 | version: 1 |
|
24 | author_id: 1 No newline at end of file | |
|
24 | author_id: 1 | |
|
25 | comments: | |
|
26 | wiki_contents_003: | |
|
27 | text: |- | |
|
28 | h1. Start page | |
|
29 | ||
|
30 | E-commerce web site start page | |
|
31 | updated_on: 2007-03-08 00:18:07 +01:00 | |
|
32 | page_id: 3 | |
|
33 | id: 3 | |
|
34 | version: 1 |
@@ -9,4 +9,9 wiki_pages_002: | |||
|
9 | 9 | title: Another_page |
|
10 | 10 | id: 2 |
|
11 | 11 | wiki_id: 1 |
|
12 | wiki_pages_003: | |
|
13 | created_on: 2007-03-08 00:18:07 +01:00 | |
|
14 | title: Start_page | |
|
15 | id: 3 | |
|
16 | wiki_id: 2 | |
|
12 | 17 | No newline at end of file |
@@ -4,3 +4,9 wikis_001: | |||
|
4 | 4 | start_page: CookBook documentation |
|
5 | 5 | project_id: 1 |
|
6 | 6 | id: 1 |
|
7 | wikis_002: | |
|
8 | status: 1 | |
|
9 | start_page: Start page | |
|
10 | project_id: 2 | |
|
11 | id: 2 | |
|
12 | No newline at end of file |
@@ -20,7 +20,7 require File.dirname(__FILE__) + '/../../test_helper' | |||
|
20 | 20 | class ApplicationHelperTest < HelperTestCase |
|
21 | 21 | include ApplicationHelper |
|
22 | 22 | include ActionView::Helpers::TextHelper |
|
23 | fixtures :projects, :repositories, :changesets, :trackers, :issue_statuses, :issues | |
|
23 | fixtures :projects, :repositories, :changesets, :trackers, :issue_statuses, :issues, :documents, :versions, :wikis, :wiki_pages, :wiki_contents | |
|
24 | 24 | |
|
25 | 25 | def setup |
|
26 | 26 | super |
@@ -66,12 +66,52 class ApplicationHelperTest < HelperTestCase | |||
|
66 | 66 | def test_redmine_links |
|
67 | 67 | issue_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3}, |
|
68 | 68 | :class => 'issue', :title => 'Error 281 when updating a recipe (New)') |
|
69 | ||
|
69 | 70 | changeset_link = link_to('r1', {:controller => 'repositories', :action => 'revision', :id => 1, :rev => 1}, |
|
70 | 71 | :class => 'changeset', :title => 'My very first commit') |
|
71 | 72 | |
|
73 | document_link = link_to('Test document', {:controller => 'documents', :action => 'show', :id => 1}, | |
|
74 | :class => 'document') | |
|
75 | ||
|
76 | version_link = link_to('1.0', {:controller => 'versions', :action => 'show', :id => 2}, | |
|
77 | :class => 'version') | |
|
78 | ||
|
72 | 79 | to_test = { |
|
73 | 80 | '#3, #3 and #3.' => "#{issue_link}, #{issue_link} and #{issue_link}.", |
|
74 | 'r1' => changeset_link | |
|
81 | 'r1' => changeset_link, | |
|
82 | 'document#1' => document_link, | |
|
83 | 'document:"Test document"' => document_link, | |
|
84 | 'version#2' => version_link, | |
|
85 | 'version:1.0' => version_link, | |
|
86 | 'version:"1.0"' => version_link, | |
|
87 | # escaping | |
|
88 | '!#3.' => '#3.', | |
|
89 | '!r1' => 'r1', | |
|
90 | '!document#1' => 'document#1', | |
|
91 | '!document:"Test document"' => 'document:"Test document"', | |
|
92 | '!version#2' => 'version#2', | |
|
93 | '!version:1.0' => 'version:1.0', | |
|
94 | '!version:"1.0"' => 'version:"1.0"', | |
|
95 | } | |
|
96 | @project = Project.find(1) | |
|
97 | to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) } | |
|
98 | end | |
|
99 | ||
|
100 | def test_wiki_links | |
|
101 | to_test = { | |
|
102 | '[[CookBook documentation]]' => '<a href="/wiki/ecookbook/CookBook_documentation" class="wiki-page">CookBook documentation</a>', | |
|
103 | '[[Another page|Page]]' => '<a href="/wiki/ecookbook/Another_page" class="wiki-page">Page</a>', | |
|
104 | # page that doesn't exist | |
|
105 | '[[Unknown page]]' => '<a href="/wiki/ecookbook/Unknown_page" class="wiki-page new">Unknown page</a>', | |
|
106 | '[[Unknown page|404]]' => '<a href="/wiki/ecookbook/Unknown_page" class="wiki-page new">404</a>', | |
|
107 | # link to another project wiki | |
|
108 | '[[onlinestore:]]' => '<a href="/wiki/onlinestore/" class="wiki-page">onlinestore</a>', | |
|
109 | '[[onlinestore:|Wiki]]' => '<a href="/wiki/onlinestore/" class="wiki-page">Wiki</a>', | |
|
110 | '[[onlinestore:Start page]]' => '<a href="/wiki/onlinestore/Start_page" class="wiki-page">Start page</a>', | |
|
111 | '[[onlinestore:Start page|Text]]' => '<a href="/wiki/onlinestore/Start_page" class="wiki-page">Text</a>', | |
|
112 | '[[onlinestore:Unknown page]]' => '<a href="/wiki/onlinestore/Unknown_page" class="wiki-page new">Unknown page</a>', | |
|
113 | # escaping | |
|
114 | '![[Another page|Page]]' => '[[Another page|Page]]', | |
|
75 | 115 | } |
|
76 | 116 | @project = Project.find(1) |
|
77 | 117 | to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) } |
General Comments 0
You need to be logged in to leave comments.
Login now