read-only-gollum 1.4.0
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.
- data/Gemfile +4 -0
- data/HISTORY.md +102 -0
- data/Home.md +3 -0
- data/LICENSE +21 -0
- data/README.md +477 -0
- data/Rakefile +142 -0
- data/bin/read-only-gollum +126 -0
- data/docs/sanitization.md +32 -0
- data/lib/gollum.rb +41 -0
- data/lib/gollum/blob_entry.rb +78 -0
- data/lib/gollum/committer.rb +218 -0
- data/lib/gollum/file.rb +64 -0
- data/lib/gollum/frontend/app.rb +225 -0
- data/lib/gollum/frontend/public/css/dialog.css +141 -0
- data/lib/gollum/frontend/public/css/editor.css +537 -0
- data/lib/gollum/frontend/public/css/gollum.css +660 -0
- data/lib/gollum/frontend/public/css/ie7.css +69 -0
- data/lib/gollum/frontend/public/css/template.css +381 -0
- data/lib/gollum/frontend/public/images/icon-sprite.png +0 -0
- data/lib/gollum/frontend/public/javascript/editor/gollum.editor.js +1096 -0
- data/lib/gollum/frontend/public/javascript/editor/langs/asciidoc.js +167 -0
- data/lib/gollum/frontend/public/javascript/editor/langs/creole.js +104 -0
- data/lib/gollum/frontend/public/javascript/editor/langs/markdown.js +211 -0
- data/lib/gollum/frontend/public/javascript/editor/langs/org.js +173 -0
- data/lib/gollum/frontend/public/javascript/editor/langs/pod.js +111 -0
- data/lib/gollum/frontend/public/javascript/editor/langs/rdoc.js +74 -0
- data/lib/gollum/frontend/public/javascript/editor/langs/textile.js +175 -0
- data/lib/gollum/frontend/public/javascript/gollum.dialog.js +263 -0
- data/lib/gollum/frontend/public/javascript/gollum.js +161 -0
- data/lib/gollum/frontend/public/javascript/gollum.placeholder.js +54 -0
- data/lib/gollum/frontend/public/javascript/jquery.color.js +123 -0
- data/lib/gollum/frontend/public/javascript/jquery.js +7179 -0
- data/lib/gollum/frontend/templates/compare.mustache +38 -0
- data/lib/gollum/frontend/templates/create.mustache +17 -0
- data/lib/gollum/frontend/templates/edit.mustache +17 -0
- data/lib/gollum/frontend/templates/editor.mustache +116 -0
- data/lib/gollum/frontend/templates/error.mustache +8 -0
- data/lib/gollum/frontend/templates/history.mustache +58 -0
- data/lib/gollum/frontend/templates/layout.mustache +28 -0
- data/lib/gollum/frontend/templates/page.mustache +37 -0
- data/lib/gollum/frontend/templates/pages.mustache +35 -0
- data/lib/gollum/frontend/templates/search.mustache +36 -0
- data/lib/gollum/frontend/templates/searchbar.mustache +10 -0
- data/lib/gollum/frontend/views/compare.rb +94 -0
- data/lib/gollum/frontend/views/create.rb +48 -0
- data/lib/gollum/frontend/views/edit.rb +52 -0
- data/lib/gollum/frontend/views/editable.rb +13 -0
- data/lib/gollum/frontend/views/error.rb +7 -0
- data/lib/gollum/frontend/views/history.rb +44 -0
- data/lib/gollum/frontend/views/layout.rb +20 -0
- data/lib/gollum/frontend/views/page.rb +57 -0
- data/lib/gollum/frontend/views/pages.rb +19 -0
- data/lib/gollum/frontend/views/search.rb +20 -0
- data/lib/gollum/git_access.rb +248 -0
- data/lib/gollum/markup.rb +489 -0
- data/lib/gollum/page.rb +430 -0
- data/lib/gollum/pagination.rb +61 -0
- data/lib/gollum/sanitization.rb +174 -0
- data/lib/gollum/tex.rb +89 -0
- data/lib/gollum/web_sequence_diagram.rb +43 -0
- data/lib/gollum/wiki.rb +636 -0
- data/read-only-gollum.gemspec +224 -0
- data/templates/formatting.html +92 -0
- data/test/examples/empty.git/HEAD +1 -0
- data/test/examples/empty.git/config +5 -0
- data/test/examples/empty.git/description +1 -0
- data/test/examples/empty.git/hooks/applypatch-msg.sample +15 -0
- data/test/examples/empty.git/hooks/commit-msg.sample +24 -0
- data/test/examples/empty.git/hooks/post-commit.sample +8 -0
- data/test/examples/empty.git/hooks/post-receive.sample +15 -0
- data/test/examples/empty.git/hooks/post-update.sample +8 -0
- data/test/examples/empty.git/hooks/pre-applypatch.sample +14 -0
- data/test/examples/empty.git/hooks/pre-commit.sample +46 -0
- data/test/examples/empty.git/hooks/pre-rebase.sample +169 -0
- data/test/examples/empty.git/hooks/prepare-commit-msg.sample +36 -0
- data/test/examples/empty.git/hooks/update.sample +128 -0
- data/test/examples/empty.git/info/exclude +6 -0
- data/test/examples/empty.git/objects/info/.gitkeep +0 -0
- data/test/examples/empty.git/objects/pack/.gitkeep +0 -0
- data/test/examples/empty.git/refs/heads/.gitkeep +0 -0
- data/test/examples/lotr.git/COMMIT_EDITMSG +1 -0
- data/test/examples/lotr.git/HEAD +1 -0
- data/test/examples/lotr.git/ORIG_HEAD +1 -0
- data/test/examples/lotr.git/config +12 -0
- data/test/examples/lotr.git/description +1 -0
- data/test/examples/lotr.git/index +0 -0
- data/test/examples/lotr.git/info/exclude +6 -0
- data/test/examples/lotr.git/logs/HEAD +3 -0
- data/test/examples/lotr.git/logs/refs/heads/master +3 -0
- data/test/examples/lotr.git/objects/06/131480411710c92a82fe2d1e76932c70feb2e5 +0 -0
- data/test/examples/lotr.git/objects/0a/de1e2916346d4c1f2fb63b863fd3c16808fe44 +0 -0
- data/test/examples/lotr.git/objects/0e/d8cbe0a25235bd867e65193c7d837c66b328ef +3 -0
- data/test/examples/lotr.git/objects/12/629d666c5e3178f82f533f543d61b53dc78c0b +0 -0
- data/test/examples/lotr.git/objects/1d/b89ebba7e2c14d93b94ff98cfa3708a4f0d4e3 +2 -0
- data/test/examples/lotr.git/objects/24/49c2681badfd3c189e8ed658dacffe8ba48fe5 +0 -0
- data/test/examples/lotr.git/objects/25/4bdc1ba27d8b8a794538a8522d9a2b56ec2dd9 +0 -0
- data/test/examples/lotr.git/objects/2c/b9156ad383914561a8502fc70f5a1d887e48ad +4 -0
- data/test/examples/lotr.git/objects/5d/cac289a8603188d2c5caf481dcba2985126aaa +0 -0
- data/test/examples/lotr.git/objects/60/f12f4254f58801b9ee7db7bca5fa8aeefaa56b +0 -0
- data/test/examples/lotr.git/objects/71/4323c104239440a5c66ab12a67ed07a83c404f +0 -0
- data/test/examples/lotr.git/objects/84/0ec5b1ba1320e8ec443f28f99566f615d5af10 +0 -0
- data/test/examples/lotr.git/objects/93/6b83ee0dd8837adb82511e40d5e4ebe59bb675 +0 -0
- data/test/examples/lotr.git/objects/94/523d7ae48aeba575099dd12926420d8fd0425d +2 -0
- data/test/examples/lotr.git/objects/96/97dc65e095658bbd1b8e8678e08881e86d32f1 +0 -0
- data/test/examples/lotr.git/objects/a3/1ca2a7c352c92531a8b99815d15843b259e814 +0 -0
- data/test/examples/lotr.git/objects/a6/59b3763b822dd97544621fd0beef162ea37b14 +4 -0
- data/test/examples/lotr.git/objects/a8/ad3c09dd842a3517085bfadd37718856dee813 +0 -0
- data/test/examples/lotr.git/objects/aa/b61fe89d56f8614c0a8151da34f939dcedfa68 +0 -0
- data/test/examples/lotr.git/objects/bc/4b5fc0ce2c2ba3acef6647e4f67256ee45ab60 +0 -0
- data/test/examples/lotr.git/objects/c3/b43e9f08966b088e7a0192e436b7a884542e05 +0 -0
- data/test/examples/lotr.git/objects/dc/596d6b2dd89ab05c66f4abd7d5eb706bc17f19 +0 -0
- data/test/examples/lotr.git/objects/ec/da3205bee14520aab5a7bb307392064b938e83 +0 -0
- data/test/examples/lotr.git/objects/f4/84ebb1f40f8eb20d1bcd8d1d71934d2b8ae961 +0 -0
- data/test/examples/lotr.git/objects/fa/e7ef5344202bba4129abdc13060d9297d99465 +3 -0
- data/test/examples/lotr.git/objects/info/packs +2 -0
- data/test/examples/lotr.git/objects/pack/pack-dcbeaf3f6ff6c5eb08ea2b0a2d83626e8763546b.idx +0 -0
- data/test/examples/lotr.git/objects/pack/pack-dcbeaf3f6ff6c5eb08ea2b0a2d83626e8763546b.pack +0 -0
- data/test/examples/lotr.git/packed-refs +2 -0
- data/test/examples/lotr.git/refs/heads/master +1 -0
- data/test/examples/lotr.git/refs/remotes/origin/HEAD +1 -0
- data/test/examples/page_file_dir.git/COMMIT_EDITMSG +1 -0
- data/test/examples/page_file_dir.git/HEAD +1 -0
- data/test/examples/page_file_dir.git/config +6 -0
- data/test/examples/page_file_dir.git/description +1 -0
- data/test/examples/page_file_dir.git/index +0 -0
- data/test/examples/page_file_dir.git/info/exclude +6 -0
- data/test/examples/page_file_dir.git/logs/HEAD +1 -0
- data/test/examples/page_file_dir.git/logs/refs/heads/master +1 -0
- data/test/examples/page_file_dir.git/objects/0c/7d27db1f575263efdcab3dc650f4502a2dbcbf +0 -0
- data/test/examples/page_file_dir.git/objects/22/b404803c966dd92865614d86ff22ca12e50c1e +0 -0
- data/test/examples/page_file_dir.git/objects/25/7cc5642cb1a054f08cc83f2d943e56fd3ebe99 +0 -0
- data/test/examples/page_file_dir.git/objects/57/16ca5987cbf97d6bb54920bea6adde242d87e6 +0 -0
- data/test/examples/page_file_dir.git/objects/5b/43e14e0a15fb6f08feab1773d1c0991e9f71e2 +0 -0
- data/test/examples/page_file_dir.git/refs/heads/master +1 -0
- data/test/examples/revert.git/COMMIT_EDITMSG +1 -0
- data/test/examples/revert.git/HEAD +1 -0
- data/test/examples/revert.git/config +12 -0
- data/test/examples/revert.git/description +1 -0
- data/test/examples/revert.git/index +0 -0
- data/test/examples/revert.git/info/exclude +6 -0
- data/test/examples/revert.git/logs/HEAD +2 -0
- data/test/examples/revert.git/logs/refs/heads/master +2 -0
- data/test/examples/revert.git/objects/20/2ced67cea93c7b6bd2928aa1daef8d1d55a20d +0 -0
- data/test/examples/revert.git/objects/41/76394bfa11222363c66ce7e84b5f154095b6d9 +0 -0
- data/test/examples/revert.git/objects/6a/69f92020f5df77af6e8813ff1232493383b708 +0 -0
- data/test/examples/revert.git/objects/b4/785957bc986dc39c629de9fac9df46972c00fc +0 -0
- data/test/examples/revert.git/objects/f4/03b791119f8232b7cb0ba455c624ac6435f433 +0 -0
- data/test/examples/revert.git/objects/info/packs +2 -0
- data/test/examples/revert.git/objects/pack/pack-a561f8437234f74d0bacb9e0eebe52d207f5770d.idx +0 -0
- data/test/examples/revert.git/objects/pack/pack-a561f8437234f74d0bacb9e0eebe52d207f5770d.pack +0 -0
- data/test/examples/revert.git/packed-refs +2 -0
- data/test/examples/revert.git/refs/heads/master +1 -0
- data/test/examples/revert.git/refs/remotes/origin/HEAD +1 -0
- data/test/examples/yubiwa.git/HEAD +1 -0
- data/test/examples/yubiwa.git/config +5 -0
- data/test/examples/yubiwa.git/description +1 -0
- data/test/examples/yubiwa.git/info/exclude +6 -0
- data/test/examples/yubiwa.git/objects/10/fa2ddc4e3b4009d8a453aace10bd6148c1ad00 +0 -0
- data/test/examples/yubiwa.git/objects/52/4b82874327ea7cbf730389964ba7cb3de966de +0 -0
- data/test/examples/yubiwa.git/objects/58/3fc201cb457fb3f1480f3e1e5999b119633835 +0 -0
- data/test/examples/yubiwa.git/objects/87/bc1dd46ab3d3874d4e898d45dd512cc20a7cc8 +1 -0
- data/test/examples/yubiwa.git/objects/89/64ed1b4e21aa90e831763bbce9034bfda81b70 +0 -0
- data/test/examples/yubiwa.git/objects/9f/f6dd0660da5fba2d3374adb2b84fa653bb538b +0 -0
- data/test/examples/yubiwa.git/objects/ac/e97abf2b177815a1972d7db22f229f58c83309 +0 -0
- data/test/examples/yubiwa.git/objects/b1/f443863a4816628807fbf86141ebef055dda34 +0 -0
- data/test/examples/yubiwa.git/refs/heads/master +1 -0
- data/test/helper.rb +66 -0
- data/test/test_app.rb +169 -0
- data/test/test_committer.rb +64 -0
- data/test/test_file.rb +27 -0
- data/test/test_git_access.rb +52 -0
- data/test/test_markup.rb +628 -0
- data/test/test_page.rb +166 -0
- data/test/test_page_revert.rb +45 -0
- data/test/test_wiki.rb +462 -0
- metadata +470 -0
|
@@ -0,0 +1,174 @@
|
|
|
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', 'ftp', 'irc', :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 elements whose contents will be removed in addition
|
|
59
|
+
# to the elements themselve
|
|
60
|
+
REMOVE_CONTENTS = [
|
|
61
|
+
'script',
|
|
62
|
+
'style'
|
|
63
|
+
].freeze
|
|
64
|
+
|
|
65
|
+
# Default transformers to force @id attributes with 'wiki-' prefix
|
|
66
|
+
TRANSFORMERS = [
|
|
67
|
+
lambda do |env|
|
|
68
|
+
node = env[:node]
|
|
69
|
+
return if env[:is_whitelisted] || !node.element?
|
|
70
|
+
prefix = env[:config][:id_prefix]
|
|
71
|
+
found_attrs = %w(id name).select do |key|
|
|
72
|
+
if value = node[key]
|
|
73
|
+
node[key] = value.gsub(/\A(#{prefix})?/, prefix)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
if found_attrs.size > 0
|
|
77
|
+
ADD_ATTRIBUTES.call(env, node)
|
|
78
|
+
{}
|
|
79
|
+
end
|
|
80
|
+
end,
|
|
81
|
+
lambda do |env|
|
|
82
|
+
node = env[:node]
|
|
83
|
+
return unless value = node['href']
|
|
84
|
+
prefix = env[:config][:id_prefix]
|
|
85
|
+
node['href'] = value.gsub(/\A\#(#{prefix})?/, '#'+prefix)
|
|
86
|
+
ADD_ATTRIBUTES.call(env, node)
|
|
87
|
+
{}
|
|
88
|
+
end
|
|
89
|
+
].freeze
|
|
90
|
+
|
|
91
|
+
# Gets an Array of whitelisted HTML elements. Default: ELEMENTS.
|
|
92
|
+
attr_reader :elements
|
|
93
|
+
|
|
94
|
+
# Gets a Hash describing which attributes are allowed in which HTML
|
|
95
|
+
# elements. Default: ATTRIBUTES.
|
|
96
|
+
attr_reader :attributes
|
|
97
|
+
|
|
98
|
+
# Gets a Hash describing which URI protocols are allowed in HTML
|
|
99
|
+
# attributes. Default: PROTOCOLS
|
|
100
|
+
attr_reader :protocols
|
|
101
|
+
|
|
102
|
+
# Gets a Hash describing which URI protocols are allowed in HTML
|
|
103
|
+
# attributes. Default: TRANSFORMERS
|
|
104
|
+
attr_reader :transformers
|
|
105
|
+
|
|
106
|
+
# Gets or sets a String prefix which is added to ID attributes.
|
|
107
|
+
# Default: 'wiki-'
|
|
108
|
+
attr_accessor :id_prefix
|
|
109
|
+
|
|
110
|
+
# Gets a Hash describing HTML attributes that Sanitize should add.
|
|
111
|
+
# Default: {}
|
|
112
|
+
attr_reader :add_attributes
|
|
113
|
+
|
|
114
|
+
# Gets an Array of element names whose contents will be removed in addition
|
|
115
|
+
# to the elements themselves. Default: REMOVE_CONTENTS
|
|
116
|
+
attr_reader :remove_contents
|
|
117
|
+
|
|
118
|
+
# Sets a boolean determining whether Sanitize allows HTML comments in the
|
|
119
|
+
# output. Default: false.
|
|
120
|
+
attr_writer :allow_comments
|
|
121
|
+
|
|
122
|
+
def initialize
|
|
123
|
+
@elements = ELEMENTS
|
|
124
|
+
@attributes = ATTRIBUTES
|
|
125
|
+
@protocols = PROTOCOLS
|
|
126
|
+
@transformers = TRANSFORMERS
|
|
127
|
+
@add_attributes = {}
|
|
128
|
+
@remove_contents = REMOVE_CONTENTS
|
|
129
|
+
@allow_comments = false
|
|
130
|
+
@id_prefix = 'wiki-'
|
|
131
|
+
yield self if block_given?
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# Determines if Sanitize should allow HTML comments.
|
|
135
|
+
#
|
|
136
|
+
# Returns True if comments are allowed, or False.
|
|
137
|
+
def allow_comments?
|
|
138
|
+
!!@allow_comments
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Modifies the current Sanitization instance to sanitize older revisions
|
|
142
|
+
# of pages.
|
|
143
|
+
#
|
|
144
|
+
# Returns a Sanitization instance.
|
|
145
|
+
def history_sanitization
|
|
146
|
+
self.class.new do |sanitize|
|
|
147
|
+
sanitize.add_attributes['a'] = {'rel' => 'nofollow'}
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# Builds a Hash of options suitable for Sanitize.clean.
|
|
152
|
+
#
|
|
153
|
+
# Returns a Hash.
|
|
154
|
+
def to_hash
|
|
155
|
+
{ :elements => elements,
|
|
156
|
+
:attributes => attributes,
|
|
157
|
+
:protocols => protocols,
|
|
158
|
+
:add_attributes => add_attributes,
|
|
159
|
+
:remove_contents => remove_contents,
|
|
160
|
+
:allow_comments => allow_comments?,
|
|
161
|
+
:transformers => transformers,
|
|
162
|
+
:id_prefix => id_prefix
|
|
163
|
+
}
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# Builds a Sanitize instance from the current options.
|
|
167
|
+
#
|
|
168
|
+
# Returns a Sanitize instance.
|
|
169
|
+
def to_sanitize
|
|
170
|
+
Sanitize.new(to_hash)
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
data/lib/gollum/tex.rb
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
require 'shellwords'
|
|
3
|
+
require 'tmpdir'
|
|
4
|
+
require 'posix/spawn'
|
|
5
|
+
|
|
6
|
+
module Gollum
|
|
7
|
+
module Tex
|
|
8
|
+
class Error < StandardError; end
|
|
9
|
+
|
|
10
|
+
extend POSIX::Spawn
|
|
11
|
+
|
|
12
|
+
Template = <<-EOS
|
|
13
|
+
\\documentclass[12pt]{article}
|
|
14
|
+
\\usepackage{color}
|
|
15
|
+
\\usepackage[dvips]{graphicx}
|
|
16
|
+
\\pagestyle{empty}
|
|
17
|
+
\\pagecolor{white}
|
|
18
|
+
\\begin{document}
|
|
19
|
+
{\\color{black}
|
|
20
|
+
\\begin{eqnarray*}
|
|
21
|
+
%s
|
|
22
|
+
\\end{eqnarray*}}
|
|
23
|
+
\\end{document}
|
|
24
|
+
EOS
|
|
25
|
+
|
|
26
|
+
class << self
|
|
27
|
+
attr_accessor :latex_path, :dvips_path, :convert_path
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
self.latex_path = 'latex'
|
|
31
|
+
self.dvips_path = 'dvips'
|
|
32
|
+
self.convert_path = 'convert'
|
|
33
|
+
|
|
34
|
+
def self.check_dependencies!
|
|
35
|
+
return if @dependencies_available
|
|
36
|
+
|
|
37
|
+
if `which latex` == ""
|
|
38
|
+
raise Error, "`latex` command not found"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
if `which dvips` == ""
|
|
42
|
+
raise Error, "`dvips` command not found"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
if `which convert` == ""
|
|
46
|
+
raise Error, "`convert` command not found"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
if `which gs` == ""
|
|
50
|
+
raise Error, "`gs` command not found"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
@dependencies_available = true
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def self.render_formula(formula)
|
|
57
|
+
check_dependencies!
|
|
58
|
+
|
|
59
|
+
Dir.mktmpdir('tex') do |path|
|
|
60
|
+
tex_path = ::File.join(path, 'formula.tex')
|
|
61
|
+
dvi_path = ::File.join(path, 'formula.dvi')
|
|
62
|
+
eps_path = ::File.join(path, 'formula.eps')
|
|
63
|
+
png_path = ::File.join(path, 'formula.png')
|
|
64
|
+
|
|
65
|
+
::File.open(tex_path, 'w') { |f| f.write(Template % formula) }
|
|
66
|
+
|
|
67
|
+
result = sh latex_path, '-interaction=batchmode', 'formula.tex', :chdir => path
|
|
68
|
+
raise Error, "`latex` command failed: #{result}" unless ::File.exist?(dvi_path)
|
|
69
|
+
|
|
70
|
+
result = sh dvips_path, '-o', eps_path, '-E', dvi_path
|
|
71
|
+
raise Error, "`dvips` command failed: #{result}" unless ::File.exist?(eps_path)
|
|
72
|
+
result = sh convert_path, '+adjoin',
|
|
73
|
+
'-antialias',
|
|
74
|
+
'-transparent', 'white',
|
|
75
|
+
'-density', '150x150',
|
|
76
|
+
eps_path, png_path
|
|
77
|
+
raise Error, "`convert` command failed: #{result}" unless ::File.exist?(png_path)
|
|
78
|
+
|
|
79
|
+
::File.read(png_path)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
private
|
|
84
|
+
def self.sh(*args)
|
|
85
|
+
pid = spawn *args
|
|
86
|
+
Process::waitpid(pid)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require 'net/http'
|
|
2
|
+
require 'uri'
|
|
3
|
+
require 'open-uri'
|
|
4
|
+
|
|
5
|
+
class Gollum::WebSequenceDiagram
|
|
6
|
+
WSD_URL = "http://www.websequencediagrams.com/index.php"
|
|
7
|
+
|
|
8
|
+
# Initialize a new WebSequenceDiagram object.
|
|
9
|
+
#
|
|
10
|
+
# code - The String containing the sequence diagram markup.
|
|
11
|
+
# style - The String containing the rendering style.
|
|
12
|
+
#
|
|
13
|
+
# Returns a new Gollum::WebSequenceDiagram object
|
|
14
|
+
def initialize(code, style)
|
|
15
|
+
@code = code
|
|
16
|
+
@style = style
|
|
17
|
+
@tag = ""
|
|
18
|
+
|
|
19
|
+
render
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Render the sequence diagram on the remote server and store the url to
|
|
23
|
+
# the rendered image.
|
|
24
|
+
#
|
|
25
|
+
# Returns nil.
|
|
26
|
+
def render
|
|
27
|
+
response = Net::HTTP.post_form(URI.parse(WSD_URL), 'style' => @style, 'message' => @code)
|
|
28
|
+
if response.body =~ /img: "(.+)"/
|
|
29
|
+
url = "http://www.websequencediagrams.com/#{$1}"
|
|
30
|
+
@tag = "<img src=\"#{url}\" />"
|
|
31
|
+
else
|
|
32
|
+
puts response.body
|
|
33
|
+
@tag ="Sorry, unable to render sequence diagram at this time."
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Gets the HTML IMG tag for the sequence diagram.
|
|
38
|
+
#
|
|
39
|
+
# Returns a String containing the IMG tag.
|
|
40
|
+
def to_tag
|
|
41
|
+
@tag
|
|
42
|
+
end
|
|
43
|
+
end
|
data/lib/gollum/wiki.rb
ADDED
|
@@ -0,0 +1,636 @@
|
|
|
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
|
+
# Array of chars to substitute whitespace for when trying to locate file in git repo.
|
|
25
|
+
attr_accessor :default_ws_subs
|
|
26
|
+
|
|
27
|
+
# Sets sanitization options. Set to false to deactivate
|
|
28
|
+
# sanitization altogether.
|
|
29
|
+
attr_writer :sanitization
|
|
30
|
+
|
|
31
|
+
# Sets sanitization options. Set to false to deactivate
|
|
32
|
+
# sanitization altogether.
|
|
33
|
+
attr_writer :history_sanitization
|
|
34
|
+
|
|
35
|
+
# Gets the page class used by all instances of this Wiki.
|
|
36
|
+
# Default: Gollum::Page.
|
|
37
|
+
def page_class
|
|
38
|
+
@page_class ||
|
|
39
|
+
if superclass.respond_to?(:page_class)
|
|
40
|
+
superclass.page_class
|
|
41
|
+
else
|
|
42
|
+
::Gollum::Page
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Gets the file class used by all instances of this Wiki.
|
|
47
|
+
# Default: Gollum::File.
|
|
48
|
+
def file_class
|
|
49
|
+
@file_class ||
|
|
50
|
+
if superclass.respond_to?(:file_class)
|
|
51
|
+
superclass.file_class
|
|
52
|
+
else
|
|
53
|
+
::Gollum::File
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Gets the markup class used by all instances of this Wiki.
|
|
58
|
+
# Default: Gollum::Markup
|
|
59
|
+
def markup_classes
|
|
60
|
+
@markup_classes ||=
|
|
61
|
+
if superclass.respond_to?(:markup_classes)
|
|
62
|
+
superclass.markup_classes
|
|
63
|
+
else
|
|
64
|
+
Hash.new(::Gollum::Markup)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Gets the default markup class used by all instances of this Wiki.
|
|
69
|
+
# Kept for backwards compatibility until Gollum v2.x
|
|
70
|
+
def markup_class(language=:default)
|
|
71
|
+
markup_classes[language]
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Sets the default markup class used by all instances of this Wiki.
|
|
75
|
+
# Kept for backwards compatibility until Gollum v2.x
|
|
76
|
+
def markup_class=(default)
|
|
77
|
+
@markup_classes = Hash.new(default).update(markup_classes)
|
|
78
|
+
default
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
alias_method :default_markup_class, :markup_class
|
|
82
|
+
alias_method :default_markup_class=, :markup_class=
|
|
83
|
+
|
|
84
|
+
# Gets the default sanitization options for current pages used by
|
|
85
|
+
# instances of this Wiki.
|
|
86
|
+
def sanitization
|
|
87
|
+
if @sanitization.nil?
|
|
88
|
+
@sanitization = Sanitization.new
|
|
89
|
+
end
|
|
90
|
+
@sanitization
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Gets the default sanitization options for older page revisions used by
|
|
94
|
+
# instances of this Wiki.
|
|
95
|
+
def history_sanitization
|
|
96
|
+
if @history_sanitization.nil?
|
|
97
|
+
@history_sanitization = sanitization ?
|
|
98
|
+
sanitization.history_sanitization :
|
|
99
|
+
false
|
|
100
|
+
end
|
|
101
|
+
@history_sanitization
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
self.default_ref = 'master'
|
|
106
|
+
self.default_committer_name = 'Anonymous'
|
|
107
|
+
self.default_committer_email = 'anon@anon.com'
|
|
108
|
+
|
|
109
|
+
self.default_ws_subs = ['_','-']
|
|
110
|
+
|
|
111
|
+
# The String base path to prefix to internal links. For example, when set
|
|
112
|
+
# to "/wiki", the page "Hobbit" will be linked as "/wiki/Hobbit". Defaults
|
|
113
|
+
# to "/".
|
|
114
|
+
attr_reader :base_path
|
|
115
|
+
|
|
116
|
+
# Gets the sanitization options for current pages used by this Wiki.
|
|
117
|
+
attr_reader :sanitization
|
|
118
|
+
|
|
119
|
+
# Gets the sanitization options for older page revisions used by this Wiki.
|
|
120
|
+
attr_reader :history_sanitization
|
|
121
|
+
|
|
122
|
+
# Gets the String ref in which all page files reside.
|
|
123
|
+
attr_reader :ref
|
|
124
|
+
|
|
125
|
+
# Gets the String directory in which all page files reside.
|
|
126
|
+
attr_reader :page_file_dir
|
|
127
|
+
|
|
128
|
+
# Gets the Array of chars to sub for ws in filenames.
|
|
129
|
+
attr_reader :ws_subs
|
|
130
|
+
|
|
131
|
+
# Public: Initialize a new Gollum Repo.
|
|
132
|
+
#
|
|
133
|
+
# path - The String path to the Git repository that holds the Gollum
|
|
134
|
+
# site.
|
|
135
|
+
# options - Optional Hash:
|
|
136
|
+
# :base_path - String base path for all Wiki links.
|
|
137
|
+
# Default: "/"
|
|
138
|
+
# :page_class - The page Class. Default: Gollum::Page
|
|
139
|
+
# :file_class - The file Class. Default: Gollum::File
|
|
140
|
+
# :markup_classes - A hash containing the markup Classes for each
|
|
141
|
+
# document type. Default: { Gollum::Markup }
|
|
142
|
+
# :sanitization - An instance of Sanitization.
|
|
143
|
+
# :page_file_dir - String the directory in which all page files reside
|
|
144
|
+
# :ref - String the repository ref to retrieve pages from
|
|
145
|
+
# :ws_subs - Array of chars to sub for ws in filenames.
|
|
146
|
+
#
|
|
147
|
+
# Returns a fresh Gollum::Repo.
|
|
148
|
+
def initialize(path, options = {})
|
|
149
|
+
if path.is_a?(GitAccess)
|
|
150
|
+
options[:access] = path
|
|
151
|
+
path = path.path
|
|
152
|
+
end
|
|
153
|
+
@path = path
|
|
154
|
+
@page_file_dir = options[:page_file_dir]
|
|
155
|
+
@access = options[:access] || GitAccess.new(path, @page_file_dir)
|
|
156
|
+
@base_path = options[:base_path] || "/"
|
|
157
|
+
@page_class = options[:page_class] || self.class.page_class
|
|
158
|
+
@file_class = options[:file_class] || self.class.file_class
|
|
159
|
+
@markup_classes = options[:markup_classes] || self.class.markup_classes
|
|
160
|
+
@repo = @access.repo
|
|
161
|
+
@ref = options[:ref] || self.class.default_ref
|
|
162
|
+
@sanitization = options[:sanitization] || self.class.sanitization
|
|
163
|
+
@ws_subs = options[:ws_subs] ||
|
|
164
|
+
self.class.default_ws_subs
|
|
165
|
+
@history_sanitization = options[:history_sanitization] ||
|
|
166
|
+
self.class.history_sanitization
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# Public: check whether the wiki's git repo exists on the filesystem.
|
|
170
|
+
#
|
|
171
|
+
# Returns true if the repo exists, and false if it does not.
|
|
172
|
+
def exist?
|
|
173
|
+
@access.exist?
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# Public: Get the formatted page for a given page name.
|
|
177
|
+
#
|
|
178
|
+
# name - The human or canonical String page name of the wiki page.
|
|
179
|
+
# version - The String version ID to find (default: @ref).
|
|
180
|
+
#
|
|
181
|
+
# Returns a Gollum::Page or nil if no matching page was found.
|
|
182
|
+
def page(name, version = @ref)
|
|
183
|
+
@page_class.new(self).find(name, version)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# Public: Get the static file for a given name.
|
|
187
|
+
#
|
|
188
|
+
# name - The full String pathname to the file.
|
|
189
|
+
# version - The String version ID to find (default: @ref).
|
|
190
|
+
#
|
|
191
|
+
# Returns a Gollum::File or nil if no matching file was found.
|
|
192
|
+
def file(name, version = @ref)
|
|
193
|
+
@file_class.new(self).find(name, version)
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# Public: Create an in-memory Page with the given data and format. This
|
|
197
|
+
# is useful for previewing what content will look like before committing
|
|
198
|
+
# it to the repository.
|
|
199
|
+
#
|
|
200
|
+
# name - The String name of the page.
|
|
201
|
+
# format - The Symbol format of the page.
|
|
202
|
+
# data - The new String contents of the page.
|
|
203
|
+
#
|
|
204
|
+
# Returns the in-memory Gollum::Page.
|
|
205
|
+
def preview_page(name, data, format)
|
|
206
|
+
page = @page_class.new(self)
|
|
207
|
+
ext = @page_class.format_to_ext(format.to_sym)
|
|
208
|
+
name = @page_class.cname(name) + '.' + ext
|
|
209
|
+
blob = OpenStruct.new(:name => name, :data => data)
|
|
210
|
+
page.populate(blob)
|
|
211
|
+
page.version = @access.commit('master')
|
|
212
|
+
page
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
# Public: Write a new version of a page to the Gollum repo root.
|
|
216
|
+
#
|
|
217
|
+
# name - The String name of the page.
|
|
218
|
+
# format - The Symbol format of the page.
|
|
219
|
+
# data - The new String contents of the page.
|
|
220
|
+
# commit - The commit Hash details:
|
|
221
|
+
# :message - The String commit message.
|
|
222
|
+
# :name - The String author full name.
|
|
223
|
+
# :email - The String email address.
|
|
224
|
+
# :parent - Optional Grit::Commit parent to this update.
|
|
225
|
+
# :tree - Optional String SHA of the tree to create the
|
|
226
|
+
# index from.
|
|
227
|
+
# :committer - Optional Gollum::Committer instance. If provided,
|
|
228
|
+
# assume that this operation is part of batch of
|
|
229
|
+
# updates and the commit happens later.
|
|
230
|
+
#
|
|
231
|
+
# Returns the String SHA1 of the newly written version, or the
|
|
232
|
+
# Gollum::Committer instance if this is part of a batch update.
|
|
233
|
+
def write_page(name, format, data, commit = {})
|
|
234
|
+
multi_commit = false
|
|
235
|
+
|
|
236
|
+
committer = if obj = commit[:committer]
|
|
237
|
+
multi_commit = true
|
|
238
|
+
obj
|
|
239
|
+
else
|
|
240
|
+
Committer.new(self, commit)
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
filename = Gollum::Page.cname(name)
|
|
244
|
+
|
|
245
|
+
committer.add_to_index('', filename, format, data)
|
|
246
|
+
|
|
247
|
+
committer.after_commit do |index, sha|
|
|
248
|
+
@access.refresh
|
|
249
|
+
index.update_working_dir('', filename, format)
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
multi_commit ? committer : committer.commit
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
# Public: Update an existing page with new content. The location of the
|
|
256
|
+
# page inside the repository will not change. If the given format is
|
|
257
|
+
# different than the current format of the page, the filename will be
|
|
258
|
+
# changed to reflect the new format.
|
|
259
|
+
#
|
|
260
|
+
# page - The Gollum::Page to update.
|
|
261
|
+
# name - The String extension-less name of the page.
|
|
262
|
+
# format - The Symbol format of the page.
|
|
263
|
+
# data - The new String contents of the page.
|
|
264
|
+
# commit - The commit Hash details:
|
|
265
|
+
# :message - The String commit message.
|
|
266
|
+
# :name - The String author full name.
|
|
267
|
+
# :email - The String email address.
|
|
268
|
+
# :parent - Optional Grit::Commit parent to this update.
|
|
269
|
+
# :tree - Optional String SHA of the tree to create the
|
|
270
|
+
# index from.
|
|
271
|
+
# :committer - Optional Gollum::Committer instance. If provided,
|
|
272
|
+
# assume that this operation is part of batch of
|
|
273
|
+
# updates and the commit happens later.
|
|
274
|
+
#
|
|
275
|
+
# Returns the String SHA1 of the newly written version, or the
|
|
276
|
+
# Gollum::Committer instance if this is part of a batch update.
|
|
277
|
+
def update_page(page, name, format, data, commit = {})
|
|
278
|
+
name ||= page.name
|
|
279
|
+
format ||= page.format
|
|
280
|
+
dir = ::File.dirname(page.path)
|
|
281
|
+
dir = '' if dir == '.'
|
|
282
|
+
filename = (rename = page.name != name) ?
|
|
283
|
+
Gollum::Page.cname(name) : page.filename_stripped
|
|
284
|
+
|
|
285
|
+
multi_commit = false
|
|
286
|
+
|
|
287
|
+
committer = if obj = commit[:committer]
|
|
288
|
+
multi_commit = true
|
|
289
|
+
obj
|
|
290
|
+
else
|
|
291
|
+
Committer.new(self, commit)
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
if !rename && page.format == format
|
|
295
|
+
committer.add(page.path, normalize(data))
|
|
296
|
+
else
|
|
297
|
+
committer.delete(page.path)
|
|
298
|
+
committer.add_to_index(dir, filename, format, data, :allow_same_ext)
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
committer.after_commit do |index, sha|
|
|
302
|
+
@access.refresh
|
|
303
|
+
index.update_working_dir(dir, page.filename_stripped, page.format)
|
|
304
|
+
index.update_working_dir(dir, filename, format)
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
multi_commit ? committer : committer.commit
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
# Public: Delete a page.
|
|
311
|
+
#
|
|
312
|
+
# page - The Gollum::Page to delete.
|
|
313
|
+
# commit - The commit Hash details:
|
|
314
|
+
# :message - The String commit message.
|
|
315
|
+
# :name - The String author full name.
|
|
316
|
+
# :email - The String email address.
|
|
317
|
+
# :parent - Optional Grit::Commit parent to this update.
|
|
318
|
+
# :tree - Optional String SHA of the tree to create the
|
|
319
|
+
# index from.
|
|
320
|
+
# :committer - Optional Gollum::Committer instance. If provided,
|
|
321
|
+
# assume that this operation is part of batch of
|
|
322
|
+
# updates and the commit happens later.
|
|
323
|
+
#
|
|
324
|
+
# Returns the String SHA1 of the newly written version, or the
|
|
325
|
+
# Gollum::Committer instance if this is part of a batch update.
|
|
326
|
+
def delete_page(page, commit)
|
|
327
|
+
multi_commit = false
|
|
328
|
+
|
|
329
|
+
committer = if obj = commit[:committer]
|
|
330
|
+
multi_commit = true
|
|
331
|
+
obj
|
|
332
|
+
else
|
|
333
|
+
Committer.new(self, commit)
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
committer.delete(page.path)
|
|
337
|
+
|
|
338
|
+
committer.after_commit do |index, sha|
|
|
339
|
+
dir = ::File.dirname(page.path)
|
|
340
|
+
dir = '' if dir == '.'
|
|
341
|
+
|
|
342
|
+
@access.refresh
|
|
343
|
+
index.update_working_dir(dir, page.filename_stripped, page.format)
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
multi_commit ? committer : committer.commit
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
# Public: Applies a reverse diff for a given page. If only 1 SHA is given,
|
|
350
|
+
# the reverse diff will be taken from its parent (^SHA...SHA). If two SHAs
|
|
351
|
+
# are given, the reverse diff is taken from SHA1...SHA2.
|
|
352
|
+
#
|
|
353
|
+
# page - The Gollum::Page to delete.
|
|
354
|
+
# sha1 - String SHA1 of the earlier parent if two SHAs are given,
|
|
355
|
+
# or the child.
|
|
356
|
+
# sha2 - Optional String SHA1 of the child.
|
|
357
|
+
# commit - The commit Hash details:
|
|
358
|
+
# :message - The String commit message.
|
|
359
|
+
# :name - The String author full name.
|
|
360
|
+
# :email - The String email address.
|
|
361
|
+
# :parent - Optional Grit::Commit parent to this update.
|
|
362
|
+
#
|
|
363
|
+
# Returns a String SHA1 of the new commit, or nil if the reverse diff does
|
|
364
|
+
# not apply.
|
|
365
|
+
def revert_page(page, sha1, sha2 = nil, commit = {})
|
|
366
|
+
if sha2.is_a?(Hash)
|
|
367
|
+
commit = sha2
|
|
368
|
+
sha2 = nil
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
patch = full_reverse_diff_for(page, sha1, sha2)
|
|
372
|
+
committer = Committer.new(self, commit)
|
|
373
|
+
parent = committer.parents[0]
|
|
374
|
+
committer.options[:tree] = @repo.git.apply_patch(parent.sha, patch)
|
|
375
|
+
return false unless committer.options[:tree]
|
|
376
|
+
committer.after_commit do |index, sha|
|
|
377
|
+
@access.refresh
|
|
378
|
+
|
|
379
|
+
files = []
|
|
380
|
+
if page
|
|
381
|
+
files << [page.path, page.filename_stripped, page.format]
|
|
382
|
+
else
|
|
383
|
+
# Grit::Diff can't parse reverse diffs.... yet
|
|
384
|
+
patch.each_line do |line|
|
|
385
|
+
if line =~ %r{^diff --git b/.+? a/(.+)$}
|
|
386
|
+
path = $1
|
|
387
|
+
ext = ::File.extname(path)
|
|
388
|
+
name = ::File.basename(path, ext)
|
|
389
|
+
if format = ::Gollum::Page.format_for(ext)
|
|
390
|
+
files << [path, name, format]
|
|
391
|
+
end
|
|
392
|
+
end
|
|
393
|
+
end
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
files.each do |(path, name, format)|
|
|
397
|
+
dir = ::File.dirname(path)
|
|
398
|
+
dir = '' if dir == '.'
|
|
399
|
+
index.update_working_dir(dir, name, format)
|
|
400
|
+
end
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
committer.commit
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
# Public: Applies a reverse diff to the repo. If only 1 SHA is given,
|
|
407
|
+
# the reverse diff will be taken from its parent (^SHA...SHA). If two SHAs
|
|
408
|
+
# are given, the reverse diff is taken from SHA1...SHA2.
|
|
409
|
+
#
|
|
410
|
+
# sha1 - String SHA1 of the earlier parent if two SHAs are given,
|
|
411
|
+
# or the child.
|
|
412
|
+
# sha2 - Optional String SHA1 of the child.
|
|
413
|
+
# commit - The commit Hash details:
|
|
414
|
+
# :message - The String commit message.
|
|
415
|
+
# :name - The String author full name.
|
|
416
|
+
# :email - The String email address.
|
|
417
|
+
#
|
|
418
|
+
# Returns a String SHA1 of the new commit, or nil if the reverse diff does
|
|
419
|
+
# not apply.
|
|
420
|
+
def revert_commit(sha1, sha2 = nil, commit = {})
|
|
421
|
+
revert_page(nil, sha1, sha2, commit)
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
# Public: Lists all pages for this wiki.
|
|
425
|
+
#
|
|
426
|
+
# treeish - The String commit ID or ref to find (default: @ref)
|
|
427
|
+
#
|
|
428
|
+
# Returns an Array of Gollum::Page instances.
|
|
429
|
+
def pages(treeish = nil)
|
|
430
|
+
tree_list(treeish || @ref)
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
# Public: Returns the number of pages accessible from a commit
|
|
434
|
+
#
|
|
435
|
+
# ref - A String ref that is either a commit SHA or references one.
|
|
436
|
+
#
|
|
437
|
+
# Returns a Fixnum
|
|
438
|
+
def size(ref = nil)
|
|
439
|
+
tree_map_for(ref || @ref).inject(0) do |num, entry|
|
|
440
|
+
num + (@page_class.valid_page_name?(entry.name) ? 1 : 0)
|
|
441
|
+
end
|
|
442
|
+
rescue Grit::GitRuby::Repository::NoSuchShaFound
|
|
443
|
+
0
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
# Public: Search all pages for this wiki.
|
|
447
|
+
#
|
|
448
|
+
# query - The string to search for
|
|
449
|
+
#
|
|
450
|
+
# Returns an Array with Objects of page name and count of matches
|
|
451
|
+
def search(query)
|
|
452
|
+
args = [{}, '-i', '-c', query, @ref, '--']
|
|
453
|
+
args << '--' << @page_file_dir if @page_file_dir
|
|
454
|
+
|
|
455
|
+
@repo.git.grep(*args).split("\n").map! do |line|
|
|
456
|
+
result = line.split(':')
|
|
457
|
+
file_name = Gollum::Page.canonicalize_filename(::File.basename(result[1]))
|
|
458
|
+
|
|
459
|
+
{
|
|
460
|
+
:count => result[2].to_i,
|
|
461
|
+
:name => file_name
|
|
462
|
+
}
|
|
463
|
+
end
|
|
464
|
+
end
|
|
465
|
+
|
|
466
|
+
# Public: All of the versions that have touched the Page.
|
|
467
|
+
#
|
|
468
|
+
# options - The options Hash:
|
|
469
|
+
# :page - The Integer page number (default: 1).
|
|
470
|
+
# :per_page - The Integer max count of items to return.
|
|
471
|
+
#
|
|
472
|
+
# Returns an Array of Grit::Commit.
|
|
473
|
+
def log(options = {})
|
|
474
|
+
@repo.log(@ref, nil, log_pagination_options(options))
|
|
475
|
+
end
|
|
476
|
+
|
|
477
|
+
# Public: Refreshes just the cached Git reference data. This should
|
|
478
|
+
# be called after every Gollum update.
|
|
479
|
+
#
|
|
480
|
+
# Returns nothing.
|
|
481
|
+
def clear_cache
|
|
482
|
+
@access.refresh
|
|
483
|
+
end
|
|
484
|
+
|
|
485
|
+
# Public: Creates a Sanitize instance using the Wiki's sanitization
|
|
486
|
+
# options.
|
|
487
|
+
#
|
|
488
|
+
# Returns a Sanitize instance.
|
|
489
|
+
def sanitizer
|
|
490
|
+
if options = sanitization
|
|
491
|
+
@sanitizer ||= options.to_sanitize
|
|
492
|
+
end
|
|
493
|
+
end
|
|
494
|
+
|
|
495
|
+
# Public: Creates a Sanitize instance using the Wiki's history sanitization
|
|
496
|
+
# options.
|
|
497
|
+
#
|
|
498
|
+
# Returns a Sanitize instance.
|
|
499
|
+
def history_sanitizer
|
|
500
|
+
if options = history_sanitization
|
|
501
|
+
@history_sanitizer ||= options.to_sanitize
|
|
502
|
+
end
|
|
503
|
+
end
|
|
504
|
+
|
|
505
|
+
#########################################################################
|
|
506
|
+
#
|
|
507
|
+
# Internal Methods
|
|
508
|
+
#
|
|
509
|
+
#########################################################################
|
|
510
|
+
|
|
511
|
+
# The Grit::Repo associated with the wiki.
|
|
512
|
+
#
|
|
513
|
+
# Returns the Grit::Repo.
|
|
514
|
+
attr_reader :repo
|
|
515
|
+
|
|
516
|
+
# The String path to the Git repository that holds the Gollum site.
|
|
517
|
+
#
|
|
518
|
+
# Returns the String path.
|
|
519
|
+
attr_reader :path
|
|
520
|
+
|
|
521
|
+
# Gets the page class used by all instances of this Wiki.
|
|
522
|
+
attr_reader :page_class
|
|
523
|
+
|
|
524
|
+
# Gets the file class used by all instances of this Wiki.
|
|
525
|
+
attr_reader :file_class
|
|
526
|
+
|
|
527
|
+
# Gets the markup class used by all instances of this Wiki.
|
|
528
|
+
attr_reader :markup_classes
|
|
529
|
+
|
|
530
|
+
# Normalize the data.
|
|
531
|
+
#
|
|
532
|
+
# data - The String data to be normalized.
|
|
533
|
+
#
|
|
534
|
+
# Returns the normalized data String.
|
|
535
|
+
def normalize(data)
|
|
536
|
+
data.gsub(/\r/, '')
|
|
537
|
+
end
|
|
538
|
+
|
|
539
|
+
# Assemble a Page's filename from its name and format.
|
|
540
|
+
#
|
|
541
|
+
# name - The String name of the page (should be pre-canonicalized).
|
|
542
|
+
# format - The Symbol format of the page.
|
|
543
|
+
#
|
|
544
|
+
# Returns the String filename.
|
|
545
|
+
def page_file_name(name, format)
|
|
546
|
+
name + '.' + @page_class.format_to_ext(format)
|
|
547
|
+
end
|
|
548
|
+
|
|
549
|
+
# Fill an array with a list of pages.
|
|
550
|
+
#
|
|
551
|
+
# ref - A String ref that is either a commit SHA or references one.
|
|
552
|
+
#
|
|
553
|
+
# Returns a flat Array of Gollum::Page instances.
|
|
554
|
+
def tree_list(ref)
|
|
555
|
+
if sha = @access.ref_to_sha(ref)
|
|
556
|
+
commit = @access.commit(sha)
|
|
557
|
+
tree_map_for(sha).inject([]) do |list, entry|
|
|
558
|
+
next list unless @page_class.valid_page_name?(entry.name)
|
|
559
|
+
list << entry.page(self, commit)
|
|
560
|
+
end
|
|
561
|
+
else
|
|
562
|
+
[]
|
|
563
|
+
end
|
|
564
|
+
end
|
|
565
|
+
|
|
566
|
+
# Creates a reverse diff for the given SHAs on the given Gollum::Page.
|
|
567
|
+
#
|
|
568
|
+
# page - The Gollum::Page to scope the patch to, or a String Path.
|
|
569
|
+
# sha1 - String SHA1 of the earlier parent if two SHAs are given,
|
|
570
|
+
# or the child.
|
|
571
|
+
# sha2 - Optional String SHA1 of the child.
|
|
572
|
+
#
|
|
573
|
+
# Returns a String of the reverse Diff to apply.
|
|
574
|
+
def full_reverse_diff_for(page, sha1, sha2 = nil)
|
|
575
|
+
sha1, sha2 = "#{sha1}^", sha1 if sha2.nil?
|
|
576
|
+
args = [{:R => true}, sha1, sha2]
|
|
577
|
+
if page
|
|
578
|
+
args << '--' << (page.respond_to?(:path) ? page.path : page.to_s)
|
|
579
|
+
end
|
|
580
|
+
repo.git.native(:diff, *args)
|
|
581
|
+
end
|
|
582
|
+
|
|
583
|
+
# Creates a reverse diff for the given SHAs.
|
|
584
|
+
#
|
|
585
|
+
# sha1 - String SHA1 of the earlier parent if two SHAs are given,
|
|
586
|
+
# or the child.
|
|
587
|
+
# sha2 - Optional String SHA1 of the child.
|
|
588
|
+
#
|
|
589
|
+
# Returns a String of the reverse Diff to apply.
|
|
590
|
+
def full_reverse_diff(sha1, sha2 = nil)
|
|
591
|
+
full_reverse_diff_for(nil, sha1, sha2)
|
|
592
|
+
end
|
|
593
|
+
|
|
594
|
+
# Gets the default name for commits.
|
|
595
|
+
#
|
|
596
|
+
# Returns the String name.
|
|
597
|
+
def default_committer_name
|
|
598
|
+
@default_committer_name ||= \
|
|
599
|
+
@repo.config['user.name'] || self.class.default_committer_name
|
|
600
|
+
end
|
|
601
|
+
|
|
602
|
+
# Gets the default email for commits.
|
|
603
|
+
#
|
|
604
|
+
# Returns the String email address.
|
|
605
|
+
def default_committer_email
|
|
606
|
+
@default_committer_email ||= \
|
|
607
|
+
@repo.config['user.email'] || self.class.default_committer_email
|
|
608
|
+
end
|
|
609
|
+
|
|
610
|
+
# Gets the commit object for the given ref or sha.
|
|
611
|
+
#
|
|
612
|
+
# ref - A string ref or SHA pointing to a valid commit.
|
|
613
|
+
#
|
|
614
|
+
# Returns a Grit::Commit instance.
|
|
615
|
+
def commit_for(ref)
|
|
616
|
+
@access.commit(ref)
|
|
617
|
+
rescue Grit::GitRuby::Repository::NoSuchShaFound
|
|
618
|
+
end
|
|
619
|
+
|
|
620
|
+
# Finds a full listing of files and their blob SHA for a given ref. Each
|
|
621
|
+
# listing is cached based on its actual commit SHA.
|
|
622
|
+
#
|
|
623
|
+
# ref - A String ref that is either a commit SHA or references one.
|
|
624
|
+
#
|
|
625
|
+
# Returns an Array of BlobEntry instances.
|
|
626
|
+
def tree_map_for(ref)
|
|
627
|
+
@access.tree(ref)
|
|
628
|
+
rescue Grit::GitRuby::Repository::NoSuchShaFound
|
|
629
|
+
[]
|
|
630
|
+
end
|
|
631
|
+
|
|
632
|
+
def inspect
|
|
633
|
+
%(#<#{self.class.name}:#{object_id} #{@repo.path}>)
|
|
634
|
+
end
|
|
635
|
+
end
|
|
636
|
+
end
|