devcenter 0.0.11 → 0.0.12

Sign up to get free protection for your applications and to get access to all the features.
@@ -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(/&#x000A;/i, "\n").gsub("&lt;", '<').gsub("&gt;", '>').gsub("&amp;", '&')
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