diff --git a/bin/gollum b/bin/gollum index d300bcea..3a4908e2 100755 --- a/bin/gollum +++ b/bin/gollum @@ -17,10 +17,10 @@ require 'optparse' require 'rubygems' require 'gollum' -exec = {} -options = { 'port' => 4567, 'bind' => '0.0.0.0' } +exec = {} +options = { 'port' => 4567, 'bind' => '0.0.0.0' } wiki_options = { - :live_preview => false, + :live_preview => false, :allow_uploads => false, } @@ -85,7 +85,7 @@ opts = OptionParser.new do |opts| end opts.on("--allow-uploads [MODE]", [:dir, :page], "Allows file uploads. Modes: dir (default, store all uploads in the same directory), page (store each upload at the same location as the page).") do |mode| - wiki_options[:allow_uploads] = true + wiki_options[:allow_uploads] = true wiki_options[:per_page_uploads] = true if mode == :page end @@ -120,8 +120,8 @@ end # --gollum-path wins over ARGV[0] gollum_path = wiki_options[:gollum_path] ? - wiki_options[:gollum_path] : - ARGV[0] || Dir.pwd + wiki_options[:gollum_path] : + ARGV[0] || Dir.pwd if options['irb'] require 'irb' @@ -151,7 +151,9 @@ if options['irb'] begin require 'gollum-lib' wiki = Gollum::Wiki.new(gollum_path, wiki_options) - if !wiki.exist? then raise Gollum::InvalidGitRepositoryError end + if !wiki.exist? then + raise Gollum::InvalidGitRepositoryError + end puts "Loaded Gollum wiki at #{File.expand_path(gollum_path).inspect}." puts puts %( page = wiki.page('page-name')) @@ -193,7 +195,7 @@ else def initialize base_path @mg = Rack::Builder.new do map '/' do - run Proc.new { [ 302, {'Location'=> "/#{base_path}" }, [] ] } + run Proc.new { [302, { 'Location' => "/#{base_path}" }, []] } end map "/#{base_path}" do @@ -209,4 +211,4 @@ else # Rack::Handler does not work with Ctrl + C. Use Rack::Server instead. Rack::Server.new(:app => MapGollum.new(base_path), :Port => options['port'], :Host => options['bind']).start end -end +end \ No newline at end of file diff --git a/gollum.gemspec b/gollum.gemspec index 170d9edb..08768902 100644 --- a/gollum.gemspec +++ b/gollum.gemspec @@ -10,10 +10,10 @@ Gem::Specification.new do |s| s.rubyforge_project = 'gollum' s.license = 'MIT' - s.summary = "A simple, Git-powered wiki." - s.description = "A simple, Git-powered wiki with a sweet API and local frontend." + s.summary = 'A simple, Git-powered wiki.' + s.description = 'A simple, Git-powered wiki with a sweet API and local frontend.' - s.authors = ["Tom Preston-Werner", "Rick Olson"] + s.authors = ['Tom Preston-Werner', 'Rick Olson'] s.email = 'tom@github.com' s.homepage = 'http://github.com/gollum/gollum' @@ -33,6 +33,7 @@ Gem::Specification.new do |s| s.add_development_dependency 'rack-test', '~> 0.6.2' s.add_development_dependency 'shoulda', '~> 3.4.0' s.add_development_dependency 'minitest-reporters', '~> 0.14.16' + s.add_development_dependency 'twitter_cldr', '~> 2.4.2' # = MANIFEST = s.files = %w[ @@ -55,6 +56,11 @@ Gem::Specification.new do |s| lib/gollum/public/gollum/css/ie7.css lib/gollum/public/gollum/css/print.css lib/gollum/public/gollum/css/template.css + lib/gollum/public/gollum/fonts/FontAwesome.otf + lib/gollum/public/gollum/fonts/fontawesome-webfont.eot + lib/gollum/public/gollum/fonts/fontawesome-webfont.svg + lib/gollum/public/gollum/fonts/fontawesome-webfont.ttf + lib/gollum/public/gollum/fonts/fontawesome-webfont.woff lib/gollum/public/gollum/images/dirty-shade.png lib/gollum/public/gollum/images/fileview/document.png lib/gollum/public/gollum/images/fileview/folder-horizontal.png @@ -533,8 +539,6 @@ Gem::Specification.new do |s| licenses/unity_asset_pool/COPYRIGHT openrc/conf.d/gollum openrc/init.d/gollum - templates/formatting.html - templates/helper_wiki.rb ] # = MANIFEST = diff --git a/lib/gollum.rb b/lib/gollum.rb index f87ebb53..70a2378a 100644 --- a/lib/gollum.rb +++ b/lib/gollum.rb @@ -13,7 +13,7 @@ require File.expand_path('../gollum/uri_encode_component', __FILE__) # Set ruby to UTF-8 mode # This is required for Ruby 1.8.7 which gollum still supports. -$KCODE = 'U' if RUBY_VERSION[0,3] == '1.8' +$KCODE = 'U' if RUBY_VERSION[0, 3] == '1.8' module Gollum VERSION = '3.0.0' @@ -22,7 +22,8 @@ module Gollum ::File.expand_path('gollum/public', ::File.dirname(__FILE__)) end - class Error < StandardError; end + class Error < StandardError; + end class DuplicatePageError < Error attr_accessor :dir diff --git a/lib/gollum/app.rb b/lib/gollum/app.rb index d75ae800..600ec654 100644 --- a/lib/gollum/app.rb +++ b/lib/gollum/app.rb @@ -43,7 +43,7 @@ module Precious register Mustache::Sinatra include Precious::Helpers - dir = File.dirname(File.expand_path(__FILE__)) + dir = File.dirname(File.expand_path(__FILE__)) # Detect unsupported browsers. Browser = Struct.new(:browser, :version) @@ -56,23 +56,23 @@ module Precious def supported_useragent?(user_agent) ua = UserAgent.parse(user_agent) - @@min_ua.detect {|min| ua >= min } + @@min_ua.detect { |min| ua >= min } end # We want to serve public assets for now set :public_folder, "#{dir}/public/gollum" - set :static, true + set :static, true set :default_markup, :markdown set :mustache, { - # Tell mustache where the Views constant lives - :namespace => Precious, + # Tell mustache where the Views constant lives + :namespace => Precious, - # Mustache templates live here - :templates => "#{dir}/templates", + # Mustache templates live here + :templates => "#{dir}/templates", - # Tell mustache where the views are - :views => "#{dir}/views" + # Tell mustache where the views are + :views => "#{dir}/views" } # Sinatra error handling @@ -90,7 +90,7 @@ module Precious # above will detect base_path when it's used with map in a config.ru settings.wiki_options.merge!({ :base_path => @base_url }) @css = settings.wiki_options[:css] - @js = settings.wiki_options[:js] + @js = settings.wiki_options[:js] end get '/' do @@ -139,9 +139,9 @@ module Precious end redirect to(live_preview_url) else - @page = page + @page = page @page.version = wiki.repo.log(wiki.ref, @page.path).first - @content = page.text_data + @content = page.text_data mustache :edit end else @@ -163,9 +163,9 @@ module Precious tempfile = params[:file][:tempfile] end - dir = wiki.per_page_uploads ? params[:upload_dest] : 'uploads' - ext = ::File.extname(fullname) - format = ext.split('.').last || 'txt' + dir = wiki.per_page_uploads ? params[:upload_dest] : 'uploads' + ext = ::File.extname(fullname) + format = ext.split('.').last || 'txt' filename = ::File.basename(fullname, ext) contents = ::File.read(tempfile) reponame = filename + '.' + format @@ -173,10 +173,10 @@ module Precious head = wiki.repo.head options = { - :message => "Uploaded file to #{dir}/#{reponame}", - :parent => wiki.repo.head.commit, + :message => "Uploaded file to #{dir}/#{reponame}", + :parent => wiki.repo.head.commit, } - author = session['gollum.author'] + author = session['gollum.author'] unless author.nil? options.merge! author end @@ -197,37 +197,37 @@ module Precious end post '/rename/*' do - wikip = wiki_page(params[:splat].first) + wikip = wiki_page(params[:splat].first) halt 500 if wikip.nil? - wiki = wikip.wiki - page = wiki.paged(wikip.name, wikip.path, exact = true) - rename = params[:rename] + wiki = wikip.wiki + page = wiki.paged(wikip.name, wikip.path, exact = true) + rename = params[:rename] halt 500 if page.nil? halt 500 if rename.nil? or rename.empty? # Fixup the rename if it is a relative path # In 1.8.7 rename[0] != rename[0..0] if rename[0..0] != '/' - source_dir = ::File.dirname(page.path) - source_dir = '' if source_dir == '.' + source_dir = ::File.dirname(page.path) + source_dir = '' if source_dir == '.' (target_dir, target_name) = ::File.split(rename) - target_dir = target_dir == '' ? source_dir : "#{source_dir}/#{target_dir}" - rename = "#{target_dir}/#{target_name}" + target_dir = target_dir == '' ? source_dir : "#{source_dir}/#{target_dir}" + rename = "#{target_dir}/#{target_name}" end committer = Gollum::Committer.new(wiki, commit_message) - commit = {:committer => committer} + commit = { :committer => committer } success = wiki.rename_page(page, rename, commit) if !success - # This occurs on NOOPs, for example renaming A => A - redirect to("/#{page.escaped_url_path}") - return + # This occurs on NOOPs, for example renaming A => A + redirect to("/#{page.escaped_url_path}") + return end committer.commit wikip = wiki_page(rename) - page = wiki.paged(wikip.name, wikip.path, exact = true) + page = wiki.paged(wikip.name, wikip.path, exact = true) return if page.nil? redirect to("/#{page.escaped_url_path}") end @@ -239,11 +239,11 @@ module Precious page = wiki.paged(page_name, path, exact = true) return if page.nil? committer = Gollum::Committer.new(wiki, commit_message) - commit = {:committer => committer} + commit = { :committer => committer } update_wiki_page(wiki, page, params[:content], commit, page.name, params[:format]) - update_wiki_page(wiki, page.header, params[:header], commit) if params[:header] - update_wiki_page(wiki, page.footer, params[:footer], commit) if params[:footer] + update_wiki_page(wiki, page.header, params[:header], commit) if params[:header] + update_wiki_page(wiki, page.footer, params[:footer], commit) if params[:footer] update_wiki_page(wiki, page.sidebar, params[:sidebar], commit) if params[:sidebar] committer.commit @@ -252,9 +252,9 @@ module Precious get '/delete/*' do wikip = wiki_page(params[:splat].first) - name = wikip.name - wiki = wikip.wiki - page = wikip.page + name = wikip.name + wiki = wikip.wiki + page = wikip.page unless page.nil? wiki.delete_page(page, { :message => "Destroyed #{name} (#{page.format})" }) end @@ -286,10 +286,10 @@ module Precious end post '/create' do - name = params[:page].to_url - path = sanitize_empty_params(params[:path]) || '' - format = params[:format].intern - wiki = wiki_new + name = params[:page].to_url + path = sanitize_empty_params(params[:path]) || '' + format = params[:format].intern + wiki = wiki_new path.gsub!(/^\//, '') @@ -305,15 +305,15 @@ module Precious end post '/revert/*/:sha1/:sha2' do - wikip = wiki_page(params[:splat].first) - @path = wikip.path - @name = wikip.name - wiki = wikip.wiki - @page = wiki.paged(@name,@path) - sha1 = params[:sha1] - sha2 = params[:sha2] + wikip = wiki_page(params[:splat].first) + @path = wikip.path + @name = wikip.name + wiki = wikip.wiki + @page = wiki.paged(@name, @path) + sha1 = params[:sha1] + sha2 = params[:sha2] - commit = commit_message + commit = commit_message commit[:message] = "Revert commit #{sha1.chars.take(7).join}" if wiki.revert_page(@page, sha1, sha2, commit) redirect to("/#{@page.escaped_url_path}") @@ -328,23 +328,23 @@ module Precious end post '/preview' do - wiki = wiki_new - @name = params[:page] || "Preview" - @page = wiki.preview_page(@name, params[:content], params[:format]) - @content = @page.formatted_data - @toc_content = wiki.universal_toc ? @page.toc_data : nil - @mathjax = wiki.mathjax - @h1_title = wiki.h1_title - @editable = false + wiki = wiki_new + @name = params[:page] || "Preview" + @page = wiki.preview_page(@name, params[:content], params[:format]) + @content = @page.formatted_data + @toc_content = wiki.universal_toc ? @page.toc_data : nil + @mathjax = wiki.mathjax + @h1_title = wiki.h1_title + @editable = false @allow_uploads = wiki.allow_uploads mustache :page end get '/history/*' do - @page = wiki_page(params[:splat].first).page - @page_num = [params[:page].to_i, 1].max + @page = wiki_page(params[:splat].first).page + @page_num = [params[:page].to_i, 1].max unless @page.nil? - @versions = @page.versions :page => @page_num + @versions = @page.versions :page => @page_num mustache :history else redirect to("/") @@ -358,10 +358,10 @@ module Precious redirect to("/history/#{@file}") else redirect to("/compare/%s/%s...%s" % [ - @file, - @versions.last, - @versions.first] - ) + @file, + @versions.last, + @versions.first] + ) end end @@ -373,14 +373,14 @@ module Precious \.{2,3} # match .. or ... (.+) # match the second SHA1 }x do |path, start_version, end_version| - wikip = wiki_page(path) - @path = wikip.path - @name = wikip.name - @versions = [start_version, end_version] - wiki = wikip.wiki - @page = wikip.page - diffs = wiki.repo.diff(@versions.first, @versions.last, @page.path) - @diff = diffs.first + wikip = wiki_page(path) + @path = wikip.path + @name = wikip.name + @versions = [start_version, end_version] + wiki = wikip.wiki + @page = wikip.page + diffs = wiki.repo.diff(@versions.first, @versions.last, @page.path) + @diff = diffs.first mustache :compare end @@ -391,8 +391,8 @@ module Precious name = wikip.name path = wikip.path if page = wikip.page - @page = page - @name = name + @page = page + @name = name @content = page.formatted_data @version = version mustache :page @@ -402,11 +402,11 @@ module Precious end get '/search' do - @query = params[:q] - wiki = wiki_new + @query = params[:q] + wiki = wiki_new # Sort wiki search results by count (desc) and then by name (asc) - @results = wiki.search(@query).sort{ |a, b| (a[:count] <=> b[:count]).nonzero? || b[:name] <=> a[:name] }.reverse - @name = @query + @results = wiki.search(@query).sort { |a, b| (a[:count] <=> b[:count]).nonzero? || b[:name] <=> a[:name] }.reverse + @name = @query mustache :search end @@ -426,16 +426,16 @@ module Precious end get '/fileview' do - wiki = wiki_new - options = settings.wiki_options - content = wiki.pages + wiki = wiki_new + options = settings.wiki_options + content = wiki.pages # if showing all files include wiki.files - content += wiki.files if options[:show_all] + content += wiki.files if options[:show_all] # must pass wiki_options to FileView # --show-all and --collapse-tree can be set. @results = Gollum::FileView.new(content, options).render_files - @ref = wiki.ref + @ref = wiki.ref mustache :file_view, { :layout => false } end @@ -450,21 +450,21 @@ module Precious path = extract_path(fullpath) || '/' if page = wiki.paged(name, path, exact = true) - @page = page - @name = name - @content = page.formatted_data - @upload_dest = settings.wiki_options[:allow_uploads] ? - (settings.wiki_options[:per_page_uploads] ? - "#{path}/#{@name}".sub(/^\/\//, '') : 'uploads' - ) : '' + @page = page + @name = name + @content = page.formatted_data + @upload_dest = settings.wiki_options[:allow_uploads] ? + (settings.wiki_options[:per_page_uploads] ? + "#{path}/#{@name}".sub(/^\/\//, '') : 'uploads' + ) : '' # Extensions and layout data - @editable = true - @page_exists = !page.versions.empty? - @toc_content = wiki.universal_toc ? @page.toc_data : nil - @mathjax = wiki.mathjax - @h1_title = wiki.h1_title - @bar_side = wiki.bar_side + @editable = true + @page_exists = !page.versions.empty? + @toc_content = wiki.universal_toc ? @page.toc_data : nil + @mathjax = wiki.mathjax + @h1_title = wiki.h1_title + @bar_side = wiki.bar_side @allow_uploads = wiki.allow_uploads mustache :page @@ -483,9 +483,9 @@ module Precious def update_wiki_page(wiki, page, content, commit, name = nil, format = nil) return if !page || - ((!content || page.raw_data == content) && page.format == format) + ((!content || page.raw_data == content) && page.format == format) name ||= page.name - format = (format || page.format).to_sym + format = (format || page.format).to_sym content ||= page.raw_data wiki.update_page(page, name, format, content.to_s, commit) end @@ -499,8 +499,8 @@ module Precious # message is sourced from the incoming request parameters # author details are sourced from the session, to be populated by rack middleware ahead of us def commit_message - msg = (params[:message].nil? or params[:message].empty?) ? "[no message]" : params[:message] - commit_message = { :message => msg } + msg = (params[:message].nil? or params[:message].empty?) ? "[no message]" : params[:message] + commit_message = { :message => msg } author_parameters = session['gollum.author'] commit_message.merge! author_parameters unless author_parameters.nil? commit_message diff --git a/lib/gollum/helpers.rb b/lib/gollum/helpers.rb index 1354f862..4fba20bf 100644 --- a/lib/gollum/helpers.rb +++ b/lib/gollum/helpers.rb @@ -22,13 +22,13 @@ module Precious end def sanitize_empty_params(param) - [nil,''].include?(param) ? nil : CGI.unescape(param) + [nil, ''].include?(param) ? nil : CGI.unescape(param) end # Ensure path begins with a single leading slash def clean_path(path) if path - (path[0] != '/' ? path.insert(0, '/') : path).gsub(/\/{2,}/,'/') + (path[0] != '/' ? path.insert(0, '/') : path).gsub(/\/{2,}/, '/') end end @@ -36,7 +36,7 @@ module Precious # Remove all double slashes def clean_url url return url if url.nil? - url.gsub('%2F','/').gsub(/^\/+/,'').gsub('//','/') + url.gsub('%2F', '/').gsub(/^\/+/, '').gsub('//', '/') end end diff --git a/lib/gollum/public/gollum/css/gollum.css b/lib/gollum/public/gollum/css/gollum.css index e856eb0f..4b582fec 100755 --- a/lib/gollum/public/gollum/css/gollum.css +++ b/lib/gollum/public/gollum/css/gollum.css @@ -46,7 +46,7 @@ a:hover, a:visited { } #head h1 { - font-size: 33px; + font-size: 2.5em; float: left; line-height: normal; margin: 0; diff --git a/lib/gollum/public/gollum/css/template.css b/lib/gollum/public/gollum/css/template.css index e75bc140..a149413a 100644 --- a/lib/gollum/public/gollum/css/template.css +++ b/lib/gollum/public/gollum/css/template.css @@ -2,19 +2,53 @@ Gollum v3 Template */ +@font-face { + font-family: 'FontAwesome'; + src: url('../fonts/fontawesome-webfont.eot?v=4.0.3'); + src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.0.3') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff?v=4.0.3') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.0.3') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.0.3#fontawesomeregular') format('svg'); + font-weight: normal; + font-style: normal; +} + +.fa { + display: inline-block; + font: normal normal 16px FontAwesome; + line-height: 1; + text-decoration: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.fa-link:before { + content: "\f0c1"; +} + /* margin & padding reset*/ * { margin: 0; padding: 0; } +div { + display: block; +} + +html { + font-family: sans-serif; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; +} + html, body { color: #333; } body { - font: 13px Helvetica, arial, freesans, clean, sans-serif; + background-color: white; + font: 13.34px Helvetica, arial, freesans, clean, sans-serif; + font-size: small; line-height: 1.4; + min-width: 980px; } img { @@ -30,26 +64,46 @@ a.absent { color: #c00; } -.markdown-body a[id].wiki-toc-anchor { +a:focus { + outline: thin dotted; +} + +a:active, a:hover { + outline: 0; +} + +.markdown-body a.anchor:focus { + outline: none; +} + +.markdown-body a[id].wiki-toc-anchor { color: inherit; text-decoration: none; } .markdown-body { + padding: 30px; font-size: 15px; line-height: 1.7; + overflow: hidden; + word-wrap: break-word; } -.markdown-body>*:first-child { - margin-top: 0!important; + +.markdown-body > *:first-child { + margin-top: 0 !important; } -.markdown-body>*:last-child { - margin-bottom: 0!important; + +.markdown-body > *:last-child { + margin-bottom: 0 !important; } + .markdown-body a.absent { color: #c00; } + .markdown-body a.anchor { display: block; + padding-right: 6px; padding-left: 30px; margin-left: -30px; cursor: pointer; @@ -58,28 +112,43 @@ a.absent { left: 0; bottom: 0; } + .markdown-body h1, .markdown-body h2, .markdown-body h3, .markdown-body h4, .markdown-body h5, .markdown-body h6 { - margin: 20px 0 10px; + margin: 1em 0 15px; padding: 0; font-weight: bold; - -webkit-font-smoothing: antialiased; + line-height: 1.7; cursor: text; position: relative; + -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; } -.markdown-body h1:hover a.anchor, -.markdown-body h2:hover a.anchor, -.markdown-body h3:hover a.anchor, -.markdown-body h4:hover a.anchor, -.markdown-body h5:hover a.anchor, -.markdown-body h6:hover a.anchor { - background: url(../images/pin-20.png) no-repeat left center; + +.markdown-body h1 .fa-link, .markdown-body h2 .fa-link, .markdown-body h3 .fa-link, .markdown-body h4 .fa-link, .markdown-body h5 .fa-link, .markdown-body h6 .fa-link { + display: none; text-decoration: none; + color: #000; } + +.markdown-body h1:hover a.anchor .fa-link, +.markdown-body h2:hover a.anchor .fa-link, +.markdown-body h3:hover a.anchor .fa-link, +.markdown-body h4:hover a.anchor .fa-link, +.markdown-body h5:hover a.anchor .fa-link, +.markdown-body h6:hover a.anchor .fa-link { + text-decoration: none; + line-height: 1; + padding-left: 8px; + margin-left: -30px; + top: 15%; + display: inline-block; +} + .markdown-body h1 tt, .markdown-body h1 code, .markdown-body h2 tt, @@ -94,30 +163,38 @@ a.absent { .markdown-body h6 code { font-size: inherit; } + .markdown-body h1 { - font-size: 28px; + font-size: 2.5em; + border-bottom: 1px solid #ddd; color: #000; margin-top: 20px; margin-bottom: 10px; } + .markdown-body h2 { - font-size: 24px; - border-bottom: 1px solid #ccc; + font-size: 2em; + border-bottom: 1px solid #eee; color: #000; } + .markdown-body h3 { - font-size: 18px; + font-size: 1.5em; } + .markdown-body h4 { - font-size: 16px; + font-size: 1.2em; } + .markdown-body h5 { - font-size: 14px; + font-size: 1em; } + .markdown-body h6 { color: #777; - font-size: 14px; + font-size: 1em; } + .markdown-body p, .markdown-body blockquote, .markdown-body ul, @@ -128,9 +205,11 @@ a.absent { .markdown-body hr { margin: 15px 0; } + .markdown-body li { margin: 0px; } + .markdown-body hr { background: transparent url(../images/dirty-shade.png) repeat-x 0 0; border: 0 none; @@ -138,16 +217,19 @@ a.absent { height: 4px; padding: 0; } -.markdown-body>h1:first-child, -.markdown-body>h2:first-child, -.markdown-body>h3:first-child, -.markdown-body>h4:first-child, -.markdown-body>h5:first-child, -.markdown-body>h6:first-child { + +.markdown-body > h1:first-child, +.markdown-body > h2:first-child, +.markdown-body > h3:first-child, +.markdown-body > h4:first-child, +.markdown-body > h5:first-child, +.markdown-body > h6:first-child { } -.markdown-body h1+h2+h3{ + +.markdown-body h1 + h2 + h3 { margin-top: 30px; } + .markdown-body a:first-child h1, .markdown-body a:first-child h2, .markdown-body a:first-child h3, @@ -157,24 +239,29 @@ a.absent { margin-top: 0; padding-top: 0; } -.markdown-body h1+p, -.markdown-body h2+p, -.markdown-body h3+p, -.markdown-body h4+p, -.markdown-body h5+p, -.markdown-body h6+p { + +.markdown-body h1 + p, +.markdown-body h2 + p, +.markdown-body h3 + p, +.markdown-body h4 + p, +.markdown-body h5 + p, +.markdown-body h6 + p { margin-top: 0; } + .markdown-body li p.first { display: inline-block; } + .markdown-body ul, .markdown-body ol { padding-left: 30px; } + .markdown-body dl { padding: 0; } + .markdown-body dl dt { font-size: 14px; font-weight: bold; @@ -182,53 +269,67 @@ a.absent { padding: 0; margin: 15px 0 5px; } + .markdown-body dl dt:first-child { padding: 0; } -.markdown-body dl dt>:first-child { + +.markdown-body dl dt > :first-child { margin-top: 0; } -.markdown-body dl dt>:last-child { + +.markdown-body dl dt > :last-child { margin-bottom: 0; } + .markdown-body dl dd { margin: 0 0 15px; padding: 0 15px; } -.markdown-body dl dd>:first-child { + +.markdown-body dl dd > :first-child { margin-top: 0; } -.markdown-body dl dd>:last-child { + +.markdown-body dl dd > :last-child { margin-bottom: 0; } + .markdown-body blockquote { border-left: 4px solid #DDD; padding: 0 15px; color: #777; } -.markdown-body blockquote>:first-child { + +.markdown-body blockquote > :first-child { margin-top: 0; } -.markdown-body blockquote>:last-child { + +.markdown-body blockquote > :last-child { margin-bottom: 0; } + .markdown-body table { padding: 0; border-collapse: collapse; border-spacing: 0; } + .markdown-body table tr { border-top: 1px solid #ccc; background-color: #fff; margin: 0; padding: 0; } + .markdown-body table tr:nth-child(2n) { background-color: #f8f8f8; } + .markdown-body table tr th { font-weight: bold; } + .markdown-body table tr th, .markdown-body table tr td { border: 1px solid #ccc; @@ -236,22 +337,27 @@ a.absent { margin: 0; padding: 6px 13px; } -.markdown-body table tr th>:first-child, -.markdown-body table tr td>:first-child { + +.markdown-body table tr th > :first-child, +.markdown-body table tr td > :first-child { margin-top: 0; } -.markdown-body table tr th>:last-child, -.markdown-body table tr td>:last-child { + +.markdown-body table tr th > :last-child, +.markdown-body table tr td > :last-child { margin-bottom: 0; } + .markdown-body img { max-width: 100%; } + .markdown-body span.frame { display: block; overflow: hidden; } -.markdown-body span.frame>span { + +.markdown-body span.frame > span { border: 1px solid #ddd; display: block; float: left; @@ -260,62 +366,74 @@ a.absent { padding: 7px; width: auto; } + .markdown-body span.frame span img { display: block; float: left; } + .markdown-body span.frame span span { clear: both; color: #333; display: block; padding: 5px 0 0; } + .markdown-body span.align-center { display: block; overflow: hidden; clear: both; } -.markdown-body span.align-center>span { + +.markdown-body span.align-center > span { display: block; overflow: hidden; margin: 13px auto 0; text-align: center; } + .markdown-body span.align-center span img { margin: 0 auto; text-align: center; } + .markdown-body span.align-right { display: block; overflow: hidden; clear: both; } -.markdown-body span.align-right>span { + +.markdown-body span.align-right > span { display: block; overflow: hidden; margin: 13px 0 0; text-align: right; } + .markdown-body span.align-right span img { margin: 0; text-align: right; } + .markdown-body span.float-left { display: block; margin-right: 13px; overflow: hidden; float: left; } + .markdown-body span.float-left span { margin: 13px 0 0; } + .markdown-body span.float-right { display: block; margin-left: 13px; overflow: hidden; float: right; } -.markdown-body span.float-right>span { + +.markdown-body span.float-right > span { display: block; overflow: hidden; margin: 13px auto 0; @@ -338,14 +456,16 @@ a.absent { background-color: #f8f8f8; border-radius: 3px; } -.markdown-body pre>tt, -.markdown-body pre>code { + +.markdown-body pre > tt, +.markdown-body pre > code { margin: 0; padding: 0; white-space: pre; border: none; background: transparent; } + .markdown-body pre { background-color: #f8f8f8; border: 1px solid #ccc; @@ -355,16 +475,19 @@ a.absent { padding: 6px 10px; border-radius: 3px; } + .markdown-body pre pre, .markdown-body pre code, .markdown-body pre tt { background-color: transparent; border: none; } + .markdown-body pre pre { margin: 0; padding: 0; } + .toc { background-color: #F7F7F7; border: 1px solid #ddd; @@ -372,6 +495,7 @@ a.absent { margin: 0; border-radius: 3px; } + .toc-title { color: #888; font-size: 14px; @@ -380,250 +504,325 @@ a.absent { border-bottom: 1px solid #ddd; margin-bottom: 3px; } + .toc ul { padding-left: 10px; margin: 0; } -.toc>ul { + +.toc > ul { margin-left: 10px; font-size: 17px; } + .toc ul ul { font-size: 15px; } + .toc ul ul ul { font-size: 14px; } -.toc ul li{ + +.toc ul li { margin: 0; } + #header-content .toc, #footer-content .toc, #sidebar-content .toc { border: none; } + .highlight { background: #fff; } + .highlight .c { color: #998; font-style: italic; } + .highlight .err { color: #a61717; background-color: #e3d2d2; } + .highlight .k { font-weight: bold; } + .highlight .o { font-weight: bold; } + .highlight .cm { color: #998; font-style: italic; } + .highlight .cp { color: #999; font-weight: bold; } + .highlight .c1 { color: #998; font-style: italic; } + .highlight .cs { color: #999; font-weight: bold; font-style: italic; } + .highlight .gd { color: #000; background-color: #fdd; } + .highlight .gd .x { color: #000; background-color: #faa; } + .highlight .ge { font-style: italic; } + .highlight .gr { color: #a00; } + .highlight .gh { color: #999; } + .highlight .gi { color: #000; background-color: #dfd; } + .highlight .gi .x { color: #000; background-color: #afa; } + .highlight .go { color: #888; } + .highlight .gp { color: #555; } + .highlight .gs { font-weight: bold; } + .highlight .gu { color: #800080; font-weight: bold; } + .highlight .gt { color: #a00; } + .highlight .kc { font-weight: bold; } + .highlight .kd { font-weight: bold; } + .highlight .kn { font-weight: bold; } + .highlight .kp { font-weight: bold; } + .highlight .kr { font-weight: bold; } + .highlight .kt { color: #458; font-weight: bold; } + .highlight .m { color: #099; } + .highlight .s { color: #d14; } + .highlight .na { color: #008080; } + .highlight .nb { color: #0086B3; } + .highlight .nc { color: #458; font-weight: bold; } + .highlight .no { color: #008080; } + .highlight .ni { color: #800080; } + .highlight .ne { color: #900; font-weight: bold; } + .highlight .nf { color: #900; font-weight: bold; } + .highlight .nn { color: #555; } + .highlight .nt { color: #000080; } + .highlight .nv { color: #008080; } + .highlight .ow { font-weight: bold; } + .highlight .w { color: #bbb; } + .highlight .mf { color: #099; } + .highlight .mh { color: #099; } + .highlight .mi { color: #099; } + .highlight .mo { color: #099; } + .highlight .sb { color: #d14; } + .highlight .sc { color: #d14; } + .highlight .sd { color: #d14; } + .highlight .s2 { color: #d14; } + .highlight .se { color: #d14; } + .highlight .sh { color: #d14; } + .highlight .si { color: #d14; } + .highlight .sx { color: #d14; } + .highlight .sr { color: #009926; } + .highlight .s1 { color: #d14; } + .highlight .ss { color: #990073; } + .highlight .bp { color: #999; } + .highlight .vc { color: #008080; } + .highlight .vg { color: #008080; } + .highlight .vi { color: #008080; } + .highlight .il { color: #099; } + .highlight .gc { color: #999; background-color: #EAF2F5; } + .type-csharp .highlight .k { color: #00F; } + .type-csharp .highlight .kt { color: #00F; } + .type-csharp .highlight .nf { color: #000; font-weight: normal; } + .type-csharp .highlight .nc { color: #2B91AF; } + .type-csharp .highlight .nn { color: #000; } + .type-csharp .highlight .s { color: #A31515; } + .type-csharp .highlight .sc { color: #A31515; } diff --git a/lib/gollum/public/gollum/fonts/FontAwesome.otf b/lib/gollum/public/gollum/fonts/FontAwesome.otf new file mode 100644 index 00000000..8b0f54e4 Binary files /dev/null and b/lib/gollum/public/gollum/fonts/FontAwesome.otf differ diff --git a/lib/gollum/public/gollum/fonts/fontawesome-webfont.eot b/lib/gollum/public/gollum/fonts/fontawesome-webfont.eot new file mode 100755 index 00000000..7c79c6a6 Binary files /dev/null and b/lib/gollum/public/gollum/fonts/fontawesome-webfont.eot differ diff --git a/lib/gollum/public/gollum/fonts/fontawesome-webfont.svg b/lib/gollum/public/gollum/fonts/fontawesome-webfont.svg new file mode 100755 index 00000000..45fdf338 --- /dev/null +++ b/lib/gollum/public/gollum/fonts/fontawesome-webfont.svg @@ -0,0 +1,414 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/gollum/public/gollum/fonts/fontawesome-webfont.ttf b/lib/gollum/public/gollum/fonts/fontawesome-webfont.ttf new file mode 100755 index 00000000..e89738de Binary files /dev/null and b/lib/gollum/public/gollum/fonts/fontawesome-webfont.ttf differ diff --git a/lib/gollum/public/gollum/fonts/fontawesome-webfont.woff b/lib/gollum/public/gollum/fonts/fontawesome-webfont.woff new file mode 100755 index 00000000..8c1748aa Binary files /dev/null and b/lib/gollum/public/gollum/fonts/fontawesome-webfont.woff differ diff --git a/lib/gollum/uri_encode_component.rb b/lib/gollum/uri_encode_component.rb index 74bccd55..2a5f7404 100644 --- a/lib/gollum/uri_encode_component.rb +++ b/lib/gollum/uri_encode_component.rb @@ -49,132 +49,164 @@ class String end end -module URI; class << self +module URI + ; + class << self # Does the char code correspond to an alpha-numeric char. # isAlphaNumeric('a'.ord) => true # isAlphaNumeric(''.ord) => false -def isAlphaNumeric(cc) - # a - z - if (97 <= cc && cc <= 122); return true end - # A - Z - if (65 <= cc && cc <= 90); return true end - # 0 - 9 - if (48 <= cc && cc <= 57); return true end + def isAlphaNumeric(cc) + # a - z + if (97 <= cc && cc <= 122); + return true + end + # A - Z + if (65 <= cc && cc <= 90); + return true + end + # 0 - 9 + if (48 <= cc && cc <= 57); + return true + end - return false -end + return false + end -def unescapePredicate(cc) - if (isAlphaNumeric(cc)); return true end - # ! - if (cc == 33); return true end - # '()* - if (39 <= cc && cc <= 42); return true end - # -. - if (45 <= cc && cc <= 46); return true end - # _ - if (cc == 95); return true end - # ~ - if (cc == 126); return true end + def unescapePredicate(cc) + if (isAlphaNumeric(cc)); + return true + end + # ! + if (cc == 33); + return true + end + # '()* + if (39 <= cc && cc <= 42); + return true + end + # -. + if (45 <= cc && cc <= 46); + return true + end + # _ + if (cc == 95); + return true + end + # ~ + if (cc == 126); + return true + end - return false -end + return false + end -def URIEncodeSingle(cc, result, index) - x = (cc >> 12) & 0xF; - y = (cc >> 6) & 63; - z = cc & 63; - octets = Array.new(3); - if (cc <= 0x007F) - octets[0] = cc; - elsif (cc <= 0x07FF) - octets[0] = y + 192; - octets[1] = z + 128; - else - octets[0] = x + 224; - octets[1] = y + 128; - octets[2] = z + 128; - end - return URIEncodeOctets(octets, result, index); -end + def URIEncodeSingle(cc, result, index) + x = (cc >> 12) & 0xF; + y = (cc >> 6) & 63; + z = cc & 63; + octets = Array.new(3); + if (cc <= 0x007F) + octets[0] = cc; + elsif (cc <= 0x07FF) + octets[0] = y + 192; + octets[1] = z + 128; + else + octets[0] = x + 224; + octets[1] = y + 128; + octets[2] = z + 128; + end + return URIEncodeOctets(octets, result, index); + end # Lazily initialized. -@@hexCharCodeArray = 0; + @@hexCharCodeArray = 0; -def URIAddEncodedOctetToBuffer(octet, result, index) - result[index] = 37; # Char code of '%'. - index += 1 - result[index] = @@hexCharCodeArray[octet >> 4]; - index += 1 - result[index] = @@hexCharCodeArray[octet & 0x0F]; - index += 1 - return index; -end + def URIAddEncodedOctetToBuffer(octet, result, index) + result[index] = 37; # Char code of '%'. + index += 1 + result[index] = @@hexCharCodeArray[octet >> 4]; + index += 1 + result[index] = @@hexCharCodeArray[octet & 0x0F]; + index += 1 + return index; + end -def URIEncodeOctets(octets, result, index) - if (@@hexCharCodeArray == 0) - @@hexCharCodeArray = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 65, 66, 67, 68, 69, 70]; - end - index = URIAddEncodedOctetToBuffer(octets[0], result, index); - if (octets[1]); index = URIAddEncodedOctetToBuffer(octets[1], result, index) end - if (octets[2]); index = URIAddEncodedOctetToBuffer(octets[2], result, index) end - if (octets[3]); index = URIAddEncodedOctetToBuffer(octets[3], result, index) end - return index; -end + def URIEncodeOctets(octets, result, index) + if (@@hexCharCodeArray == 0) + @@hexCharCodeArray = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 65, 66, 67, 68, 69, 70]; + end + index = URIAddEncodedOctetToBuffer(octets[0], result, index); + if (octets[1]); + index = URIAddEncodedOctetToBuffer(octets[1], result, index) + end + if (octets[2]); + index = URIAddEncodedOctetToBuffer(octets[2], result, index) + end + if (octets[3]); + index = URIAddEncodedOctetToBuffer(octets[3], result, index) + end + return index; + end -def URIEncodePair(cc1 , cc2, result, index) - u = ((cc1 >> 6) & 0xF) + 1; - w = (cc1 >> 2) & 0xF; - x = cc1 & 3; - y = (cc2 >> 6) & 0xF; - z = cc2 & 63; - octets = Array.new(4); - octets[0] = (u >> 2) + 240; - octets[1] = (((u & 3) << 4) | w) + 128; - octets[2] = ((x << 4) | y) + 128; - octets[3] = z + 128; - return URIEncodeOctets(octets, result, index); -end + def URIEncodePair(cc1, cc2, result, index) + u = ((cc1 >> 6) & 0xF) + 1; + w = (cc1 >> 2) & 0xF; + x = cc1 & 3; + y = (cc2 >> 6) & 0xF; + z = cc2 & 63; + octets = Array.new(4); + octets[0] = (u >> 2) + 240; + octets[1] = (((u & 3) << 4) | w) + 128; + octets[2] = ((x << 4) | y) + 128; + octets[3] = z + 128; + return URIEncodeOctets(octets, result, index); + end # component must be String -def URIEncodeComponent(componentString) - Encode(componentString, :unescapePredicate); -end + def URIEncodeComponent(componentString) + Encode(componentString, :unescapePredicate); + end # ECMA-262, section 15.1.3 -def Encode(uri, unescape) - uriLength = uri.length; - # We are going to pass result to %StringFromCharCodeArray - # which does not expect any getters/setters installed - # on the incoming array. - result = Array.new(uriLength); - index = 0; - k = -1; - while ((k+=1) < uriLength) do - cc1 = uri.charCodeAt(k); - next if cc1.nil? - if (self.send(unescape, cc1)) - result[index] = cc1; - index += 1 - else - if (cc1 >= 0xDC00 && cc1 <= 0xDFFF); throw("URI malformed") end - if (cc1 < 0xD800 || cc1 > 0xDBFF) - index = URIEncodeSingle(cc1, result, index); - else - k+=1; - if (k == uriLength); throw("URI malformed") end - cc2 = uri.charCodeAt(k); - if (cc2 < 0xDC00 || cc2 > 0xDFFF); throw("URI malformed") end - index = URIEncodePair(cc1, cc2, result, index); + def Encode(uri, unescape) + uriLength = uri.length; + # We are going to pass result to %StringFromCharCodeArray + # which does not expect any getters/setters installed + # on the incoming array. + result = Array.new(uriLength); + index = 0; + k = -1; + while ((k+=1) < uriLength) do + cc1 = uri.charCodeAt(k); + next if cc1.nil? + if (self.send(unescape, cc1)) + result[index] = cc1; + index += 1 + else + if (cc1 >= 0xDC00 && cc1 <= 0xDFFF); + throw("URI malformed") + end + if (cc1 < 0xD800 || cc1 > 0xDBFF) + index = URIEncodeSingle(cc1, result, index); + else + k+=1; + if (k == uriLength); + throw("URI malformed") + end + cc2 = uri.charCodeAt(k); + if (cc2 < 0xDC00 || cc2 > 0xDFFF); + throw("URI malformed") + end + index = URIEncodePair(cc1, cc2, result, index); + end + end end + # use .compact to get rid of nils from charCodeAt + # return %StringFromCharCodeArray(result); + # 'c' = 8 bit signed char + # http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-pack + return result.compact.pack 'c*' end - end - # use .compact to get rid of nils from charCodeAt - # return %StringFromCharCodeArray(result); - # 'c' = 8 bit signed char - # http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-pack - return result.compact.pack 'c*' -end -end # class << self + end # class << self end # module diff --git a/lib/gollum/views/compare.rb b/lib/gollum/views/compare.rb index 3cf825fa..df2e3a3a 100644 --- a/lib/gollum/views/compare.rb +++ b/lib/gollum/views/compare.rb @@ -47,43 +47,45 @@ module Precious end @left_diff_line_number = nil + def left_diff_line_number(id, line) if line =~ /^@@/ - m, li = *line.match(/\-(\d+)/) + m, li = *line.match(/\-(\d+)/) @left_diff_line_number = li.to_i - @current_line_number = @left_diff_line_number - ret = '...' + @current_line_number = @left_diff_line_number + ret = '...' elsif line[0] == ?- - ret = @left_diff_line_number.to_s + ret = @left_diff_line_number.to_s @left_diff_line_number += 1 - @current_line_number = @left_diff_line_number - 1 + @current_line_number = @left_diff_line_number - 1 elsif line[0] == ?+ ret = ' ' else - ret = @left_diff_line_number.to_s + ret = @left_diff_line_number.to_s @left_diff_line_number += 1 - @current_line_number = @left_diff_line_number - 1 + @current_line_number = @left_diff_line_number - 1 end ret end @right_diff_line_number = nil + def right_diff_line_number(id, line) if line =~ /^@@/ - m, ri = *line.match(/\+(\d+)/) + m, ri = *line.match(/\+(\d+)/) @right_diff_line_number = ri.to_i - @current_line_number = @right_diff_line_number - ret = '...' + @current_line_number = @right_diff_line_number + ret = '...' elsif line[0] == ?- ret = ' ' elsif line[0] == ?+ - ret = @right_diff_line_number.to_s + ret = @right_diff_line_number.to_s @right_diff_line_number += 1 - @current_line_number = @right_diff_line_number - 1 + @current_line_number = @right_diff_line_number - 1 else - ret = @right_diff_line_number.to_s + ret = @right_diff_line_number.to_s @right_diff_line_number += 1 - @current_line_number = @right_diff_line_number - 1 + @current_line_number = @right_diff_line_number - 1 end ret end diff --git a/lib/gollum/views/edit.rb b/lib/gollum/views/edit.rb index 583a5ca1..0909e5af 100755 --- a/lib/gollum/views/edit.rb +++ b/lib/gollum/views/edit.rb @@ -6,10 +6,10 @@ module Precious attr_reader :page, :content - # return path set in app.rb not @page.path - def path - @path - end + # return path set in app.rb not @page.path + def path + @path + end def title "#{@page.title}" diff --git a/lib/gollum/views/editable.rb b/lib/gollum/views/editable.rb index 365573ad..472b22a4 100644 --- a/lib/gollum/views/editable.rb +++ b/lib/gollum/views/editable.rb @@ -4,7 +4,7 @@ module Precious Gollum::Markup.formats.map do |key, val| { :name => val[:name], :id => key.to_s, - :selected => selected == key} + :selected => selected == key } end.sort do |a, b| a[:name].downcase <=> b[:name].downcase end diff --git a/lib/gollum/views/file_view.rb b/lib/gollum/views/file_view.rb index c1a582ab..3aec9a0a 100644 --- a/lib/gollum/views/file_view.rb +++ b/lib/gollum/views/file_view.rb @@ -10,8 +10,8 @@ module Precious def has_results !@results.empty? end - - def no_results + + def no_results @results.empty? end end diff --git a/lib/gollum/views/history.rb b/lib/gollum/views/history.rb index ff486564..ca51254c 100644 --- a/lib/gollum/views/history.rb +++ b/lib/gollum/views/history.rb @@ -13,16 +13,16 @@ module Precious i = @versions.size + 1 @versions.map do |v| i -= 1 - { :id => v.id, - :id7 => v.id[0..6], - :num => i, - :selected => @page.version.id == v.id, - :author => v.author.name.respond_to?(:force_encoding) ? v.author.name.force_encoding('UTF-8') : v.author.name, - :message => v.message.respond_to?(:force_encoding) ? v.message.force_encoding('UTF-8') : v.message, - :date => v.authored_date.strftime("%B %d, %Y"), - :gravatar => Digest::MD5.hexdigest(v.author.email.strip.downcase), + { :id => v.id, + :id7 => v.id[0..6], + :num => i, + :selected => @page.version.id == v.id, + :author => v.author.name.respond_to?(:force_encoding) ? v.author.name.force_encoding('UTF-8') : v.author.name, + :message => v.message.respond_to?(:force_encoding) ? v.message.force_encoding('UTF-8') : v.message, + :date => v.authored_date.strftime("%B %d, %Y"), + :gravatar => Digest::MD5.hexdigest(v.author.email.strip.downcase), :identicon => self._identicon_code(v.author.email), - :date_full=> v.authored_date, + :date_full => v.authored_date, } end end @@ -36,16 +36,16 @@ module Precious def string_to_code string # sha bytes - b = [Digest::SHA1.hexdigest(string)[0,20]].pack('H*').bytes.to_a + b = [Digest::SHA1.hexdigest(string)[0, 20]].pack('H*').bytes.to_a # Thanks donpark's IdenticonUtil.java for this. # Match the following Java code # ((b[0] & 0xFF) << 24) | ((b[1] & 0xFF) << 16) | # ((b[2] & 0xFF) << 8) | (b[3] & 0xFF) return left_shift(b[0], 24) | - left_shift(b[1], 16) | - left_shift(b[2], 8) | - b[3] & 0xFF + left_shift(b[1], 16) | + left_shift(b[2], 8) | + b[3] & 0xFF end def _identicon_code(blob) @@ -53,7 +53,7 @@ module Precious end def use_identicon - @page.wiki.user_icons == 'identicon' + @page.wiki.user_icons == 'identicon' end def partial(name) diff --git a/lib/gollum/views/page.rb b/lib/gollum/views/page.rb index 90d7a5a1..5c20d59a 100644 --- a/lib/gollum/views/page.rb +++ b/lib/gollum/views/page.rb @@ -4,9 +4,9 @@ module Precious include HasPage attr_reader :content, :page, :header, :footer - DATE_FORMAT = "%Y-%m-%d %H:%M:%S" + DATE_FORMAT = "%Y-%m-%d %H:%M:%S" DEFAULT_AUTHOR = 'you' - @@to_xml = { :save_with => Nokogiri::XML::Node::SaveOptions::DEFAULT_XHTML ^ 1, :indent => 0, :encoding => 'UTF-8' } + @@to_xml = { :save_with => Nokogiri::XML::Node::SaveOptions::DEFAULT_XHTML ^ 1, :indent => 0, :encoding => 'UTF-8' } def title h1 = @h1_title ? page_header_from_content(@content) : false @@ -23,14 +23,14 @@ module Precious def author page_versions = @page.versions - first = page_versions ? page_versions.first : false + first = page_versions ? page_versions.first : false return DEFAULT_AUTHOR unless first first.author.name.respond_to?(:force_encoding) ? first.author.name.force_encoding('UTF-8') : first.author.name end def date page_versions = @page.versions - first = page_versions ? page_versions.first : false + first = page_versions ? page_versions.first : false return Time.now.strftime(DATE_FORMAT) unless first first.authored_date.strftime(DATE_FORMAT) end @@ -50,7 +50,7 @@ module Precious def allow_uploads @allow_uploads end - + def upload_dest @upload_dest end @@ -80,7 +80,7 @@ module Precious def footer_format has_footer && @footer.format.to_s end - + def bar_side @bar_side.to_s end @@ -153,7 +153,7 @@ module Precious # Extracts title from page if present. # def page_header_from_content(content) - doc = build_document(content) + doc = build_document(content) title = find_header_node(doc).inner_text.strip title = nil if title.empty? title @@ -162,11 +162,11 @@ module Precious # Returns page content without title if it was extracted. # def content_without_page_header(content) - doc = build_document(content) + doc = build_document(content) title = find_header_node(doc) title.remove unless title.empty? # .inner_html will cause href escaping on UTF-8 - doc.css("div#gollum-root").children.to_xml( @@to_xml ) + doc.css("div#gollum-root").children.to_xml(@@to_xml) end end end diff --git a/lib/gollum/views/pages.rb b/lib/gollum/views/pages.rb index 6bf95721..d2a85f5e 100644 --- a/lib/gollum/views/pages.rb +++ b/lib/gollum/views/pages.rb @@ -11,7 +11,7 @@ module Precious def breadcrumb if @path - path = Pathname.new(@path) + path = Pathname.new(@path) breadcrumb = [%{Home}] path.descend do |crumb| title = crumb.basename @@ -34,7 +34,7 @@ module Precious folder_links = [] @results.map { |page| - page_path = page.path.sub(/^#{@path}\//,'') + page_path = page.path.sub(/^#{@path}\//, '') if page_path.include?('/') folder = page_path.split('/').first diff --git a/templates/formatting.html b/templates/formatting.html deleted file mode 100644 index dd0b3df5..00000000 --- a/templates/formatting.html +++ /dev/null @@ -1,92 +0,0 @@ - - -

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas hendrerit eros felis. Nunc non enim at dolor malesuada pellentesque a quis nibh. Aliquam sit amet pretium ante. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas hendrerit eros felis. Nunc non enim at dolor malesuada pellentesque a quis nibh. Aliquam sit amet pretium ante. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas hendrerit eros felis. Nunc non enim at dolor malesuada pellentesque a quis nibh. Aliquam sit amet pretium ante. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas hendrerit eros felis. Nunc non enim at dolor malesuada pellentesque a quis nibh. Aliquam sit amet pretium ante. - -

