devcenter 0.0.11 → 0.0.12
Sign up to get free protection for your applications and to get access to all the features.
- data/devcenter.gemspec +2 -3
- data/lib/devcenter.rb +1 -1
- data/lib/devcenter/coderay_extensions.rb +30 -17
- data/lib/devcenter/commands/pull.rb +1 -1
- data/lib/devcenter/previewer.rb +0 -1
- data/lib/devcenter/previewer/assets/public.css +1810 -1779
- data/lib/devcenter/previewer/views/article.erb +16 -7
- data/lib/devcenter/previewer/views/layout.erb +33 -265
- data/lib/devcenter/previewer/web_app.rb +6 -1
- data/lib/devcenter/version.rb +1 -1
- metadata +26 -43
- data/lib/devcenter/md_parser.rb +0 -118
data/lib/devcenter/md_parser.rb
DELETED
@@ -1,118 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
require 'maruku'
|
3
|
-
require 'nokogiri'
|
4
|
-
require 'coderay'
|
5
|
-
require 'sanitize'
|
6
|
-
|
7
|
-
module Devcenter::MdParser
|
8
|
-
class InvalidMarkdownError < Exception; end
|
9
|
-
class InvalidRawHTMLError < Exception; end
|
10
|
-
|
11
|
-
def self.to_html(markdown)
|
12
|
-
html = to_unsanitized_html(markdown)
|
13
|
-
html = sanitize(html)
|
14
|
-
highlight(html)
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.to_unsanitized_html(markdown)
|
18
|
-
html = Maruku.new(markdown, :on_error => :raise).to_html
|
19
|
-
html = Nokogiri::HTML::DocumentFragment.parse(html).to_html(:encoding => 'utf-8')
|
20
|
-
verify_raw_html(html)
|
21
|
-
html = underscores_to_dashes_in_subheader_anchors(html)
|
22
|
-
rescue InvalidRawHTMLError => e
|
23
|
-
raise InvalidMarkdownError, e.message
|
24
|
-
rescue => e
|
25
|
-
raise InvalidMarkdownError, parse_maruku_error(e.message)
|
26
|
-
end
|
27
|
-
|
28
|
-
def self.sanitize(html)
|
29
|
-
Sanitize.clean(html, sanitize_config)
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.sanitize_config
|
33
|
-
return @@sanitize_config if defined?(@@sanitize_config)
|
34
|
-
config = Sanitize::Config::RELAXED
|
35
|
-
config[:attributes][:all] += %w{ id class style name width height border align }
|
36
|
-
config[:attributes]['a'] += %w{ target }
|
37
|
-
config[:elements] += %w{ div span hr tt }
|
38
|
-
|
39
|
-
# embedded videos
|
40
|
-
config[:attributes][:all] += %w{ value src type allowscriptaccess allowfullscreen }
|
41
|
-
config[:elements] += %w{ object param embed }
|
42
|
-
config[:add_attributes] = {
|
43
|
-
'object' => {'allowscriptaccess' => 'never'},
|
44
|
-
'embed' => {'allowscriptaccess' => 'never'},
|
45
|
-
'param' => {'allowscriptaccess' => 'never'}
|
46
|
-
}
|
47
|
-
|
48
|
-
@@sanitize_config = config.merge({remove_contents: true, allow_comments: true})
|
49
|
-
end
|
50
|
-
|
51
|
-
def self.highlight(html)
|
52
|
-
element = "pre>code"
|
53
|
-
pattern = /\A\s*:::(\w+)\s*\n/i
|
54
|
-
|
55
|
-
doc = Nokogiri::HTML(html, nil, 'UTF-8')
|
56
|
-
nodes = doc.search(element)
|
57
|
-
nodes.each do |node|
|
58
|
-
s = node.inner_html || "[++where is the code?++]"
|
59
|
-
highlighted = to_coderay(s, pattern)
|
60
|
-
node.parent.swap(highlighted)
|
61
|
-
end
|
62
|
-
doc.to_html
|
63
|
-
end
|
64
|
-
|
65
|
-
def self.unescape_html(string)
|
66
|
-
string.to_s.gsub(/
/i, "\n").gsub("<", '<').gsub(">", '>').gsub("&", '&')
|
67
|
-
end
|
68
|
-
|
69
|
-
def self.to_coderay(string, pattern)
|
70
|
-
lang = 'unknown'
|
71
|
-
refs = pattern.match(string) # extract language name
|
72
|
-
if refs
|
73
|
-
lang = refs[1]
|
74
|
-
str = unescape_html(string.sub(pattern, ""))
|
75
|
-
"<pre class='CodeRay'>#{::CodeRay.encoder(:html).encode str, lang}</pre>"
|
76
|
-
else
|
77
|
-
"<pre class='CodeRay'>#{string}</pre>"
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def self.underscores_to_dashes_in_subheader_anchors(html)
|
82
|
-
doc = Nokogiri::HTML::DocumentFragment.parse(html)
|
83
|
-
|
84
|
-
doc.css("h2,h3,h4,h5,h6").each do |node|
|
85
|
-
if node.attributes['id'] && node.attributes['id'].value
|
86
|
-
node.attributes['id'].value = node.attributes['id'].value.gsub(/_+/,'-')
|
87
|
-
end
|
88
|
-
end
|
89
|
-
doc.to_html
|
90
|
-
end
|
91
|
-
|
92
|
-
def self.valid_markdown?(markdown)
|
93
|
-
return true, to_html(markdown)
|
94
|
-
rescue InvalidMarkdownError => e
|
95
|
-
return false, e.message
|
96
|
-
end
|
97
|
-
|
98
|
-
def self.verify_raw_html(html)
|
99
|
-
raise(InvalidRawHTMLError, parse_raw_html_error(html)) if invalid_raw_html?(html)
|
100
|
-
end
|
101
|
-
|
102
|
-
def self.invalid_raw_html?(html)
|
103
|
-
html.to_s.include?('markdown-html-error')
|
104
|
-
end
|
105
|
-
|
106
|
-
def self.parse_maruku_error(error_message)
|
107
|
-
lines = error_message.to_s.split("\n")
|
108
|
-
return lines unless lines.size > 1
|
109
|
-
msg = lines[4].gsub(/\A\|(\s)+|EOF\Z/,'').strip
|
110
|
-
code = lines[6].gsub(/\A\|(\s)+|EOF\Z/,'').strip
|
111
|
-
"#{msg} in \"#{code}\""
|
112
|
-
end
|
113
|
-
|
114
|
-
def self.parse_raw_html_error(html)
|
115
|
-
broken_html = html.match(/REXML could not parse this XML\/HTML\:(.+)<\/pre>/m)[1].strip rescue nil
|
116
|
-
broken_html.blank? ? "Contains broken raw HTML." : "This raw HTML is invalid: #{CGI.unescapeHTML(broken_html)}"
|
117
|
-
end
|
118
|
-
end
|