gollum-lib 4.0.3-java → 4.1.0-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.
- checksums.yaml +8 -8
- data/README.md +1 -1
- data/Rakefile +3 -3
- data/gemspec.rb +9 -6
- data/lib/gollum-lib/blob_entry.rb +1 -0
- data/lib/gollum-lib/committer.rb +5 -5
- data/lib/gollum-lib/file.rb +7 -7
- data/lib/gollum-lib/file_view.rb +14 -15
- data/lib/gollum-lib/filter/code.rb +28 -29
- data/lib/gollum-lib/filter/macro.rb +16 -16
- data/lib/gollum-lib/filter/metadata.rb +3 -3
- data/lib/gollum-lib/filter/plantuml.rb +167 -0
- data/lib/gollum-lib/filter/remote_code.rb +8 -8
- data/lib/gollum-lib/filter/render.rb +2 -2
- data/lib/gollum-lib/filter/sanitize.rb +2 -2
- data/lib/gollum-lib/filter/tags.rb +31 -30
- data/lib/gollum-lib/filter/toc.rb +7 -7
- data/lib/gollum-lib/filter/wsd.rb +3 -3
- data/lib/gollum-lib/git_access.rb +6 -6
- data/lib/gollum-lib/gitcode.rb +3 -3
- data/lib/gollum-lib/helpers.rb +1 -1
- data/lib/gollum-lib/macro/global_toc.rb +12 -0
- data/lib/gollum-lib/macro/series.rb +48 -0
- data/lib/gollum-lib/markup.rb +8 -3
- data/lib/gollum-lib/markups.rb +2 -2
- data/lib/gollum-lib/page.rb +9 -9
- data/lib/gollum-lib/sanitization.rb +3 -3
- data/lib/gollum-lib/version.rb +1 -1
- data/lib/gollum-lib/wiki.rb +17 -17
- metadata +7 -4
@@ -0,0 +1,167 @@
|
|
1
|
+
# ~*~ encoding: utf-8 ~*~
|
2
|
+
require 'net/http'
|
3
|
+
require 'uri'
|
4
|
+
require 'open-uri'
|
5
|
+
require 'zlib'
|
6
|
+
|
7
|
+
# PlantUML Diagrams
|
8
|
+
#
|
9
|
+
# This filter replaces PlantUML blocks with HTML img tags. These img tags
|
10
|
+
# point to a PlantUML web service that converts the UML text blocks into nice
|
11
|
+
# diagrams.
|
12
|
+
#
|
13
|
+
# For this to work you must have your own PlantUML server running somewhere.
|
14
|
+
# Just follow the instructions on the github page to run your own server:
|
15
|
+
#
|
16
|
+
# https://github.com/plantuml/plantuml-server
|
17
|
+
#
|
18
|
+
# Once you start you own plantuml server you need to configure this filter to
|
19
|
+
# point to it:
|
20
|
+
#
|
21
|
+
# Gollum::Filter::PlantUML.configure do |config|
|
22
|
+
# config.url = "http://localhost:8080/plantuml/png"
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# Then in your wiki pages simply add PlantUML blocks anywhere you want a
|
26
|
+
# diagram:
|
27
|
+
#
|
28
|
+
# @startuml
|
29
|
+
# Alice -> Bob: Authentication Request
|
30
|
+
# Bob --> Alice: Authentication Response
|
31
|
+
# Alice -> Bob: Another authentication Request
|
32
|
+
# Alice <-- Bob: another authentication Response
|
33
|
+
# @enduml
|
34
|
+
#
|
35
|
+
# To learn more about how to create cool PlantUML diagrams check the examples
|
36
|
+
# at: http://plantuml.sourceforge.net/
|
37
|
+
#
|
38
|
+
class Gollum::Filter::PlantUML < Gollum::Filter
|
39
|
+
|
40
|
+
DEFAULT_URL = "http://localhost:8080/plantuml/png"
|
41
|
+
|
42
|
+
# Configuration class used to change the behaviour of the PlatnUML filter.
|
43
|
+
#
|
44
|
+
# url: PlantUML server URL (e.g. http://localhost:8080)
|
45
|
+
# test: Set to true when running tests to skip the server check.
|
46
|
+
#
|
47
|
+
class Configuration
|
48
|
+
attr_accessor :url, :test
|
49
|
+
|
50
|
+
def initialize
|
51
|
+
@url = DEFAULT_URL
|
52
|
+
@test = false
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
class << self
|
57
|
+
attr_writer :configuration
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.configuration
|
61
|
+
@configuration ||= Configuration.new
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.configure
|
65
|
+
yield(configuration)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Extract all sequence diagram blocks into the map and replace with
|
69
|
+
# placeholders.
|
70
|
+
def extract(data)
|
71
|
+
return data if @markup.format == :txt
|
72
|
+
data.gsub(/(@startuml\r?\n.+?\r?\n@enduml\r?$)/m) do
|
73
|
+
id = Digest::SHA1.hexdigest($1)
|
74
|
+
@map[id] = { :code => $1 }
|
75
|
+
id
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# Process all diagrams from the map and replace the placeholders with
|
80
|
+
# the final HTML.
|
81
|
+
def process(data)
|
82
|
+
@map.each do |id, spec|
|
83
|
+
data.gsub!(id) do
|
84
|
+
render_plantuml(id, spec[:code])
|
85
|
+
end
|
86
|
+
end
|
87
|
+
data
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def server_url
|
93
|
+
PlantUML::configuration.url
|
94
|
+
end
|
95
|
+
|
96
|
+
def test?
|
97
|
+
PlantUML::configuration.test
|
98
|
+
end
|
99
|
+
|
100
|
+
def render_plantuml(id, code)
|
101
|
+
if check_server
|
102
|
+
plantuml_url = gen_url(code)
|
103
|
+
"<img src=\"#{gen_url(code)}\" />"
|
104
|
+
else
|
105
|
+
html_error("Sorry, unable to render PlantUML diagram at this time")
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Compression code used to generate PlantUML URLs. Taken directly from the
|
110
|
+
# Transcoder class in the PlantUML java code.
|
111
|
+
def gen_url(text)
|
112
|
+
result = ""
|
113
|
+
compressedData = Zlib::Deflate.deflate(text)
|
114
|
+
compressedData.chars.each_slice(3) do |bytes|
|
115
|
+
#print bytes[0], ' ' , bytes[1] , ' ' , bytes[2]
|
116
|
+
b1 = bytes[0].nil? ? 0 : (bytes[0].ord & 0xFF)
|
117
|
+
b2 = bytes[1].nil? ? 0 : (bytes[1].ord & 0xFF)
|
118
|
+
b3 = bytes[2].nil? ? 0 : (bytes[2].ord & 0xFF)
|
119
|
+
result += append3bytes(b1, b2, b3)
|
120
|
+
end
|
121
|
+
"#{server_url}/#{result}"
|
122
|
+
end
|
123
|
+
|
124
|
+
def encode6bit(b)
|
125
|
+
if b < 10
|
126
|
+
return ('0'.ord + b).chr
|
127
|
+
end
|
128
|
+
b = b - 10
|
129
|
+
if b < 26
|
130
|
+
return ('A'.ord + b).chr
|
131
|
+
end
|
132
|
+
b = b - 26
|
133
|
+
if b < 26
|
134
|
+
return ('a'.ord + b).chr
|
135
|
+
end
|
136
|
+
b = b - 26
|
137
|
+
if b == 0
|
138
|
+
return '-'
|
139
|
+
end
|
140
|
+
if b == 1
|
141
|
+
return '_'
|
142
|
+
end
|
143
|
+
return '?'
|
144
|
+
end
|
145
|
+
|
146
|
+
def append3bytes(b1, b2, b3)
|
147
|
+
c1 = b1 >> 2
|
148
|
+
c2 = ((b1 & 0x3) << 4) | (b2 >> 4)
|
149
|
+
c3 = ((b2 & 0xF) << 2) | (b3 >> 6)
|
150
|
+
c4 = b3 & 0x3F
|
151
|
+
return encode6bit(c1 & 0x3F).chr +
|
152
|
+
encode6bit(c2 & 0x3F).chr +
|
153
|
+
encode6bit(c3 & 0x3F).chr +
|
154
|
+
encode6bit(c4 & 0x3F).chr
|
155
|
+
end
|
156
|
+
|
157
|
+
# Make a call to the PlantUML server with the simplest diagram possible to
|
158
|
+
# check if the server is available or not.
|
159
|
+
def check_server
|
160
|
+
return true if test?
|
161
|
+
check_url = "#{server_url}/SyfFKj2rKt3CoKnELR1Io4ZDoSa70000"
|
162
|
+
response = Net::HTTP.get_response(URI(check_url))
|
163
|
+
return response.is_a?(Net::HTTPSuccess)
|
164
|
+
rescue
|
165
|
+
return false
|
166
|
+
end
|
167
|
+
end
|
@@ -14,14 +14,14 @@ require 'open-uri'
|
|
14
14
|
class Gollum::Filter::RemoteCode < Gollum::Filter
|
15
15
|
def extract(data)
|
16
16
|
return data if @markup.format == :txt
|
17
|
-
data.gsub
|
18
|
-
language =
|
19
|
-
uri =
|
20
|
-
protocol =
|
17
|
+
data.gsub(/^[ \t]*``` ?([^:\n\r]+):((http)?[^`\n\r]+)```/) do
|
18
|
+
language = Regexp.last_match[1]
|
19
|
+
uri = Regexp.last_match[2]
|
20
|
+
protocol = Regexp.last_match[3]
|
21
21
|
|
22
22
|
# Detect local file
|
23
23
|
if protocol.nil?
|
24
|
-
if file = @markup.find_file(uri, @markup.wiki.ref)
|
24
|
+
if (file = @markup.find_file(uri, @markup.wiki.ref))
|
25
25
|
contents = file.raw_data
|
26
26
|
else
|
27
27
|
# How do we communicate a render error?
|
@@ -35,13 +35,13 @@ class Gollum::Filter::RemoteCode < Gollum::Filter
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
def process(
|
39
|
-
|
38
|
+
def process(data)
|
39
|
+
data
|
40
40
|
end
|
41
41
|
|
42
42
|
private
|
43
43
|
|
44
|
-
def req
|
44
|
+
def req(uri, cut = 1)
|
45
45
|
uri = URI(uri)
|
46
46
|
return "Too many redirects or retries" if cut >= 10
|
47
47
|
http = Net::HTTP.new uri.host, uri.port
|
@@ -6,23 +6,23 @@ class Gollum::Filter::Tags < Gollum::Filter
|
|
6
6
|
def extract(data)
|
7
7
|
return data if @markup.format == :txt || @markup.format == :asciidoc
|
8
8
|
data.gsub!(/(.?)\[\[(.+?)\]\]([^\[]?)/m) do
|
9
|
-
if
|
10
|
-
"[[#{
|
11
|
-
elsif
|
12
|
-
if
|
13
|
-
pre =
|
14
|
-
post =
|
15
|
-
parts =
|
9
|
+
if Regexp.last_match[1] == "'" && Regexp.last_match[3] != "'"
|
10
|
+
"[[#{Regexp.last_match[2]}]]#{Regexp.last_match[3]}"
|
11
|
+
elsif Regexp.last_match[2].include?('][')
|
12
|
+
if Regexp.last_match[2][0..4] == 'file:'
|
13
|
+
pre = Regexp.last_match[1]
|
14
|
+
post = Regexp.last_match[3]
|
15
|
+
parts = Regexp.last_match[2].split('][')
|
16
16
|
parts[0][0..4] = ""
|
17
17
|
link = "#{parts[1]}|#{parts[0].sub(/\.org/, '')}"
|
18
18
|
id = register_tag(link)
|
19
19
|
"#{pre}#{id}#{post}"
|
20
20
|
else
|
21
|
-
|
21
|
+
Regexp.last_match[0]
|
22
22
|
end
|
23
23
|
else
|
24
|
-
id = register_tag(
|
25
|
-
"#{
|
24
|
+
id = register_tag(Regexp.last_match[2])
|
25
|
+
"#{Regexp.last_match[1]}#{id}#{Regexp.last_match[3]}"
|
26
26
|
end
|
27
27
|
end
|
28
28
|
data
|
@@ -42,7 +42,7 @@ class Gollum::Filter::Tags < Gollum::Filter
|
|
42
42
|
if node.text? then
|
43
43
|
content = node.content
|
44
44
|
content.gsub!(/TAG[a-f0-9]+TAG/) do |id|
|
45
|
-
if tag = @map[id] then
|
45
|
+
if (tag = @map[id]) then
|
46
46
|
if is_preformatted?(node) then
|
47
47
|
"[[#{tag}]]"
|
48
48
|
else
|
@@ -77,13 +77,13 @@ class Gollum::Filter::Tags < Gollum::Filter
|
|
77
77
|
%{[[#{tag}]]}
|
78
78
|
elsif tag =~ /^_$/
|
79
79
|
%{<div class="clearfloats"></div>}
|
80
|
-
elsif html = process_include_tag(tag)
|
80
|
+
elsif (html = process_include_tag(tag))
|
81
81
|
html
|
82
|
-
elsif html = process_image_tag(tag)
|
82
|
+
elsif (html = process_image_tag(tag))
|
83
83
|
html
|
84
|
-
elsif html = process_external_link_tag(tag)
|
84
|
+
elsif (html = process_external_link_tag(tag))
|
85
85
|
html
|
86
|
-
elsif html = process_file_link_tag(tag)
|
86
|
+
elsif (html = process_file_link_tag(tag))
|
87
87
|
html
|
88
88
|
else
|
89
89
|
process_page_link_tag(tag)
|
@@ -125,11 +125,11 @@ class Gollum::Filter::Tags < Gollum::Filter
|
|
125
125
|
return if parts.size.zero?
|
126
126
|
|
127
127
|
name = parts[0].strip
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
128
|
+
if (file = @markup.find_file(name))
|
129
|
+
path = ::File.join @markup.wiki.base_path, file.path
|
130
|
+
elsif name =~ /^https?:\/\/.+(jpg|png|gif|svg|bmp)$/i
|
131
|
+
path = name
|
132
|
+
end
|
133
133
|
|
134
134
|
if path
|
135
135
|
opts = parse_image_tag_options(tag)
|
@@ -155,19 +155,19 @@ class Gollum::Filter::Tags < Gollum::Filter
|
|
155
155
|
end
|
156
156
|
end
|
157
157
|
|
158
|
-
if width = opts['width']
|
158
|
+
if (width = opts['width'])
|
159
159
|
if width =~ /^\d+(\.\d+)?(em|px)$/
|
160
160
|
attrs << %{width="#{width}"}
|
161
161
|
end
|
162
162
|
end
|
163
163
|
|
164
|
-
if height = opts['height']
|
164
|
+
if (height = opts['height'])
|
165
165
|
if height =~ /^\d+(\.\d+)?(em|px)$/
|
166
166
|
attrs << %{height="#{height}"}
|
167
167
|
end
|
168
168
|
end
|
169
169
|
|
170
|
-
if alt = opts['alt']
|
170
|
+
if (alt = opts['alt'])
|
171
171
|
attrs << %{alt="#{alt}"}
|
172
172
|
end
|
173
173
|
|
@@ -207,6 +207,7 @@ class Gollum::Filter::Tags < Gollum::Filter
|
|
207
207
|
# nil if it is not.
|
208
208
|
def process_external_link_tag(tag)
|
209
209
|
parts = tag.split('|')
|
210
|
+
parts.reverse! if @markup.reverse_links?
|
210
211
|
return if parts.size.zero?
|
211
212
|
if parts.size == 1
|
212
213
|
url = parts[0].strip
|
@@ -245,11 +246,11 @@ class Gollum::Filter::Tags < Gollum::Filter
|
|
245
246
|
|
246
247
|
name = parts[0].strip
|
247
248
|
path = parts[1] && parts[1].strip
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
249
|
+
if path && file = @markup.find_file(path)
|
250
|
+
path = ::File.join @markup.wiki.base_path, file.path
|
251
|
+
else
|
252
|
+
path = nil
|
253
|
+
end
|
253
254
|
|
254
255
|
if name && path && file
|
255
256
|
%{<a href="#{::File.join @markup.wiki.base_path, file.path}">#{name}</a>}
|
@@ -269,7 +270,7 @@ class Gollum::Filter::Tags < Gollum::Filter
|
|
269
270
|
# if it is not.
|
270
271
|
def process_page_link_tag(tag)
|
271
272
|
parts = tag.split('|')
|
272
|
-
parts.reverse! if @markup.
|
273
|
+
parts.reverse! if @markup.reverse_links?
|
273
274
|
|
274
275
|
name, page_name = *parts.compact.map(&:strip)
|
275
276
|
cname = @markup.wiki.page_class.cname(page_name || name)
|
@@ -313,7 +314,7 @@ class Gollum::Filter::Tags < Gollum::Filter
|
|
313
314
|
if page
|
314
315
|
return page
|
315
316
|
end
|
316
|
-
if pos = cname.index('#')
|
317
|
+
if (pos = cname.index('#'))
|
317
318
|
[@markup.wiki.page(cname[0...pos]), cname[pos..-1]]
|
318
319
|
end
|
319
320
|
end
|
@@ -78,22 +78,22 @@ class Gollum::Filter::TOC < Gollum::Filter
|
|
78
78
|
# Adds an entry to the TOC for the given header. The generated entry
|
79
79
|
# is a link to the given anchor name
|
80
80
|
def add_entry_to_toc(header, name)
|
81
|
-
@toc
|
82
|
-
tail
|
83
|
-
tail_level
|
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
84
|
|
85
85
|
level = header.name.gsub(/[hH]/, '').to_i
|
86
86
|
|
87
87
|
while tail_level < level
|
88
|
-
node
|
89
|
-
tail
|
88
|
+
node = Nokogiri::XML::Node.new('ul', @doc)
|
89
|
+
tail = tail.add_child(node)
|
90
90
|
tail_level += 1
|
91
91
|
end
|
92
92
|
|
93
93
|
while tail_level > level
|
94
|
-
tail
|
94
|
+
tail = tail.parent
|
95
95
|
tail_level -= 1
|
96
|
-
|
96
|
+
end
|
97
97
|
node = Nokogiri::XML::Node.new('li', @doc)
|
98
98
|
# % -> %25 so anchors work on Firefox. See issue #475
|
99
99
|
node.add_child(%Q{<a href="##{name}">#{header.content}</a>})
|
@@ -16,8 +16,8 @@ class Gollum::Filter::WSD < Gollum::Filter
|
|
16
16
|
def extract(data)
|
17
17
|
return data if @markup.format == :txt
|
18
18
|
data.gsub(/^\{\{\{\{\{\{ ?(.+?)\r?\n(.+?)\r?\n\}\}\}\}\}\}\r?$/m) do
|
19
|
-
id = Digest::SHA1.hexdigest(
|
20
|
-
@map[id] = { :style =>
|
19
|
+
id = Digest::SHA1.hexdigest(Regexp.last_match[2])
|
20
|
+
@map[id] = { :style => Regexp.last_match[1], :code => Regexp.last_match[2] }
|
21
21
|
id
|
22
22
|
end
|
23
23
|
end
|
@@ -44,7 +44,7 @@ class Gollum::Filter::WSD < Gollum::Filter
|
|
44
44
|
def render_wsd(code, style)
|
45
45
|
response = Net::HTTP.post_form(URI.parse(WSD_URL), 'style' => style, 'message' => code)
|
46
46
|
if response.body =~ /img: "(.+)"/
|
47
|
-
url = "//www.websequencediagrams.com/#{
|
47
|
+
url = "//www.websequencediagrams.com/#{Regexp.last_match[1]}"
|
48
48
|
"<img src=\"#{url}\" />"
|
49
49
|
else
|
50
50
|
puts response.body
|
@@ -49,7 +49,7 @@ module Gollum
|
|
49
49
|
#
|
50
50
|
# Returns an Array of BlobEntry instances.
|
51
51
|
def tree(ref)
|
52
|
-
if sha = ref_to_sha(ref)
|
52
|
+
if (sha = ref_to_sha(ref))
|
53
53
|
get_cache(:tree, sha) { tree!(sha) }
|
54
54
|
else
|
55
55
|
[]
|
@@ -74,10 +74,10 @@ module Gollum
|
|
74
74
|
if sha?(ref)
|
75
75
|
get_cache(:commit, ref) { commit!(ref) }
|
76
76
|
else
|
77
|
-
if sha = get_cache(:ref, ref)
|
77
|
+
if (sha = get_cache(:ref, ref))
|
78
78
|
commit(sha)
|
79
79
|
else
|
80
|
-
if cm = commit!(ref)
|
80
|
+
if (cm = commit!(ref))
|
81
81
|
set_cache(:ref, ref, cm.id)
|
82
82
|
set_cache(:commit, cm.id, cm)
|
83
83
|
end
|
@@ -164,7 +164,7 @@ module Gollum
|
|
164
164
|
items << BlobEntry.new(entry[:sha], entry[:path], entry[:size], entry[:mode].to_i(8))
|
165
165
|
end
|
166
166
|
end
|
167
|
-
if dir = @page_file_dir
|
167
|
+
if (dir = @page_file_dir)
|
168
168
|
regex = /^#{dir}\//
|
169
169
|
items.select { |i| i.path =~ regex }
|
170
170
|
else
|
@@ -226,7 +226,7 @@ module Gollum
|
|
226
226
|
#
|
227
227
|
# Returns an Array of BlobEntry instances.
|
228
228
|
def parse_tree_line(line)
|
229
|
-
mode,
|
229
|
+
mode, _type, sha, size, *name = line.split(/\s+/)
|
230
230
|
BlobEntry.new(sha, name.join(' '), size.to_i, mode.to_i(8))
|
231
231
|
end
|
232
232
|
|
@@ -240,7 +240,7 @@ module Gollum
|
|
240
240
|
path = path[1...-1]
|
241
241
|
path.gsub!(/\\\d{3}/) { |m| m[1..-1].to_i(8).chr }
|
242
242
|
end
|
243
|
-
path.gsub!(/\\[rn"\\]/) { |m| eval(%("#{m
|
243
|
+
path.gsub!(/\\[rn"\\]/) { |m| eval(%("#{m}")) }
|
244
244
|
path
|
245
245
|
end
|
246
246
|
end
|