-
- -

Google

-
-
- -Fusce ullamcorper orci enim. Duis lectus elit, convallis ac convallis sit amet, euismod imperdiet dolor. Nunc egestas nisi quis magna feugiat vitae fringilla elit fermentum. - -
-
- -

Google

-
-
- -Vivamus sollicitudin dolor sit amet elit mollis ultricies. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas hendrerit eros felis. Nunc non enim at dolor malesuada pellentesque a quis nibh. Aliquam sit amet pretium ante. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas hendrerit eros felis. Nunc non enim at dolor malesuada pellentesque a quis nibh. Aliquam sit amet pretium ante. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas hendrerit eros felis. Nunc non enim at dolor malesuada pellentesque a quis nibh. Aliquam sit amet pretium ante.

- -

-
- -

Google

-
-
- -

Phasellus porta dignissim leo vel hendrerit. Nulla pellentesque nisi ac nunc malesuada aliquam. Nullam et cursus augue. Sed rhoncus pharetra odio, vel dictum diam facilisis et. Etiam molestie justo ut purus elementum rhoncus. Fusce nec augue lectus. Proin a nisl ac lectus facilisis tempus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Praesent blandit tempus libero, in interdum odio dignissim quis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec quis arcu a metus tincidunt scelerisque eget sed mauris. Nullam pellentesque faucibus sodales. Integer ullamcorper enim id nibh tempor ultricies.

