forked from lobsters/lobsters
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmarkdowner.rb
91 lines (70 loc) · 2.18 KB
/
markdowner.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
class Markdowner
# opts[:allow_images] allows <img> tags
def self.to_html(text, opts = {})
if text.blank?
return ""
end
exts = [:tagfilter, :autolink, :strikethrough]
root = CommonMarker.render_doc(text.to_s, [:SMART], exts)
walk_text_nodes(root) {|n| postprocess_text_node(n) }
ng = Nokogiri::HTML(root.to_html([:DEFAULT], exts))
# change <h1>, <h2>, etc. headings to just bold tags
ng.css("h1, h2, h3, h4, h5, h6").each do |h|
h.name = "strong"
end
# This should happen before adding rel=ugc to all links
convert_images_to_links(ng) unless opts[:allow_images]
# make links have rel=ugc
ng.css("a").each do |h|
h[:rel] = "ugc" unless (URI.parse(h[:href]).host.nil? rescue false)
end
if ng.at_css("body")
ng.at_css("body").inner_html
else
""
end
end
def self.walk_text_nodes(node, &block)
return if node.type == :link
return block.call(node) if node.type == :text
node.each do |child|
walk_text_nodes(child, &block)
end
end
def self.postprocess_text_node(node)
while node
return unless node.string_content =~ /\B(@#{User::VALID_USERNAME})/
before, user, after = $`, $1, $'
node.string_content = before
if User.exists?(:username => user[1..-1])
link = CommonMarker::Node.new(:link)
link.url = Rails.application.root_url + "u/#{user[1..-1]}"
node.insert_after(link)
link_text = CommonMarker::Node.new(:text)
link_text.string_content = user
link.append_child(link_text)
node = link
else
node.string_content += user
end
if after.length > 0
remainder = CommonMarker::Node.new(:text)
remainder.string_content = after
node.insert_after(remainder)
node = remainder
else
node = nil
end
end
end
def self.convert_images_to_links(node)
node.css("img").each do |img|
link = node.create_element('a')
link['href'], title, alt = img.attributes
.values_at('src', 'title', 'alt')
.map(&:to_s)
link.content = [title, alt, link['href']].find(&:present?)
img.replace link
end
end
end