gollum-lib 5.0.a.4 → 5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +2 -1
- data/README.md +12 -7
- data/Rakefile +5 -5
- data/adapter_dependencies.rb +7 -0
- data/gemspec.rb +18 -10
- data/gollum-lib.gemspec +2 -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 +22 -60
- 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 +10 -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 -47
- 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/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/warn.rb +11 -0
- data/lib/gollum-lib/markup.rb +17 -32
- data/lib/gollum-lib/markups.rb +11 -7
- data/lib/gollum-lib/page.rb +79 -165
- data/lib/gollum-lib/pagination.rb +7 -6
- data/lib/gollum-lib/redirects.rb +38 -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 +73 -28
- data/ROADMAP +0 -6
@@ -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'] ||= []
|
@@ -218,30 +218,5 @@ module Gollum
|
|
218
218
|
cache = instance_variable_get("@#{name}_map")
|
219
219
|
cache[key] = value || :_nil
|
220
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}")) }
|
244
|
-
path
|
245
|
-
end
|
246
221
|
end
|
247
222
|
end
|
data/lib/gollum-lib/helpers.rb
CHANGED
@@ -1,13 +1,23 @@
|
|
1
1
|
# ~*~ encoding: utf-8 ~*~
|
2
|
+
|
2
3
|
module Gollum
|
3
4
|
module Helpers
|
4
|
-
|
5
|
-
|
6
|
-
|
5
|
+
|
6
|
+
# If url starts with a leading slash, trim down its number of leading slashes to 1. Else, return url unchanged.
|
7
|
+
def trim_leading_slashes(url)
|
8
|
+
return nil if url.nil?
|
7
9
|
url.gsub!('%2F', '/')
|
8
10
|
return '/' + url.gsub(/^\/+/, '') if url[0, 1] == '/'
|
9
11
|
url
|
10
12
|
end
|
13
|
+
|
14
|
+
# Take a link path and turn it into a string for display as link text.
|
15
|
+
# For example:
|
16
|
+
# '/opt/local/bin/ruby.ext' -> 'ruby'
|
17
|
+
def path_to_link_text(str)
|
18
|
+
return nil unless str
|
19
|
+
::File.basename(str, ::File.extname(str))
|
20
|
+
end
|
11
21
|
|
12
22
|
end
|
13
23
|
end
|
@@ -3,7 +3,8 @@ module Gollum
|
|
3
3
|
class GlobalTOC < Gollum::Macro
|
4
4
|
def render(title = "Global Table of Contents")
|
5
5
|
if @wiki.pages.size > 0
|
6
|
-
|
6
|
+
prepath = @wiki.base_path.sub(/\/$/, '')
|
7
|
+
result = '<ul>' + @wiki.pages.map { |p| "<li><a href=\"#{prepath}/#{p.escaped_url_path}\">#{p.url_path}</a></li>" }.join + '</ul>'
|
7
8
|
end
|
8
9
|
"<div class=\"toc\"><div class=\"toc-title\">#{title}</div>#{result}</div>"
|
9
10
|
end
|
@@ -2,12 +2,14 @@ module Gollum
|
|
2
2
|
class Macro
|
3
3
|
class Navigation < Gollum::Macro
|
4
4
|
|
5
|
-
def render(title = "Navigate
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
5
|
+
def render(title = "Navigate this directory", toc_root_path = ::File.dirname(@page.url_path), full_path = false)
|
6
|
+
pages = @wiki.pages
|
7
|
+
if pages.size > 0
|
8
|
+
prepath=@wiki.base_path.sub(/\/$/, '')
|
9
|
+
list_items = pages.map do |page|
|
10
|
+
if toc_root_path == '.' || page.url_path =~ /^#{toc_root_path}\//
|
11
|
+
path_display = (full_path || toc_root_path == '.') ? page.url_path : page.url_path.sub(/^#{toc_root_path}\//,"").sub(/^\//,'')
|
12
|
+
"<li><a href=\"#{prepath}/#{page.escaped_url_path}\">#{path_display}</a></li>"
|
11
13
|
end
|
12
14
|
end
|
13
15
|
result = "<ul>#{list_items.join}</ul>"
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Gollum
|
2
|
+
class Macro
|
3
|
+
class Note < Gollum::Macro
|
4
|
+
def render(notice, octicon = 'info')
|
5
|
+
icon = ""
|
6
|
+
unless octicon.empty?
|
7
|
+
begin
|
8
|
+
icon = Octicons::Octicon.new(octicon, {width: 24, height: 24})
|
9
|
+
rescue RuntimeError
|
10
|
+
icon = Octicons::Octicon.new('info', {width: 24, height: 24})
|
11
|
+
end
|
12
|
+
icon.options[:class] << ' mr-2'
|
13
|
+
icon = icon.to_svg
|
14
|
+
end
|
15
|
+
"<div class='flash'>#{icon}#{notice}</div>"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Gollum
|
2
|
+
class Macro
|
3
|
+
class Octicon < Gollum::Macro
|
4
|
+
def render(symbol, height = nil, width = nil)
|
5
|
+
parameters = {}
|
6
|
+
parameters[:height] = height if height
|
7
|
+
parameters[:width] = width if width
|
8
|
+
"<div>#{Octicons::Octicon.new(symbol, parameters).to_svg}</div>"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Gollum
|
2
|
+
class Macro
|
3
|
+
class Warn < Gollum::Macro
|
4
|
+
def render(warning)
|
5
|
+
icon = Octicons::Octicon.new('alert', {width: 24, height: 24})
|
6
|
+
icon.options[:class] << ' mr-2'
|
7
|
+
"<div class='flash flash-warn'>#{icon.to_svg}#{warning}</div>"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
data/lib/gollum-lib/markup.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# ~*~ encoding: utf-8 ~*~
|
2
2
|
require 'digest/sha1'
|
3
|
-
require 'cgi'
|
4
3
|
require 'rouge'
|
5
4
|
require 'base64'
|
6
5
|
|
@@ -23,6 +22,10 @@ module Gollum
|
|
23
22
|
|
24
23
|
class << self
|
25
24
|
|
25
|
+
def to_xml_opts
|
26
|
+
{ :save_with => Nokogiri::XML::Node::SaveOptions::DEFAULT_XHTML ^ 1, :indent => 0, :encoding => 'UTF-8' }
|
27
|
+
end
|
28
|
+
|
26
29
|
# Only use the formats that are specified in config.rb
|
27
30
|
def formats
|
28
31
|
if defined? Gollum::Page::FORMAT_NAMES
|
@@ -66,7 +69,6 @@ module Gollum
|
|
66
69
|
attr_accessor :toc
|
67
70
|
attr_accessor :metadata
|
68
71
|
attr_reader :encoding
|
69
|
-
attr_reader :sanitize
|
70
72
|
attr_reader :format
|
71
73
|
attr_reader :wiki
|
72
74
|
attr_reader :page
|
@@ -74,8 +76,8 @@ module Gollum
|
|
74
76
|
attr_reader :sub_page
|
75
77
|
attr_reader :name
|
76
78
|
attr_reader :include_levels
|
77
|
-
attr_reader :to_xml_opts
|
78
79
|
attr_reader :dir
|
80
|
+
attr_reader :historical
|
79
81
|
|
80
82
|
# Initialize a new Markup object.
|
81
83
|
#
|
@@ -91,9 +93,8 @@ module Gollum
|
|
91
93
|
@sub_page = page.sub_page
|
92
94
|
@parent_page = page.parent_page
|
93
95
|
@page = page
|
94
|
-
@dir = ::File.dirname(page.
|
96
|
+
@dir = ::File.dirname("/#{@page.url_path}")
|
95
97
|
@metadata = nil
|
96
|
-
@to_xml_opts = { :save_with => Nokogiri::XML::Node::SaveOptions::DEFAULT_XHTML ^ 1, :indent => 0, :encoding => 'UTF-8' }
|
97
98
|
end
|
98
99
|
|
99
100
|
# Whether or not this markup's format uses reversed-order links ([description | url] rather than [url | description]). Defaults to false.
|
@@ -124,6 +125,11 @@ module Gollum
|
|
124
125
|
data = filter.extract(data)
|
125
126
|
end
|
126
127
|
|
128
|
+
# Since the last 'extract' action in our chain *should* be the markup
|
129
|
+
# to HTML converter, we now have HTML which we can parse and yield, for
|
130
|
+
# anyone who wants it
|
131
|
+
yield Nokogiri::HTML::DocumentFragment.parse(data) if block_given?
|
132
|
+
|
127
133
|
# Then we process the data through the chain *backwards*
|
128
134
|
filter_chain.reverse.each do |filter|
|
129
135
|
data = filter.process(data)
|
@@ -133,48 +139,27 @@ module Gollum
|
|
133
139
|
end
|
134
140
|
|
135
141
|
# Render the content with Gollum wiki syntax on top of the file's own
|
136
|
-
# markup language.
|
142
|
+
# markup language. Takes an optional block that will be executed after
|
143
|
+
# the markup rendering step in the filter chain.
|
137
144
|
#
|
138
145
|
# no_follow - Boolean that determines if rel="nofollow" is added to all
|
139
146
|
# <a> tags.
|
140
147
|
# encoding - Encoding Constant or String.
|
141
148
|
#
|
142
149
|
# Returns the formatted String content.
|
143
|
-
def render(no_follow = false, encoding = nil, include_levels = 10)
|
144
|
-
@
|
145
|
-
|
150
|
+
def render(no_follow = false, encoding = nil, include_levels = 10, &block)
|
151
|
+
@historical = no_follow
|
146
152
|
@encoding = encoding
|
147
153
|
@include_levels = include_levels
|
148
154
|
|
149
|
-
data
|
155
|
+
data = @data.dup
|
150
156
|
|
151
157
|
filter_chain = @wiki.filter_chain.reject {|filter| skip_filter?(filter)}
|
152
158
|
filter_chain.map! do |filter_sym|
|
153
159
|
Gollum::Filter.const_get(filter_sym).new(self)
|
154
160
|
end
|
155
161
|
|
156
|
-
|
157
|
-
# to HTML converter, we now have HTML which we can parse and yield, for
|
158
|
-
# anyone who wants it
|
159
|
-
if block_given?
|
160
|
-
yield Nokogiri::HTML::DocumentFragment.parse(data)
|
161
|
-
end
|
162
|
-
|
163
|
-
process_chain data, filter_chain
|
164
|
-
end
|
165
|
-
|
166
|
-
# Find the given file in the repo.
|
167
|
-
#
|
168
|
-
# name - The String absolute or relative path of the file.
|
169
|
-
#
|
170
|
-
# Returns the Gollum::File or nil if none was found.
|
171
|
-
def find_file(name, version=@version)
|
172
|
-
if name =~ /^\//
|
173
|
-
@wiki.file(name[1..-1], version)
|
174
|
-
else
|
175
|
-
path = @dir == '.' ? name : ::File.join(@dir, name)
|
176
|
-
@wiki.file(path, version)
|
177
|
-
end
|
162
|
+
process_chain(data, filter_chain, &block)
|
178
163
|
end
|
179
164
|
|
180
165
|
# Hook for getting the formatted value of extracted tag data.
|
data/lib/gollum-lib/markups.rb
CHANGED
@@ -55,12 +55,16 @@ end
|
|
55
55
|
|
56
56
|
module Gollum
|
57
57
|
class Markup
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
58
|
+
if gem_exists?('pandoc-ruby')
|
59
|
+
GitHub::Markup::Markdown::MARKDOWN_GEMS.delete('kramdown')
|
60
|
+
GitHub::Markup::Markdown::MARKDOWN_GEMS['pandoc-ruby'] = proc { |content|
|
61
|
+
PandocRuby.convert(content, :from => :markdown, :to => :html, :filter => 'pandoc-citeproc')
|
62
|
+
}
|
63
|
+
else
|
64
|
+
GitHub::Markup::Markdown::MARKDOWN_GEMS['kramdown'] = proc { |content|
|
65
|
+
Kramdown::Document.new(content, :input => "GFM", :hard_wrap => 'false', :auto_ids => false, :math_engine => nil, :smart_quotes => ["'", "'", '"', '"'].map{|char| char.codepoints.first}).to_html
|
66
|
+
}
|
67
|
+
end
|
64
68
|
|
65
69
|
# markdown, rdoc, and plain text are always supported.
|
66
70
|
register(:markdown, "Markdown", :extensions => ['md','mkd','mkdn','mdown','markdown'])
|
@@ -76,7 +80,7 @@ module Gollum
|
|
76
80
|
register(:creole, "Creole",
|
77
81
|
:enabled => MarkupRegisterUtils::gem_exists?("creole"),
|
78
82
|
:reverse_links => true)
|
79
|
-
register(:
|
83
|
+
register(:rst, "reStructuredText",
|
80
84
|
:enabled => MarkupRegisterUtils::executable_exists?("python2"),
|
81
85
|
:extensions => ['rest', 'rst'])
|
82
86
|
register(:asciidoc, "AsciiDoc",
|
data/lib/gollum-lib/page.rb
CHANGED
@@ -1,21 +1,28 @@
|
|
1
1
|
# ~*~ encoding: utf-8 ~*~
|
2
2
|
module Gollum
|
3
|
-
class Page
|
3
|
+
class Page < Gollum::File
|
4
4
|
include Pagination
|
5
|
-
|
6
|
-
Wiki.page_class = self
|
7
5
|
|
8
6
|
SUBPAGENAMES = [:header, :footer, :sidebar]
|
9
|
-
|
10
|
-
# Sets a Boolean determing whether this page is a historical version.
|
11
|
-
#
|
12
|
-
# Returns nothing.
|
13
|
-
attr_writer :historical
|
14
7
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
8
|
+
class << self
|
9
|
+
# For use with self.find: returns true if the given query corresponds to the in-repo path of the BlobEntry.
|
10
|
+
#
|
11
|
+
# query - The String path to match.
|
12
|
+
# entry - The BlobEntry to check against.
|
13
|
+
# global_match - If true, find a File matching path's filename, but not its directory (so anywhere in the repo)
|
14
|
+
def path_match(query, entry, global_match = false, hyphened_tags = false, case_insensitive = false)
|
15
|
+
return false if "#{entry.name}".empty?
|
16
|
+
return false unless valid_extension?(entry.name)
|
17
|
+
entry_name = valid_extension?(query) ? entry.name : strip_filename(entry.name)
|
18
|
+
match_path = ::File.join([
|
19
|
+
'/',
|
20
|
+
global_match ? nil : entry.dir,
|
21
|
+
entry_name
|
22
|
+
].compact)
|
23
|
+
path_compare(query, match_path, hyphened_tags, case_insensitive)
|
24
|
+
end
|
25
|
+
end
|
19
26
|
|
20
27
|
# Checks if a filename has a valid, registered extension
|
21
28
|
#
|
@@ -27,14 +34,14 @@ module Gollum
|
|
27
34
|
end
|
28
35
|
|
29
36
|
# Checks if a filename has a valid extension understood by GitHub::Markup.
|
30
|
-
# Also, checks if the filename
|
31
|
-
# _Footer.md).
|
37
|
+
# Also, checks if the filename is subpages (such as _Footer.md).
|
32
38
|
#
|
33
39
|
# filename - String filename, like "Home.md".
|
34
40
|
#
|
35
41
|
# Returns true or false.
|
36
42
|
def self.valid_page_name?(filename)
|
37
|
-
|
43
|
+
subpage_names = SUBPAGENAMES.map(&:capitalize).join("|")
|
44
|
+
filename =~ /^_(#{subpage_names})/ ? false : self.valid_extension?(filename)
|
38
45
|
end
|
39
46
|
|
40
47
|
# Public: The format of a given filename.
|
@@ -59,32 +66,27 @@ module Gollum
|
|
59
66
|
::File.basename(filename.to_s, ::File.extname(filename.to_s))
|
60
67
|
end
|
61
68
|
|
62
|
-
# Public: Initialize a
|
69
|
+
# Public: Initialize a Page.
|
63
70
|
#
|
64
|
-
# wiki - The Gollum::Wiki
|
71
|
+
# wiki - The Gollum::Wiki
|
72
|
+
# blob - The Gollum::Git::Blob
|
73
|
+
# path - The String path
|
74
|
+
# version - The String SHA or Gollum::Git::Commit version
|
75
|
+
# try_on_disk - If true, try to get an on disk reference for this page.
|
65
76
|
#
|
66
77
|
# Returns a newly initialized Gollum::Page.
|
67
|
-
def initialize(wiki)
|
68
|
-
|
69
|
-
@blob = nil
|
78
|
+
def initialize(wiki, blob, path, version, try_on_disk = false)
|
79
|
+
super
|
70
80
|
@formatted_data = nil
|
71
81
|
@doc = nil
|
72
82
|
@parent_page = nil
|
83
|
+
@historical = @version.to_s == version.to_s
|
73
84
|
end
|
74
85
|
|
75
|
-
#
|
76
|
-
#
|
77
|
-
# Returns the String SHA.
|
78
|
-
def sha
|
79
|
-
@blob && @blob.id
|
80
|
-
end
|
81
|
-
|
82
|
-
# Public: The on-disk filename of the page including extension.
|
86
|
+
# Parent page if this is a sub page
|
83
87
|
#
|
84
|
-
# Returns
|
85
|
-
|
86
|
-
@blob && @blob.name
|
87
|
-
end
|
88
|
+
# Returns a Page
|
89
|
+
attr_accessor :parent_page
|
88
90
|
|
89
91
|
# Public: The on-disk filename of the page with extension stripped.
|
90
92
|
#
|
@@ -105,7 +107,7 @@ module Gollum
|
|
105
107
|
#
|
106
108
|
# Returns the fully sanitized String title.
|
107
109
|
def title
|
108
|
-
|
110
|
+
@wiki.sanitizer.clean(name).strip
|
109
111
|
end
|
110
112
|
|
111
113
|
# Public: Determines if this is a sub-page
|
@@ -116,30 +118,11 @@ module Gollum
|
|
116
118
|
filename =~ /^_/
|
117
119
|
end
|
118
120
|
|
119
|
-
# Public: The path of the page within the repo.
|
120
|
-
#
|
121
|
-
# Returns the String path.
|
122
|
-
attr_reader :path
|
123
|
-
|
124
|
-
# Public: The url path required to reach this page within the repo.
|
125
|
-
#
|
126
|
-
# Returns the String url_path
|
127
|
-
def url_path
|
128
|
-
construct_path(filename)
|
129
|
-
end
|
130
|
-
|
131
121
|
# Public: Defines title for page.rb
|
132
122
|
#
|
133
123
|
# Returns the String title
|
134
124
|
def url_path_title
|
135
|
-
metadata_title ||
|
136
|
-
end
|
137
|
-
|
138
|
-
# Public: The url_path, but CGI escaped.
|
139
|
-
#
|
140
|
-
# Returns the String url_path
|
141
|
-
def escaped_url_path
|
142
|
-
CGI.escape(self.url_path).gsub('%2F', '/')
|
125
|
+
metadata_title || name
|
143
126
|
end
|
144
127
|
|
145
128
|
# Public: Metadata title
|
@@ -148,35 +131,16 @@ module Gollum
|
|
148
131
|
#
|
149
132
|
# Returns the String title or nil if not defined
|
150
133
|
def metadata_title
|
151
|
-
|
152
|
-
title = metadata['title']
|
153
|
-
return title unless title.nil?
|
154
|
-
end
|
155
|
-
|
156
|
-
nil
|
134
|
+
metadata ? metadata['title'] : nil
|
157
135
|
end
|
158
136
|
|
159
137
|
# Public: Whether or not to display the metadata
|
160
138
|
def display_metadata?
|
161
|
-
return false if
|
139
|
+
return false if (metadata.keys - ['title', 'header_enum']).empty?
|
162
140
|
return false if metadata['display_metadata'] == false
|
163
141
|
@wiki.display_metadata
|
164
142
|
end
|
165
143
|
|
166
|
-
# Public: The raw contents of the page.
|
167
|
-
#
|
168
|
-
# Returns the String data.
|
169
|
-
def raw_data
|
170
|
-
return nil unless @blob
|
171
|
-
|
172
|
-
if !@wiki.repo.bare && @blob.is_symlink
|
173
|
-
new_path = @blob.symlink_target(::File.join(@wiki.repo.path, '..', self.path))
|
174
|
-
return IO.read(new_path) if new_path
|
175
|
-
end
|
176
|
-
|
177
|
-
@blob.data
|
178
|
-
end
|
179
|
-
|
180
144
|
# Public: A text data encoded in specified encoding.
|
181
145
|
#
|
182
146
|
# encoding - An Encoding or nil
|
@@ -225,8 +189,12 @@ module Gollum
|
|
225
189
|
#
|
226
190
|
# Returns Hash of metadata.
|
227
191
|
def metadata
|
228
|
-
|
229
|
-
|
192
|
+
unless @metadata
|
193
|
+
formatted_data if markup.metadata == nil
|
194
|
+
@metadata = @wiki.metadata.merge(markup.metadata || {})
|
195
|
+
else
|
196
|
+
@metadata
|
197
|
+
end
|
230
198
|
end
|
231
199
|
|
232
200
|
# Public: The format of the page.
|
@@ -240,20 +208,15 @@ module Gollum
|
|
240
208
|
#
|
241
209
|
# Returns a Gollum::Markup instance.
|
242
210
|
def markup
|
243
|
-
@markup ||=
|
211
|
+
@markup ||= ::Gollum::Markup.new(self)
|
244
212
|
end
|
245
213
|
|
246
|
-
# Public: The current version of the page.
|
247
|
-
#
|
248
|
-
# Returns the Gollum::Git::Commit.
|
249
|
-
attr_reader :version
|
250
|
-
|
251
214
|
# Public: All of the versions that have touched the Page.
|
252
215
|
#
|
253
216
|
# options - The options Hash:
|
254
|
-
# :
|
255
|
-
# :per_page
|
256
|
-
# :follow
|
217
|
+
# :page_num - The Integer page number (default: 1).
|
218
|
+
# :per_page - The Integer max count of items to return.
|
219
|
+
# :follow - Follow's a file across renames, slower. (default: false)
|
257
220
|
#
|
258
221
|
# Returns an Array of Gollum::Git::Commit.
|
259
222
|
def versions(options = {})
|
@@ -317,77 +280,11 @@ module Gollum
|
|
317
280
|
format == :markdown ? "md" : format.to_s
|
318
281
|
end
|
319
282
|
|
320
|
-
#########################################################################
|
321
|
-
#
|
322
|
-
# Internal Methods
|
323
|
-
#
|
324
|
-
#########################################################################
|
325
|
-
|
326
283
|
# The underlying wiki repo.
|
327
284
|
#
|
328
285
|
# Returns the Gollum::Wiki containing the page.
|
329
286
|
attr_reader :wiki
|
330
287
|
|
331
|
-
# Set the Gollum::Git::Commit version of the page.
|
332
|
-
#
|
333
|
-
# Returns nothing.
|
334
|
-
attr_writer :version
|
335
|
-
|
336
|
-
# Find a page in the given Gollum repo.
|
337
|
-
#
|
338
|
-
# name - The human or canonical String page name to find.
|
339
|
-
# version - The String version ID to find.
|
340
|
-
#
|
341
|
-
# Returns a Gollum::Page or nil if the page could not be found.
|
342
|
-
def find(name, version, dir = nil, exact = false)
|
343
|
-
map = @wiki.tree_map_for(version.to_s)
|
344
|
-
if (page = find_page_in_tree(map, name, dir, exact))
|
345
|
-
page.version = version.is_a?(Gollum::Git::Commit) ?
|
346
|
-
version : @wiki.commit_for(version)
|
347
|
-
page.historical = page.version.to_s == version.to_s
|
348
|
-
page
|
349
|
-
end
|
350
|
-
rescue Gollum::Git::NoSuchShaFound
|
351
|
-
end
|
352
|
-
|
353
|
-
# Find a page in a given tree.
|
354
|
-
#
|
355
|
-
# map - The Array tree map from Wiki#tree_map.
|
356
|
-
# name - The canonical String page name.
|
357
|
-
# checked_dir - Optional String of the directory a matching page needs
|
358
|
-
# to be in. The string should
|
359
|
-
#
|
360
|
-
# Returns a Gollum::Page or nil if the page could not be found.
|
361
|
-
def find_page_in_tree(map, name, checked_dir = nil, exact = false)
|
362
|
-
return nil if !map || name.to_s.empty?
|
363
|
-
|
364
|
-
checked_dir = BlobEntry.normalize_dir(checked_dir)
|
365
|
-
checked_dir = '' if exact && checked_dir.nil?
|
366
|
-
query = checked_dir ? ::File.join(checked_dir, name) : name
|
367
|
-
|
368
|
-
map.each do |entry|
|
369
|
-
next if entry.name.to_s.empty? || !self.class.valid_extension?(entry.name)
|
370
|
-
entry_name = ::File.extname(name).empty? ? ::Gollum::Page.strip_filename(entry.name) : entry.name
|
371
|
-
path = checked_dir ? ::File.join(entry.dir, entry_name) : entry_name
|
372
|
-
next unless query.downcase == path.downcase
|
373
|
-
return entry.page(@wiki, @version)
|
374
|
-
end
|
375
|
-
|
376
|
-
return nil # nothing was found
|
377
|
-
end
|
378
|
-
|
379
|
-
# Populate the Page with information from the Blob.
|
380
|
-
#
|
381
|
-
# blob - The Gollum::Git::Blob that contains the info.
|
382
|
-
# path - The String directory path of the page file.
|
383
|
-
#
|
384
|
-
# Returns the populated Gollum::Page.
|
385
|
-
def populate(blob, path=nil)
|
386
|
-
@blob = blob
|
387
|
-
@path = "#{path}/#{blob.name}"[1..-1]
|
388
|
-
self
|
389
|
-
end
|
390
|
-
|
391
288
|
# The full directory path for the given tree.
|
392
289
|
#
|
393
290
|
# treemap - The Hash treemap containing parentage information.
|
@@ -396,7 +293,7 @@ module Gollum
|
|
396
293
|
# Returns the String path.
|
397
294
|
def tree_path(treemap, tree)
|
398
295
|
if (ptree = treemap[tree])
|
399
|
-
tree_path(treemap, ptree)
|
296
|
+
"#{tree_path(treemap, ptree)}#{::File::SEPARATOR}#{tree.name}"
|
400
297
|
else
|
401
298
|
''
|
402
299
|
end
|
@@ -409,7 +306,7 @@ module Gollum
|
|
409
306
|
def find_sub_pages(subpagenames = SUBPAGENAMES, map = nil)
|
410
307
|
subpagenames.each{|subpagename| instance_variable_set("@#{subpagename}", nil)}
|
411
308
|
return nil if self.filename =~ /^_/ || ! self.version
|
412
|
-
|
309
|
+
|
413
310
|
map ||= @wiki.tree_map_for(@wiki.ref, true)
|
414
311
|
valid_names = subpagenames.map(&:capitalize).join("|")
|
415
312
|
# From Ruby 2.2 onwards map.select! could be used
|
@@ -425,34 +322,51 @@ module Gollum
|
|
425
322
|
searchpath = dir == Pathname.new('.') ? Pathname.new(filename) : dir + filename
|
426
323
|
entrypath = ::Pathname.new(blob_entry.path)
|
427
324
|
# Ignore extentions
|
428
|
-
entrypath = entrypath.dirname + entrypath.basename(entrypath.extname)
|
325
|
+
entrypath = entrypath.dirname + entrypath.basename(entrypath.extname)
|
429
326
|
entrypath == searchpath
|
430
327
|
end
|
431
|
-
|
328
|
+
|
432
329
|
if subpageblob
|
433
330
|
instance_variable_set("@#{subpagename}", subpageblob.page(@wiki, @version) )
|
331
|
+
instance_variable_get("@#{subpagename}").parent_page = self
|
434
332
|
break
|
435
333
|
end
|
436
334
|
|
437
335
|
break if dir == Pathname.new('.')
|
438
336
|
end
|
439
|
-
end
|
337
|
+
end
|
440
338
|
end
|
441
339
|
|
442
340
|
def inspect
|
443
341
|
%(#<#{self.class.name}:#{object_id} #{name} (#{format}) @wiki=#{@wiki.repo.path.inspect}>)
|
444
342
|
end
|
445
343
|
|
446
|
-
|
344
|
+
end
|
447
345
|
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
346
|
+
class PreviewPage < Gollum::Page
|
347
|
+
include Pagination
|
348
|
+
|
349
|
+
SUBPAGENAMES.each do |subpage|
|
350
|
+
define_method(subpage) do
|
351
|
+
instance_variable_get("@#{subpage}")
|
352
|
+
end
|
353
|
+
define_method("set_#{subpage}") do |val|
|
354
|
+
instance_variable_set("@#{subpage}", PreviewPage.new(@wiki, "_#{subpage.to_s.capitalize}.md", val, @version, self))
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
attr_accessor :path
|
359
|
+
|
360
|
+
def initialize(wiki, name, data, version, parent_page = nil)
|
361
|
+
@wiki = wiki
|
362
|
+
@path = name
|
363
|
+
@blob = OpenStruct.new(:name => name, :data => data, :is_symlink => false)
|
364
|
+
@version = version
|
365
|
+
@formatted_data = nil
|
366
|
+
@doc = nil
|
367
|
+
@parent_page = parent_page
|
368
|
+
@historical = false
|
455
369
|
end
|
456
|
-
|
457
370
|
end
|
371
|
+
|
458
372
|
end
|