- -
-
- -

Google

-
-
- -

Phasellus porta dignissim leo vel hendrerit. Nulla pellentesque nisi ac nunc malesuada aliquam. Nullam et cursus augue. Sed rhoncus pharetra odio, vel dictum diam facilisis et. Etiam molestie justo ut purus elementum rhoncus. Fusce nec augue lectus. Proin a nisl ac lectus facilisis tempus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Praesent blandit tempus libero, in interdum odio dignissim quis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec quis arcu a metus tincidunt scelerisque eget sed mauris. Nullam pellentesque faucibus sodales. Integer ullamcorper enim id nibh tempor ultricies.

- -

-

-
- -
-
-

- -

Phasellus porta dignissim leo vel hendrerit. Nulla pellentesque nisi ac nunc malesuada aliquam. Nullam et cursus augue. Sed rhoncus pharetra odio, vel dictum diam facilisis et. Etiam molestie justo ut purus elementum rhoncus. Fusce nec augue lectus. Proin a nisl ac lectus facilisis tempus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Praesent blandit tempus libero, in interdum odio dignissim quis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec quis arcu a metus tincidunt scelerisque eget sed mauris. Nullam pellentesque faucibus sodales. Integer ullamcorper enim id nibh tempor ultricies.

-
- -
-
Phasellus porta dignissim leo vel hendrerit. Nulla pellentesque nisi ac nunc malesuada aliquam. Nullam et cursus augue. Sed rhoncus pharetra odio, vel dictum diam facilisis et. Etiam molestie justo ut purus elementum rhoncus. Fusce nec augue lectus. Proin a nisl ac lectus facilisis tempus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Praesent blandit tempus libero, in interdum odio dignissim quis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec quis arcu a metus tincidunt scelerisque eget sed mauris. Nullam pellentesque faucibus sodales. Integer ullamcorper enim id nibh tempor ultricies.

