gollum-lib 5.0.a.3 → 5.0.a.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/HISTORY.md +7 -0
- data/gemspec.rb +10 -4
- data/lib/gollum-lib.rb +3 -6
- data/lib/gollum-lib/file.rb +7 -0
- data/lib/gollum-lib/filter.rb +2 -2
- data/lib/gollum-lib/filter/bibtex.rb +55 -0
- data/lib/gollum-lib/filter/code.rb +0 -2
- data/lib/gollum-lib/filter/emoji.rb +10 -3
- data/lib/gollum-lib/filter/pandoc_bib.rb +52 -0
- data/lib/gollum-lib/filter/plain_text.rb +4 -0
- data/lib/gollum-lib/filter/plantuml.rb +3 -4
- data/lib/gollum-lib/filter/remote_code.rb +0 -1
- data/lib/gollum-lib/filter/sanitize.rb +1 -1
- data/lib/gollum-lib/filter/tags.rb +196 -173
- data/lib/gollum-lib/macro/video.rb +9 -0
- data/lib/gollum-lib/markup.rb +25 -41
- data/lib/gollum-lib/markups.rb +36 -3
- data/lib/gollum-lib/sanitization.rb +215 -14
- data/lib/gollum-lib/version.rb +1 -1
- data/lib/gollum-lib/wiki.rb +8 -1
- metadata +53 -15
- data/lib/gollum-lib/filter/wsd.rb +0 -54
data/lib/gollum-lib/markup.rb
CHANGED
@@ -57,6 +57,7 @@ module Gollum
|
|
57
57
|
@formats[ext] = { :name => name,
|
58
58
|
:extensions => new_extension,
|
59
59
|
:reverse_links => options.fetch(:reverse_links, false),
|
60
|
+
:skip_filters => options.fetch(:skip_filters, nil),
|
60
61
|
:enabled => options.fetch(:enabled, true) }
|
61
62
|
@extensions.concat(new_extension)
|
62
63
|
end
|
@@ -82,44 +83,33 @@ module Gollum
|
|
82
83
|
#
|
83
84
|
# Returns a new Gollum::Markup object, ready for rendering.
|
84
85
|
def initialize(page)
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
@dir = ::File.dirname(page.path)
|
95
|
-
end
|
86
|
+
@wiki = page.wiki
|
87
|
+
@name = page.filename
|
88
|
+
@data = page.text_data
|
89
|
+
@version = page.version.id if page.version
|
90
|
+
@format = page.format
|
91
|
+
@sub_page = page.sub_page
|
92
|
+
@parent_page = page.parent_page
|
93
|
+
@page = page
|
94
|
+
@dir = ::File.dirname(page.path)
|
96
95
|
@metadata = nil
|
97
96
|
@to_xml_opts = { :save_with => Nokogiri::XML::Node::SaveOptions::DEFAULT_XHTML ^ 1, :indent => 0, :encoding => 'UTF-8' }
|
98
97
|
end
|
99
98
|
|
99
|
+
# Whether or not this markup's format uses reversed-order links ([description | url] rather than [url | description]). Defaults to false.
|
100
100
|
def reverse_links?
|
101
101
|
self.class.formats[@format][:reverse_links]
|
102
102
|
end
|
103
103
|
|
104
|
-
#
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
# set instance vars so we're able to render data without a wiki or page.
|
113
|
-
@format = format
|
114
|
-
@name = name
|
115
|
-
|
116
|
-
chain = [:YAML, :PlainText, :Emoji, :TOC, :RemoteCode, :Code, :Sanitize, :WSD, :Tags, :Render]
|
117
|
-
|
118
|
-
filter_chain = chain.map do |r|
|
119
|
-
Gollum::Filter.const_get(r).new(self)
|
104
|
+
# Whether or not a particular filter should be skipped for this format.
|
105
|
+
def skip_filter?(filter)
|
106
|
+
if self.class.formats[@format][:skip_filters].respond_to?(:include?)
|
107
|
+
self.class.formats[@format][:skip_filters].include?(filter)
|
108
|
+
elsif self.class.formats[@format][:skip_filters].respond_to?(:call)
|
109
|
+
self.class.formats[@format][:skip_filters].call(filter)
|
110
|
+
else
|
111
|
+
false
|
120
112
|
end
|
121
|
-
|
122
|
-
process_chain data, filter_chain
|
123
113
|
end
|
124
114
|
|
125
115
|
# Process the filter chain
|
@@ -139,11 +129,6 @@ module Gollum
|
|
139
129
|
data = filter.process(data)
|
140
130
|
end
|
141
131
|
|
142
|
-
# Finally, a little bit of cleanup, just because
|
143
|
-
data.gsub!(/<p><\/p>/) do
|
144
|
-
''
|
145
|
-
end
|
146
|
-
|
147
132
|
data
|
148
133
|
end
|
149
134
|
|
@@ -156,16 +141,16 @@ module Gollum
|
|
156
141
|
#
|
157
142
|
# Returns the formatted String content.
|
158
143
|
def render(no_follow = false, encoding = nil, include_levels = 10)
|
159
|
-
@sanitize = no_follow ?
|
160
|
-
@wiki.history_sanitizer :
|
161
|
-
@wiki.sanitizer
|
144
|
+
@sanitize = no_follow ? @wiki.history_sanitizer : @wiki.sanitizer
|
162
145
|
|
163
146
|
@encoding = encoding
|
164
147
|
@include_levels = include_levels
|
165
148
|
|
166
|
-
data
|
167
|
-
|
168
|
-
|
149
|
+
data = @data.dup
|
150
|
+
|
151
|
+
filter_chain = @wiki.filter_chain.reject {|filter| skip_filter?(filter)}
|
152
|
+
filter_chain.map! do |filter_sym|
|
153
|
+
Gollum::Filter.const_get(filter_sym).new(self)
|
169
154
|
end
|
170
155
|
|
171
156
|
# Since the last 'extract' action in our chain *should* be the markup
|
@@ -212,5 +197,4 @@ module Gollum
|
|
212
197
|
end
|
213
198
|
end
|
214
199
|
|
215
|
-
MarkupGFM = Markup
|
216
200
|
end
|
data/lib/gollum-lib/markups.rb
CHANGED
@@ -1,15 +1,23 @@
|
|
1
1
|
# ~*~ encoding: utf-8 ~*~
|
2
2
|
|
3
|
-
require
|
3
|
+
require 'pathname'
|
4
4
|
|
5
5
|
module Gollum
|
6
6
|
module MarkupRegisterUtils
|
7
|
+
|
7
8
|
# Check if a gem exists. This implementation requires Gem::Specificaton to
|
8
9
|
# be filled.
|
9
10
|
def gem_exists?(name)
|
10
11
|
Gem::Specification.find {|spec| spec.name == name} != nil
|
11
12
|
end
|
12
13
|
|
14
|
+
def all_gems_available?(names)
|
15
|
+
names.each do |name|
|
16
|
+
return false unless gem_exists?(name)
|
17
|
+
end
|
18
|
+
true
|
19
|
+
end
|
20
|
+
|
13
21
|
# Check if an executable exists. This implementation comes from
|
14
22
|
# stackoverflow question 2108727.
|
15
23
|
def executable_exists?(name)
|
@@ -23,21 +31,42 @@ module Gollum
|
|
23
31
|
end
|
24
32
|
return false
|
25
33
|
end
|
34
|
+
|
35
|
+
# Whether the current markdown renderer is pandoc
|
36
|
+
def using_pandoc?
|
37
|
+
GitHub::Markup::Markdown.implementation_name == 'pandoc-ruby'
|
38
|
+
end
|
26
39
|
end
|
27
40
|
end
|
28
41
|
|
29
42
|
include Gollum::MarkupRegisterUtils
|
30
43
|
|
44
|
+
module GitHub
|
45
|
+
module Markup
|
46
|
+
class Markdown < Implementation
|
47
|
+
class << self
|
48
|
+
def implementation_name
|
49
|
+
@implementation_name ||= MARKDOWN_GEMS.keys.detect {|gem_name| self.new.send(:try_require, gem_name) }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
31
56
|
module Gollum
|
32
57
|
class Markup
|
33
58
|
GitHub::Markup::Markdown::MARKDOWN_GEMS['kramdown'] = proc { |content|
|
34
59
|
Kramdown::Document.new(content, :auto_ids => false, :smart_quotes => ["'", "'", '"', '"'].map{|char| char.codepoints.first}).to_html
|
35
60
|
}
|
61
|
+
GitHub::Markup::Markdown::MARKDOWN_GEMS['pandoc-ruby'] = proc { |content|
|
62
|
+
PandocRuby.convert(content, :s, :from => :markdown, :to => :html, :filter => 'pandoc-citeproc')
|
63
|
+
} if gem_exists?('pandoc-ruby')
|
36
64
|
|
37
65
|
# markdown, rdoc, and plain text are always supported.
|
38
66
|
register(:markdown, "Markdown", :extensions => ['md','mkd','mkdn','mdown','markdown'])
|
39
67
|
register(:rdoc, "RDoc")
|
40
|
-
register(:txt, "Plain Text"
|
68
|
+
register(:txt, "Plain Text",
|
69
|
+
:skip_filters => Proc.new {|filter| ![:PlainText,:YAML].include?(filter) })
|
41
70
|
# the following formats are available only when certain gem is installed
|
42
71
|
# or certain program exists.
|
43
72
|
register(:textile, "Textile",
|
@@ -49,13 +78,17 @@ module Gollum
|
|
49
78
|
:reverse_links => true)
|
50
79
|
register(:rest, "reStructuredText",
|
51
80
|
:enabled => MarkupRegisterUtils::executable_exists?("python2"),
|
52
|
-
:extensions => ['rest', 'rst'
|
81
|
+
:extensions => ['rest', 'rst'])
|
53
82
|
register(:asciidoc, "AsciiDoc",
|
83
|
+
:skip_filters => [:Tags],
|
54
84
|
:enabled => MarkupRegisterUtils::gem_exists?("asciidoctor"))
|
55
85
|
register(:mediawiki, "MediaWiki",
|
56
86
|
:enabled => MarkupRegisterUtils::gem_exists?("wikicloth"),
|
57
87
|
:extensions => ['mediawiki','wiki'], :reverse_links => true)
|
58
88
|
register(:pod, "Pod",
|
59
89
|
:enabled => MarkupRegisterUtils::executable_exists?("perl"))
|
90
|
+
register(:bib, "BibTeX", :extensions => ['bib'],
|
91
|
+
:enabled => MarkupRegisterUtils::all_gems_available?(["bibtex-ruby", "citeproc-ruby", "csl"]),
|
92
|
+
:skip_filters => Proc.new {|filter| true unless [:YAML,:BibTeX,:Sanitize].include?(filter)})
|
60
93
|
end
|
61
94
|
end
|
@@ -5,22 +5,223 @@ module Gollum
|
|
5
5
|
# This class does not yet support all options of Sanitize library.
|
6
6
|
# See http://github.com/rgrove/sanitize/.
|
7
7
|
class Sanitization
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
'thead', 'tr', 'tt', 'u', 'ul', 'var'
|
8
|
+
|
9
|
+
# Default whitelisted elements required for MathML. See https://developer.mozilla.org/en-US/docs/Web/MathML/Element
|
10
|
+
# For some help on generating MATHML_ELEMENTS and MATHML_ATTRS, see https://gist.github.com/dometto/52d9cb8b45d68bfc7665e5e6683b75a0
|
11
|
+
MATHML_ELEMENTS = [
|
12
|
+
'math', 'maction', 'maligngroup', 'malignmark', 'menclose',
|
13
|
+
'merror', 'mfenced', 'mfrac', 'mglyph', 'mi', 'mlabeledtr',
|
14
|
+
'mlongdiv', 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded',
|
15
|
+
'mphantom', 'mroot', 'mrow', 'ms', 'mscarries', 'mscarry',
|
16
|
+
'msgroup', 'msline', 'mspace', 'msqrt', 'msrow', 'mstack',
|
17
|
+
'mstyle', 'msub', 'msup', 'msubsup', 'mtable', 'mtd',
|
18
|
+
'mtext', 'mtr', 'munder', 'munderover', 'semantics'
|
20
19
|
].freeze
|
21
20
|
|
21
|
+
|
22
|
+
# Default whitelisted attributes required for MathML. See https://developer.mozilla.org/en-US/docs/Web/MathML/Attribute
|
23
|
+
MATHML_ATTRS = {
|
24
|
+
'math'=>
|
25
|
+
['altimg',
|
26
|
+
'altimg-width',
|
27
|
+
'altimg-height',
|
28
|
+
'altimg-valign',
|
29
|
+
'alttext',
|
30
|
+
'dir',
|
31
|
+
'display',
|
32
|
+
'xmlns',
|
33
|
+
'href',
|
34
|
+
'id',
|
35
|
+
'mathbackground',
|
36
|
+
'mathcolor'],
|
37
|
+
'maction'=>
|
38
|
+
['actiontype', 'selection', 'href', 'id', 'mathbackground', 'mathcolor'],
|
39
|
+
'maligngroup'=>['href', 'id', 'mathbackground', 'mathcolor'],
|
40
|
+
'malignmark'=>['href', 'id', 'mathbackground', 'mathcolor'],
|
41
|
+
'menclose'=>['notation', 'href', 'id', 'mathbackground', 'mathcolor'],
|
42
|
+
'merror'=>['href', 'id', 'mathbackground', 'mathcolor'],
|
43
|
+
'mfenced'=>
|
44
|
+
['close', 'open', 'separators', 'href', 'id', 'mathbackground', 'mathcolor'],
|
45
|
+
'mfrac'=>
|
46
|
+
['bevelled',
|
47
|
+
'denomalign',
|
48
|
+
'linethickness',
|
49
|
+
'numalign',
|
50
|
+
'href',
|
51
|
+
'id',
|
52
|
+
'mathbackground',
|
53
|
+
'mathcolor'],
|
54
|
+
'mglyph'=>['height', 'width', 'href', 'id', 'mathbackground', 'mathcolor'],
|
55
|
+
'mi'=>
|
56
|
+
['dir',
|
57
|
+
'mathbackground',
|
58
|
+
'mathcolor',
|
59
|
+
'mathsize',
|
60
|
+
'mathvariant',
|
61
|
+
'href',
|
62
|
+
'id',
|
63
|
+
'mathbackground',
|
64
|
+
'mathcolor'],
|
65
|
+
'mlabeledtr'=>['columnalign', 'href', 'id', 'mathbackground', 'mathcolor'],
|
66
|
+
'mlongdiv'=>['href', 'id', 'mathbackground', 'mathcolor'],
|
67
|
+
'mmultiscripts'=>
|
68
|
+
['subscriptshift',
|
69
|
+
'supscriptshift',
|
70
|
+
'href',
|
71
|
+
'id',
|
72
|
+
'mathbackground',
|
73
|
+
'mathcolor'],
|
74
|
+
'mn'=>
|
75
|
+
['mathbackground',
|
76
|
+
'mathcolor',
|
77
|
+
'mathsize',
|
78
|
+
'mathvariant',
|
79
|
+
'href',
|
80
|
+
'id',
|
81
|
+
'mathbackground',
|
82
|
+
'mathcolor'],
|
83
|
+
'mo'=>
|
84
|
+
['accent',
|
85
|
+
'dir',
|
86
|
+
'fence',
|
87
|
+
'href',
|
88
|
+
'id',
|
89
|
+
'largeop',
|
90
|
+
'lspace',
|
91
|
+
'mathbackground',
|
92
|
+
'mathcolor',
|
93
|
+
'mathsize',
|
94
|
+
'mathvariant',
|
95
|
+
'maxsize',
|
96
|
+
'minsize',
|
97
|
+
'movablelimits',
|
98
|
+
'rspace',
|
99
|
+
'separator',
|
100
|
+
'stretchy',
|
101
|
+
'symmetric',
|
102
|
+
'href',
|
103
|
+
'id',
|
104
|
+
'mathbackground',
|
105
|
+
'mathcolor'],
|
106
|
+
'mover'=>['accent', 'align', 'href', 'id', 'mathbackground', 'mathcolor'],
|
107
|
+
'mpadded'=>
|
108
|
+
['depth',
|
109
|
+
'height',
|
110
|
+
'lspace',
|
111
|
+
'voffset',
|
112
|
+
'width',
|
113
|
+
'href',
|
114
|
+
'id',
|
115
|
+
'mathbackground',
|
116
|
+
'mathcolor'],
|
117
|
+
'mphantom'=>['href', 'id', 'mathbackground', 'mathcolor'],
|
118
|
+
'mroot'=>['href', 'id', 'mathbackground', 'mathcolor'],
|
119
|
+
'mrow'=>['dir', 'href', 'id', 'mathbackground', 'mathcolor'],
|
120
|
+
'ms'=>
|
121
|
+
['dir',
|
122
|
+
'lquote',
|
123
|
+
'mathbackground',
|
124
|
+
'mathcolor',
|
125
|
+
'mathsize',
|
126
|
+
'mathvariant',
|
127
|
+
'rquote',
|
128
|
+
'href',
|
129
|
+
'id',
|
130
|
+
'mathbackground',
|
131
|
+
'mathcolor'],
|
132
|
+
'mscarries'=>['href', 'id', 'mathbackground', 'mathcolor'],
|
133
|
+
'mscarry'=>['href', 'id', 'mathbackground', 'mathcolor'],
|
134
|
+
'msgroup'=>['href', 'id', 'mathbackground', 'mathcolor'],
|
135
|
+
'msline'=>['length', 'href', 'id', 'mathbackground', 'mathcolor'],
|
136
|
+
'mspace'=>['height', 'width', 'href', 'id', 'mathbackground', 'mathcolor'],
|
137
|
+
'msqrt'=>['href', 'id', 'mathbackground', 'mathcolor'],
|
138
|
+
'msrow'=>['href', 'id', 'mathbackground', 'mathcolor'],
|
139
|
+
'mstack'=>['align', 'href', 'id', 'mathbackground', 'mathcolor'],
|
140
|
+
'mstyle'=>
|
141
|
+
['displaystyle',
|
142
|
+
'scriptlevel',
|
143
|
+
'scriptminsize',
|
144
|
+
'scriptsizemultiplier',
|
145
|
+
'href',
|
146
|
+
'id',
|
147
|
+
'mathbackground',
|
148
|
+
'mathcolor'],
|
149
|
+
'msub'=>['subscriptshift', 'href', 'id', 'mathbackground', 'mathcolor'],
|
150
|
+
'msup'=>['supscriptshift', 'href', 'id', 'mathbackground', 'mathcolor'],
|
151
|
+
'msubsup'=>
|
152
|
+
['subscriptshift',
|
153
|
+
'supscriptshift',
|
154
|
+
'href',
|
155
|
+
'id',
|
156
|
+
'mathbackground',
|
157
|
+
'mathcolor'],
|
158
|
+
'mtable'=>
|
159
|
+
['align',
|
160
|
+
'columnalign',
|
161
|
+
'columnlines',
|
162
|
+
'columnspacing',
|
163
|
+
'displaystyle',
|
164
|
+
'frame',
|
165
|
+
'framespacing',
|
166
|
+
'rowalign',
|
167
|
+
'rowlines',
|
168
|
+
'rowspacing',
|
169
|
+
'width',
|
170
|
+
'href',
|
171
|
+
'id',
|
172
|
+
'mathbackground',
|
173
|
+
'mathcolor'],
|
174
|
+
'mtd'=>
|
175
|
+
['columnalign',
|
176
|
+
'columnspan',
|
177
|
+
'rowalign',
|
178
|
+
'rowspan',
|
179
|
+
'href',
|
180
|
+
'id',
|
181
|
+
'mathbackground',
|
182
|
+
'mathcolor'],
|
183
|
+
'mtext'=>
|
184
|
+
['dir',
|
185
|
+
'mathbackground',
|
186
|
+
'mathcolor',
|
187
|
+
'mathsize',
|
188
|
+
'mathvariant',
|
189
|
+
'href',
|
190
|
+
'id',
|
191
|
+
'mathbackground',
|
192
|
+
'mathcolor'],
|
193
|
+
'mtr'=>
|
194
|
+
['columnalign', 'rowalign', 'href', 'id', 'mathbackground', 'mathcolor'],
|
195
|
+
'munder'=>
|
196
|
+
['accentunder', 'align', 'href', 'id', 'mathbackground', 'mathcolor'],
|
197
|
+
'munderover'=>
|
198
|
+
['accent',
|
199
|
+
'accentunder',
|
200
|
+
'align',
|
201
|
+
'href',
|
202
|
+
'id',
|
203
|
+
'mathbackground',
|
204
|
+
'mathcolor'],
|
205
|
+
'semantics'=>['href', 'id', 'mathbackground', 'mathcolor']
|
206
|
+
}.freeze
|
207
|
+
|
208
|
+
# Default whitelisted elements.
|
209
|
+
ELEMENTS = ([
|
210
|
+
'a', 'abbr', 'acronym', 'address', 'area', 'b', 'big',
|
211
|
+
'blockquote', 'br', 'button', 'caption', 'center', 'cite',
|
212
|
+
'code', 'col', 'colgroup', 'dd', 'del', 'dfn', 'dir', 'div',
|
213
|
+
'dl', 'dt', 'em', 'fieldset', 'font', 'form', 'h1', 'h2', 'h3',
|
214
|
+
'h4', 'h5', 'h6', 'hr', 'i', 'img', 'input', 'ins', 'kbd', 'label',
|
215
|
+
'legend', 'li', 'map', 'mark', 'math', 'menu', 'mfrac', 'mi', 'mn',
|
216
|
+
'mo', 'mrow', 'msqrt', 'msubsup', 'msup', 'mtext', 'ol', 'optgroup',
|
217
|
+
'option', 'p', 'pre', 'q', 's', 'samp', 'select', 'small', 'span',
|
218
|
+
'strike', 'strong', 'sub', 'sup', 'table', 'tbody', 'td', 'textarea',
|
219
|
+
'tfoot', 'th', 'thead', 'tr', 'tt', 'u', 'ul', 'var'
|
220
|
+
] + MATHML_ELEMENTS).freeze
|
221
|
+
|
222
|
+
|
22
223
|
# Default whitelisted attributes.
|
23
|
-
ATTRIBUTES = {
|
224
|
+
ATTRIBUTES = ({
|
24
225
|
'a' => ['href'],
|
25
226
|
'img' => ['src'],
|
26
227
|
:all => ['abbr', 'accept', 'accept-charset',
|
@@ -40,7 +241,7 @@ module Gollum
|
|
40
241
|
'start', 'summary', 'tabindex', 'target',
|
41
242
|
'title', 'type', 'usemap', 'valign', 'value',
|
42
243
|
'vspace', 'width']
|
43
|
-
}.freeze
|
244
|
+
}.merge(MATHML_ATTRS)).freeze
|
44
245
|
|
45
246
|
# Default whitelisted protocols for URLs.
|
46
247
|
PROTOCOLS = {
|