diff --git a/lib/gollum.rb b/lib/gollum.rb index 5cc1e40f..c2dd3d32 100644 --- a/lib/gollum.rb +++ b/lib/gollum.rb @@ -15,6 +15,7 @@ require File.expand_path('../gollum/blob_entry', __FILE__) require File.expand_path('../gollum/wiki', __FILE__) require File.expand_path('../gollum/page', __FILE__) require File.expand_path('../gollum/file', __FILE__) +require File.expand_path('../gollum/file_view', __FILE__) require File.expand_path('../gollum/markup', __FILE__) require File.expand_path('../gollum/sanitization', __FILE__) require File.expand_path('../gollum/tex', __FILE__) diff --git a/lib/gollum/file_view.rb b/lib/gollum/file_view.rb new file mode 100644 index 00000000..4074334d --- /dev/null +++ b/lib/gollum/file_view.rb @@ -0,0 +1,155 @@ +module Gollum +=begin + FileView requires that: + - All files in root dir are processed first + - Then all the folders are sorted and processed +=end + class FileView + def initialize pages + @pages = pages + end + + def enclose_tree string + %Q(
    \n) + string + %Q(\n
) + end + + def new_page page + '' + %Q(
  • #{page.name2}
  • \n) + end + + def new_folder page + new_sub_folder ::File.dirname(page.path), page.name, page.name2 + end + + def new_sub_folder path, name, name2 + <<-HTML + +
  • + +
      +
    1. #{name2}
    2. + HTML + end + + def end_folder + <<-HTML + +
    +
  • + HTML + end + + def render_files + html = '' + count = @pages.size + folder_start = -1 + + # Process all pages until folders start + count.times do | index | + page = @pages[ index ] + path = page.path + + unless path.include? '/' + # Page processed (not contained in a folder) + html += new_page page + else + # Folders start at the next index + folder_start = index + break # Pages finished, move on to folders + end + end + + # If there are no folders, then we're done. + return enclose_tree(html) if folder_start <= -1 + + # Handle special case of only one folder. + if (count - folder_start == 1) + path = @pages[ folder_start ] + + html += <<-HTML +
  • + +
      +
    1. #{page.name2}
    2. +
    +
  • + HTML + + return enclose_tree html + end + + sorted_folders = [] + (folder_start).upto count - 1 do | index | + sorted_folders += [[ @pages[ index ].path, index ]] + end + + # http://stackoverflow.com/questions/3482814/sorting-list-of-string-paths-in-vb-net + sorted_folders.sort! do |first,second| + a = first[0] + b = second[0] + + # use :: operator because gollum defines its own conflicting File class + dir_compare = ::File.dirname(a) <=> ::File.dirname(b) + + # Sort based on directory name unless they're equal (0) in + # which case sort based on file name. + if dir_compare == 0 + ::File.basename(a) <=> ::File.basename(b) + else + dir_compare + end + end + + # Process first folder + page = @pages[ sorted_folders[ 0 ][1] ] + html += new_folder page + + last_folder = ::File.dirname page.path # define last_folder + + # keep track of folder depth, 0 = at root. + depth = 0 + + # process rest of folders + 1.upto(sorted_folders.size - 1) do | index | + page = @pages[ sorted_folders[ index ][1] ] + path = page.path + folder = ::File.dirname path + + if last_folder == folder + # same folder + html += new_page page + elsif folder.include?('/') + # check if we're going up or down a depth level + if last_folder.scan('/').size > folder.scan('/').size + # end tag for 1 subfolder & 1 parent folder + # so emit 2 end tags + 2.times { html += end_folder; } + depth -= 1 + else + depth += 1 + end + + # subfolder + html += new_sub_folder ::File.dirname(page.path).split('/').last, page.name, page.name2 + else + # depth+1 because we need an additional end_folder + (depth+1).times { html += end_folder; } + depth = 0 + # New root folder + html += new_folder page + end + + last_folder = folder + end + + # Process last folder's ending tags. + (depth+1).times { + depth.times { html += end_folder; } + depth = 0 + } + + # return the completed html + enclose_tree html + end # end render_files + end # end FileView class +end # end Gollum module diff --git a/lib/gollum/frontend/app.rb b/lib/gollum/frontend/app.rb index c597d4ba..9549e335 100644 --- a/lib/gollum/frontend/app.rb +++ b/lib/gollum/frontend/app.rb @@ -200,6 +200,13 @@ module Precious mustache :pages end + get '/fileview' do + wiki = Gollum::Wiki.new(settings.gollum_path, settings.wiki_options) + @results = Gollum::FileView.new(wiki.pages).render_files + @ref = wiki.ref + mustache :fileview + end + get '/*' do show_page_or_file(params[:splat].first) end diff --git a/lib/gollum/frontend/public/gollum/css/_styles.css b/lib/gollum/frontend/public/gollum/css/_styles.css new file mode 100644 index 00000000..d70f29ed --- /dev/null +++ b/lib/gollum/frontend/public/gollum/css/_styles.css @@ -0,0 +1,110 @@ +/* Just some base styles not needed for example to function */ +*, html { font-family: Verdana, Arial, Helvetica, sans-serif; } + + +#results a:hover { + background-color: #4c4c4c; +} + +#home_button { + position: absolute; + top: 10px; + left: 50%; +} + +#home_button .minibutton { +/* controls size of home btn */ +font-size: 1em; +text-align: center; +} + +#results { + position: absolute; + top: 60px; + left: 10px; +} + + +body, form, ul, li, p, h1, h2, h3, h4, h5 +{ + margin: 0; + padding: 0; +} +body { background-color: #606061; color: #ffffff; margin: 0; } +img { border: none; } +p +{ + font-size: 1em; + margin: 0 0 1em 0; +} + +html { font-size: 100%; /* IE hack */ } +body { font-size: 1em; /* Sets base font size to 16px */ } +table { font-size: 100%; /* IE hack */ } +input, select, textarea, th, td { font-size: 1em; } + +/* CSS Tree menu styles */ +ol.tree +{ + padding: 0 0 0 30px; + width: 300px; +} + li + { + position: relative; + margin-left: -15px; + list-style: none; + } + li.file + { + margin-left: -1px !important; + height: 1.5em; + } + li.file a + { + background: url(/images/fileview/document.png) 0 0 no-repeat; + color: #fff; + padding-left: 21px; + text-decoration: none; + display: block; + } + li.file a[href *= '.pdf'] { background: url(/images/fileview/document.png) 0 0 no-repeat; } + li.file a[href *= '.html'] { background: url(/images/fileview/document.png) 0 0 no-repeat; } + li.file a[href $= '.css'] { background: url(/images/fileview/document.png) 0 0 no-repeat; } + li.file a[href $= '.js'] { background: url(/images/fileview/document.png) 0 0 no-repeat; } + li input + { + position: absolute; + left: 0; + margin-left: 0; + opacity: 0; + z-index: 2; + cursor: pointer; + height: 1em; + width: 1em; + top: 0; + } + li input + ol + { + background: url(/images/fileview/toggle-small-expand.png) 40px 0 no-repeat; + margin: -1.188em 0 0 -44px; /* 15px */ + height: 1.5em; + } + li input + ol > li { display: none; margin-left: -14px !important; padding-left: 1px; } + li label + { + background: url(/images/fileview/folder-horizontal.png) 15px 1px no-repeat; + cursor: pointer; + display: block; + padding-left: 37px; + } + + li input:checked + ol + { + background: url(/images/fileview/toggle-small.png) 40px 5px no-repeat; + margin: -1.5em 0 0 -44px; /* 20px */ + padding: 1.563em 0 0 80px; + height: auto; + } + li input:checked + ol > li { display: block; margin: 0 0 0.125em; /* 2px */} + li input:checked + ol > li:last-child { margin: 0 0 0.063em; /* 1px */ } diff --git a/lib/gollum/frontend/public/gollum/images/fileview/document.png b/lib/gollum/frontend/public/gollum/images/fileview/document.png new file mode 100644 index 00000000..f125928c Binary files /dev/null and b/lib/gollum/frontend/public/gollum/images/fileview/document.png differ diff --git a/lib/gollum/frontend/public/gollum/images/fileview/folder-horizontal.png b/lib/gollum/frontend/public/gollum/images/fileview/folder-horizontal.png new file mode 100644 index 00000000..58e5cf7a Binary files /dev/null and b/lib/gollum/frontend/public/gollum/images/fileview/folder-horizontal.png differ diff --git a/lib/gollum/frontend/public/gollum/images/fileview/toggle-small-expand.png b/lib/gollum/frontend/public/gollum/images/fileview/toggle-small-expand.png new file mode 100644 index 00000000..969f5e8a Binary files /dev/null and b/lib/gollum/frontend/public/gollum/images/fileview/toggle-small-expand.png differ diff --git a/lib/gollum/frontend/public/gollum/images/fileview/toggle-small.png b/lib/gollum/frontend/public/gollum/images/fileview/toggle-small.png new file mode 100644 index 00000000..700af04c Binary files /dev/null and b/lib/gollum/frontend/public/gollum/images/fileview/toggle-small.png differ diff --git a/lib/gollum/frontend/templates/fileview.mustache b/lib/gollum/frontend/templates/fileview.mustache new file mode 100644 index 00000000..4b62888c --- /dev/null +++ b/lib/gollum/frontend/templates/fileview.mustache @@ -0,0 +1,29 @@ + + + + + + File View + + + +
    + +
    + +{{#has_results}} +
    + {{{results}}} +
    +{{/has_results}} + +{{#no_results}} +

    + There are no pages in {{ref}}. +

    +{{/no_results}} + + diff --git a/lib/gollum/page.rb b/lib/gollum/page.rb index 6894ca2b..04b71974 100644 --- a/lib/gollum/page.rb +++ b/lib/gollum/page.rb @@ -116,14 +116,21 @@ module Gollum self.class.strip_filename(filename) end - # Public: The canonical page name without extension, and dashes converted - # to spaces. + # Public: The canonical page name without extension. # # Returns the String name. def name self.class.canonicalize_filename(filename) end + # Public: The canonical page name without extension, and dashes + # really converted to spaces. + # + # Returns the String name. + def name2 + self.class.canonicalize_filename(filename).gsub('-', ' ') + end + # Public: The title will be constructed from the # filename by stripping the extension and replacing any dashes with # spaces.