gollum-lib 5.0.a.4 → 5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -1
  3. data/README.md +12 -7
  4. data/Rakefile +5 -5
  5. data/adapter_dependencies.rb +7 -0
  6. data/gemspec.rb +18 -10
  7. data/gollum-lib.gemspec +2 -6
  8. data/gollum-lib_java.gemspec +2 -2
  9. data/lib/gollum-lib.rb +9 -9
  10. data/lib/gollum-lib/blob_entry.rb +2 -8
  11. data/lib/gollum-lib/committer.rb +22 -60
  12. data/lib/gollum-lib/file.rb +105 -82
  13. data/lib/gollum-lib/file_view.rb +8 -4
  14. data/lib/gollum-lib/filter.rb +12 -0
  15. data/lib/gollum-lib/filter/code.rb +9 -13
  16. data/lib/gollum-lib/filter/critic_markup.rb +97 -0
  17. data/lib/gollum-lib/filter/emoji.rb +10 -8
  18. data/lib/gollum-lib/filter/macro.rb +5 -2
  19. data/lib/gollum-lib/filter/plantuml.rb +1 -1
  20. data/lib/gollum-lib/filter/remote_code.rb +3 -2
  21. data/lib/gollum-lib/filter/render.rb +25 -2
  22. data/lib/gollum-lib/filter/sanitize.rb +1 -8
  23. data/lib/gollum-lib/filter/tags.rb +57 -47
  24. data/lib/gollum-lib/filter/toc.rb +17 -21
  25. data/lib/gollum-lib/filter/yaml.rb +1 -1
  26. data/lib/gollum-lib/git_access.rb +0 -25
  27. data/lib/gollum-lib/helpers.rb +13 -3
  28. data/lib/gollum-lib/macro/audio.rb +9 -0
  29. data/lib/gollum-lib/macro/global_toc.rb +2 -1
  30. data/lib/gollum-lib/macro/navigation.rb +8 -6
  31. data/lib/gollum-lib/macro/note.rb +19 -0
  32. data/lib/gollum-lib/macro/octicon.rb +12 -0
  33. data/lib/gollum-lib/macro/warn.rb +11 -0
  34. data/lib/gollum-lib/markup.rb +17 -32
  35. data/lib/gollum-lib/markups.rb +11 -7
  36. data/lib/gollum-lib/page.rb +79 -165
  37. data/lib/gollum-lib/pagination.rb +7 -6
  38. data/lib/gollum-lib/redirects.rb +38 -0
  39. data/lib/gollum-lib/sanitization.rb +32 -357
  40. data/lib/gollum-lib/version.rb +1 -1
  41. data/lib/gollum-lib/wiki.rb +216 -404
  42. metadata +73 -28
  43. data/ROADMAP +0 -6
@@ -16,22 +16,23 @@ module Gollum
16
16
  # page - Integer page number.
17
17
  #
18
18
  # Returns an Integer.
19
- def page_to_skip(page)
20
- ([1, page.to_i].max - 1) * per_page
19
+ def page_to_skip(page, count = per_page)
20
+ ([1, page.to_i].max - 1) * count
21
21
  end
22
22
 
23
23
  # Fills in git-specific options for the log command using simple
24
24
  # pagination options.
25
25
  #
26
26
  # options - Hash of options:
27
- # page - Optional Integer page number (default: 1)
28
- # per_page - Optional Integer max count of items to return.
27
+ # :page_num - Optional Integer page number (default: 1)
28
+ # :per_page - Optional Integer max count of items to return.
29
29
  # Defaults to #per_class class method.
30
30
  #
31
31
  # Returns Hash with :max_count and :skip keys.
32
32
  def log_pagination_options(options = {})
33
- skip = page_to_skip(options.delete(:page))
34
- options[:max_count] = [options.delete(:per_page).to_i, per_page].max
33
+ options[:max_count] = options.fetch(:per_page, per_page)
34
+ options.delete(:per_page)
35
+ skip = page_to_skip(options.delete(:page_num), options[:max_count])
35
36
  options[:skip] = skip if skip > 0
36
37
  options
37
38
  end