\ No newline at end of file diff --git a/templates/helper_wiki.rb b/templates/helper_wiki.rb deleted file mode 100644 index e43db0d4..00000000 --- a/templates/helper_wiki.rb +++ /dev/null @@ -1,10 +0,0 @@ -class WikiFactory - def self.create p - examples = testpath "examples" - path = File.join(examples, "test.git") - FileUtils.cp_r File.join(examples, "empty.git"), path, :remove_destination => true - Gollum::Wiki.default_options = {:universal_toc => false} - cleanup = Proc.new { FileUtils.rm_r File.join(File.dirname(__FILE__), *%w[examples test.git]) } - Gollum::Wiki.new(@path), @path, cleanup - end -end diff --git a/test/helper.rb b/test/helper.rb index 2cf30787..fd4bf782 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -5,6 +5,11 @@ require 'shoulda' require 'mocha/setup' require 'fileutils' require 'minitest/reporters' +require 'twitter_cldr' + +# Silence locale validation warning +require 'i18n' +I18n.enforce_available_locales = false MiniTest::Reporters.use! @@ -21,7 +26,7 @@ $METADATA = false # Make sure we're in the test dir, the tests expect that to be the current # directory. -TEST_DIR = File.join(File.dirname(__FILE__), *%w[.]) +TEST_DIR = File.join(File.dirname(__FILE__), *%w[.]) def testpath(path) File.join(TEST_DIR, path) @@ -59,14 +64,26 @@ def context(*args, &block) require 'test/unit' klass = Class.new(defined?(ActiveSupport::TestCase) ? ActiveSupport::TestCase : Test::Unit::TestCase) do def self.test(name, &block) - define_method("test_#{name.gsub(/\W/,'_')}", &block) if block + define_method("test_#{name.gsub(/\W/, '_')}", &block) if block + end + + def self.xtest(*args) + end + + def self.setup(&block) + define_method(:setup, &block) + end + + def self.teardown(&block) + define_method(:teardown, &block) end - def self.xtest(*args) end - def self.setup(&block) define_method(:setup, &block) end - def self.teardown(&block) define_method(:teardown, &block) end end - (class << klass; self end).send(:define_method, :name) { name.gsub(/\W/,'_') } + ( + class << klass; + self + end).send(:define_method, :name) { name.gsub(/\W/, '_') } $contexts << klass klass.class_eval &block end + $contexts = [] diff --git a/test/test_app.rb b/test/test_app.rb index 2e2de80c..ef0fc318 100644 --- a/test/test_app.rb +++ b/test/test_app.rb @@ -16,8 +16,8 @@ context "Frontend" do end test "urls transform unicode" do - header = '_Header' - footer = '_Footer' + header = '_Header' + footer = '_Footer' sidebar = '_Sidebar' # header, footer, and sidebar must be preserved @@ -63,9 +63,13 @@ context "Frontend" do assert_match /
one\ntwo\nthree\nfour\n<\/code><\/pre>\n/m, last_response.body
   end
 
