9 class TextileFormatter < RedCloth
10 RULES = [:inline_auto_link, :inline_auto_mailto, :textile, :inline_toc]
15 self.no_span_caps=true
25 # Patch for RedCloth. Fixed in RedCloth r128 but _why hasn't released it yet.
26 # <a href="http://code.whytheluckystiff.net/redcloth/changeset/128">http://code.whytheluckystiff.net/redcloth/changeset/128</a>
27 def hard_break( text )
28 text.gsub!( /(.)\n(?!\n|\Z| *([#*=]+(\s|$)|[{|]))/, "\\1<br />" ) if hard_breaks
31 # Patch to add code highlighting support to RedCloth
32 def smooth_offtags( text )
33 unless @pre_list.empty?
34 ## replace <pre> content
35 text.gsub!(/<redpre#(\d+)>/) do
36 content = @pre_list[$1.to_i]
37 if content.match(/<code\s+class="(\w+)">\s?(.+)/m)
38 content = "<code class=\"#{$1} CodeRay\">" +
39 CodeRay.scan($2, $1).html(:escape => false, :line_numbers => :inline)
46 # Patch to add 'table of content' support to RedCloth
47 def textile_p_withtoc(tag, atts, cite, content)
49 @toc << [$1.to_i, content]
51 content = "<a name=\"#{@toc.length}\" class=\"wiki-page\"></a>" + content
52 textile_p(tag, atts, cite, content)
55 alias :textile_h1 :textile_p_withtoc
56 alias :textile_h2 :textile_p_withtoc
57 alias :textile_h3 :textile_p_withtoc
60 text.gsub!(/<p>\{\{([<>]?)toc\}\}<\/p>/i) do
62 div_class << ' right' if $1 == '>'
63 div_class << ' left' if $1 == '<'
64 out = "<div class=\"#{div_class}\">"
65 @toc.each_with_index do |heading, index|
66 # remove wiki links from the item
67 toc_item = heading.last.gsub(/(\[\[|\]\])/, '')
68 out << "<a href=\"##{index+1}\" class=\"heading#{heading.first}\">#{toc_item}</a>"
77 <\w+.*?>| # leading HTML tag, or
78 [^=<>!:'"/]| # leading punctuation, or
82 (?:https?://)| # protocol spec, or
91 }x unless const_defined?(:AUTO_LINK_RE)
93 # Turns all urls into clickable links (code from Rails).
94 def inline_auto_link(text)
95 text.gsub!(AUTO_LINK_RE) do
96 all, leading, proto, url, post = $&, $1, $2, $3, $6
97 if leading =~ /<a\s/i || leading =~ /![<>=]?/
98 # don't replace URL's that are already linked
99 # and URL's prefixed with ! !> !< != (textile images)
102 %(#{leading}<a class="external" href="#{proto=="www."?"http://www.":proto}#{url}">#{proto + url}</a>#{post})
107 # Turns all email addresses into clickable links (code from Rails).
108 def inline_auto_mailto(text)
109 text.gsub!(/([\w\.!#\$%\-+.]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)+)/) do
111 %{<a href="mailto:#{$1}" class="email">#{text}</a>}
118 def self.to_html(text, options = {})
119 TextileFormatter.new(text).to_html