@@ -0,0 +1,38 @@
1
+ require 'yaml'
2
+
3
+ REDIRECTS_FILE = '.redirects.gollum'
4
+
5
+ module Gollum
6
+
7
+ module Redirects
8
+
9
+ def stale?
10
+ @current_head != @wiki.repo.head.commit.sha
11
+ end
12
+
13
+ def init(wiki)
14
+ @wiki = wiki
15
+ @current_head = @wiki.repo.head.commit.sha
16
+ end
17
+
18
+ def load
19
+ file = @wiki.file(REDIRECTS_FILE)
20
+ redirects = {}
21
+ if file
22
+ begin
23
+ redirects = YAML.load(file.raw_data)
24
+ rescue YAML::Error
25
+ # TODO handle error
26
+ end
27
+ end
28
+ self.clear
29
+ self.merge!(redirects)
30
+ end
31
+
32
+ def dump
33
+ @wiki.overwrite_file(REDIRECTS_FILE, self.to_yaml, {})
34
+ end
35
+
36
+ end # Redirects Module
37
+
38
+ end # Gollum Module
@@ -1,377 +1,52 @@
1
- # ~*~ encoding: utf-8 ~*~
1
+ ::Loofah::HTML5::SafeList::ACCEPTABLE_PROTOCOLS.add('apt')
2
+
2
3
  module Gollum
3
- # Encapsulate sanitization options.
4
- #
5
- # This class does not yet support all options of Sanitize library.
6
- # See http://github.com/rgrove/sanitize/.
7
4
  class Sanitization
8
5
 
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'
19
- ].freeze
20
-
6
+ @@accepted_protocols = ::Loofah::HTML5::SafeList::ACCEPTABLE_PROTOCOLS.to_a.freeze
21
7
 
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
8
+ # This class method is used in the Tag filter to determine whether a link has an acceptable URI scheme.
9
+ def self.accepted_protocols
10
+ @@accepted_protocols
11
+ end
207
12
 
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
13
+ REMOVE_NODES = ['style', 'script']
221
14
 
15
+ SCRUB_REMOVE = Loofah::Scrubber.new do |node|
16
+ node.remove if REMOVE_NODES.include?(node.name)
17
+ end
222
18
 
223
- # Default whitelisted attributes.
224
- ATTRIBUTES = ({
225
- 'a' => ['href'],
226
- 'img' => ['src'],
227
- :all => ['abbr', 'accept', 'accept-charset',
228
- 'accesskey', 'action', 'align', 'alt', 'axis',
229
- 'border', 'cellpadding', 'cellspacing', 'char',
230
- 'charoff', 'class', 'charset', 'checked', 'cite',
231
- 'clear', 'cols', 'colspan', 'color',
232
- 'compact', 'coords', 'datetime', 'dir',
233
- 'disabled', 'enctype', 'for', 'frame',
234
- 'headers', 'height', 'hreflang',
235
- 'hspace', 'id', 'ismap', 'label', 'lang',
236
- 'longdesc', 'maxlength', 'media', 'method',
237
- 'multiple', 'name', 'nohref', 'noshade',
238
- 'nowrap', 'prompt', 'readonly', 'rel', 'rev',
239
- 'rows', 'rowspan', 'rules', 'scope',
240
- 'selected', 'shape', 'size', 'span',
241
- 'start', 'summary', 'tabindex', 'target',
242
- 'title', 'type', 'usemap', 'valign', 'value',
243
- 'vspace', 'width']
244
- }.merge(MATHML_ATTRS)).freeze
19
+ attr_reader :id_prefix
245
20
 
246
- # Default whitelisted protocols for URLs.
247
- PROTOCOLS = {
248
- 'a' => { 'href' => ['http', 'https', 'mailto', 'ftp', 'irc', 'apt', :relative] },
249
- 'img' => { 'src' => ['http', 'https', :relative] },
250
- 'form' => { 'action' => ['http', 'https', :relative] }
251
- }.freeze
21
+ def initialize(to_xml_opts = {})
22
+ @to_xml_opts = to_xml_opts
23
+ end
252
24
 
253
- ADD_ATTRIBUTES = lambda do |env, node|
254
- if (add = env[:config][:add_attributes][node.name])
255
- add.each do |key, value|
256
- node[key] = value
257
- end
258
- end
25
+ def clean(data, historical = false)
26
+ doc = Loofah.fragment(data)
27
+ doc.scrub!(SCRUB_REMOVE)
28
+ doc.scrub!(:strip)
29
+ doc.scrub!(:nofollow) if historical
30
+ doc.scrub!(wiki_id_scrubber) if id_prefix
31
+ doc.to_xml(@to_xml_opts).gsub('<p></p>', '')
259
32
  end
260
33
 
261
- # Default elements whose contents will be removed in addition
262
- # to the elements themselve
263
- REMOVE_CONTENTS = [
264
- 'script',
265
- 'style'
266
- ].freeze
34
+ private
267
35
 
