lib/gollum-lib/page.rb in gitlab-gollum-lib-1.1.0 vs lib/gollum-lib/page.rb in gitlab-gollum-lib-4.2.7

- old
+ new

@@ -2,11 +2,13 @@ module Gollum class Page include Pagination Wiki.page_class = self - + + SUBPAGENAMES = [:header, :footer, :sidebar] + # Sets a Boolean determing whether this page is a historical version. # # Returns nothing. attr_writer :historical @@ -21,11 +23,11 @@ # filename - String filename, like "Home.md" # # Returns e.g. ["Home", :markdown], or [] if the extension is unregistered def self.parse_filename(filename) return [] unless filename =~ /^(.+)\.([a-zA-Z]\w*)$/i - pref, ext = $1, $2 + pref, ext = Regexp.last_match[1], Regexp.last_match[2] Gollum::Markup.formats.each_pair do |name, format| return [pref, name] if ext =~ format[:regexp] end [] @@ -82,14 +84,15 @@ # # wiki - The Gollum::Wiki in question. # # Returns a newly initialized Gollum::Page. def initialize(wiki) - @wiki = wiki - @blob = @header = @footer = @sidebar = nil - @doc = nil - @parent_page = nil + @wiki = wiki + @blob = nil + @formatted_data = nil + @doc = nil + @parent_page = nil end # Public: The on-disk filename of the page including extension. # # Returns the String name. @@ -137,24 +140,31 @@ # Public: The url path required to reach this page within the repo. # # Returns the String url_path def url_path path = if self.path.include?('/') - self.path.sub(/\/[^\/]+$/, '/') - else - '' - end + self.path.sub(/\/[^\/]+$/, '/') + else + '' + end path << Page.cname(self.name, '-', '-') path end + # Public: The display form of the url path required to reach this page within the repo. + # + # Returns the String url_path + def url_path_display + url_path.gsub("-", " ") + end + # Public: Defines title for page.rb # # Returns the String title def url_path_title - metadata_title || url_path.gsub("-", " ") + metadata_title || url_path_display end # Public: Metadata title # # Set with <!-- --- title: New Title --> in page content @@ -171,11 +181,11 @@ # Public: The url_path, but CGI escaped. # # Returns the String url_path def escaped_url_path - CGI.escape(self.url_path).gsub('%2F','/') + CGI.escape(self.url_path).gsub('%2F', '/') end # Public: The raw contents of the page. # # Returns the String data. @@ -206,32 +216,40 @@ # Public: The formatted contents of the page. # # encoding - Encoding Constant or String. # # Returns the String data. - def formatted_data(encoding = nil, &block) - @blob && markup_class.render(historical?, encoding) do |doc| - @doc = doc - yield doc if block_given? + def formatted_data(encoding = nil, include_levels = 10, &block) + return nil unless @blob + + if @formatted_data && @doc then + yield @doc if block_given? + else + @formatted_data = markup_class.render(historical?, encoding, include_levels) do |doc| + @doc = doc + yield doc if block_given? + end end + + @formatted_data end # Public: The table of contents of the page. # # formatted_data - page already marked up in html. # # Returns the String data. - def toc_data() + def toc_data return @parent_page.toc_data if @parent_page and @sub_page formatted_data if markup_class.toc == nil markup_class.toc end # Public: Embedded metadata. # # Returns Hash of metadata. - def metadata() + def metadata formatted_data if markup_class.metadata == nil markup_class.metadata end # Public: The format of the page. @@ -248,60 +266,62 @@ @markup_class ||= @wiki.markup_classes[format].new(self) end # Public: The current version of the page. # - # Returns the Grit::Commit. + # Returns the Gollum::Git::Commit. attr_reader :version # Public: All of the versions that have touched the Page. # # options - The options Hash: # :page - The Integer page number (default: 1). # :per_page - The Integer max count of items to return. - # :follow - Follow's a file across renames, but falls back - # to a slower Grit native call. (default: false) + # :follow - Follow's a file across renames, slower. (default: false) # - # Returns an Array of Grit::Commit. + # Returns an Array of Gollum::Git::Commit. def versions(options = {}) - if options[:follow] - options[:pretty] = 'raw' - options.delete :max_count - options.delete :skip - log = @wiki.repo.git.native "log", options, @wiki.ref, "--", @path - Grit::Commit.list_from_string(@wiki.repo, log) - else - @wiki.repo.log(@wiki.ref, @path, log_pagination_options(options)) - end + @wiki.repo.git.versions_for_path(@path, @wiki.ref, log_pagination_options(options)) end + # Public: The last version that has touched the Page. Can be nil. + # + # Returns Gollum::Git::Commit, or nil. + def last_version + return @last_version if defined? @last_version + @last_version = @wiki.repo.git.versions_for_path(@path, @wiki.ref, {:max_count => 1}).first + end + # Public: The first 7 characters of the current version. # # Returns the first 7 characters of the current version. - def version_short - version.to_s[0,7] - end + def version_short + version.to_s[0, 7] + end # Public: The header Page. # # Returns the header Page or nil if none exists. def header - @header ||= find_sub_page(:header) + find_sub_pages unless defined?(@header) + @header end # Public: The footer Page. # # Returns the footer Page or nil if none exists. def footer - @footer ||= find_sub_page(:footer) + find_sub_pages unless defined?(@footer) + @footer end # Public: The sidebar Page. # # Returns the sidebar Page or nil if none exists. def sidebar - @sidebar ||= find_sub_page(:sidebar) + find_sub_pages unless defined?(@sidebar) + @sidebar end # Gets a Boolean determining whether this page is a historical version. # Historical pages are pulled using exact SHA hashes and format all links # with rel="nofollow" @@ -332,12 +352,12 @@ # # => 'Bilbo_Baggins' # # Returns the String canonical name. def self.cname(name, char_white_sub = '-', char_other_sub = '-') name.respond_to?(:gsub) ? - name.gsub(%r{\s},char_white_sub).gsub(%r{[<>+]}, char_other_sub) : - '' + name.gsub(%r(\s), char_white_sub).gsub(%r([<>+]), char_other_sub) : + '' end # Convert a format Symbol into an extension String. # # format - The format Symbol. @@ -356,11 +376,11 @@ # The underlying wiki repo. # # Returns the Gollum::Wiki containing the page. attr_reader :wiki - # Set the Grit::Commit version of the page. + # Set the Gollum::Git::Commit version of the page. # # Returns nothing. attr_writer :version # Find a page in the given Gollum repo. @@ -369,17 +389,17 @@ # version - The String version ID to find. # # Returns a Gollum::Page or nil if the page could not be found. def find(name, version, dir = nil, exact = false) map = @wiki.tree_map_for(version.to_s) - if page = find_page_in_tree(map, name, dir, exact) - page.version = version.is_a?(Grit::Commit) ? - version : @wiki.commit_for(version) + if (page = find_page_in_tree(map, name, dir, exact)) + page.version = version.is_a?(Gollum::Git::Commit) ? + version : @wiki.commit_for(version) page.historical = page.version.to_s == version.to_s page end - rescue Grit::GitRuby::Repository::NoSuchShaFound + rescue Gollum::Git::NoSuchShaFound end # Find a page in a given tree. # # map - The Array tree map from Wiki#tree_map. @@ -388,29 +408,28 @@ # to be in. The string should # # Returns a Gollum::Page or nil if the page could not be found. def find_page_in_tree(map, name, checked_dir = nil, exact = false) return nil if !map || name.to_s.empty? - if checked_dir = BlobEntry.normalize_dir(checked_dir) - checked_dir.downcase! - end + checked_dir = BlobEntry.normalize_dir(checked_dir) checked_dir = '' if exact && checked_dir.nil? + name = ::File.join(checked_dir, name) if checked_dir map.each do |entry| next if entry.name.to_s.empty? - next unless checked_dir.nil? || entry.dir.downcase == checked_dir - next unless page_match(name, entry.name) + path = checked_dir ? ::File.join(entry.dir, entry.name) : entry.name + next unless page_match(name, path) return entry.page(@wiki, @version) end return nil # nothing was found end # Populate the Page with information from the Blob. # - # blob - The Grit::Blob that contains the info. + # blob - The Gollum::Git::Blob that contains the info. # path - The String directory path of the page file. # # Returns the populated Gollum::Page. def populate(blob, path=nil) @blob = blob @@ -419,67 +438,77 @@ end # The full directory path for the given tree. # # treemap - The Hash treemap containing parentage information. - # tree - The Grit::Tree for which to compute the path. + # tree - The Gollum::Git::Tree for which to compute the path. # # Returns the String path. def tree_path(treemap, tree) - if ptree = treemap[tree] + if (ptree = treemap[tree]) tree_path(treemap, ptree) + '/' + tree.name else '' end end # Compare the canonicalized versions of the two names. # # name - The human or canonical String page name. - # filename - the String filename on disk (including extension). + # path - the String path on disk (including file extension). # # Returns a Boolean. - def page_match(name, filename) - if match = self.class.valid_filename?(filename) + def page_match(name, path) + if (match = self.class.valid_filename?(path)) @wiki.ws_subs.each do |sub| return true if Page.cname(name).downcase == Page.cname(match, sub).downcase end end false end - # Loads a sub page. Sub page names (footers, headers, sidebars) are prefixed with + + # Loads sub pages. Sub page names (footers, headers, sidebars) are prefixed with # an underscore to distinguish them from other Pages. If there is not one within # the current directory, starts walking up the directory tree to try and find one # within parent directories. - # - # name - String page name. - # - # Returns the Page or nil if none exists. - def find_sub_page(name) - return nil unless self.version - return nil if self.filename =~ /^_/ - name = "_#{name.to_s.capitalize}" - return nil if page_match(name, self.filename) + def find_sub_pages(subpagenames = SUBPAGENAMES, map = nil) + subpagenames.each{|subpagename| instance_variable_set("@#{subpagename}", nil)} + return nil if self.filename =~ /^_/ || ! self.version + + map ||= @wiki.tree_map_for(@wiki.ref, true) + valid_names = subpagenames.map(&:capitalize).join("|") + # From Ruby 2.2 onwards map.select! could be used + map = map.select{|entry| entry.name =~ /^_(#{valid_names})/ } + return if map.empty? - dirs = self.path.split('/') - dirs.pop - map = @wiki.tree_map_for(@wiki.ref, true) - while !dirs.empty? - if page = find_page_in_tree(map, name, dirs.join('/')) - page.parent_page = self - return page - end - dirs.pop - end + subpagenames.each do |subpagename| + dir = ::Pathname.new(self.path) + while dir = dir.parent do + subpageblob = map.find do |blob_entry| - if page = find_page_in_tree(map, name, '') - page.parent_page = self - end - page + filename = "_#{subpagename.to_s.capitalize}" + searchpath = dir == Pathname.new('.') ? Pathname.new(filename) : dir + filename + entrypath = ::Pathname.new(blob_entry.path) + # Ignore extentions + entrypath = entrypath.dirname + entrypath.basename(entrypath.extname) + entrypath == searchpath + end + + if subpageblob + subpage = subpageblob.page(@wiki, @version) + subpage.parent_page = self + instance_variable_set("@#{subpagename}", subpage) + break + end + + break if dir == Pathname.new('.') + end + end end def inspect %(#<#{self.class.name}:#{object_id} #{name} (#{format}) @wiki=#{@wiki.repo.path.inspect}>) end + end end