gollum-lib 5.0.a.4-java → 5.0.5-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 +4 -4
- data/Gemfile +2 -1
- data/HISTORY.md +4 -0
- data/README.md +12 -7
- data/Rakefile +8 -7
- data/gemspec.rb +17 -10
- data/gollum-lib.gemspec +8 -6
- data/gollum-lib_java.gemspec +2 -2
- data/lib/gollum-lib.rb +9 -9
- data/lib/gollum-lib/blob_entry.rb +2 -8
- data/lib/gollum-lib/committer.rb +23 -61
- data/lib/gollum-lib/file.rb +105 -82
- data/lib/gollum-lib/file_view.rb +8 -4
- data/lib/gollum-lib/filter.rb +12 -0
- data/lib/gollum-lib/filter/code.rb +9 -13
- data/lib/gollum-lib/filter/critic_markup.rb +97 -0
- data/lib/gollum-lib/filter/emoji.rb +11 -8
- data/lib/gollum-lib/filter/macro.rb +5 -2
- data/lib/gollum-lib/filter/plantuml.rb +1 -1
- data/lib/gollum-lib/filter/remote_code.rb +3 -2
- data/lib/gollum-lib/filter/render.rb +25 -2
- data/lib/gollum-lib/filter/sanitize.rb +1 -8
- data/lib/gollum-lib/filter/tags.rb +57 -46
- data/lib/gollum-lib/filter/toc.rb +17 -21
- data/lib/gollum-lib/filter/yaml.rb +1 -1
- data/lib/gollum-lib/git_access.rb +0 -25
- data/lib/gollum-lib/helpers.rb +13 -3
- data/lib/gollum-lib/macro.rb +4 -0
- data/lib/gollum-lib/macro/audio.rb +9 -0
- data/lib/gollum-lib/macro/global_toc.rb +2 -1
- data/lib/gollum-lib/macro/navigation.rb +8 -6
- data/lib/gollum-lib/macro/note.rb +19 -0
- data/lib/gollum-lib/macro/octicon.rb +12 -0
- data/lib/gollum-lib/macro/series.rb +2 -2
- data/lib/gollum-lib/macro/warn.rb +11 -0
- data/lib/gollum-lib/markup.rb +17 -32
- data/lib/gollum-lib/markups.rb +13 -8
- data/lib/gollum-lib/page.rb +80 -166
- data/lib/gollum-lib/pagination.rb +7 -6
- data/lib/gollum-lib/redirects.rb +42 -0
- data/lib/gollum-lib/sanitization.rb +32 -357
- data/lib/gollum-lib/version.rb +1 -1
- data/lib/gollum-lib/wiki.rb +216 -404
- metadata +65 -27
- data/ROADMAP +0 -6
@@ -14,17 +14,11 @@ class Gollum::Filter::Emoji < Gollum::Filter
|
|
14
14
|
(?!\]{^2})
|
15
15
|
}ix
|
16
16
|
|
17
|
-
PROCESS_PATTERN = %r{
|
18
|
-
=EEMMOOJJII=
|
19
|
-
(?<name>[\w-]+)
|
20
|
-
=IIJJOOMMEE=
|
21
|
-
}ix
|
22
|
-
|
23
17
|
def extract(data)
|
24
18
|
data.gsub! EXTRACT_PATTERN do
|
25
19
|
case
|
26
20
|
when $~[:escape] then $&[1..-1]
|
27
|
-
when emoji_exists?($~[:name]) then "
|
21
|
+
when emoji_exists?($~[:name]) then "#{open_pattern}#{$~[:name]}#{close_pattern}"
|
28
22
|
else $&
|
29
23
|
end
|
30
24
|
end
|
@@ -32,12 +26,21 @@ class Gollum::Filter::Emoji < Gollum::Filter
|
|
32
26
|
end
|
33
27
|
|
34
28
|
def process(data)
|
35
|
-
|
29
|
+
src = ::File.join(@markup.wiki.base_path, '/gollum/emoji/\\k<name>')
|
30
|
+
data.gsub! process_pattern, %Q(<img src="#{src}" alt="\\k<name>" class="emoji">)
|
36
31
|
data
|
37
32
|
end
|
38
33
|
|
39
34
|
private
|
40
35
|
|
36
|
+
def process_pattern
|
37
|
+
%r{
|
38
|
+
#{open_pattern}
|
39
|
+
(?<name>[\w-]+)
|
40
|
+
#{close_pattern}
|
41
|
+
}ix
|
42
|
+
end
|
43
|
+
|
41
44
|
def emoji_exists?(name)
|
42
45
|
@index ||= Gemojione::Index.new
|
43
46
|
!!@index.find_by_name(name)
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# ~*~ encoding: utf-8 ~*~
|
2
|
+
require 'octicons'
|
2
3
|
|
3
4
|
# Replace specified tokens with dynamically generated content.
|
4
5
|
class Gollum::Filter::Macro < Gollum::Filter
|
@@ -12,7 +13,7 @@ class Gollum::Filter::Macro < Gollum::Filter
|
|
12
13
|
|
13
14
|
data.gsub(/('?)\<\<\s*([A-Z][A-Za-z0-9]*)\s*\(#{arg_list}\)\s*\>\>/) do
|
14
15
|
next CGI.escape_html($&[1..-1]) unless Regexp.last_match[1].empty?
|
15
|
-
id = Digest::SHA1.hexdigest(Regexp.last_match[2] + Regexp.last_match[3])
|
16
|
+
id = "#{open_pattern}#{Digest::SHA1.hexdigest(Regexp.last_match[2] + Regexp.last_match[3])}#{close_pattern}"
|
16
17
|
macro = Regexp.last_match[2]
|
17
18
|
argstr = Regexp.last_match[3]
|
18
19
|
args = []
|
@@ -47,7 +48,9 @@ class Gollum::Filter::Macro < Gollum::Filter
|
|
47
48
|
begin
|
48
49
|
Gollum::Macro.instance(macro, @markup.wiki, @markup.page).render(*args)
|
49
50
|
rescue StandardError => e
|
50
|
-
|
51
|
+
icon = Octicons::Octicon.new('zap', {width: 24, height: 24})
|
52
|
+
icon.options[:class] << ' mr-2'
|
53
|
+
"<div class='flash flash-error'>#{icon.to_svg}Macro Error for #{macro}: #{e.message}</div>"
|
51
54
|
end
|
52
55
|
end
|
53
56
|
end
|
@@ -70,7 +70,7 @@ class Gollum::Filter::PlantUML < Gollum::Filter
|
|
70
70
|
# placeholders.
|
71
71
|
def extract(data)
|
72
72
|
data.gsub(/(@startuml\r?\n.+?\r?\n@enduml\r?$)/m) do
|
73
|
-
id = Digest::SHA1.hexdigest($1)
|
73
|
+
id = "#{open_pattern}#{Digest::SHA1.hexdigest($1)}#{close_pattern}"
|
74
74
|
@map[id] = { :code => $1 }
|
75
75
|
id
|
76
76
|
end
|
@@ -20,7 +20,7 @@ class Gollum::Filter::RemoteCode < Gollum::Filter
|
|
20
20
|
|
21
21
|
# Detect local file
|
22
22
|
if protocol.nil?
|
23
|
-
if (file = @markup.
|
23
|
+
if (file = @markup.wiki.file(uri, @markup.wiki.ref))
|
24
24
|
contents = file.raw_data
|
25
25
|
else
|
26
26
|
# How do we communicate a render error?
|
@@ -45,7 +45,8 @@ class Gollum::Filter::RemoteCode < Gollum::Filter
|
|
45
45
|
return "Too many redirects or retries" if cut >= 10
|
46
46
|
http = Net::HTTP.new uri.host, uri.port
|
47
47
|
http.use_ssl = true
|
48
|
-
|
48
|
+
path = uri.path.empty? ? '/' : uri.path
|
49
|
+
resp = http.get path, {
|
49
50
|
'Accept' => 'text/plain',
|
50
51
|
'Cache-Control' => 'no-cache',
|
51
52
|
'Connection' => 'keep-alive',
|
@@ -3,7 +3,11 @@
|
|
3
3
|
class Gollum::Filter::Render < Gollum::Filter
|
4
4
|
def extract(data)
|
5
5
|
begin
|
6
|
-
|
6
|
+
working_dir = Pathname.new(@markup.wiki.path).join(@markup.dir)
|
7
|
+
working_dir = working_dir.exist? ? working_dir.to_s : '.'
|
8
|
+
Dir.chdir(working_dir) do
|
9
|
+
data = GitHub::Markup.render_s(@markup.format, data)
|
10
|
+
end
|
7
11
|
if data.nil?
|
8
12
|
raise "There was an error converting #{@markup.name} to HTML."
|
9
13
|
end
|
@@ -15,6 +19,25 @@ class Gollum::Filter::Render < Gollum::Filter
|
|
15
19
|
end
|
16
20
|
|
17
21
|
def process(data)
|
22
|
+
data = add_editable_header_class(data)
|
18
23
|
data
|
19
24
|
end
|
20
|
-
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def add_editable_header_class(data)
|
29
|
+
doc = Nokogiri::HTML::DocumentFragment.parse(data)
|
30
|
+
doc.css('h1,h2,h3,h4,h5,h6').each_with_index do |header, i|
|
31
|
+
next if header.content.empty?
|
32
|
+
next if header.inner_html.match(PLACEHOLDER_PATTERN)
|
33
|
+
klass = header['class']
|
34
|
+
if klass
|
35
|
+
header['class'] = klass << ' editable'
|
36
|
+
else
|
37
|
+
header['class'] = 'editable'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
doc.to_xml(@markup.class.to_xml_opts)
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -6,13 +6,6 @@ class Gollum::Filter::Sanitize < Gollum::Filter
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def process(data)
|
9
|
-
|
10
|
-
doc = Nokogiri::HTML::DocumentFragment.parse(data)
|
11
|
-
doc = @markup.sanitize.clean_node!(doc)
|
12
|
-
|
13
|
-
doc.to_xml(@markup.to_xml_opts).gsub(/<p><\/p>/, '')
|
14
|
-
else
|
15
|
-
data
|
16
|
-
end
|
9
|
+
sanitize(data)
|
17
10
|
end
|
18
11
|
end
|
@@ -34,7 +34,7 @@ class Gollum::Filter::Tags < Gollum::Filter
|
|
34
34
|
doc.traverse do |node|
|
35
35
|
if node.text? then
|
36
36
|
content = node.content
|
37
|
-
content.gsub!(
|
37
|
+
content.gsub!(%r{#{open_pattern}[a-f0-9]+#{close_pattern}}) do |id|
|
38
38
|
if (tag = @map[id]) then
|
39
39
|
if is_preformatted?(node) then
|
40
40
|
"[[#{tag}]]"
|
@@ -56,7 +56,7 @@ class Gollum::Filter::Tags < Gollum::Filter
|
|
56
56
|
INCLUDE_TAG = 'include:'
|
57
57
|
|
58
58
|
def register_tag(tag)
|
59
|
-
id = "
|
59
|
+
id = "#{open_pattern}#{Digest::SHA1.hexdigest(tag)}#{close_pattern}"
|
60
60
|
@map[id] = tag
|
61
61
|
id
|
62
62
|
end
|
@@ -77,7 +77,6 @@ class Gollum::Filter::Tags < Gollum::Filter
|
|
77
77
|
return generate_link('', nil, nil, :page_absent) if link_part.nil?
|
78
78
|
img_args = extra ? [extra, link_part] : [link_part]
|
79
79
|
mime = MIME::Types.type_for(::File.extname(img_args.first.to_s)).first
|
80
|
-
|
81
80
|
result = if tag =~ /^_TOC_/
|
82
81
|
%{[[#{tag}]]}
|
83
82
|
elsif link_part =~ /^_$/
|
@@ -122,9 +121,9 @@ class Gollum::Filter::Tags < Gollum::Filter
|
|
122
121
|
len = INCLUDE_TAG.length
|
123
122
|
return html_error('Cannot process include directive: no page name given') if tag.length <= len
|
124
123
|
page_name = tag[len..-1]
|
125
|
-
resolved_page_name = ::File.
|
124
|
+
resolved_page_name = ::File.join(@markup.dir, page_name)
|
126
125
|
if @markup.include_levels > 0
|
127
|
-
page =
|
126
|
+
page = find_page_or_file_from_path(resolved_page_name)
|
128
127
|
if page
|
129
128
|
page.formatted_data(@markup.encoding, @markup.include_levels-1)
|
130
129
|
else
|
@@ -146,8 +145,8 @@ class Gollum::Filter::Tags < Gollum::Filter
|
|
146
145
|
opts = parse_image_tag_options(options)
|
147
146
|
if path =~ /^https?:\/\/.+$/i
|
148
147
|
generate_image(path, opts)
|
149
|
-
elsif file =
|
150
|
-
generate_image(generate_href_for_path(file.
|
148
|
+
elsif file = find_page_or_file_from_path(path, :file)
|
149
|
+
generate_image(generate_href_for_path(file.url_path), opts)
|
151
150
|
else
|
152
151
|
generate_image('', opts)
|
153
152
|
end
|
@@ -173,14 +172,8 @@ class Gollum::Filter::Tags < Gollum::Filter
|
|
173
172
|
# Return the String HTML if the tag is a valid external link tag or
|
174
173
|
# nil if it is not.
|
175
174
|
def process_external_link_tag(url, pretty_name = nil)
|
176
|
-
|
177
|
-
if
|
178
|
-
accepted_protocols.select!{|protocol| protocol != :relative}
|
179
|
-
regexp = %r{^((#{accepted_protocols.join("|")}):)?(//)}
|
180
|
-
else
|
181
|
-
regexp = %r{^((#{accepted_protocols.join("|")}):)}
|
182
|
-
end
|
183
|
-
if url =~ regexp
|
175
|
+
@accepted_protocols_regex ||= %r{^((#{::Gollum::Sanitization.accepted_protocols.join('|')}):)?(//)}
|
176
|
+
if url =~ @accepted_protocols_regex
|
184
177
|
generate_link(url, pretty_name, nil, :external)
|
185
178
|
else
|
186
179
|
nil
|
@@ -195,8 +188,9 @@ class Gollum::Filter::Tags < Gollum::Filter
|
|
195
188
|
# Returns the String HTML if the tag is a valid file link tag or nil
|
196
189
|
# if it is not.
|
197
190
|
def process_file_link_tag(link_part, pretty_name)
|
198
|
-
|
199
|
-
|
191
|
+
return nil if ::Gollum::Page.valid_extension?(link_part)
|
192
|
+
if file = find_page_or_file_from_path(link_part, :file)
|
193
|
+
generate_link(file.url_path, pretty_name, nil, :file)
|
200
194
|
else
|
201
195
|
nil
|
202
196
|
end
|
@@ -212,18 +206,32 @@ class Gollum::Filter::Tags < Gollum::Filter
|
|
212
206
|
def process_page_link_tag(link_part, pretty_name = nil)
|
213
207
|
presence = :page_absent
|
214
208
|
link = link_part
|
215
|
-
page =
|
209
|
+
page = find_page_or_file_from_path(link)
|
216
210
|
|
217
211
|
# If no match yet, try finding page with anchor removed
|
218
|
-
if
|
219
|
-
|
220
|
-
|
221
|
-
|
212
|
+
if page.nil?
|
213
|
+
if pos = link.rindex('#')
|
214
|
+
extra = link[pos..-1]
|
215
|
+
link = link[0...pos]
|
216
|
+
else
|
217
|
+
extra = nil
|
218
|
+
end
|
219
|
+
|
220
|
+
if link.empty? && extra # Internal anchor link, don't search for the page but return immediately
|
221
|
+
return generate_link(nil, pretty_name, extra, :internal_anchor)
|
222
|
+
end
|
223
|
+
|
224
|
+
page = find_page_or_file_from_path(link)
|
225
|
+
end
|
226
|
+
presence = :page_present if page
|
227
|
+
|
228
|
+
if pretty_name
|
229
|
+
name = pretty_name
|
230
|
+
else
|
231
|
+
name = page ? path_to_link_text(link) : link
|
222
232
|
end
|
223
|
-
presence = :page_present if page
|
224
233
|
|
225
|
-
|
226
|
-
link = page ? page.escaped_url_path : CGI.escape(link)
|
234
|
+
link = page ? page.escaped_url_path : ERB::Util.url_encode(link).force_encoding('utf-8')
|
227
235
|
generate_link(link, name, extra, presence)
|
228
236
|
end
|
229
237
|
|
@@ -232,15 +240,15 @@ class Gollum::Filter::Tags < Gollum::Filter
|
|
232
240
|
# path - The String path to search for.
|
233
241
|
#
|
234
242
|
# Returns a Gollum::Page instance if a page is found, or nil otherwise
|
235
|
-
def
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
243
|
+
def find_page_or_file_from_path(path, kind = :page)
|
244
|
+
if Pathname.new(path).relative?
|
245
|
+
result = @markup.wiki.send(kind, ::File.join(@markup.dir, path))
|
246
|
+
if result.nil? && @markup.wiki.global_tag_lookup # 4.x link compatibility option. Slow!
|
247
|
+
result = @markup.wiki.send(kind, path, nil, true)
|
248
|
+
end
|
249
|
+
result
|
242
250
|
else
|
243
|
-
@markup.wiki.
|
251
|
+
@markup.wiki.send(kind, path)
|
244
252
|
end
|
245
253
|
end
|
246
254
|
|
@@ -264,7 +272,8 @@ class Gollum::Filter::Tags < Gollum::Filter
|
|
264
272
|
#
|
265
273
|
# Returns a String href.
|
266
274
|
def generate_href_for_path(path, extra = nil)
|
267
|
-
|
275
|
+
return extra if !path && extra # Internal anchor link
|
276
|
+
"#{trim_leading_slashes(::File.join(@markup.wiki.base_path, path))}#{extra}"
|
268
277
|
end
|
269
278
|
|
270
279
|
# Construct a CSS class and attribute string for different kinds of links: internal Pages (absent or present) and Files, and External links.
|
@@ -278,6 +287,8 @@ class Gollum::Filter::Tags < Gollum::Filter
|
|
278
287
|
'class="internal absent"'
|
279
288
|
when :page_present
|
280
289
|
'class="internal present"'
|
290
|
+
when :internal_anchor
|
291
|
+
'class="internal anchorlink"'
|
281
292
|
when :file
|
282
293
|
nil
|
283
294
|
when :external
|
@@ -299,10 +310,10 @@ class Gollum::Filter::Tags < Gollum::Filter
|
|
299
310
|
attr_string = attrs.map {|key, value| "#{key}=\"#{value}\""}.join(' ')
|
300
311
|
|
301
312
|
if containered
|
302
|
-
%{<span class="#{classes.join(' ')}">} +
|
303
|
-
%{<span>} +
|
313
|
+
%{<span class="d-flex #{classes[:container].join(' ')}">} +
|
314
|
+
%{<span class="#{classes[:nested].join(' ')}">} +
|
304
315
|
%{<img src="#{path}" #{attr_string}/>} +
|
305
|
-
(attrs[:alt] ? %{<span>#{attrs[:alt]}</span>} : '') +
|
316
|
+
(options[:frame] && attrs[:alt] ? %{<span class="clearfix">#{attrs[:alt]}</span>} : '') +
|
306
317
|
%{</span>} +
|
307
318
|
%{</span>}
|
308
319
|
else
|
@@ -314,31 +325,31 @@ class Gollum::Filter::Tags < Gollum::Filter
|
|
314
325
|
#
|
315
326
|
# options - The Hash of parsed image options.
|
316
327
|
#
|
317
|
-
# Returns
|
328
|
+
# Returns a Hash containing CSS class Arrays, a Hash of CSS attributes, and a Boolean indicating whether or not the image is containered.
|
318
329
|
def generate_image_attributes(options)
|
319
330
|
containered = false
|
320
|
-
classes = [] # applied to
|
331
|
+
classes = {container: [], nested: []} # applied to the container(s)
|
321
332
|
attrs = {} # applied to the image
|
322
333
|
|
323
334
|
align = options[:align]
|
324
335
|
if options[:float]
|
325
336
|
containered = true
|
326
|
-
align
|
327
|
-
|
328
|
-
classes << "float-#{align}"
|
329
|
-
end
|
337
|
+
align = 'left' unless align == 'right'
|
338
|
+
classes[:container] << "float-#{align} pb-4"
|
330
339
|
elsif %w{top texttop middle absmiddle bottom absbottom baseline}.include?(align)
|
331
340
|
attrs[:align] = align
|
332
341
|
elsif align
|
333
342
|
if %w{left center right}.include?(align)
|
334
343
|
containered = true
|
335
|
-
|
344
|
+
text_align = "text-#{align}"
|
345
|
+
align = 'end' if align == 'right'
|
346
|
+
classes[:container] << "flex-justify-#{align} #{text_align}"
|
336
347
|
end
|
337
348
|
end
|
338
349
|
|
339
|
-
if options[:frame]
|
350
|
+
if options[:frame]
|
340
351
|
containered = true
|
341
|
-
classes << '
|
352
|
+
classes[:nested] << 'border p-4'
|
342
353
|
end
|
343
354
|
|
344
355
|
attrs[:alt] = options[:alt] if options[:alt]
|
@@ -21,15 +21,14 @@ class Gollum::Filter::TOC < Gollum::Filter
|
|
21
21
|
next if (i == 0 && header.name =~ /[Hh]1/) && @markup.wiki && @markup.wiki.h1_title
|
22
22
|
|
23
23
|
anchor_name = generate_anchor_name(header)
|
24
|
-
|
25
24
|
add_anchor_to_header header, anchor_name
|
26
25
|
add_entry_to_toc header, anchor_name
|
27
26
|
end
|
28
27
|
if not @toc_doc.nil?
|
29
|
-
toc_str = @toc_doc.to_xml(@markup.to_xml_opts)
|
28
|
+
toc_str = @toc_doc.to_xml(@markup.class.to_xml_opts)
|
30
29
|
end
|
31
30
|
|
32
|
-
data = @doc.to_xml(@markup.to_xml_opts)
|
31
|
+
data = @doc.to_xml(@markup.class.to_xml_opts)
|
33
32
|
end
|
34
33
|
|
35
34
|
@markup.toc = toc_str
|
@@ -51,7 +50,7 @@ class Gollum::Filter::TOC < Gollum::Filter
|
|
51
50
|
e.remove
|
52
51
|
end
|
53
52
|
end
|
54
|
-
toc_clone.to_xml(@markup.to_xml_opts)
|
53
|
+
toc_clone.to_xml(@markup.class.to_xml_opts)
|
55
54
|
end
|
56
55
|
end
|
57
56
|
|
@@ -60,9 +59,9 @@ class Gollum::Filter::TOC < Gollum::Filter
|
|
60
59
|
|
61
60
|
private
|
62
61
|
|
63
|
-
# Generates the anchor name from the given header element
|
62
|
+
# Generates the anchor name from the given header element
|
64
63
|
# removing all non alphanumeric characters, replacing them
|
65
|
-
# with single dashes.
|
64
|
+
# with single dashes.
|
66
65
|
#
|
67
66
|
# Generates heading ancestry prefixing the headings
|
68
67
|
# ancestor names to the generated name.
|
@@ -70,31 +69,28 @@ class Gollum::Filter::TOC < Gollum::Filter
|
|
70
69
|
# Prefixes duplicate anchors with an index
|
71
70
|
def generate_anchor_name(header)
|
72
71
|
name = header.content
|
73
|
-
level = header.name
|
72
|
+
level = header.name[1..-1].to_i
|
74
73
|
|
75
74
|
# normalize the header name
|
76
|
-
name.gsub!(/[^\d\w\u00C0-\u1FFF\u2C00-\uD7FF]/,
|
77
|
-
name.gsub!(/-+/,
|
78
|
-
name.gsub!(/^-/,
|
79
|
-
name.gsub!(/-$/,
|
75
|
+
name.gsub!(/[^\d\w\u00C0-\u1FFF\u2C00-\uD7FF]/, '-')
|
76
|
+
name.gsub!(/-+/, '-')
|
77
|
+
name.gsub!(/^-/, '')
|
78
|
+
name.gsub!(/-$/, '')
|
80
79
|
name.downcase!
|
81
80
|
|
82
|
-
@current_ancestors[level - 1] = name
|
83
|
-
@current_ancestors = @current_ancestors.take(level)
|
84
|
-
anchor_name = @current_ancestors.compact.join("_")
|
85
|
-
|
86
81
|
# Ensure duplicate anchors have a unique prefix or the toc will break
|
87
|
-
index = increment_anchor_index(
|
88
|
-
|
89
|
-
|
90
|
-
anchor_name
|
82
|
+
index = increment_anchor_index(name)
|
83
|
+
index.zero? ? name : "#{name}-#{index}"
|
91
84
|
end
|
92
85
|
|
93
86
|
# Creates an anchor element with the given name and adds it before
|
94
87
|
# the given header element.
|
95
88
|
def add_anchor_to_header(header, name)
|
96
|
-
|
97
|
-
|
89
|
+
a = Nokogiri::XML::Node.new('a', @doc)
|
90
|
+
a['class'] = 'anchor'
|
91
|
+
a['id'] = name
|
92
|
+
a['href'] = "##{name}"
|
93
|
+
header.children.before(a) # Add anchor element before the header
|
98
94
|
end
|
99
95
|
|
100
96
|
# Adds an entry to the TOC for the given header. The generated entry
|
@@ -10,7 +10,7 @@ class Gollum::Filter::YAML < Gollum::Filter
|
|
10
10
|
data.gsub!(YAML_FRONT_MATTER_REGEXP) do
|
11
11
|
@markup.metadata ||= {}
|
12
12
|
begin
|
13
|
-
frontmatter = ::YAML.safe_load(
|
13
|
+
frontmatter = ::YAML.safe_load(sanitize(Regexp.last_match[1]))
|
14
14
|
@markup.metadata.merge!(frontmatter) if frontmatter.respond_to?(:keys) && frontmatter.respond_to?(:values)
|
15
15
|
rescue ::Psych::SyntaxError, ::Psych::DisallowedClass, ::Psych::BadAlias => error
|
16
16
|
@markup.metadata['errors'] ||= []
|