##// END OF EJS Templates
Fixed: Links to other wiki pages in headings get corrupted (class attributes shown)....
Jean-Philippe Lang -
r758:e1bb4a5baa34
parent child
Show More
@@ -1,122 +1,124
1 require 'redcloth'
1 require 'redcloth'
2 require 'coderay'
2 require 'coderay'
3
3
4 module Redmine
4 module Redmine
5 module WikiFormatting
5 module WikiFormatting
6
6
7 private
7 private
8
8
9 class TextileFormatter < RedCloth
9 class TextileFormatter < RedCloth
10 RULES = [:inline_auto_link, :inline_auto_mailto, :textile, :inline_toc]
10 RULES = [:inline_auto_link, :inline_auto_mailto, :textile, :inline_toc]
11
11
12 def initialize(*args)
12 def initialize(*args)
13 super
13 super
14 self.hard_breaks=true
14 self.hard_breaks=true
15 end
15 end
16
16
17 def to_html
17 def to_html
18 @toc = []
18 @toc = []
19 super(*RULES).to_s
19 super(*RULES).to_s
20 end
20 end
21
21
22 private
22 private
23
23
24 # Patch for RedCloth. Fixed in RedCloth r128 but _why hasn't released it yet.
24 # Patch for RedCloth. Fixed in RedCloth r128 but _why hasn't released it yet.
25 # <a href="http://code.whytheluckystiff.net/redcloth/changeset/128">http://code.whytheluckystiff.net/redcloth/changeset/128</a>
25 # <a href="http://code.whytheluckystiff.net/redcloth/changeset/128">http://code.whytheluckystiff.net/redcloth/changeset/128</a>
26 def hard_break( text )
26 def hard_break( text )
27 text.gsub!( /(.)\n(?!\n|\Z| *([#*=]+(\s|$)|[{|]))/, "\\1<br />" ) if hard_breaks
27 text.gsub!( /(.)\n(?!\n|\Z| *([#*=]+(\s|$)|[{|]))/, "\\1<br />" ) if hard_breaks
28 end
28 end
29
29
30 # Patch to add code highlighting support to RedCloth
30 # Patch to add code highlighting support to RedCloth
31 def smooth_offtags( text )
31 def smooth_offtags( text )
32 unless @pre_list.empty?
32 unless @pre_list.empty?
33 ## replace <pre> content
33 ## replace <pre> content
34 text.gsub!(/<redpre#(\d+)>/) do
34 text.gsub!(/<redpre#(\d+)>/) do
35 content = @pre_list[$1.to_i]
35 content = @pre_list[$1.to_i]
36 if content.match(/<code\s+class="(\w+)">\s?(.+)/m)
36 if content.match(/<code\s+class="(\w+)">\s?(.+)/m)
37 content = "<code class=\"#{$1} CodeRay\">" +
37 content = "<code class=\"#{$1} CodeRay\">" +
38 CodeRay.scan($2, $1).html(:escape => false, :line_numbers => :inline)
38 CodeRay.scan($2, $1).html(:escape => false, :line_numbers => :inline)
39 end
39 end
40 content
40 content
41 end
41 end
42 end
42 end
43 end
43 end
44
44
45 # Patch to add 'table of content' support to RedCloth
45 # Patch to add 'table of content' support to RedCloth
46 def textile_p_withtoc(tag, atts, cite, content)
46 def textile_p_withtoc(tag, atts, cite, content)
47 if tag =~ /^h(\d)$/
47 if tag =~ /^h(\d)$/
48 @toc << [$1.to_i, content]
48 @toc << [$1.to_i, content]
49 end
49 end
50 content = "<a name=\"#{@toc.length}-#{content}\" class=\"wiki-page\"></a>" + content
50 content = "<a name=\"#{@toc.length}\" class=\"wiki-page\"></a>" + content
51 textile_p(tag, atts, cite, content)
51 textile_p(tag, atts, cite, content)
52 end
52 end
53
53
54 alias :textile_h1 :textile_p_withtoc
54 alias :textile_h1 :textile_p_withtoc
55 alias :textile_h2 :textile_p_withtoc
55 alias :textile_h2 :textile_p_withtoc
56 alias :textile_h3 :textile_p_withtoc
56 alias :textile_h3 :textile_p_withtoc
57
57
58 def inline_toc(text)
58 def inline_toc(text)
59 text.gsub!(/<p>\{\{([<>]?)toc\}\}<\/p>/i) do
59 text.gsub!(/<p>\{\{([<>]?)toc\}\}<\/p>/i) do
60 div_class = 'toc'
60 div_class = 'toc'
61 div_class << ' right' if $1 == '>'
61 div_class << ' right' if $1 == '>'
62 out = "<div class=\"#{div_class}\">"
62 out = "<div class=\"#{div_class}\">"
63 @toc.each_with_index do |heading, index|
63 @toc.each_with_index do |heading, index|
64 out << "<a href=\"##{index+1}-#{heading.last}\" class=\"heading#{heading.first}\">#{heading.last}</a>"
64 # remove wiki links from the item
65 toc_item = heading.last.gsub(/(\[\[|\]\])/, '')
66 out << "<a href=\"##{index+1}\" class=\"heading#{heading.first}\">#{toc_item}</a>"
65 end
67 end
66 out << '</div>'
68 out << '</div>'
67 out
69 out
68 end
70 end
69 end
71 end
70
72
71 AUTO_LINK_RE = %r{
73 AUTO_LINK_RE = %r{
72 ( # leading text
74 ( # leading text
73 <\w+.*?>| # leading HTML tag, or
75 <\w+.*?>| # leading HTML tag, or
74 [^=<>!:'"/]| # leading punctuation, or
76 [^=<>!:'"/]| # leading punctuation, or
75 ^ # beginning of line
77 ^ # beginning of line
76 )
78 )
77 (
79 (
78 (?:https?://)| # protocol spec, or
80 (?:https?://)| # protocol spec, or
79 (?:www\.) # www.*
81 (?:www\.) # www.*
80 )
82 )
81 (
83 (
82 [-\w]+ # subdomain or domain
84 [-\w]+ # subdomain or domain
83 (?:\.[-\w]+)* # remaining subdomains or domain
85 (?:\.[-\w]+)* # remaining subdomains or domain
84 (?::\d+)? # port
86 (?::\d+)? # port
85 (?:/(?:(?:[~\w\+%-]|(?:[,.;:][^\s$]))+)?)* # path
87 (?:/(?:(?:[~\w\+%-]|(?:[,.;:][^\s$]))+)?)* # path
86 (?:\?[\w\+%&=.;-]+)? # query string
88 (?:\?[\w\+%&=.;-]+)? # query string
87 (?:\#[\w\-]*)? # trailing anchor
89 (?:\#[\w\-]*)? # trailing anchor
88 )
90 )
89 ([[:punct:]]|\s|<|$) # trailing text
91 ([[:punct:]]|\s|<|$) # trailing text
90 }x unless const_defined?(:AUTO_LINK_RE)
92 }x unless const_defined?(:AUTO_LINK_RE)
91
93
92 # Turns all urls into clickable links (code from Rails).
94 # Turns all urls into clickable links (code from Rails).
93 def inline_auto_link(text)
95 def inline_auto_link(text)
94 text.gsub!(AUTO_LINK_RE) do
96 text.gsub!(AUTO_LINK_RE) do
95 all, a, b, c, d = $&, $1, $2, $3, $4
97 all, a, b, c, d = $&, $1, $2, $3, $4
96 if a =~ /<a\s/i || a =~ /![<>=]?/
98 if a =~ /<a\s/i || a =~ /![<>=]?/
97 # don't replace URL's that are already linked
99 # don't replace URL's that are already linked
98 # and URL's prefixed with ! !> !< != (textile images)
100 # and URL's prefixed with ! !> !< != (textile images)
99 all
101 all
100 else
102 else
101 text = b + c
103 text = b + c
102 %(#{a}<a href="#{b=="www."?"http://www.":b}#{c}">#{text}</a>#{d})
104 %(#{a}<a href="#{b=="www."?"http://www.":b}#{c}">#{text}</a>#{d})
103 end
105 end
104 end
106 end
105 end
107 end
106
108
107 # Turns all email addresses into clickable links (code from Rails).
109 # Turns all email addresses into clickable links (code from Rails).
108 def inline_auto_mailto(text)
110 def inline_auto_mailto(text)
109 text.gsub!(/([\w\.!#\$%\-+.]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)+)/) do
111 text.gsub!(/([\w\.!#\$%\-+.]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)+)/) do
110 text = $1
112 text = $1
111 %{<a href="mailto:#{$1}" class="email">#{text}</a>}
113 %{<a href="mailto:#{$1}" class="email">#{text}</a>}
112 end
114 end
113 end
115 end
114 end
116 end
115
117
116 public
118 public
117
119
118 def self.to_html(text, options = {})
120 def self.to_html(text, options = {})
119 TextileFormatter.new(text).to_html
121 TextileFormatter.new(text).to_html
120 end
122 end
121 end
123 end
122 end
124 end
General Comments 0
You need to be logged in to leave comments. Login now