gollum-lib 4.0.3-java

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.
Files changed (41) hide show
  1. checksums.yaml +15 -0
  2. data/Gemfile +3 -0
  3. data/HISTORY.md +11 -0
  4. data/LICENSE +21 -0
  5. data/README.md +286 -0
  6. data/Rakefile +187 -0
  7. data/docs/sanitization.md +33 -0
  8. data/gemspec.rb +100 -0
  9. data/gollum-lib.gemspec +4 -0
  10. data/gollum-lib_java.gemspec +4 -0
  11. data/lib/gollum-lib.rb +64 -0
  12. data/lib/gollum-lib/blob_entry.rb +95 -0
  13. data/lib/gollum-lib/committer.rb +243 -0
  14. data/lib/gollum-lib/file.rb +158 -0
  15. data/lib/gollum-lib/file_view.rb +155 -0
  16. data/lib/gollum-lib/filter.rb +78 -0
  17. data/lib/gollum-lib/filter/code.rb +145 -0
  18. data/lib/gollum-lib/filter/macro.rb +57 -0
  19. data/lib/gollum-lib/filter/metadata.rb +29 -0
  20. data/lib/gollum-lib/filter/plain_text.rb +16 -0
  21. data/lib/gollum-lib/filter/remote_code.rb +63 -0
  22. data/lib/gollum-lib/filter/render.rb +20 -0
  23. data/lib/gollum-lib/filter/sanitize.rb +18 -0
  24. data/lib/gollum-lib/filter/tags.rb +320 -0
  25. data/lib/gollum-lib/filter/toc.rb +109 -0
  26. data/lib/gollum-lib/filter/wsd.rb +54 -0
  27. data/lib/gollum-lib/git_access.rb +247 -0
  28. data/lib/gollum-lib/gitcode.rb +48 -0
  29. data/lib/gollum-lib/helpers.rb +13 -0
  30. data/lib/gollum-lib/hook.rb +35 -0
  31. data/lib/gollum-lib/macro.rb +43 -0
  32. data/lib/gollum-lib/macro/all_pages.rb +11 -0
  33. data/lib/gollum-lib/markup.rb +197 -0
  34. data/lib/gollum-lib/markups.rb +20 -0
  35. data/lib/gollum-lib/page.rb +491 -0
  36. data/lib/gollum-lib/pagination.rb +62 -0
  37. data/lib/gollum-lib/sanitization.rb +176 -0
  38. data/lib/gollum-lib/version.rb +5 -0
  39. data/lib/gollum-lib/wiki.rb +925 -0
  40. data/licenses/licenses.txt +6 -0
  41. metadata +410 -0
