Fix most auto-correctable rubocop issues
[rails.git] / lib / rich_text.rb
1 module RichText
2   def self.new(format, text)
3     case format
4     when "html" then HTML.new(text || "")
5     when "markdown" then Markdown.new(text || "")
6     when "text" then Text.new(text || "")
7     else; nil
8     end
9   end
10
11   class SimpleFormat
12     include ActionView::Helpers::TextHelper
13     include ActionView::Helpers::OutputSafetyHelper
14
15     def sanitize(text)
16       Sanitize.clean(text, Sanitize::Config::OSM).html_safe
17     end
18   end
19
20   class Base < String
21     include ActionView::Helpers::TagHelper
22
23     def spam_score
24       link_count = 0
25       link_size = 0
26
27       doc = Nokogiri::HTML(to_html)
28
29       if doc.content.length > 0
30         doc.xpath("//a").each do |link|
31           link_count += 1
32           link_size += link.content.length
33         end
34
35         link_proportion = link_size.to_f / doc.content.length.to_f
36       else
37         link_proportion = 0
38       end
39
40       [link_proportion - 0.2, 0.0].max * 200 + link_count * 40
41     end
42
43     protected
44
45     def simple_format(text)
46       SimpleFormat.new.simple_format(text)
47     end
48
49     def linkify(text)
50       if text.html_safe?
51         Rinku.auto_link(text, :urls, tag_options(:rel => "nofollow")).html_safe
52       else
53         Rinku.auto_link(text, :urls, tag_options(:rel => "nofollow"))
54       end
55     end
56   end
57
58   class HTML < Base
59     def to_html
60       linkify(sanitize(simple_format(self)))
61     end
62
63     def to_text
64       to_s
65     end
66
67     private
68
69     def sanitize(text)
70       Sanitize.clean(text, Sanitize::Config::OSM).html_safe
71     end
72   end
73
74   class Markdown < Base
75     def to_html
76       html_parser.render(self).html_safe
77     end
78
79     def to_text
80       to_s
81     end
82
83     private
84
85     def html_parser
86       @@html_renderer ||= Renderer.new(:filter_html => true, :safe_links_only => true)
87       @@html_parser ||= Redcarpet::Markdown.new(@@html_renderer,         :no_intra_emphasis => true, :autolink => true, :space_after_headers => true)
88     end
89
90     class Renderer < Redcarpet::Render::XHTML
91       def link(link, _title, alt_text)
92         "<a rel=\"nofollow\" href=\"#{link}\">#{alt_text}</a>"
93       end
94
95       def autolink(link, link_type)
96         if link_type == :email
97           "<a rel=\"nofollow\" href=\"mailto:#{link}\">#{link}</a>"
98         else
99           "<a rel=\"nofollow\" href=\"#{link}\">#{link}</a>"
100         end
101       end
102     end
103   end
104
105   class Text < Base
106     def to_html
107       linkify(simple_format(ERB::Util.html_escape(self)))
108     end
109
110     def to_text
111       to_s
112     end
113   end
114 end