RTFMd 0.10301.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,61 @@
1
+ module Gollum
2
+ module Pagination
3
+ def self.included(klass)
4
+ klass.extend ClassMethods
5
+ class << klass
6
+ # Default Integer max count of items to return in git commands.
7
+ attr_accessor :per_page
8
+ end
9
+ klass.per_page = 30
10
+ end
11
+
12
+ module ClassMethods
13
+ # Turns a page number into an offset number for the git skip option.
14
+ #
15
+ # page - Integer page number.
16
+ #
17
+ # Returns an Integer.
18
+ def page_to_skip(page)
19
+ ([1, page.to_i].max - 1) * per_page
20
+ end
21
+
22
+ # Fills in git-specific options for the log command using simple
23
+ # pagination options.
24
+ #
25
+ # options - Hash of options:
26
+ # page - Optional Integer page number (default: 1)
27
+ # per_page - Optional Integer max count of items to return.
28
+ # Defaults to #per_class class method.
29
+ #
30
+ # Returns Hash with :max_count and :skip keys.
31
+ def log_pagination_options(options = {})
32
+ skip = page_to_skip(options.delete(:page))
33
+ options[:max_count] = [options.delete(:per_page).to_i, per_page].max
34
+ options[:skip] = skip if skip > 0
35
+ options
36
+ end
37
+ end
38
+
39
+ # Turns a page number into an offset number for the git skip option.
40
+ #
41
+ # page - Integer page number.
42
+ #
43
+ # Returns an Integer.
44
+ def page_to_skip(page)
45
+ self.class.page_to_skip(page)
46
+ end
47
+
48
+ # Fills in git-specific options for the log command using simple
49
+ # pagination options.
50
+ #
51
+ # options - Hash of options:
52
+ # page - Optional Integer page number (default: 1)
53
+ # per_page - Optional Integer max count of items to return.
54
+ # Defaults to #per_class class method.
55
+ #
56
+ # Returns Hash with :max_count and :skip keys.
57
+ def log_pagination_options(options = {})
58
+ self.class.log_pagination_options(options)
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,161 @@
1
+ module Gollum
2
+ # Encapsulate sanitization options.
3
+ #
4
+ # This class does not yet support all options of Sanitize library.
5
+ # See http://github.com/rgrove/sanitize/.
6
+ class Sanitization
7
+ # Default whitelisted elements.
8
+ ELEMENTS = [
9
+ 'a', 'abbr', 'acronym', 'address', 'area', 'b', 'big',
10
+ 'blockquote', 'br', 'button', 'caption', 'center', 'cite',
11
+ 'code', 'col', 'colgroup', 'dd', 'del', 'dfn', 'dir',
12
+ 'div', 'dl', 'dt', 'em', 'fieldset', 'font', 'form', 'h1',
13
+ 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'input',
14
+ 'ins', 'kbd', 'label', 'legend', 'li', 'map', 'menu',
15
+ 'ol', 'optgroup', 'option', 'p', 'pre', 'q', 's', 'samp',
16
+ 'select', 'small', 'span', 'strike', 'strong', 'sub',
17
+ 'sup', 'table', 'tbody', 'td', 'textarea', 'tfoot', 'th',
18
+ 'thead', 'tr', 'tt', 'u', 'ul', 'var'
19
+ ].freeze
20
+
21
+ # Default whitelisted attributes.
22
+ ATTRIBUTES = {
23
+ 'a' => ['href'],
24
+ 'img' => ['src'],
25
+ :all => ['abbr', 'accept', 'accept-charset',
26
+ 'accesskey', 'action', 'align', 'alt', 'axis',
27
+ 'border', 'cellpadding', 'cellspacing', 'char',
28
+ 'charoff', 'class', 'charset', 'checked', 'cite',
29
+ 'clear', 'cols', 'colspan', 'color',
30
+ 'compact', 'coords', 'datetime', 'dir',
31
+ 'disabled', 'enctype', 'for', 'frame',
32
+ 'headers', 'height', 'hreflang',
33
+ 'hspace', 'ismap', 'label', 'lang',
34
+ 'longdesc', 'maxlength', 'media', 'method',
35
+ 'multiple', 'name', 'nohref', 'noshade',
36
+ 'nowrap', 'prompt', 'readonly', 'rel', 'rev',
37
+ 'rows', 'rowspan', 'rules', 'scope',
38
+ 'selected', 'shape', 'size', 'span',
39
+ 'start', 'summary', 'tabindex', 'target',
40
+ 'title', 'type', 'usemap', 'valign', 'value',
41
+ 'vspace', 'width']
42
+ }.freeze
43
+
44
+ # Default whitelisted protocols for URLs.
45
+ PROTOCOLS = {
46
+ 'a' => {'href' => ['http', 'https', 'mailto', :relative]},
47
+ 'img' => {'src' => ['http', 'https', :relative]}
48
+ }.freeze
49
+
50
+ ADD_ATTRIBUTES = lambda do |env, node|
51
+ if add = env[:config][:add_attributes][node.name]
52
+ add.each do |key, value|
53
+ node[key] = value
54
+ end
55
+ end
56
+ end
57
+
58
+ # Default transformers to force @id attributes with 'wiki-' prefix
59
+ TRANSFORMERS = [
60
+ lambda do |env|
61
+ node = env[:node]
62
+ return if env[:is_whitelisted] || !node.element?
63
+ prefix = env[:config][:id_prefix]
64
+ found_attrs = %w(id name).select do |key|
65
+ if value = node[key]
66
+ node[key] = value.gsub(/\A(#{prefix})?/, prefix)
67
+ end
68
+ end
69
+ if found_attrs.size > 0
70
+ ADD_ATTRIBUTES.call(env, node)
71
+ {}
72
+ end
73
+ end,
74
+ lambda do |env|
75
+ node = env[:node]
76
+ return unless value = node['href']
77
+ prefix = env[:config][:id_prefix]
78
+ node['href'] = value.gsub(/\A\#(#{prefix})?/, '#'+prefix)
79
+ ADD_ATTRIBUTES.call(env, node)
80
+ {}
81
+ end
82
+ ].freeze
83
+
84
+ # Gets an Array of whitelisted HTML elements. Default: ELEMENTS.
85
+ attr_reader :elements
86
+
87
+ # Gets a Hash describing which attributes are allowed in which HTML
88
+ # elements. Default: ATTRIBUTES.
89
+ attr_reader :attributes
90
+
91
+ # Gets a Hash describing which URI protocols are allowed in HTML
92
+ # attributes. Default: PROTOCOLS
93
+ attr_reader :protocols
94
+
95
+ # Gets a Hash describing which URI protocols are allowed in HTML
96
+ # attributes. Default: TRANSFORMERS
97
+ attr_reader :transformers
98
+
99
+ # Gets or sets a String prefix which is added to ID attributes.
100
+ # Default: 'wiki-'
101
+ attr_accessor :id_prefix
102
+
103
+ # Gets a Hash describing HTML attributes that Sanitize should add.
104
+ # Default: {}
105
+ attr_reader :add_attributes
106
+
107
+ # Sets a boolean determining whether Sanitize allows HTML comments in the
108
+ # output. Default: false.
109
+ attr_writer :allow_comments
110
+
111
+ def initialize
112
+ @elements = ELEMENTS
113
+ @attributes = ATTRIBUTES
114
+ @protocols = PROTOCOLS
115
+ @transformers = TRANSFORMERS
116
+ @add_attributes = {}
117
+ @allow_comments = false
118
+ @id_prefix = 'wiki-'
119
+ yield self if block_given?
120
+ end
121
+
122
+ # Determines if Sanitize should allow HTML comments.
123
+ #
124
+ # Returns True if comments are allowed, or False.
125
+ def allow_comments?
126
+ !!@allow_comments
127
+ end
128
+
129
+ # Modifies the current Sanitization instance to sanitize older revisions
130
+ # of pages.
131
+ #
132
+ # Returns a Sanitization instance.
133
+ def history_sanitization
134
+ self.class.new do |sanitize|
135
+ sanitize.add_attributes['a'] = {'rel' => 'nofollow'}
136
+ end
137
+ end
138
+
139
+ # Builds a Hash of options suitable for Sanitize.clean.
140
+ #
141
+ # Returns a Hash.
142
+ def to_hash
143
+ { :elements => elements,
144
+ :attributes => attributes,
145
+ :protocols => protocols,
146
+ :add_attributes => add_attributes,
147
+ :allow_comments => allow_comments?,
148
+ :transformers => transformers,
149
+ :id_prefix => id_prefix
150
+ }
151
+ end
152
+
153
+ # Builds a Sanitize instance from the current options.
154
+ #
155
+ # Returns a Sanitize instance.
156
+ def to_sanitize
157
+ Sanitize.new(to_hash)
158
+ end
159
+ end
160
+ end
161
+
@@ -0,0 +1,378 @@
1
+ module Gollum
2
+ class Wiki
3
+ include Pagination
4
+
5
+ class << self
6
+ # Sets the page class used by all instances of this Wiki.
7
+ attr_writer :page_class
8
+
9
+ # Sets the file class used by all instances of this Wiki.
10
+ attr_writer :file_class
11
+
12
+ # Sets the markup class used by all instances of this Wiki.
13
+ attr_writer :markup_classes
14
+
15
+ # Sets the default ref for the wiki.
16
+ attr_accessor :default_ref
17
+
18
+ # Sets the default name for commits.
19
+ attr_accessor :default_committer_name
20
+
21
+ # Sets the default email for commits.
22
+ attr_accessor :default_committer_email
23
+
24
+ # Sets sanitization options. Set to false to deactivate
25
+ # sanitization altogether.
26
+ attr_writer :sanitization
27
+
28
+ # Sets sanitization options. Set to false to deactivate
29
+ # sanitization altogether.
30
+ attr_writer :history_sanitization
31
+
32
+ # Gets the page class used by all instances of this Wiki.
33
+ # Default: Gollum::Page.
34
+ def page_class
35
+ @page_class ||
36
+ if superclass.respond_to?(:page_class)
37
+ superclass.page_class
38
+ else
39
+ ::Gollum::Page
40
+ end
41
+ end
42
+
43
+ # Gets the file class used by all instances of this Wiki.
44
+ # Default: Gollum::File.
45
+ def file_class
46
+ @file_class ||
47
+ if superclass.respond_to?(:file_class)
48
+ superclass.file_class
49
+ else
50
+ ::Gollum::File
51
+ end
52
+ end
53
+
54
+ # Gets the markup class used by all instances of this Wiki.
55
+ # Default: Gollum::Markup
56
+ def markup_classes
57
+ @markup_classes ||=
58
+ if superclass.respond_to?(:markup_classes)
59
+ superclass.markup_classes
60
+ else
61
+ Hash.new(::Gollum::Markup)
62
+ end
63
+ end
64
+
65
+ # Gets the default markup class used by all instances of this Wiki.
66
+ # Kept for backwards compatibility until Gollum v2.x
67
+ def markup_class(language=:default)
68
+ markup_classes[language]
69
+ end
70
+
71
+ # Sets the default markup class used by all instances of this Wiki.
72
+ # Kept for backwards compatibility until Gollum v2.x
73
+ def markup_class=(default)
74
+ @markup_classes = Hash.new(default).update(markup_classes)
75
+ default
76
+ end
77
+
78
+ alias_method :default_markup_class, :markup_class
79
+ alias_method :default_markup_class=, :markup_class=
80
+
81
+ # Gets the default sanitization options for current pages used by
82
+ # instances of this Wiki.
83
+ def sanitization
84
+ if @sanitization.nil?
85
+ @sanitization = Sanitization.new
86
+ end
87
+ @sanitization
88
+ end
89
+
90
+ # Gets the default sanitization options for older page revisions used by
91
+ # instances of this Wiki.
92
+ def history_sanitization
93
+ if @history_sanitization.nil?
94
+ @history_sanitization = sanitization ?
95
+ sanitization.history_sanitization :
96
+ false
97
+ end
98
+ @history_sanitization
99
+ end
100
+ end
101
+
102
+ self.default_ref = 'master'
103
+ self.default_committer_name = 'Anonymous'
104
+ self.default_committer_email = 'anon@anon.com'
105
+
106
+ # The String base path to prefix to internal links. For example, when set
107
+ # to "/wiki", the page "Hobbit" will be linked as "/wiki/Hobbit". Defaults
108
+ # to "/".
109
+ attr_reader :base_path
110
+
111
+ # Gets the sanitization options for current pages used by this Wiki.
112
+ attr_reader :sanitization
113
+
114
+ # Gets the sanitization options for older page revisions used by this Wiki.
115
+ attr_reader :history_sanitization
116
+
117
+ # Gets the String ref in which all page files reside.
118
+ attr_reader :ref
119
+
120
+ # Gets the String directory in which all page files reside.
121
+ attr_reader :page_file_dir
122
+
123
+ # Public: Initialize a new Gollum Repo.
124
+ #
125
+ # path - The String path to the Git repository that holds the Gollum
126
+ # site.
127
+ # options - Optional Hash:
128
+ # :base_path - String base path for all Wiki links.
129
+ # Default: "/"
130
+ # :page_class - The page Class. Default: Gollum::Page
131
+ # :file_class - The file Class. Default: Gollum::File
132
+ # :markup_classes - A hash containing the markup Classes for each
133
+ # document type. Default: { Gollum::Markup }
134
+ # :sanitization - An instance of Sanitization.
135
+ # :page_file_dir - String the directory in which all page files reside
136
+ # :ref - String the repository ref to retrieve pages from
137
+ #
138
+ # Returns a fresh Gollum::Repo.
139
+ def initialize(path, options = {})
140
+ if path.is_a?(GitAccess)
141
+ options[:access] = path
142
+ path = path.path
143
+ end
144
+ @path = path
145
+ @page_file_dir = options[:page_file_dir]
146
+ @access = options[:access] || GitAccess.new(path, @page_file_dir)
147
+ @base_path = options[:base_path] || "/"
148
+ @page_class = options[:page_class] || self.class.page_class
149
+ @file_class = options[:file_class] || self.class.file_class
150
+ @markup_classes = options[:markup_classes] || self.class.markup_classes
151
+ @repo = @access.repo
152
+ @ref = options[:ref] || self.class.default_ref
153
+ @sanitization = options[:sanitization] || self.class.sanitization
154
+ @history_sanitization = options[:history_sanitization] ||
155
+ self.class.history_sanitization
156
+ end
157
+
158
+ # Public: check whether the wiki's git repo exists on the filesystem.
159
+ #
160
+ # Returns true if the repo exists, and false if it does not.
161
+ def exist?
162
+ @access.exist?
163
+ end
164
+
165
+ # Public: Get the formatted page for a given page name.
166
+ #
167
+ # name - The human or canonical String page name of the wiki page.
168
+ # version - The String version ID to find (default: @ref).
169
+ #
170
+ # Returns a Gollum::Page or nil if no matching page was found.
171
+ def page(name, version = @ref)
172
+ @page_class.new(self).find(name, version)
173
+ end
174
+
175
+ # Public: Get the static file for a given name.
176
+ #
177
+ # name - The full String pathname to the file.
178
+ # version - The String version ID to find (default: @ref).
179
+ #
180
+ # Returns a Gollum::File or nil if no matching file was found.
181
+ def file(name, version = @ref)
182
+ @file_class.new(self).find(name, version)
183
+ end
184
+
185
+ # Public: Lists all pages for this wiki.
186
+ #
187
+ # treeish - The String commit ID or ref to find (default: @ref)
188
+ #
189
+ # Returns an Array of Gollum::Page instances.
190
+ def pages(treeish = nil)
191
+ tree_list(treeish || @ref)
192
+ end
193
+
194
+ # Public: Returns the number of pages accessible from a commit
195
+ #
196
+ # ref - A String ref that is either a commit SHA or references one.
197
+ #
198
+ # Returns a Fixnum
199
+ def size(ref = nil)
200
+ tree_map_for(ref || @ref).inject(0) do |num, entry|
201
+ num + (@page_class.valid_page_name?(entry.name) ? 1 : 0)
202
+ end
203
+ rescue Grit::GitRuby::Repository::NoSuchShaFound
204
+ 0
205
+ end
206
+
207
+ # Public: All of the versions that have touched the Page.
208
+ #
209
+ # options - The options Hash:
210
+ # :page - The Integer page number (default: 1).
211
+ # :per_page - The Integer max count of items to return.
212
+ #
213
+ # Returns an Array of Grit::Commit.
214
+ def log(options = {})
215
+ @repo.log(@ref, nil, log_pagination_options(options))
216
+ end
217
+
218
+ # Public: Refreshes just the cached Git reference data. This should
219
+ # be called after every Gollum update.
220
+ #
221
+ # Returns nothing.
222
+ def clear_cache
223
+ @access.refresh
224
+ end
225
+
226
+ # Public: Creates a Sanitize instance using the Wiki's sanitization
227
+ # options.
228
+ #
229
+ # Returns a Sanitize instance.
230
+ def sanitizer
231
+ if options = sanitization
232
+ @sanitizer ||= options.to_sanitize
233
+ end
234
+ end
235
+
236
+ # Public: Creates a Sanitize instance using the Wiki's history sanitization
237
+ # options.
238
+ #
239
+ # Returns a Sanitize instance.
240
+ def history_sanitizer
241
+ if options = history_sanitization
242
+ @history_sanitizer ||= options.to_sanitize
243
+ end
244
+ end
245
+
246
+ #########################################################################
247
+ #
248
+ # Internal Methods
249
+ #
250
+ #########################################################################
251
+
252
+ # The Grit::Repo associated with the wiki.
253
+ #
254
+ # Returns the Grit::Repo.
255
+ attr_reader :repo
256
+
257
+ # The String path to the Git repository that holds the Gollum site.
258
+ #
259
+ # Returns the String path.
260
+ attr_reader :path
261
+
262
+ # Gets the page class used by all instances of this Wiki.
263
+ attr_reader :page_class
264
+
265
+ # Gets the file class used by all instances of this Wiki.
266
+ attr_reader :file_class
267
+
268
+ # Gets the markup class used by all instances of this Wiki.
269
+ attr_reader :markup_classes
270
+
271
+ # Normalize the data.
272
+ #
273
+ # data - The String data to be normalized.
274
+ #
275
+ # Returns the normalized data String.
276
+ def normalize(data)
277
+ data.gsub(/\r/, '')
278
+ end
279
+
280
+ # Assemble a Page's filename from its name and format.
281
+ #
282
+ # name - The String name of the page (may be in human format).
283
+ # format - The Symbol format of the page.
284
+ #
285
+ # Returns the String filename.
286
+ def page_file_name(name, format)
287
+ ext = @page_class.format_to_ext(format)
288
+ @page_class.cname(name) + '.' + ext
289
+ end
290
+
291
+ # Fill an array with a list of pages.
292
+ #
293
+ # ref - A String ref that is either a commit SHA or references one.
294
+ #
295
+ # Returns a flat Array of Gollum::Page instances.
296
+ def tree_list(ref)
297
+ if sha = @access.ref_to_sha(ref)
298
+ commit = @access.commit(sha)
299
+ tree_map_for(sha).inject([]) do |list, entry|
300
+ next list unless @page_class.valid_page_name?(entry.name)
301
+ list << entry.page(self, commit)
302
+ end
303
+ else
304
+ []
305
+ end
306
+ end
307
+
308
+ # Creates a reverse diff for the given SHAs on the given Gollum::Page.
309
+ #
310
+ # page - The Gollum::Page to scope the patch to, or a String Path.
311
+ # sha1 - String SHA1 of the earlier parent if two SHAs are given,
312
+ # or the child.
313
+ # sha2 - Optional String SHA1 of the child.
314
+ #
315
+ # Returns a String of the reverse Diff to apply.
316
+ def full_reverse_diff_for(page, sha1, sha2 = nil)
317
+ sha1, sha2 = "#{sha1}^", sha1 if sha2.nil?
318
+ args = [{:R => true}, sha1, sha2]
319
+ if page
320
+ args << '--' << (page.respond_to?(:path) ? page.path : page.to_s)
321
+ end
322
+ repo.git.native(:diff, *args)
323
+ end
324
+
325
+ # Creates a reverse diff for the given SHAs.
326
+ #
327
+ # sha1 - String SHA1 of the earlier parent if two SHAs are given,
328
+ # or the child.
329
+ # sha2 - Optional String SHA1 of the child.
330
+ #
331
+ # Returns a String of the reverse Diff to apply.
332
+ def full_reverse_diff(sha1, sha2 = nil)
333
+ full_reverse_diff_for(nil, sha1, sha2)
334
+ end
335
+
336
+ # Gets the default name for commits.
337
+ #
338
+ # Returns the String name.
339
+ def default_committer_name
340
+ @default_committer_name ||= \
341
+ @repo.config['user.name'] || self.class.default_committer_name
342
+ end
343
+
344
+ # Gets the default email for commits.
345
+ #
346
+ # Returns the String email address.
347
+ def default_committer_email
348
+ @default_committer_email ||= \
349
+ @repo.config['user.email'] || self.class.default_committer_email
350
+ end
351
+
352
+ # Gets the commit object for the given ref or sha.
353
+ #
354
+ # ref - A string ref or SHA pointing to a valid commit.
355
+ #
356
+ # Returns a Grit::Commit instance.
357
+ def commit_for(ref)
358
+ @access.commit(ref)
359
+ rescue Grit::GitRuby::Repository::NoSuchShaFound
360
+ end
361
+
362
+ # Finds a full listing of files and their blob SHA for a given ref. Each
363
+ # listing is cached based on its actual commit SHA.
364
+ #
365
+ # ref - A String ref that is either a commit SHA or references one.
366
+ #
367
+ # Returns an Array of BlobEntry instances.
368
+ def tree_map_for(ref)
369
+ @access.tree(ref)
370
+ rescue Grit::GitRuby::Repository::NoSuchShaFound
371
+ []
372
+ end
373
+
374
+ def inspect
375
+ %(#<#{self.class.name}:#{object_id} #{@repo.path}>)
376
+ end
377
+ end
378
+ end