From ebcd30fadcdbefc7d177b37575b81d60f9f2fd2a Mon Sep 17 00:00:00 2001 From: bootstraponline Date: Fri, 18 May 2012 11:50:38 -0600 Subject: [PATCH] Add file view. --- lib/gollum.rb | 1 + lib/gollum/file_view.rb | 155 ++++++++++++++++++ lib/gollum/frontend/app.rb | 7 + .../frontend/public/gollum/css/_styles.css | 110 +++++++++++++ .../gollum/images/fileview/document.png | Bin 0 -> 177 bytes .../images/fileview/folder-horizontal.png | Bin 0 -> 271 bytes .../images/fileview/toggle-small-expand.png | Bin 0 -> 433 bytes .../gollum/images/fileview/toggle-small.png | Bin 0 -> 462 bytes .../frontend/templates/fileview.mustache | 29 ++++ lib/gollum/page.rb | 11 +- 10 files changed, 311 insertions(+), 2 deletions(-) create mode 100644 lib/gollum/file_view.rb create mode 100644 lib/gollum/frontend/public/gollum/css/_styles.css create mode 100644 lib/gollum/frontend/public/gollum/images/fileview/document.png create mode 100644 lib/gollum/frontend/public/gollum/images/fileview/folder-horizontal.png create mode 100644 lib/gollum/frontend/public/gollum/images/fileview/toggle-small-expand.png create mode 100644 lib/gollum/frontend/public/gollum/images/fileview/toggle-small.png create mode 100644 lib/gollum/frontend/templates/fileview.mustache 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 0000000000000000000000000000000000000000..f125928c64c724189667e3f14400874eb2bf6b33 GIT binary patch literal 177 zcmeAS@N?(olHy`uVBq!ia0vp^d_XM3!3HF=W8NDADaPU;cPEB*=VV@j#5`RbLo80e zoe;?75Fp}`o_Fno*g>Z^ol{h{9kH{it}rvSQ*nLrv&?S!xxJSI4)QA$-*K28bXv!O zHTK&3owlCKh36g$kxSy)64t$*LBY`^M`VxWK8I`T?Jh0dlX5%hW6kPc-TN~p9Lw;Q Z3hx(`S8};?>NL<=22WQ%mvv4FO#qS1K~?|& literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..58e5cf7a4bde4e7396ec4acb7f8fb5a5f062a667 GIT binary patch literal 271 zcmV+q0r38bP)Px#$w@>(R5;76l0OcDFc`((tKy$kL*n8ENW6oCE2DZD2N&;RbY#NG#5-^aq7Dv* zMEG2=p(GHfysd4%U*4}RgIEL=87u5oQy$PD3}O-ACCdl5r_5d{f>f}m8und|^rEg& zUCMI`9i=l+zr1m|%Q4BYZKLN9q0#925U(kum<*U3pj5E2(HatG1C$8XHlQAHQbny) z;8{ST<%E&yLd$smf3!5{Uo8##ShgADZ8YeeVQ=-D^ZNk+<-4Rqgl!=X5&pCQ;0v)@ VOTQYTASD0*002ovPDHLkV1hCyZMFaa literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..969f5e8a1d3d7fe2b1b0da046c96410ca05d7494 GIT binary patch literal 433 zcmV;i0Z#sjP)Px#24YJ`L;(K){{a7>y{D4^00CJ^L_t(I%Z-!2N^C(4hrb95dY9W+h~S?UTYJI6 zLhuFDC$JD~EqnkQU%^MPwowp47O}MwL9q}7K?_|J@o+6Zn;boR++A*9n9OAIOD6dR zYN9eo>h`D`BcjwNfJtB+D1ZmxE+XDakn(L8vO1*hs#of}Kk}%at82fqsW{K7x9QMU zH`O_HQQc9CTzl$pugJIRhq~S8|4sEI18j8FBh$9(tah!+{i)hfTi*rCKey{e?E|o= z{!_Px@@^7n0sH^cO5hr}1eQvGao`VdmgiPx$h)G02R5;6hle+N7`vAz-6m;RD$C z3KH@F);0-U1t8`MPQA*tI_-I!9! z_vgS6FbGt@Z(u*AbdpK3?+s?Pp)RXC>OZgLK>eyt-+D~}ZmW9%=%};m3w2ywQmgn@ z)b6_?@2RKi;ywBIsv8mD{f&CWvn|2uYxRvfqc#iurh25dt_l`8cWMz&iWG4 zU1)@E2xtMTwO0Kv_|A*_F7O?g$OMBx5AY@aAFEwJqX0copQ&9br9wQmQiM5=pYpFKyzs8vp + + + + + 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.