268
- # Default transformers to force @id attributes with 'wiki-' prefix
269
- TRANSFORMERS = [
270
- lambda do |env|
271
- node = env[:node]
272
- return if env[:is_whitelisted] || !node.element?
273
- prefix = env[:config][:id_prefix]
274
- found_attrs = %w(id name).select do |key|
36
+ # Returns a Loofah::Scrubber if the `id_prefix` attribute is set, or nil otherwise.
37
+ def wiki_id_scrubber
38
+ @id_scrubber ||= Loofah::Scrubber.new do |node|
39
+ if node.name == 'a' && val = node['href']
40
+ node['href'] = val.gsub(/\A\#(#{id_prefix})?/, '#' + id_prefix) unless node[:class] == 'internal anchorlink' # Don't prefix pure anchor links
41
+ else
42
+ %w(id name).each do |key|
275
43
  if (value = node[key])
276
- node[key] = value.gsub(/\A(#{prefix})?/, prefix)
44
+ node[key] = value.gsub(/\A(#{id_prefix})?/, id_prefix)
277
45
  end
278
46
  end
279
- if found_attrs.size > 0
280
- ADD_ATTRIBUTES.call(env, node)
281
- {}
282
- end
283
- end,
284
- lambda do |env|
285
- node = env[:node]
286
- return unless (value = node['href'])
287
- prefix = env[:config][:id_prefix]
288
- node['href'] = value.gsub(/\A\#(#{prefix})?/, '#'+prefix)
289
- ADD_ATTRIBUTES.call(env, node)
290
- {}
291
47
  end
292
- ].freeze
293
-
294
- # Gets an Array of whitelisted HTML elements. Default: ELEMENTS.
295
- attr_reader :elements
296
-
297
- # Gets a Hash describing which attributes are allowed in which HTML
298
- # elements. Default: ATTRIBUTES.
299
- attr_reader :attributes
300
-
301
- # Gets a Hash describing which URI protocols are allowed in HTML
302
- # attributes. Default: PROTOCOLS
303
- attr_reader :protocols
304
-
305
- # Gets a Hash describing which URI protocols are allowed in HTML
306
- # attributes. Default: TRANSFORMERS
307
- attr_reader :transformers
308
-
309
- # Gets or sets a String prefix which is added to ID attributes.
310
- # Default: ''
311
- attr_accessor :id_prefix
312
-
313
- # Gets a Hash describing HTML attributes that Sanitize should add.
314
- # Default: {}
315
- attr_reader :add_attributes
316
-
317
- # Gets an Array of element names whose contents will be removed in addition
318
- # to the elements themselves. Default: REMOVE_CONTENTS
319
- attr_reader :remove_contents
320
-
321
- # Sets a boolean determining whether Sanitize allows HTML comments in the
322
- # output. Default: false.
323
- attr_writer :allow_comments
324
-
325
- def initialize
326
- @elements = ELEMENTS.dup
327
- @attributes = ATTRIBUTES.dup
328
- @protocols = PROTOCOLS.dup
329
- @transformers = TRANSFORMERS.dup
330
- @add_attributes = {}
331
- @remove_contents = REMOVE_CONTENTS.dup
332
- @allow_comments = false
333
- @id_prefix = ''
334
- yield self if block_given?
335
- end
336
-
337
- # Determines if Sanitize should allow HTML comments.
338
- #
339
- # Returns True if comments are allowed, or False.
340
- def allow_comments?
341
- !!@allow_comments
342
- end
343
-
344
- # Modifies the current Sanitization instance to sanitize older revisions
345
- # of pages.
346
- #
347
- # Returns a Sanitization instance.
348
- def history_sanitization
349
- self.class.new do |sanitize|
350
- sanitize.add_attributes['a'] = { 'rel' => 'nofollow' }
351
48
  end
352
49
  end
353
50
 
354
- # Builds a Hash of options suitable for Sanitize.clean.
355
- #
356
- # Returns a Hash.
357
- def to_hash
358
- { :elements => elements,
359
- :attributes => attributes,
360
- :protocols => protocols,
361
- :add_attributes => add_attributes,
362
- :remove_contents => remove_contents,
363
- :allow_comments => allow_comments?,
364
- :transformers => transformers,
365
- :id_prefix => id_prefix
366
- }
367
- end
368
-
369
- # Builds a Sanitize instance from the current options.
370
- #
371
- # Returns a Sanitize instance.
372
- def to_sanitize
373
- Sanitize.new(to_hash)
374
- end
375
51
  end
376
- end
377
-
52
+ end