+  def nfd utf8
+    TwitterCldr::Normalization::NFD.normalize utf8
+  end
+
   test "UTF-8 headers href preserved" do
     page = 'utfh1'
-    text = '한글'
+    text = nfd('한글')
 
     # don't use h1 or it will be promoted to replace file name
     # which doesn't generate a normal header link
@@ -74,7 +78,10 @@ context "Frontend" do
 
     get page
 
-    assert_match /

#{text}<\/a><\/h2>/, last_response.body + expected = "

#{text}

" + actual = nfd(last_response.body) + + assert_match /#{expected}/, actual end test "retain edit information" do @@ -101,7 +108,7 @@ context "Frontend" do test "edits page" do page_1 = @wiki.page('A') post "/edit/A", :content => 'abc', :page => 'A', - :format => page_1.format, :message => 'def' + :format => page_1.format, :message => 'def' follow_redirect! assert last_response.ok? @@ -115,7 +122,7 @@ context "Frontend" do test "edit page with empty message" do page_1 = @wiki.page('A') post "/edit/A", :content => 'abc', :page => 'A', - :format => page_1.format + :format => page_1.format follow_redirect! assert last_response.ok? @@ -129,39 +136,39 @@ context "Frontend" do test "edit page with slash" do page_1 = @wiki.page('A') post "/edit/A", :content => 'abc', :page => 'A', :path => '/////', - :format => page_1.format, :message => 'def' + :format => page_1.format, :message => 'def' follow_redirect! assert last_response.ok? end test "edits page header footer and sidebar" do - commits = @wiki.repo.commits('master').size - page_1 = @wiki.page('A') + commits = @wiki.repo.commits('master').size + page_1 = @wiki.page('A') header_1 = page_1.header - foot_1 = page_1.footer - side_1 = page_1.sidebar + foot_1 = page_1.footer + side_1 = page_1.sidebar post "/edit/A", :header => 'header', - :footer => 'footer', :page => "A", :sidebar => 'sidebar', :message => 'def' + :footer => 'footer', :page => "A", :sidebar => 'sidebar', :message => 'def' follow_redirect! assert_equal "/A", last_request.fullpath assert last_response.ok? @wiki.clear_cache - page_2 = @wiki.page(page_1.name) + page_2 = @wiki.page(page_1.name) header_2 = page_2.header - foot_2 = page_2.footer - side_2 = page_2.sidebar + foot_2 = page_2.footer + side_2 = page_2.sidebar assert_equal page_1.raw_data, page_2.raw_data assert_equal 'header', header_2.raw_data assert_equal 'footer', foot_2.raw_data - assert_equal 'def', foot_2.version.message + assert_equal 'def', foot_2.version.message assert_not_equal foot_1.version.sha, foot_2.version.sha assert_not_equal header_1.version.sha, header_2.version.sha assert_equal 'sidebar', side_2.raw_data - assert_equal 'def', side_2.version.message + assert_equal 'def', side_2.version.message assert_not_equal side_1.version.sha, side_2.version.sha assert_equal commits+1, @wiki.repo.commits('master').size end @@ -241,7 +248,7 @@ context "Frontend" do test "creates page" do post "/create", :content => 'abc', :page => "D", - :format => 'markdown', :message => 'def' + :format => 'markdown', :message => 'def' follow_redirect! assert last_response.ok? @@ -252,7 +259,7 @@ context "Frontend" do test "creates pages with escaped characters in title" do post "/create", :content => 'abc', :page => 'Title with spaces', - :format => 'markdown', :message => 'foo' + :format => 'markdown', :message => 'foo' assert_equal 'http://example.org/Title-with-spaces', last_response.headers['Location'] get "/Title-with-spaces" assert_match /abc/, last_response.body @@ -276,7 +283,7 @@ context "Frontend" do test "accessing redirectory redirects to index page" do post "/create", :content => 'abc', :page => 'Home', :path => '/foo/', - :format => 'markdown', :message => 'foo' + :format => 'markdown', :message => 'foo' assert_equal "http://example.org/foo/Home", last_response.headers['Location'] @@ -301,7 +308,7 @@ context "Frontend" do end test "create sets the correct path for a relative path subdirectory" do - dir = "foodir" + dir = "foodir" name = "#{dir}/bar" get "/create/#{name}" assert_match(/\/#{dir}/, last_response.body) @@ -309,14 +316,14 @@ context "Frontend" do end test "create sets the correct path for a relative path subdirectory with the page file directory set" do - Precious::App.set(:wiki_options, {:page_file_dir => "foo"}) - dir = "bardir" + Precious::App.set(:wiki_options, { :page_file_dir => "foo" }) + dir = "bardir" name = "#{dir}/baz" get "/create/foo/#{name}" assert_match(/\/#{dir}/, last_response.body) assert_no_match(/[^\/]#{dir}/, last_response.body) # reset page_file_dir - Precious::App.set(:wiki_options, {:page_file_dir => nil}) + Precious::App.set(:wiki_options, { :page_file_dir => nil }) end test "edit returns nil for non-existant page" do @@ -324,7 +331,7 @@ context "Frontend" do page = 'not-real-page' path = '/' post '/edit/', :content => 'edit_msg', - :page => page, :path => path, :message => '' + :page => page, :path => path, :message => '' page_e = @wiki.paged(page, path) assert_equal nil, page_e end @@ -334,7 +341,7 @@ context "Frontend" do path = 'a/b/' # path must end with / post '/create', :content => 'create_msg', :page => page, - :path => path, :format => 'markdown', :message => '' + :path => path, :format => 'markdown', :message => '' page_c = @wiki.paged(page, path) assert_equal 'create_msg', page_c.raw_data @@ -343,7 +350,7 @@ context "Frontend" do # post '/edit' fails. post '/edit/' works. post '/edit/', :content => 'edit_msg', - :page => page, :path => path, :message => '' + :page => page, :path => path, :message => '' page_e = @wiki.paged(page, path) assert_equal 'edit_msg', page_e.raw_data @@ -362,7 +369,7 @@ context "Frontend" do test "guards against creation of existing page" do name = "A" post "/create", :content => 'abc', :page => name, - :format => 'markdown', :message => 'def' + :format => 'markdown', :message => 'def' assert last_response.ok? @@ -374,7 +381,7 @@ context "Frontend" do test "delete a page" do name = "deleteme" post "/create", :content => 'abc', :page => name, - :format => 'markdown', :message => 'foo' + :format => 'markdown', :message => 'foo' page = @wiki.page(name) assert_equal 'abc', page.raw_data @@ -467,7 +474,7 @@ context "Frontend" do page1 = @wiki.page('A') gollum_author = { :name => 'ghi', :email => 'jkl' } - session = { 'gollum.author' => gollum_author } + session = { 'gollum.author' => gollum_author } post "/edit/A", { :content => 'abc', :page => 'A', :format => page1.format, :message => 'def' }, { 'rack.session' => session } follow_redirect! @@ -507,12 +514,12 @@ context "Frontend" do test "show edit page with header and footer and sidebar of multibyte" do post "/create", - :content => 'りんご', - :page => 'Multibyte', :format => :markdown, :message => 'mesg' + :content => 'りんご', + :page => 'Multibyte', :format => :markdown, :message => 'mesg' post "/edit/Multibyte", - :content => 'りんご', :header => 'みかん', :footer => 'バナナ', :sidebar => 'スイカ', - :page => 'Multibyte', :format => :markdown, :message => 'mesg' + :content => 'りんご', :header => 'みかん', :footer => 'バナナ', :sidebar => 'スイカ', + :page => 'Multibyte', :format => :markdown, :message => 'mesg' get "edit/Multibyte" @@ -620,7 +627,7 @@ context "Frontend with lotr" do Precious::App.set(:wiki_options, { :base_path => 'wiki' }) page = 'path' post "/create", :content => '123', :page => page, - :path => 'Mordor', :format => 'markdown', :message => 'oooh, scary' + :path => 'Mordor', :format => 'markdown', :message => 'oooh, scary' # should be wiki/Mordor/path assert_equal 'http://example.org/Mordor/' + page, last_response.headers['Location'] get '/Mordor/' + page @@ -632,7 +639,7 @@ context "Frontend with lotr" do test "create pages within sub-directories using page file dir" do post "/create", :content => 'one two', :page => 'base', - :path => 'wiki/Mordor', :format => 'markdown', :message => 'oooh, scary' + :path => 'wiki/Mordor', :format => 'markdown', :message => 'oooh, scary' assert_equal 'http://example.org/wiki/Mordor/base', last_response.headers['Location'] get "/wiki/Mordor/base" @@ -642,13 +649,13 @@ context "Frontend with lotr" do test "create pages within sub-directories" do post "/create", :content => 'big smelly creatures', :page => 'Orc', - :path => 'Mordor', :format => 'markdown', :message => 'oooh, scary' + :path => 'Mordor', :format => 'markdown', :message => 'oooh, scary' assert_equal 'http://example.org/Mordor/Orc', last_response.headers['Location'] get "/Mordor/Orc" assert_match /big smelly creatures/, last_response.body post "/create", :content => 'really big smelly creatures', :page => 'Uruk Hai', - :path => 'Mordor', :format => 'markdown', :message => 'oooh, very scary' + :path => 'Mordor', :format => 'markdown', :message => 'oooh, very scary' assert_equal 'http://example.org/Mordor/Uruk-Hai', last_response.headers['Location'] get "/Mordor/Uruk-Hai" assert_match /really big smelly creatures/, last_response.body @@ -656,12 +663,12 @@ context "Frontend with lotr" do test "edit pages within sub-directories" do post "/create", :content => 'big smelly creatures', :page => 'Orc', - :path => 'Mordor', :format => 'markdown', :message => 'oooh, scary' + :path => 'Mordor', :format => 'markdown', :message => 'oooh, scary' assert_equal 'http://example.org/Mordor/Orc', last_response.headers['Location'] post "/edit/Mordor/Orc", :content => 'not so big smelly creatures', - :page => 'Orc', :path => 'Mordor', :message => 'minor edit' + :page => 'Orc', :path => 'Mordor', :message => 'minor edit' assert_equal 'http://example.org/Mordor/Orc', last_response.headers['Location'] get "/Mordor/Orc" diff --git a/test/test_page_view.rb b/test/test_page_view.rb index d2376686..c4da61d4 100644 --- a/test/test_page_view.rb +++ b/test/test_page_view.rb @@ -5,7 +5,7 @@ require File.expand_path '../../lib/gollum/views/page', __FILE__ context "Precious::Views::Page" do setup do examples = testpath "examples" - @path = File.join(examples, "test.git") + @path = File.join(examples, "test.git") FileUtils.cp_r File.join(examples, "empty.git"), @path, :remove_destination => true @wiki = Gollum::Wiki.new(@path) end diff --git a/test/test_unicode.rb b/test/test_unicode.rb index 7df8e019..3dac8900 100644 --- a/test/test_unicode.rb +++ b/test/test_unicode.rb @@ -38,7 +38,7 @@ context "Frontend Unicode support" do test "creates korean page which contains korean content" do post "/create", :content => '한글 text', :page => "k", - :format => 'markdown', :message => 'def' + :format => 'markdown', :message => 'def' follow_redirect! assert last_response.ok? @@ -49,7 +49,7 @@ context "Frontend Unicode support" do test "heavy use 1" do post "/create", :content => '한글 text', :page => "PG", - :format => 'markdown', :message => 'def' + :format => 'markdown', :message => 'def' follow_redirect! assert last_response.ok? @@ -62,36 +62,36 @@ context "Frontend Unicode support" do assert last_response.ok? @wiki = Gollum::Wiki.new(@path) - page = @wiki.page('PG') + page = @wiki.page('PG') assert_equal '바뀐 text', utf8(page.raw_data) assert_equal 'ghi', page.version.message end test "heavy use 2" do post "/create", :content => '한글 text', :page => "k", - :format => 'markdown', :message => 'def' + :format => 'markdown', :message => 'def' follow_redirect! assert last_response.ok? @wiki.update_page(@wiki.page('k'), nil, nil, '다른 text', {}) @wiki = Gollum::Wiki.new(@path) - page = @wiki.page('k') + page = @wiki.page('k') assert_equal '다른 text', utf8(page.raw_data) post '/edit/' + CGI.escape('한글'), :page => 'k', :content => '바뀐 text', - :format => 'markdown', :message => 'ghi' + :format => 'markdown', :message => 'ghi' follow_redirect! assert last_response.ok? @wiki = Gollum::Wiki.new(@path) - page = @wiki.page('k') + page = @wiki.page('k') assert_equal '바뀐 text', utf8(page.raw_data) assert_equal 'ghi', page.version.message end test 'transliteration' do # TODO: Remove to_url once write_page changes are merged. - @wiki.write_page('ééééé'.to_url, :markdown, '한글 text', { :name => '', :email => '' } ) + @wiki.write_page('ééééé'.to_url, :markdown, '한글 text', { :name => '', :email => '' }) page = @wiki.page('eeeee') assert_equal '한글 text', utf8(page.raw_data) end