@@ -0,0 +1,109 @@
1
+ # Inserts header anchors and creates TOC
2
+ class Gollum::Filter::TOC < Gollum::Filter
3
+ def extract(data)
4
+ data
5
+ end
6
+
7
+ def process(data)
8
+
9
+ @doc = Nokogiri::HTML::DocumentFragment.parse(data)
10
+ @toc = nil
11
+ @anchor_names = {}
12
+ @current_ancestors = []
13
+
14
+ if @markup.sub_page && @markup.parent_page
15
+ @toc = @markup.parent_page.toc_data
16
+ else
17
+ @doc.css('h1,h2,h3,h4,h5,h6').each_with_index do |header, i|
18
+ next if header.content.empty?
19
+ # omit the first H1 (the page title) from the TOC if so configured
20
+ next if (i == 0 && header.name =~ /[Hh]1/) && @markup.wiki && @markup.wiki.h1_title
21
+
22
+ anchor_name = generate_anchor_name(header)
23
+
24
+ add_anchor_to_header header, anchor_name
25
+ add_entry_to_toc header, anchor_name
26
+ end
27
+
28
+ @toc = @toc.to_xml(@markup.to_xml_opts) if @toc != nil
29
+ data = @doc.to_xml(@markup.to_xml_opts)
30
+
31
+ end
32
+
33
+ @markup.toc = @toc
34
+ data.gsub("[[_TOC_]]") do
35
+ @toc.nil? ? '' : @toc
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ # Generates the anchor name from the given header element
42
+ # removing all non alphanumeric characters, replacing them
43
+ # with single dashes.
44
+ #
45
+ # Generates heading ancestry prefixing the headings
46
+ # ancestor names to the generated name.
47
+ #
48
+ # Prefixes duplicate anchors with an index
49
+ def generate_anchor_name(header)
50
+ name = header.content
51
+ level = header.name.gsub(/[hH]/, '').to_i
52
+
53
+ # normalize the header name
54
+ name.gsub!(/[^\d\w\u00C0-\u1FFF\u2C00-\uD7FF]/, "-")
55
+ name.gsub!(/-+/, "-")
56
+ name.gsub!(/^-/, "")
57
+ name.gsub!(/-$/, "")
58
+ name.downcase!
59
+
60
+ @current_ancestors[level - 1] = name
61
+ @current_ancestors = @current_ancestors.take(level)
62
+ anchor_name = @current_ancestors.compact.join("_")
63
+
64
+ # Ensure duplicate anchors have a unique prefix or the toc will break
65
+ index = increment_anchor_index(anchor_name)
66
+ anchor_name = "#{index}-#{anchor_name}" unless index.zero? # if the index is zero this name is unique
67
+
68
+ anchor_name
69
+ end
70
+
71
+ # Creates an anchor element with the given name and adds it before
72
+ # the given header element.
73
+ def add_anchor_to_header(header, name)
74
+ anchor_element = %Q(<a class="anchor" id="#{name}" href="##{name}"><i class="fa fa-link"></i></a>)
75
+ header.children.before anchor_element # Add anchor element before the header
76
+ end
77
+
78
+ # Adds an entry to the TOC for the given header. The generated entry
79
+ # is a link to the given anchor name
80
+ def add_entry_to_toc(header, name)
81
+ @toc ||= Nokogiri::XML::DocumentFragment.parse('<div class="toc"><div class="toc-title">Table of Contents</div></div>')
82
+ tail ||= @toc.child
83
+ tail_level ||= 0
84
+
85
+ level = header.name.gsub(/[hH]/, '').to_i
86
+
87
+ while tail_level < level
88
+ node = Nokogiri::XML::Node.new('ul', @doc)
89
+ tail = tail.add_child(node)
90
+ tail_level += 1
91
+ end
92
+
93
+ while tail_level > level
94
+ tail = tail.parent
95
+ tail_level -= 1
96
+ end
97
+ node = Nokogiri::XML::Node.new('li', @doc)
98
+ # % -> %25 so anchors work on Firefox. See issue #475
99
+ node.add_child(%Q{<a href="##{name}">#{header.content}</a>})
100
+ tail.add_child(node)
101
+ end
102
+
103
+ # Increments the number of anchors with the given name
104
+ # and returns the current index
105
+ def increment_anchor_index(name)
106
+ @anchor_names = {} if @anchor_names.nil?
107
+ @anchor_names[name].nil? ? @anchor_names[name] = 0 : @anchor_names[name] += 1
108
+ end
109
+ end
@@ -0,0 +1,54 @@
1
+ # ~*~ encoding: utf-8 ~*~
2
+ require 'net/http'
3
+ require 'uri'
4
+ require 'open-uri'
5
+
6
+ # Web Sequence Diagrams
7
+ #
8
+ # Render an inline web sequence diagram by sending the WSD code through the
9
+ # online renderer available from www.websequencediagrams.com.
10
+ #
11
+ class Gollum::Filter::WSD < Gollum::Filter
12
+ WSD_URL = "http://www.websequencediagrams.com/index.php"
13
+
14
+ # Extract all sequence diagram blocks into the map and replace with
15
+ # placeholders.
16
+ def extract(data)
17
+ return data if @markup.format == :txt
18
+ data.gsub(/^\{\{\{\{\{\{ ?(.+?)\r?\n(.+?)\r?\n\}\}\}\}\}\}\r?$/m) do
19
+ id = Digest::SHA1.hexdigest($2)
20
+ @map[id] = { :style => $1, :code => $2 }
21
+ id
22
+ end
23
+ end
24
+
25
+ # Process all diagrams from the map and replace the placeholders with
26
+ # the final HTML.
27
+ #
28
+ # data - The String data (with placeholders).
29
+ #
30
+ # Returns the marked up String data.
31
+ def process(data)
32
+ @map.each do |id, spec|
33
+ data.gsub!(id) do
34
+ render_wsd(spec[:code], spec[:style])
35
+ end
36
+ end
37
+ data
38
+ end
39
+
40
+ private
41
+ # Render the sequence diagram on the remote server.
42
+ #
43
+ # Returns an <img> tag to the rendered image, or an HTML error.
44
+ def render_wsd(code, style)
45
+ response = Net::HTTP.post_form(URI.parse(WSD_URL), 'style' => style, 'message' => code)
46
+ if response.body =~ /img: "(.+)"/
47
+ url = "//www.websequencediagrams.com/#{$1}"
48
+ "<img src=\"#{url}\" />"
49
+ else
50
+ puts response.body
51
+ html_error("Sorry, unable to render sequence diagram at this time.")
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,247 @@
1
+ # ~*~ encoding: utf-8 ~*~
2
+ module Gollum
3
+ # Controls all access to the Git objects from Gollum. Extend this class to
4
+ # add custom caching for special cases.
5
+ class GitAccess
6
+ # Initializes the GitAccess instance.
7
+ #
8
+ # path - The String path to the Git repository that holds the
9
+ # Gollum site.
10
+ # page_file_dir - String the directory in which all page files reside
11
+ #
12
+ # Returns this instance.
13
+ def initialize(path, page_file_dir = nil, bare = nil)
14
+ @page_file_dir = page_file_dir
15
+ @path = path
16
+ @repo = Gollum::Git::Repo.new(path, { :is_bare => bare })
17
+ clear
18
+ end
19
+
20
+ # Public: Determines whether the Git repository exists on disk.
21
+ #
22
+ # Returns true if it exists, or false.
23
+ def exist?
24
+ @repo.git.exist?
25
+ end
26
+
27
+ # Public: Converts a given Git reference to a SHA, using the cache if
28
+ # available.
29
+ #
30
+ # ref - a String Git reference (ex: "master")
31
+ #
32
+ # Returns a String, or nil if the ref isn't found.
33
+ def ref_to_sha(ref)
34
+ ref = ref.to_s
35
+ return if ref.empty?
36
+ sha =
37
+ if sha?(ref)
38
+ ref
39
+ else
40
+ get_cache(:ref, ref) { ref_to_sha!(ref) }
41
+ end.to_s
42
+ sha.empty? ? nil : sha
43
+ end
44
+
45
+ # Public: Gets a recursive list of Git blobs for the whole tree at the
46
+ # given commit.
47
+ #
48
+ # ref - A String Git reference or Git SHA to a commit.
49
+ #
50
+ # Returns an Array of BlobEntry instances.
51
+ def tree(ref)
52
+ if sha = ref_to_sha(ref)
53
+ get_cache(:tree, sha) { tree!(sha) }
54
+ else
55
+ []
56
+ end
57
+ end
58
+
59
+ # Public: Fetches the contents of the Git blob at the given SHA.
60
+ #
61
+ # sha - A String Git SHA.
62
+ #
63
+ # Returns the String content of the blob.
64
+ def blob(sha)
65
+ cat_file!(sha)
66
+ end
67
+
68
+ # Public: Looks up the Git commit using the given Git SHA or ref.
69
+ #
70
+ # ref - A String Git SHA or ref.
71
+ #
72
+ # Returns a Gollum::Git::Commit.
73
+ def commit(ref)
74
+ if sha?(ref)
75
+ get_cache(:commit, ref) { commit!(ref) }
76
+ else
77
+ if sha = get_cache(:ref, ref)
78
+ commit(sha)
79
+ else
80
+ if cm = commit!(ref)
81
+ set_cache(:ref, ref, cm.id)
82
+ set_cache(:commit, cm.id, cm)
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+ # Public: Clears all of the cached data that this GitAccess is tracking.
89
+ #
90
+ # Returns nothing.
91
+ def clear
92
+ @ref_map = {}
93
+ @tree_map = {}
94
+ @commit_map = {}
95
+ end
96
+
97
+ # Public: Refreshes just the cached Git reference data. This should
98
+ # be called after every Gollum update.
99
+ #
100
+ # Returns nothing.
101
+ def refresh
102
+ @ref_map.clear
103
+ end
104
+
105
+ #########################################################################
106
+ #
107
+ # Internal Methods
108
+ #
109
+ #########################################################################
110
+
111
+ # Gets the String path to the Git repository.
112
+ attr_reader :path
113
+
114
+ # Gets the Gollum::Git::Repo instance for the Git repository.
115
+ attr_reader :repo
116
+
117
+ # Gets a Hash cache of refs to commit SHAs.
118
+ #
119
+ # {"master" => "abc123", ...}
120
+ #
121
+ attr_reader :ref_map
122
+
123
+ # Gets a Hash cache of commit SHAs to a recursive tree of blobs.
124
+ #
125
+ # {"abc123" => [<BlobEntry>, <BlobEntry>]}
126
+ #
127
+ attr_reader :tree_map
128
+
129
+ # Gets a Hash cache of commit SHAs to the Gollum::Git::Commit instance.
130
+ #
131
+ # {"abcd123" => <Gollum::Git::Commit>}
132
+ #
133
+ attr_reader :commit_map
134
+
135
+ # Checks to see if the given String is a 40 character hex SHA.
136
+ #
137
+ # str - Possible String SHA.
138
+ #
139
+ # Returns true if the String is a SHA, or false.
140
+ def sha?(str)
141
+ !!(str =~ /^[0-9a-f]{40}$/)
142
+ end
143
+
144
+ # Looks up the Git SHA for the given Git ref.
145
+ #
146
+ # ref - String Git ref.
147
+ #
148
+ # Returns a String SHA.
149
+ def ref_to_sha!(ref)
150
+ commit = @repo.commit(ref)
151
+ commit ? commit.id : nil
152
+ end
153
+
154
+ # Looks up the Git blobs for a given commit.
155
+ #
156
+ # sha - String commit SHA.
157
+ #
158
+ # Returns an Array of BlobEntry instances.
159
+ def tree!(sha)
160
+ tree = @repo.lstree(sha, { :recursive => true })
161
+ items = []
162
+ tree.each do |entry|
163
+ if entry[:type] == 'blob'
164
+ items << BlobEntry.new(entry[:sha], entry[:path], entry[:size], entry[:mode].to_i(8))
165
+ end
166
+ end
167
+ if dir = @page_file_dir
168
+ regex = /^#{dir}\//
169
+ items.select { |i| i.path =~ regex }
170
+ else
171
+ items
172
+ end
173
+ end
174
+
175
+ # Reads the content from the Git db at the given SHA.
176
+ #
177
+ # sha - The String SHA.
178
+ #
179
+ # Returns the String content of the Git object.
180
+ def cat_file!(sha)
181
+ @repo.git.cat_file({ :p => true }, sha)
182
+ end
183
+
184
+ # Reads a Git commit.
185
+ #
186
+ # sha - The string SHA of the Git commit.
187
+ #
188
+ # Returns a Gollum::Git::Commit.
189
+ def commit!(sha)
190
+ @repo.commit(sha)
191
+ end
192
+
193
+ # Attempts to get the given data from a cache. If it doesn't exist, it'll
194
+ # pass the results of the yielded block to the cache for future accesses.
195
+ #
196
+ # name - The cache prefix used in building the full cache key.
197
+ # key - The unique cache key suffix, usually a String Git SHA.
198
+ #
199
+ # Yields a block to pass to the cache.
200
+ # Returns the cached result.
201
+ def get_cache(name, key)
202
+ cache = instance_variable_get("@#{name}_map")
203
+ value = cache[key]
204
+ if value.nil? && block_given?
205
+ set_cache(name, key, value = yield)
206
+ end
207
+ value == :_nil ? nil : value
208
+ end
209
+
210
+ # Writes some data to the internal cache.
211
+ #
212
+ # name - The cache prefix used in building the full cache key.
213
+ # key - The unique cache key suffix, usually a String Git SHA.
214
+ # value - The value to write to the cache.
215
+ #
216
+ # Returns nothing.
217
+ def set_cache(name, key, value)
218
+ cache = instance_variable_get("@#{name}_map")
219
+ cache[key] = value || :_nil
220
+ end
221
+
222
+ # Parses a line of output from the `ls-tree` command.
223
+ #
224
+ # line - A String line of output:
225
+ # "100644 blob 839c2291b30495b9a882c17d08254d3c90d8fb53 Home.md"
226
+ #
227
+ # Returns an Array of BlobEntry instances.
228
+ def parse_tree_line(line)
229
+ mode, type, sha, size, *name = line.split(/\s+/)
230
+ BlobEntry.new(sha, name.join(' '), size.to_i, mode.to_i(8))
231
+ end
232
+
233
+ # Decode octal sequences (\NNN) in tree path names.
234
+ #
235
+ # path - String path name.
236
+ #
237
+ # Returns a decoded String.
238
+ def decode_git_path(path)
239
+ if path[0] == ?" && path[-1] == ?"
240
+ path = path[1...-1]
241
+ path.gsub!(/\\\d{3}/) { |m| m[1..-1].to_i(8).chr }
242
+ end
243
+ path.gsub!(/\\[rn"\\]/) { |m| eval(%("#{m.to_s}")) }
244
+ path
245
+ end
246
+ end
247
+ end
@@ -0,0 +1,48 @@
1
+ # ~*~ encoding: utf-8 ~*~
2
+ require 'net/http'
3
+ require 'net/https' # ruby 1.8.7 fix, remove at upgrade
4
+ require 'uri'
5
+ require 'open-uri'
6
+
7
+ module Gollum
8
+ class Gitcode
9
+ def initialize path
10
+ raise(ArgumentError, 'path is nil or empty') if path.nil? or path.empty?
11
+
12
+ @uri = URI::HTTP.build({
13
+ :path => self.unchomp(path),
14
+ :host => 'raw.github.com',
15
+ :scheme => 'https',
16
+ :port => 443 })
17
+ end
18
+
19
+ def contents
20
+ @contents ||= self.req @uri
21
+ end
22
+
23
+ def unchomp p
24
+ return p if p.nil?
25
+ p[0] == '/' ? p : ('/' + p)
26
+ end
27
+
28
+ def req uri, cut = 1
29
+ return "Too many redirects or retries" if cut >= 10
30
+ http = Net::HTTP.new uri.host, uri.port
31
+ http.use_ssl = true
32
+ resp = http.get uri.path, {
33
+ 'Accept' => 'text/plain',
34
+ 'Cache-Control' => 'no-cache',
35
+ 'Connection' => 'keep-alive',
36
+ 'Host' => uri.host,
37
+ 'User-Agent' => 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:15.0) Gecko/20100101 Firefox/15.0'
38
+ }
39
+ code = resp.code.to_i
40
+ return resp.body if code == 200
41
+ return "Not Found" if code == 404
42
+ return "Unhandled Response Code #{code}" unless code == 304 or not resp.header['location'].nil?
43
+ loc = URI.parse resp.header['location']
44
+ uri2 = loc.relative?() ? (uri + loc) : loc # overloads (+)
45
+ return req uri2, (cut + 1)
46
+ end
47
+ end
48
+ end