-
Notifications
You must be signed in to change notification settings - Fork 27
/
Copy pathmarkdown_processor.rb
154 lines (113 loc) · 3.68 KB
/
markdown_processor.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
module Jekyll
require 'html/pipeline'
class LangFilter < HTML::Pipeline::Filter
def call
doc.css('pre[lang]').each do |node|
node['data-lang'] = node['lang']
node.remove_attribute('lang')
end
doc
end
end
class ApiHeaderIdFilter < HTML::Pipeline::Filter
def call
# Headers in the new API design
doc.css('div.api-article').each do |node|
node = node.next_element
until node.nil?
if node.name == 'h3'
node['id'] = node.text == 'Related Properties' ? 'related-properties' : sanitaze_id(node.text)
end
node = node.next_element
end
end
# Headers in the old API design
doc.css('h2').each do |node|
text = node.text
next unless text =~ /^(Configuration|Events|Properties|Methods|Class Methods|Fields|Constructor Parameters)$/
prefix = text.downcase.gsub(' ', '-')
node = node.next_element
until node.nil?
break if node.name == 'h2'
if node.name == 'h3'
id = sanitaze_id(node.text)
node['id'] = "#{prefix}-#{id}"
end
node = node.next_element
end
end
doc
end
def sanitaze_id(id)
id.gsub!(/ .*/, '')
id.gsub!(/`[^`]*`/, '')
id.gsub!(/\\/,'')
id.gsub!(/\*[^*]*\*/, '')
id
end
end
class RootRelativeFilter < HTML::Pipeline::Filter
def call
doc.search('a').each do |a|
next if a['href'].nil?
href = a['href'].strip
if href.start_with? '/'
a['href'] = context[:baseurl] + href unless href.start_with? context[:baseurl]
end
end
doc.search('img').each do |img|
next if img['src'].nil?
src = img['src'].strip
if src.start_with? '/'
img['src'] = context[:baseurl] + src unless src.start_with? context[:baseurl]
end
end
doc
end
end
class HeaderLinkFilter < HTML::Pipeline::Filter
PUNCTUATION_REGEXP = /[^\p{Word}\- ]/u
def call()
doc.css('h1, h2, h3').each do |heading|
desc_node = heading.children.first()
if desc_node
id = desc_node.text
else
id = heading.text
end
id = id.downcase.strip
id.gsub!(PUNCTUATION_REGEXP, '') # remove punctuation
id.gsub!(' ', '-') # replace spaces with dash
heading['id'] = id
a = Nokogiri::XML::Node.new('a', doc)
a['href'] = "##{id}"
if desc_node
a.children = desc_node
end
if next_child = heading.children.first()
next_child.before(a)
else
heading.add_child a
end
end
doc
end
end
class Converters::Markdown::MarkdownProcessor
def initialize(config)
@config = config
context = {
:gfm => false,
:baseurl => @config['baseurl'],
}
if @config['code_lang']
@pipeline = HTML::Pipeline.new [ HTML::Pipeline::MarkdownFilter, LangFilter, RootRelativeFilter, HeaderLinkFilter ], context
else
@pipeline = HTML::Pipeline.new [ HTML::Pipeline::MarkdownFilter, RootRelativeFilter, HeaderLinkFilter ], context
end
end
def convert(content)
@pipeline.call(content)[:output].to_s
end
end
end