| 20 |
20 |
|
| 21 |
21 |
module Redmine
|
| 22 |
22 |
module WikiFormatting
|
| 23 |
|
|
| 24 |
|
private
|
| 25 |
|
|
|
23 |
|
|
24 |
private
|
|
25 |
|
| 26 |
26 |
class TextileFormatter < RedCloth
|
| 27 |
27 |
|
| 28 |
28 |
# auto_link rule after textile rules so that it doesn't break !image_url! tags
|
| ... | ... | |
| 39 |
39 |
@macros_runner = block
|
| 40 |
40 |
super(*RULES).to_s
|
| 41 |
41 |
end
|
| 42 |
|
|
| 43 |
|
private
|
| 44 |
|
|
|
42 |
|
|
43 |
private
|
|
44 |
|
| 45 |
45 |
# Patch for RedCloth. Fixed in RedCloth r128 but _why hasn't released it yet.
|
| 46 |
46 |
# <a href="http://code.whytheluckystiff.net/redcloth/changeset/128">http://code.whytheluckystiff.net/redcloth/changeset/128</a>
|
| 47 |
47 |
def hard_break( text )
|
| ... | ... | |
| 71 |
71 |
content = "<a name=\"#{@toc.length}\" class=\"wiki-page\"></a>" + content
|
| 72 |
72 |
textile_p(tag, atts, cite, content)
|
| 73 |
73 |
end
|
| 74 |
|
|
|
74 |
|
| 75 |
75 |
alias :textile_h1 :textile_p_withtoc
|
| 76 |
76 |
alias :textile_h2 :textile_p_withtoc
|
| 77 |
77 |
alias :textile_h3 :textile_p_withtoc
|
| ... | ... | |
| 121 |
121 |
end
|
| 122 |
122 |
end
|
| 123 |
123 |
|
|
124 |
|
|
125 |
|
| 124 |
126 |
AUTO_LINK_RE = %r{
|
| 125 |
|
( # leading text
|
| 126 |
|
<\w+.*?>| # leading HTML tag, or
|
| 127 |
|
[^=<>!:'"/]| # leading punctuation, or
|
| 128 |
|
^ # beginning of line
|
| 129 |
|
)
|
| 130 |
|
(
|
| 131 |
|
(?:https?://)| # protocol spec, or
|
| 132 |
|
(?:ftp://)|
|
| 133 |
|
(?:www\.) # www.*
|
| 134 |
|
)
|
| 135 |
|
(
|
| 136 |
|
(\S+?) # url
|
| 137 |
|
(\/)? # slash
|
| 138 |
|
)
|
| 139 |
|
([^\w\=\/;]*?) # post
|
| 140 |
|
(?=<|\s|$)
|
| 141 |
|
}x unless const_defined?(:AUTO_LINK_RE)
|
|
127 |
( # leading text
|
|
128 |
<\w+.*?>| # leading HTML tag, or
|
|
129 |
[^=!:'"/]| # leading punctuation, or
|
|
130 |
^ # beginning of line
|
|
131 |
)
|
|
132 |
(
|
|
133 |
(?:https?://)| # protocol spec, or
|
|
134 |
(?:www\.)|
|
|
135 |
(?:ftp://) # www.*
|
|
136 |
)
|
|
137 |
(
|
|
138 |
(?:[-_.\w]+(?::[^@\s]+)?@)? # username:password@
|
|
139 |
[-\w]+ # subdomain or domain
|
|
140 |
(?:\.[-\w]+)* # remaining subdomains or domain
|
|
141 |
(?::\d+)? # port
|
|
142 |
(?:/(?:(?:[~\w\+@%=\(\)-]|(?:[,.;:'][^\s$]))+)?)* # path
|
|
143 |
(?:\?[\w\+@%&=.;-]+)? # query string
|
|
144 |
(?:\#[\w\-_:.]*[\w])? # trailing anchor
|
|
145 |
)
|
|
146 |
([[:punct:]]|<|$|) # trailing text
|
|
147 |
}x unless const_defined?(:AUTO_LINK_RE)
|
|
148 |
|
| 142 |
149 |
|
| 143 |
|
# Turns all urls into clickable links (code from Rails).
|
|
150 |
|
|
151 |
|
|
152 |
|
|
153 |
# Turns all urls into clickable links.
|
| 144 |
154 |
def inline_auto_link(text)
|
| 145 |
155 |
text.gsub!(AUTO_LINK_RE) do
|
| 146 |
|
all, leading, proto, url, post = $&, $1, $2, $3, $6
|
| 147 |
|
if leading =~ /<a\s/i || leading =~ /![<>=]?/
|
|
156 |
all, a, b, c, d = $&, $1, $2, $3, $4
|
|
157 |
if a =~ /<a\s/i || a =~ /![<>=]?/
|
| 148 |
158 |
# don't replace URL's that are already linked
|
| 149 |
|
# and URL's prefixed with ! !> !< != (textile images)
|
| 150 |
159 |
all
|
| 151 |
|
else
|
| 152 |
|
%(#{leading}<a class="external" href="#{proto=="www."?"http://www.":proto}#{url}">#{proto + url}</a>#{post})
|
|
160 |
else
|
|
161 |
text = b + c
|
|
162 |
%(#{a}<a class="external" href="#{b=="www."?"http://www.":b}#{c}">#{text}</a>#{d})
|
| 153 |
163 |
end
|
| 154 |
164 |
end
|
| 155 |
165 |
end
|
| 156 |
166 |
|
|
167 |
|
| 157 |
168 |
# Turns all email addresses into clickable links (code from Rails).
|
| 158 |
169 |
def inline_auto_mailto(text)
|
| 159 |
170 |
text.gsub!(/([\w\.!#\$%\-+.]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)+)/) do
|
| ... | ... | |
| 167 |
178 |
end
|
| 168 |
179 |
end
|
| 169 |
180 |
|
| 170 |
|
public
|
| 171 |
|
|
|
181 |
public
|
|
182 |
|
| 172 |
183 |
def self.to_html(text, options = {}, &block)
|
| 173 |
184 |
TextileFormatter.new(text).to_html(&block)
|
| 174 |
185 |
end
|