This repository has been archived by the owner on Oct 2, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
maildown.rb
104 lines (93 loc) · 2.8 KB
/
maildown.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
92
93
94
95
96
97
98
99
100
101
102
103
104
require "maildown/version"
require 'nokogiri'
module Maildown
def self.from_html html
Parser.new(html).result
end # self.from_html
class Parser
def initialize html
@doc = Nokogiri::HTML(html.gsub(/\n/, ''))
@links = []
end # initialize
def result
@result ||= parse
end
# private
def parse
@result = @doc.children.map { |ele| parse_element(ele) }.join
@result = @result + "\n\n" + @links.join("\n") if @links.any?
@result.gsub!(/\n{3,}/, "\n\n") # Removes lines breaks where there are more than two.
@result.strip!
@result.lstrip!
return @result
end
def parse_element element
if element.is_a? Nokogiri::XML::Text
return element.text.gsub(/^$\n/, '') # remove empty lines
else
if (children = element.children).count > 0
return wrap_node(element, children.map {|element| parse_element(element)}.join )
else
return wrap_node(element, element.text)
end
end
end # parse_element
# wrap node with markdown
def wrap_node(node, contents=nil)
result = ''
# contents.strip! unless contents == nil
# check if there is a custom parse exist
if respond_to? "parse_#{node.name}"
return self.send("parse_#{node.name}", node, contents)
end
# skip hidden node
return '' if node['style'] and node['style'] =~ /display:\s*none/
# default parse
case node.name.downcase
when 'i'
result << "*#{contents}*"
when 'p'
result << "#{contents}\n\n"
when 'br'
result << "#{contents}\n"
when 'script'
when 'strike'
result << "--#{contents}--"
when 'style'
when 'li'
result << "*#{contents}\n"
when 'blockquote'
result << "\n"
contents.lines.each do |part|
result << "> #{part.strip}\n"
end
result << "\n"
when 'b'
result << "**#{contents}**"
when 'strong'
result << "**#{contents}**"
when 'h1'
result << "##{contents}\n"
when 'h2'
result << "###{contents}\n"
when 'h3'
result << "####{contents}\n"
when 'hr'
result << "****\n"
when 'img'
result << "![#{node['alt']}](#{node['src']})"
when 'a'
if node['href'].start_with? 'mailto:' # skip mailto: links
result << "#{contents}"
else
number = @links.count + 1
result << "#{contents}[#{number}]"
@links << "[#{number}] #{node['href']}"
end
else
result << contents unless contents == nil
end
result
end
end # class
end # module