Compare commits

...

71 Commits

Author SHA1 Message Date
Vicent Marti 1c475f3215 Release 2.2.0 2012-09-01 12:24:17 +02:00
Vicent Marti ab699d94b0 Do not render LaTeX locally
Offload the rendering service to MathTran.org, the free and open-source
LaTeX rendering engine.
2012-09-01 12:23:02 +02:00
bootstraponline 942d32c9b6 Fix uninstall command 2012-08-30 21:36:11 -06:00
bootstraponline 97f15f0b18 Add edit hotkey. #496 2012-08-30 21:07:57 -06:00
bootstraponline ed49358c50 Add h1-3 shortcuts. #496 2012-08-30 20:54:20 -06:00
bootstraponline 85eeecd140 Add save hotkey. 2012-08-30 20:48:44 -06:00
bootstraponline 30fd40fbe5 Fix #498
Ruby 1.8.7 and ri can't deal with <!-- appearing in documentation.
Please upgrade to the latest Ruby if you're able to.
2012-08-30 20:29:53 -06:00
bootstraponline 2ed262cacd v2.1.9 2012-08-30 20:12:28 -06:00
bootstraponline 29a1ef8f8a Skip doc on install 2012-08-30 20:04:20 -06:00
bootstraponline 772d18ee62 Fix uninstall command 2012-08-30 20:00:54 -06:00
bootstraponline dd604d9942 Fix #498 2012-08-30 19:57:20 -06:00
bootstraponline 85abc83427 v2.1.8 2012-08-30 19:41:54 -06:00
bootstraponline 6d8220629c Fix #500 2012-08-30 19:37:57 -06:00
bootstraponline 6ff7ada096 Fix #495 2012-08-30 18:31:35 -03:00
bootstraponline 8575049de5 Update get /data
Remove leading slash from page
Fix edge case with path set to '/'
2012-08-30 11:40:07 -03:00
bootstraponline bb6fb0c253 pathName is undefined when not found instead of 0 2012-08-30 11:18:02 -03:00
bootstraponline eb2ad9f840 Fix path
.key now returns undefined on failure so path can be 0.
If path is undefined then use an empty string.
2012-08-30 11:14:24 -03:00
bootstraponline d0dd23fc11 Fix path 2012-08-30 11:09:44 -03:00
bootstraponline 7ae4acbdb0 Fix #497 #492
Data url now includes path.
2012-08-30 11:03:11 -03:00
bootstraponline 881590ab37 Merge pull request #494 from releu/fix-requiring-uri-encoding-components
Move require "uri_encode_component"
2012-08-28 18:33:18 -07:00
Jan Bernacki 5e479dc5d9 move require 2012-08-28 22:44:09 +04:00
bootstraponline 7db9c2e762 Merge pull request #487 from jm/master
Fix bug with missing variable 'ext'
2012-08-27 11:08:19 -07:00
bootstraponline ce6b0ac095 v2.1.7 2012-08-25 19:21:13 -06:00
bootstraponline 420bb06988 Fix create test. 2012-08-25 18:58:20 -06:00
bootstraponline 20566f8acf Fix #484 2012-08-25 18:54:07 -06:00
bootstraponline 1d5f69704a Clean paths so they start with one slash. 2012-08-25 18:41:13 -06:00
bootstraponline 0da664299e Fix edit. 2012-08-24 13:47:17 -06:00
bootstraponline 6e8fb2b457 Disable exact on edit for now. 2012-08-24 13:38:34 -06:00
bootstraponline d1c72a4ff3 Fix #483 and #481
Exact matching of requested pages

- /page is no longer the same as /a/page
- Deleting /page only deletes /page (before it would delete /a/page instead of /page)
- Edit currently breaks the unit tests if exact matching is enabled
- Fix redirect on create
- Add @giga's checked_dir = '' fix https://github.com/giga/gollum/commit/936958b47324a09c683cb90a2560484b47e09529
- Fix create unit test
2012-08-24 13:35:37 -06:00
bootstraponline 0bf05392e4 Redirect to correct path. #481 2012-08-24 12:26:59 -06:00
bootstraponline 7ecef0c045 Fix #479 2012-08-23 14:11:28 -06:00
bootstraponline 33ca329253 Handle nil slash. 2012-08-23 12:30:08 -06:00
bootstraponline 01fa4770cb Fix page lookup. #473 2012-08-23 12:16:40 -06:00
bootstraponline b76257c49c Restore foward slash. 2012-08-23 11:59:56 -06:00
bootstraponline e2fbf22f38 Fix #473. 2012-08-23 11:51:20 -06:00
bootstraponline 134432d029 v2.1.6 2012-08-23 11:33:00 -06:00
bootstraponline 8d4d6e80b8 Fix #475. 2012-08-23 11:27:40 -06:00
bootstraponline 85e6ef3dca v2.1.5 2012-08-22 19:57:22 -06:00
bootstraponline 60f1467229 Fix encoding for 1.8. 2012-08-22 18:51:41 -06:00
bootstraponline 1757242382 Don't unpack Fixnum. 2012-08-22 17:40:53 -06:00
bootstraponline 55df7bb9c4 Use encodeURIComponent instead of CGI::escape when output is sent to browser. 2012-08-22 17:30:46 -06:00
bootstraponline 686b8acd38 Fix encodeURIComponent on Ruby 1.8.
Replace .ord with .unpack('U')[0]
2012-08-22 17:23:08 -06:00
bootstraponline a5f9df6170 Restore CGI::escape. 2012-08-22 16:57:24 -06:00
bootstraponline 27f61a870a Merge pull request #477 from LuminosoInsight/master
Fix titles created with the "New" button.
2012-08-22 15:54:23 -07:00
bootstraponline a48e8d1c5c New editor style.
Disable MathJax in live preview. Parser isn't MathJax aware.
Performance of MathJax in live preview is not great.
Auto hide editor overflow.
2012-08-22 16:50:57 -06:00
bootstraponline b80f74bccd Remove protocol and host. 2012-08-22 13:32:18 -06:00
bootstraponline 1e768734ef Disable MathJax by default.
GitHub.com doesn't support MathJax. The parser is not MathJax aware which causes problems.

--mathjax enables MathJax.
2012-08-22 13:31:21 -06:00
bootstraponline 11c9cabeb3 Fix edit baseUrl. 2012-08-22 13:21:01 -06:00
bootstraponline 3a14ab92f0 Fix new page when using map '/wiki' in config.ru. 2012-08-22 13:15:18 -06:00
bootstraponline 62d5f52398 Fix anchor for Firefox. 2012-08-22 13:10:11 -06:00
Rob Speer 2b4848566c Fix names created with the 'New' button.
Previously, a page created with the 'New' button would get all of its
spaces turned into the + symbol when submitted, which Gollum would then
convert into "-plus-" in the title. So, for example, a request to create
a page called "Test page" would instead get "test plus page".

This change changes + to - in the parameter received by /create/.
2012-08-22 14:15:20 -04:00
bootstraponline 7c825e877c Remove protocol + host. 2012-08-20 15:51:07 -06:00
bootstraponline 8417c277e6 Fix delete link when using baseUrl. 2012-08-20 15:23:07 -06:00
bootstraponline 9cef423908 Remove default value in new page. 2012-08-19 14:25:02 -06:00
bootstraponline e73c84490e Remove prefix. #470. 2012-08-16 12:01:03 -06:00
bootstraponline 6cfc807db0 Revert still broken in Grit. 2012-08-15 12:22:03 -06:00
bootstraponline be366f8103 v2.1.4 2012-08-15 12:06:12 -06:00
bootstraponline 2d13bd796f Improve #470 fix. 2012-08-15 12:03:48 -06:00
bootstraponline 523f8f80ca Fix #470. 2012-08-15 11:48:17 -06:00
bootstraponline b76fef9143 Update version to 2.1.3 2012-08-13 11:37:56 -06:00
bootstraponline e935af83d5 Update gemspec. 2012-08-13 11:35:15 -06:00
bootstraponline d4e019ef42 Merge pull request #331 from tjh/home-page-link-issue
Redirect from root to /Home, fixes #250
2012-08-09 10:41:31 -07:00
bootstraponline 2e738828c6 Merge pull request #467 from jamesduncombe/pygments_initialize
Added Pygments.start to initialize Pygments on startup, fixes #465
2012-08-09 10:21:59 -07:00
James Duncombe fd7dc93778 Added Pygments.start to initialize Pygments on startup 2012-08-09 09:14:55 +01:00
bootstraponline 3df407d9ee Merge pull request #464 from giga/master
Fix editor when base url is '/'
2012-08-08 10:53:45 -07:00
Jean-Philippe Garcia Ballester 6fbba84725 Revert "Base path is relative."
This reverts commit 69e453ea0b.
2012-08-08 13:49:11 +02:00
Jean-Philippe Garcia Ballester 37d20fa9cc Base url without trailing '/'
This will allow cleaner url in templates and javascripts.
2012-08-08 13:49:09 +02:00
bootstraponline 410cd912ac Fix releasing. 2012-08-06 18:31:36 -06:00
bootstraponline d234bbd861 Test get %r{/(.+?)/([0-9a-f]{40})} do 2012-08-06 18:27:12 -06:00
Jeremy McAnally 3767a11d21 Rename variables to be more clear and fix reference to non-existent 'ext' variable 2012-07-04 12:33:09 -04:00
Tim Harvey 43d2143506 Redirect from root to /Home, fixes #250 2012-05-10 08:55:56 -04:00
33 changed files with 332 additions and 521 deletions
+5 -3
View File
@@ -520,14 +520,16 @@ your changes merged back into core is as follows:
1. Send a pull request to the github/gollum project. 1. Send a pull request to the github/gollum project.
## RELEASING ## RELEASING
Update VERSION in lib/gollum.rb
$ rake gemspec $ rake gemspec
$ git tag vX.Y.Z
$ git push origin vX.Y.Z
$ gem build gollum.gemspec $ gem build gollum.gemspec
$ gem push gollum-X.Y.Z.gem $ gem push gollum-X.Y.Z.gem
## BUILDING THE GEM FROM MASTER ## BUILDING THE GEM FROM MASTER
$ gem uninstall -aix gollum $ gem uninstall -aIx gollum
$ git clone https://github.com/github/gollum.git $ git clone https://github.com/github/gollum.git
$ cd gollum $ cd gollum
gollum$ rake build gollum$ rake build
gollum$ gem install pkg/gollum*.gem gollum$ gem install --no-ri --no-rdoc pkg/gollum*.gem
+2 -2
View File
@@ -65,8 +65,8 @@ opts = OptionParser.new do |opts|
wiki_options[:live_preview] = false wiki_options[:live_preview] = false
end end
opts.on("--no-mathjax", "Disables mathjax.") do opts.on("--mathjax", "Enables mathjax.") do
options['mathjax'] = false options['mathjax'] = true
end end
end end
+3 -3
View File
@@ -5,8 +5,8 @@ Gem::Specification.new do |s|
s.required_ruby_version = ">= 1.8.7" s.required_ruby_version = ">= 1.8.7"
s.name = 'gollum' s.name = 'gollum'
s.version = '2.1.2' s.version = '2.2.0'
s.date = '2012-08-06' s.date = '2012-09-01'
s.rubyforge_project = 'gollum' s.rubyforge_project = 'gollum'
s.summary = "A simple, Git-powered wiki." s.summary = "A simple, Git-powered wiki."
@@ -27,7 +27,7 @@ Gem::Specification.new do |s|
s.add_dependency('github-markup', [">= 0.7.0", "< 1.0.0"]) s.add_dependency('github-markup', [">= 0.7.0", "< 1.0.0"])
s.add_dependency('github-markdown') s.add_dependency('github-markdown')
s.add_dependency('pygments.rb', "~> 0.2.0") s.add_dependency('pygments.rb', "~> 0.2.0")
s.add_dependency('posix-spawn', "~> 0.3.0") s.add_dependency('escape_utils', "0.2.4")
s.add_dependency('sinatra', "~> 1.0") s.add_dependency('sinatra', "~> 1.0")
s.add_dependency('mustache', [">= 0.11.2", "< 1.0.0"]) s.add_dependency('mustache', [">= 0.11.2", "< 1.0.0"])
s.add_dependency('sanitize', "~> 2.0.0") s.add_dependency('sanitize', "~> 2.0.0")
+2 -1
View File
@@ -20,9 +20,10 @@ require File.expand_path('../gollum/markup', __FILE__)
require File.expand_path('../gollum/sanitization', __FILE__) require File.expand_path('../gollum/sanitization', __FILE__)
require File.expand_path('../gollum/tex', __FILE__) require File.expand_path('../gollum/tex', __FILE__)
require File.expand_path('../gollum/web_sequence_diagram', __FILE__) require File.expand_path('../gollum/web_sequence_diagram', __FILE__)
require File.expand_path('../gollum/frontend/uri_encode_component', __FILE__)
module Gollum module Gollum
VERSION = '2.1.2' VERSION = '2.2.0'
def self.assets_path def self.assets_path
::File.expand_path('gollum/frontend/public', ::File.dirname(__FILE__)) ::File.expand_path('gollum/frontend/public', ::File.dirname(__FILE__))
+7 -3
View File
@@ -100,9 +100,13 @@ module Gollum
tree.blobs.each do |blob| tree.blobs.each do |blob|
next if page_path_scheduled_for_deletion?(index.tree, fullpath) next if page_path_scheduled_for_deletion?(index.tree, fullpath)
file = blob.name.downcase.sub(/\.\w+$/, '')
file_ext = ::File.extname(blob.name).sub(/^\./, '') existing_file = blob.name.downcase.sub(/\.\w+$/, '')
if downpath == file && !(allow_same_ext && file_ext == ext) existing_file_ext = ::File.extname(blob.name).sub(/^\./, '')
new_file_ext = ::File.extname(path).sub(/^\./, '')
if downpath == existing_file && !(allow_same_ext && new_file_ext == existing_file_ext)
raise DuplicatePageError.new(dir, blob.name, path) raise DuplicatePageError.new(dir, blob.name, path)
end end
end end
+27 -25
View File
@@ -9,7 +9,6 @@ require 'gollum/frontend/views/layout'
require 'gollum/frontend/views/editable' require 'gollum/frontend/views/editable'
require 'gollum/frontend/views/has_page' require 'gollum/frontend/views/has_page'
require File.expand_path '../uri_encode_component', __FILE__
require File.expand_path '../helpers', __FILE__ require File.expand_path '../helpers', __FILE__
# Fix to_url # Fix to_url
@@ -82,12 +81,18 @@ module Precious
end end
before do before do
@base_url = url('/', false) @base_url = url('/', false).chomp('/')
settings.wiki_options.merge!({ :base_path => @base_url }) unless settings.wiki_options.has_key? :base_path settings.wiki_options.merge!({ :base_path => @base_url }) unless settings.wiki_options.has_key? :base_path
end end
get '/' do get '/' do
show_page_or_file('Home') redirect File.join(settings.wiki_options[:base_path].to_s, 'Home')
end
# Removes all slashes from the start of string.
def clean_url url
return url if url.nil?
url.gsub('%2F','/').gsub(/^\/+/,'')
end end
# path is set to name if path is nil. # path is set to name if path is nil.
@@ -95,14 +100,15 @@ module Precious
# path must have a trailing slash 'a/b/' or # path must have a trailing slash 'a/b/' or
# extract_path will trim path to 'a' # extract_path will trim path to 'a'
# name, path, version # name, path, version
def wiki_page( name, path = nil, version = nil) def wiki_page(name, path = nil, version = nil, exact = true)
path = name if path.nil? path = name if path.nil?
name = extract_name(name) name = extract_name(name)
path = extract_path(path) path = extract_path(path)
path = '/' if exact && path.nil?
wiki = wiki_new wiki = wiki_new
OpenStruct.new(:wiki => wiki, :page => wiki.paged(name, path, version), OpenStruct.new(:wiki => wiki, :page => wiki.paged(name, path, exact, version),
:name => name, :path => path) :name => name, :path => path)
end end
@@ -136,19 +142,19 @@ module Precious
mustache :edit mustache :edit
end end
else else
redirect to("/create/#{CGI.escape(@name)}") redirect to("/create/#{encodeURIComponent(@name)}")
end end
end end
post '/edit/*' do post '/edit/*' do
wikip = wiki_page(CGI.unescape(params[:page]), sanitize_empty_params(params[:path])) path = '/' + clean_url(sanitize_empty_params(params[:path])).to_s
path = wikip.path page_name = CGI.unescape(params[:page])
wiki = wikip.wiki wiki = wiki_new
page = wikip.page page = wiki.paged(page_name, path, exact = true)
rename = params[:rename].to_url if params[:rename] rename = params[:rename].to_url if params[:rename]
name = rename || page.name name = rename || page.name
committer = Gollum::Committer.new(wiki, commit_message) committer = Gollum::Committer.new(wiki, commit_message)
commit = {:committer => committer} commit = {:committer => committer}
update_wiki_page(wiki, page, params[:content], commit, name, params[:format]) update_wiki_page(wiki, page, params[:content], commit, name, params[:format])
update_wiki_page(wiki, page.header, params[:header], commit) if params[:header] update_wiki_page(wiki, page.header, params[:header], commit) if params[:header]
@@ -172,7 +178,7 @@ module Precious
end end
get '/create/*' do get '/create/*' do
wikip = wiki_page(params[:splat].first) wikip = wiki_page(params[:splat].first.gsub('+', '-'))
@name = wikip.name.to_url @name = wikip.name.to_url
@path = wikip.path @path = wikip.path
@@ -187,6 +193,7 @@ module Precious
post '/create' do post '/create' do
name = params[:page].to_url name = params[:page].to_url
path = sanitize_empty_params(params[:path]) path = sanitize_empty_params(params[:path])
path = '' if path.nil?
format = params[:format].intern format = params[:format].intern
# write_page is not directory aware so use wiki_options to emulate dir support. # write_page is not directory aware so use wiki_options to emulate dir support.
@@ -195,8 +202,7 @@ module Precious
begin begin
wiki.write_page(name, format, params[:content], commit_message) wiki.write_page(name, format, params[:content], commit_message)
page = wiki.page(name) redirect to("/#{clean_url(CGI.escape(::File.join(path,name)))}")
redirect to("/#{page.escaped_url_path}") unless page.nil?
rescue Gollum::DuplicatePageError => e rescue Gollum::DuplicatePageError => e
@message = "Duplicate page: #{e.message}" @message = "Duplicate page: #{e.message}"
mustache :error mustache :error
@@ -276,12 +282,6 @@ module Precious
mustache :compare mustache :compare
end end
get '/_tex.png' do
content_type 'image/png'
formula = Base64.decode64(params[:data])
Gollum::Tex.render_formula(formula)
end
get %r{^/(javascript|css|images)} do get %r{^/(javascript|css|images)} do
halt 404 halt 404
end end
@@ -341,7 +341,9 @@ module Precious
path = extract_path(fullpath) path = extract_path(fullpath)
wiki = wiki_new wiki = wiki_new
if page = wiki.paged(name, path) path = '/' if path.nil?
if page = wiki.paged(name, path, exact = true)
@page = page @page = page
@name = name @name = name
@editable = true @editable = true
@@ -354,7 +356,7 @@ module Precious
file.raw_data file.raw_data
else else
page_path = [path, name].compact.join('/') page_path = [path, name].compact.join('/')
redirect to("/create/#{CGI.escape(page_path).gsub('%2F','/')}") redirect to("/create/#{clean_url(encodeURIComponent(page_path))}")
end end
end end
@@ -196,7 +196,9 @@
LanguageDefinition.getHookFunctionFor("activate")(); LanguageDefinition.getHookFunctionFor("activate")();
} }
function hotkey( cmd ) { function hotkey( e, cmd ) {
e.preventDefault();
var def = LanguageDefinition.getDefinitionFor( cmd ); var def = LanguageDefinition.getDefinitionFor( cmd );
if ( typeof def == 'object' ) { if ( typeof def == 'object' ) {
FunctionBar.executeAction( def ); FunctionBar.executeAction( def );
@@ -205,8 +207,17 @@
return false; return false;
} }
Mousetrap.bind(['command+b', 'ctrl+b'], function(){ hotkey('function-bold'); }); Mousetrap.bind(['command+1', 'ctrl+1'], function( e ){ hotkey( e, 'function-h1' ); });
Mousetrap.bind(['command+i', 'ctrl+i'], function(){ hotkey('function-italic'); }); Mousetrap.bind(['command+2', 'ctrl+2'], function( e ){ hotkey( e, 'function-h2' ); });
Mousetrap.bind(['command+3', 'ctrl+3'], function( e ){ hotkey( e, 'function-h3' ); });
Mousetrap.bind(['command+b', 'ctrl+b'], function( e ){ hotkey( e, 'function-bold' ); });
Mousetrap.bind(['command+i', 'ctrl+i'], function( e ){ hotkey( e, 'function-italic' ); });
Mousetrap.bind(['command+s', 'ctrl+s'], function( e ){
e.preventDefault();
$("#gollum-editor-submit").trigger("click");
return false;
});
} ); } );
} else { } else {
LanguageDefinition._ACTIVE_LANG = name; LanguageDefinition._ACTIVE_LANG = name;
@@ -277,7 +288,7 @@
} }
// attempt to load the definition for this language // attempt to load the definition for this language
var script_uri = '.' + baseUrl + '/javascript/editor/langs/' + markup_name + '.js'; var script_uri = baseUrl + '/javascript/editor/langs/' + markup_name + '.js';
$.ajax({ $.ajax({
url: script_uri, url: script_uri,
dataType: 'script', dataType: 'script',
@@ -4,7 +4,7 @@ $(document).ready(function() {
var ok = confirm($(this).data('confirm')); var ok = confirm($(this).data('confirm'));
if ( ok ) { if ( ok ) {
var loc = window.location; var loc = window.location;
loc = baseUrl + 'delete' + loc.pathname loc = baseUrl + '/delete' + loc.pathname.replace(baseUrl,'');
window.location = loc; window.location = loc;
} }
// Don't navigate on cancel. // Don't navigate on cancel.
@@ -138,10 +138,10 @@ $(document).ready(function() {
var msg = 'Renamed ' + oldName + ' to ' + newName; var msg = 'Renamed ' + oldName + ' to ' + newName;
jQuery.ajax( { jQuery.ajax( {
type: 'POST', type: 'POST',
url: baseUrl + 'edit/' + oldName, url: baseUrl + '/edit/' + oldName,
data: { path: path, rename: newName, page: oldName, message: msg }, data: { path: path, rename: newName, page: oldName, message: msg },
success: function() { success: function() {
window.location = baseUrl + encodeURIComponent(newName); window.location = baseUrl + '/' + encodeURIComponent(newName);
} }
}); });
} }
@@ -154,14 +154,6 @@ $(document).ready(function() {
$('#minibutton-new-page').click(function(e) { $('#minibutton-new-page').click(function(e) {
e.preventDefault(); e.preventDefault();
var path = location.pathname;
// ensure there's more than one slash in pathname.
if (path.split('/').length > 2) {
path = path.substr(0, path.lastIndexOf('/') + 1);
} else {
path = '';
}
$.GollumDialog.init({ $.GollumDialog.init({
title: 'Create New Page', title: 'Create New Page',
fields: [ fields: [
@@ -169,7 +161,7 @@ $(document).ready(function() {
id: 'name', id: 'name',
name: 'Page Name', name: 'Page Name',
type: 'text', type: 'text',
defaultValue: path || '' defaultValue: ''
} }
], ],
OK: function( res ) { OK: function( res ) {
@@ -177,7 +169,7 @@ $(document).ready(function() {
if ( res['name'] ) { if ( res['name'] ) {
name = res['name']; name = res['name'];
} }
window.location = baseUrl + encodeURIComponent(name); window.location = baseUrl + '/' + encodeURIComponent(name);
} }
}); });
}); });
@@ -2,6 +2,10 @@ body {
overflow: hidden; overflow: hidden;
} }
#editor .ace_sb {
overflow-y: auto !important;
}
#darkness { #darkness {
visibility: hidden; visibility: hidden;
position: absolute; position: absolute;
@@ -49,7 +53,7 @@ so editor doesn't display in the background. */
#contentframe { #contentframe {
margin: 0 auto; margin: 0 auto;
overflow: visible; overflow: visible;
width: 80%; width: 90%;
} }
#previewframe { #previewframe {
@@ -63,14 +67,35 @@ so editor doesn't display in the background. */
right: 0; right: 0;
} }
.editor_bg {
position: fixed;
top: 0;
margin: 0;
padding: 0;
background: black;
width: 50%;
height: 100%;
z-index: -2;
}
.toolpanel_bg {
position: fixed;
background: #666;
top: 0;
height: 30px;
width: 100%;
padding: 5px 0;
margin: 0;
z-index: -1;
}
/* -- Start from notepag.es -- */ /* -- Start from notepag.es -- */
.toolpanel { .toolpanel {
position: fixed; position: fixed;
background: #666; background: #666;
top: 0; top: 0;
height: 30px; height: 30px;
right: 20px; width: 50%;
width: 80px;
vertical-align: middle; vertical-align: middle;
padding: 5px 0; padding: 5px 0;
margin: 0; margin: 0;
@@ -16,6 +16,9 @@
<a id='toggle' class='edit' href='javascript:void(0)' onclick='jsm.toggleLeftRight();'><img src='images/lr_24.png' alt='Toggle left to right' title='Toggle left to right'></a> <a id='toggle' class='edit' href='javascript:void(0)' onclick='jsm.toggleLeftRight();'><img src='images/lr_24.png' alt='Toggle left to right' title='Toggle left to right'></a>
</div> </div>
<div id='editor_bg' class='editor_bg'></div>
<div class='toolpanel_bg'></div>
<div id='commenttoolpanel' class='toolpanel edit' style='width: 500px; right: 0px; '> <div id='commenttoolpanel' class='toolpanel edit' style='width: 500px; right: 0px; '>
<a id='savecommentconfirm' class='edit'><img src='images/savecomment_24.png' alt='Confirm save with comment' title='Confirm save with comment'></a> <a id='savecommentconfirm' class='edit'><img src='images/savecomment_24.png' alt='Confirm save with comment' title='Confirm save with comment'></a>
<a id='commentcancel' class='edit'><img src='images/cancel_24.png' alt='Cancel save with comment' title='Cancel save with comment'></a> <a id='commentcancel' class='edit'><img src='images/cancel_24.png' alt='Cancel save with comment' title='Cancel save with comment'></a>
@@ -36,11 +39,11 @@ var require = {
<script src='js/sundown.js'></script> <script src='js/sundown.js'></script>
<script src='js/md_sundown.js'></script> <script src='js/md_sundown.js'></script>
<script src='js/livepreview.js'></script> <script src='js/livepreview.js'></script>
<script>(function(d,j){ <!--<script>(function(d,j){
j = d.createElement('script'); j = d.createElement('script');
j.src = 'https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML'; j.src = 'https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
(d.head || d.getElementsByTagName('head')[0]).appendChild(j); (d.head || d.getElementsByTagName('head')[0]).appendChild(j);
}(document)); }(document));
</script> </script>-->
</body> </body>
</html> </html>
@@ -62,9 +62,10 @@ initAce( commentEditor, commentEditorSession );
var baseUrl = location.pathname.split('/').slice(0,-2).join('/'); var baseUrl = location.pathname.split('/').slice(0,-2).join('/');
// RegExp from http://stackoverflow.com/questions/901115/get-query-string-values-in-javascript // RegExp from http://stackoverflow.com/questions/901115/get-query-string-values-in-javascript
// Returns value on success and undefined on failure.
$.key = function( key ) { $.key = function( key ) {
var value = new RegExp( '[\\?&]' + key + '=([^&#]*)' ).exec( location.href ); var value = new RegExp( '[\\?&]' + key + '=([^&#]*)' ).exec( location.href );
return ( !value ) ? 0 : value[ 1 ] || 0; return ( !value ) ? undefined : value[ 1 ] || undefined;
} }
// True if &create=true // True if &create=true
@@ -73,10 +74,6 @@ var create = $.key( 'create' );
var pageName = $.key( 'page' ); var pageName = $.key( 'page' );
var pathName = $.key( 'path' ); var pathName = $.key( 'path' );
if ( pathName === 0 ) {
pathName = undefined;
}
defaultCommitMessage = function() { defaultCommitMessage = function() {
var msg = pageName + ' (markdown)'; var msg = pageName + ' (markdown)';
@@ -97,15 +94,23 @@ $.save = function( commitMessage ) {
var markdown = 'markdown'; var markdown = 'markdown';
var txt = editorSession.getValue(); var txt = editorSession.getValue();
var msg = defaultCommitMessage(); var msg = defaultCommitMessage();
var newLocation = location.protocol + '//' + location.host + baseUrl; var newLocation = baseUrl;
function clean( str ) {
return str.replace(/^\/+/, '/');
}
// 'a%2Fb' => a/b // 'a%2Fb' => a/b
if (pathName) { if ( pathName ) {
newLocation += '/' + unescape(pathName); pathName = unescape( pathName );
newLocation += '/' + pathName;
pathName = pathName + '/'; // pathName must end with / pathName = pathName + '/'; // pathName must end with /
pathName = clean( pathName );
} }
newLocation += '/' + pageName; newLocation += '/' + pageName;
newLocation = clean( newLocation );
// if &create=true then handle create instead of edit. // if &create=true then handle create instead of edit.
if ( create ) { if ( create ) {
@@ -333,10 +338,23 @@ var applyTimeout = function () {
/* Load markdown from /data/page into the ace editor. /* Load markdown from /data/page into the ace editor.
~-1 == false; !~-1 == true; ~-1 == false; !~-1 == true;
*/ */
if ( !~location.host.indexOf('github.com') ) { if ( !~ location.host.indexOf( 'github.com' ) ) {
// returns unescaped key with leading slashes removed
function key_no_leading_slash( key ) {
return unescape( $.key( key ) || '' ).replace( /^\/+/, '' );
}
// ensure leading / is removed from path and that it ends with /
var path = key_no_leading_slash( 'path' );
// don't append '/' if path is empty from removing leading slash
if ( path !== '' && path.charAt( path.length - 1 ) !== '/' ) {
path += '/';
}
jQuery.ajax( { jQuery.ajax( {
type: 'GET', type: 'GET',
url: baseUrl + '/data/' + $.key( 'page' ), url: baseUrl + '/data/' + path + key_no_leading_slash( 'page' ),
success: function( data ) { success: function( data ) {
editorSession.setValue( data ); editorSession.setValue( data );
} }
@@ -397,7 +415,8 @@ var applyTimeout = function () {
var heightHalf = height / 2; var heightHalf = height / 2;
// height minus 50 so the end of document text doesn't flow off the page. // height minus 50 so the end of document text doesn't flow off the page.
var editorContainerStyle = 'width:' + widthHalf + 'px;' + // + 15 for scroll bar
var editorContainerStyle = 'width:' + (widthHalf + 15) + 'px;' +
'height:' + (height - 50) + 'px;' + 'height:' + (height - 50) + 'px;' +
'left:' + (leftRight === false ? widthHalf + 'px;' : '0px;') + 'left:' + (leftRight === false ? widthHalf + 'px;' : '0px;') +
'top:' + '40px;'; // use 40px for tool menu 'top:' + '40px;'; // use 40px for tool menu
@@ -408,12 +427,12 @@ var applyTimeout = function () {
var previewStyle = 'width:' + (widthHalf - 2 - 10) + 'px;' + var previewStyle = 'width:' + (widthHalf - 2 - 10) + 'px;' +
'height:' + height + 'px;' + 'height:' + height + 'px;' +
'left:' + (leftRight === false ? '10px;' : widthHalf + 'px;') + 'left:' + (leftRight === false ? '10px;' : widthHalf + 'px;') +
'top:' + '0px;'; // preview panel top is equal to height of comment tool panel (40px) + 1
'top:41px;';
cssSet( preview, previewStyle ); cssSet( preview, previewStyle );
// Resize tool panel // Resize tool panel
var toolPanelStyle = 'width:' + widthHalf + 'px;' + var toolPanelStyle = 'width:50%;';
'left:' + (leftRight === false ? widthHalf + 'px;' : '0px;');
cssSet( toolPanel, toolPanelStyle ); cssSet( toolPanel, toolPanelStyle );
// Resize comment related elements. // Resize comment related elements.
@@ -428,10 +447,12 @@ var applyTimeout = function () {
cssSet( commentEditorContainer, commentEditorContainerStyle ); cssSet( commentEditorContainer, commentEditorContainerStyle );
commentEditor.resize(); commentEditor.resize();
var commentToolPanelHeight = height / 4 - 40;
// In top subtract height (40px) of comment tool panel. // In top subtract height (40px) of comment tool panel.
var commentToolPanelStyle = 'width:' + widthHalf + 'px;' + var commentToolPanelStyle = 'width:' + widthHalf + 'px;' +
'left:' + widthFourth + 'px;' + 'left:' + widthFourth + 'px;' +
'top:' + (height / 4 - 40) + 'px;' + 'top:' + commentToolPanelHeight + 'px;' +
commentHidden; commentHidden;
cssSet( commentToolPanel, commentToolPanelStyle ); cssSet( commentToolPanel, commentToolPanelStyle );
@@ -444,6 +465,11 @@ var applyTimeout = function () {
win.jsm.resize = resize; win.jsm.resize = resize;
// remove editor_bg after loading because
// it'll cause problems if toggle left right is used
var ebg = doc.getElementById('editor_bg');
ebg.parentNode.removeChild(ebg);
/* /*
Resize can be called an absurd amount of times Resize can be called an absurd amount of times
and will crash the page without debouncing. and will crash the page without debouncing.
@@ -6,11 +6,11 @@
<li class="minibutton"> <li class="minibutton">
{{>searchbar}} {{>searchbar}}
</li> </li>
<li class="minibutton"><a href="{{base_url}}{{escaped_url_path}}" <li class="minibutton"><a href="{{base_url}}/{{escaped_url_path}}"
class="action-view-page">View Page</a></li> class="action-view-page">View Page</a></li>
<li class="minibutton"><a href="{{base_url}}edit/{{escaped_url_path}}" <li class="minibutton"><a href="{{base_url}}/edit/{{escaped_url_path}}"
class="action-edit-page">Edit Page</a></li> class="action-edit-page">Edit Page</a></li>
<li class="minibutton"><a href="{{base_url}}history/{{escaped_url_path}}" <li class="minibutton"><a href="{{base_url}}/history/{{escaped_url_path}}"
class="action-page-history">Page History</a></li> class="action-page-history">Page History</a></li>
</ul> </ul>
</div> </div>
@@ -23,10 +23,10 @@
{{#show_revert}} {{#show_revert}}
<ul class="actions"> <ul class="actions">
<li class="minibutton"><a href="{{base_url}}history/{{escaped_url_path}}" <li class="minibutton"><a href="{{base_url}}/history/{{escaped_url_path}}"
class="action-page-history">Back to Page History</a></li> class="action-page-history">Back to Page History</a></li>
<li class="minibutton"> <li class="minibutton">
<form name="gollum-revert" action="{{base_url}}revert/{{escaped_url_path}}/{{before}}/{{after}}" method="post" id="gollum-revert-form"> <form name="gollum-revert" action="{{base_url}}/revert/{{escaped_url_path}}/{{before}}/{{after}}" method="post" id="gollum-revert-form">
<a href="#" class="gollum-revert-button">Revert Changes</a> <a href="#" class="gollum-revert-button">Revert Changes</a>
</form> </form>
</li> </li>
@@ -49,7 +49,7 @@
</div> </div>
<div id="footer"> <div id="footer">
<ul class="actions"> <ul class="actions">
<li class="minibutton"><a href="{{base_url}}history/{{escaped_url_path}}" <li class="minibutton"><a href="{{base_url}}/history/{{escaped_url_path}}"
class="action-page-history">Back to Page History</a></li> class="action-page-history">Back to Page History</a></li>
{{#show_revert}} {{#show_revert}}
<li class="minibutton"> <li class="minibutton">
+2 -2
View File
@@ -2,9 +2,9 @@
<div id="head"> <div id="head">
<h1>Editing <strong>{{title}}</strong></h1> <h1>Editing <strong>{{title}}</strong></h1>
<ul class="actions"> <ul class="actions">
<li class="minibutton"><a href="{{base_url}}{{escaped_url_path}}" <li class="minibutton"><a href="{{base_url}}/{{escaped_url_path}}"
class="action-view-page">View Page</a></li> class="action-view-page">View Page</a></li>
<li class="minibutton"><a href="{{base_url}}history/{{escaped_url_path}}" <li class="minibutton"><a href="{{base_url}}/history/{{escaped_url_path}}"
class="action-page-history">Page History</a></li> class="action-page-history">Page History</a></li>
</ul> </ul>
</div> </div>
@@ -1,9 +1,9 @@
<div id="gollum-editor" data-escaped-name="{{escaped_name}}" class="{{#is_create_page}}create{{/is_create_page}}{{#is_edit_page}}edit{{/is_edit_page}}"> <div id="gollum-editor" data-escaped-name="{{escaped_name}}" class="{{#is_create_page}}create{{/is_create_page}}{{#is_edit_page}}edit{{/is_edit_page}}">
{{#is_create_page}} {{#is_create_page}}
<form name="gollum-editor" action="{{base_url}}create" method="post"> <form name="gollum-editor" action="{{base_url}}/create" method="post">
{{/is_create_page}} {{/is_create_page}}
{{#is_edit_page}} {{#is_edit_page}}
<form name="gollum-editor" action="{{base_url}}edit/{{escaped_name}}" method="post"> <form name="gollum-editor" action="{{base_url}}/edit/{{escaped_name}}" method="post">
{{/is_edit_page}} {{/is_edit_page}}
<fieldset id="gollum-editor-fields"> <fieldset id="gollum-editor-fields">
{{#is_create_page}} {{#is_create_page}}
@@ -126,7 +126,7 @@
<span class="jaws"><br></span> <span class="jaws"><br></span>
<input type="submit" id="gollum-editor-submit" value="Save" title="Save current changes"> <input type="submit" id="gollum-editor-submit" value="Save" title="Save current changes">
<a href="{{base_url}}preview" id="gollum-editor-preview" class="minibutton" title="Preview this Page">Preview</a> <a href="{{base_url}}/preview" id="gollum-editor-preview" class="minibutton" title="Preview this Page">Preview</a>
</fieldset> </fieldset>
</form> </form>
</div> </div>
@@ -2,9 +2,9 @@
<html> <html>
<head> <head>
<meta http-equiv="Content-type" content="text/html;charset=utf-8"> <meta http-equiv="Content-type" content="text/html;charset=utf-8">
<link rel="stylesheet" type="text/css" href="{{base_url}}css/gollum.css" media="all"> <link rel="stylesheet" type="text/css" href="{{base_url}}/css/gollum.css" media="all">
<link rel="stylesheet" type="text/css" href="{{base_url}}css/template.css" media="all"> <link rel="stylesheet" type="text/css" href="{{base_url}}/css/template.css" media="all">
<link rel="stylesheet" type="text/css" href="{{base_url}}css/_styles.css" media="all"> <link rel="stylesheet" type="text/css" href="{{base_url}}/css/_styles.css" media="all">
<title>{{title}}</title> <title>{{title}}</title>
</head> </head>
<body> <body>
@@ -12,7 +12,7 @@
<div id="home_button"> <div id="home_button">
<ul class="actions"> <ul class="actions">
<li class="minibutton"> <li class="minibutton">
<a href="{{base_url}}" class="action-edit-page">Home</a> <a href="{{base_url}}/" class="action-edit-page">Home</a>
</li> </li>
</ul> </ul>
</div> </div>
@@ -5,9 +5,9 @@
<li class="minibutton"> <li class="minibutton">
{{>searchbar}} {{>searchbar}}
</li> </li>
<li class="minibutton"><a href="{{base_url}}{{escaped_url_path}}" <li class="minibutton"><a href="{{base_url}}/{{escaped_url_path}}"
class="action-view-page">View Page</a></li> class="action-view-page">View Page</a></li>
<li class="minibutton"><a href="{{base_url}}edit/{{escaped_url_path}}" <li class="minibutton"><a href="{{base_url}}/edit/{{escaped_url_path}}"
class="action-edit-page">Edit Page</a></li> class="action-edit-page">Edit Page</a></li>
</ul> </ul>
</div> </div>
@@ -19,7 +19,7 @@
</ul> </ul>
<form name="compare-versions" id="version-form" method="post" <form name="compare-versions" id="version-form" method="post"
action="{{base_url}}compare/{{escaped_url_path}}"> action="{{base_url}}/compare/{{escaped_url_path}}">
<fieldset> <fieldset>
<table> <table>
<tbody> <tbody>
@@ -39,7 +39,7 @@
<td class="commit-name"> <td class="commit-name">
<span class="time-elapsed">{{date}}:</span>&nbsp; <span class="time-elapsed">{{date}}:</span>&nbsp;
{{message}} {{message}}
[<a href="{{base_url}}{{escaped_url_path}}/{{id}}" title="View commit">{{id7}}</a>] [<a href="{{base_url}}/{{escaped_url_path}}/{{id}}" title="View commit">{{id7}}</a>]
</td> </td>
</tr> </tr>
{{/versions}} {{/versions}}
+11 -11
View File
@@ -2,22 +2,22 @@
<html> <html>
<head> <head>
<meta http-equiv="Content-type" content="text/html;charset=utf-8"> <meta http-equiv="Content-type" content="text/html;charset=utf-8">
<link rel="stylesheet" type="text/css" href="{{base_url}}css/gollum.css" media="all"> <link rel="stylesheet" type="text/css" href="{{base_url}}/css/gollum.css" media="all">
<link rel="stylesheet" type="text/css" href="{{base_url}}css/editor.css" media="all"> <link rel="stylesheet" type="text/css" href="{{base_url}}/css/editor.css" media="all">
<link rel="stylesheet" type="text/css" href="{{base_url}}css/dialog.css" media="all"> <link rel="stylesheet" type="text/css" href="{{base_url}}/css/dialog.css" media="all">
<link rel="stylesheet" type="text/css" href="{{base_url}}css/template.css" media="all"> <link rel="stylesheet" type="text/css" href="{{base_url}}/css/template.css" media="all">
<!--[if IE 7]> <!--[if IE 7]>
<link rel="stylesheet" type="text/css" href="{{base_url}}css/ie7.css" media="all"> <link rel="stylesheet" type="text/css" href="{{base_url}}/css/ie7.css" media="all">
<![endif]--> <![endif]-->
<script>var baseUrl = '{{base_url}}'</script> <script>var baseUrl = '{{base_url}}'</script>
<script type="text/javascript" src="{{base_url}}javascript/jquery-1.7.2.min.js"></script> <script type="text/javascript" src="{{base_url}}/javascript/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="{{base_url}}javascript/mousetrap.min.js"></script> <script type="text/javascript" src="{{base_url}}/javascript/mousetrap.min.js"></script>
<script type="text/javascript" src="{{base_url}}javascript/gollum.js"></script> <script type="text/javascript" src="{{base_url}}/javascript/gollum.js"></script>
<script type="text/javascript" src="{{base_url}}javascript/gollum.dialog.js"></script> <script type="text/javascript" src="{{base_url}}/javascript/gollum.dialog.js"></script>
<script type="text/javascript" src="{{base_url}}javascript/gollum.placeholder.js"></script> <script type="text/javascript" src="{{base_url}}/javascript/gollum.placeholder.js"></script>
<script type="text/javascript" src="{{base_url}}javascript/editor/gollum.editor.js"></script> <script type="text/javascript" src="{{base_url}}/javascript/editor/gollum.editor.js"></script>
{{#mathjax}}<script>(function(d,j){ {{#mathjax}}<script>(function(d,j){
j = d.createElement('script'); j = d.createElement('script');
j.src = 'https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML'; j.src = 'https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
+13 -6
View File
@@ -1,3 +1,10 @@
<script>
Mousetrap.bind(['e'], function( e ) {
e.preventDefault();
window.location = "/edit" + window.location.pathname;
return false;
});
</script>
<div id="wiki-wrapper" class="page"> <div id="wiki-wrapper" class="page">
<div id="head"> <div id="head">
<h1>{{title}}</h1> <h1>{{title}}</h1>
@@ -5,21 +12,21 @@
<li class="minibutton"> <li class="minibutton">
{{>searchbar}} {{>searchbar}}
</li> </li>
<li class="minibutton"><a href="{{base_url}}" <li class="minibutton"><a href="{{base_url}}/"
class="action-edit-page">Home</a></li> class="action-edit-page">Home</a></li>
<li class="minibutton"><a href="{{base_url}}pages" <li class="minibutton"><a href="{{base_url}}/pages"
class="action-all-pages">All</a></li> class="action-all-pages">All</a></li>
<li class="minibutton"><a href="{{base_url}}fileview" <li class="minibutton"><a href="{{base_url}}/fileview"
class="action-all-pages">Files</a></li> class="action-all-pages">Files</a></li>
<li class="minibutton" class="jaws"> <li class="minibutton" class="jaws">
<a href="#" id="minibutton-new-page">New</a></li> <a href="#" id="minibutton-new-page">New</a></li>
<li class="minibutton" class="jaws"> <li class="minibutton" class="jaws">
<a href="#" id="minibutton-rename-page">Rename</a></li> <a href="#" id="minibutton-rename-page">Rename</a></li>
{{#editable}} {{#editable}}
<li class="minibutton"><a href="{{base_url}}edit/{{escaped_url_path}}" <li class="minibutton"><a href="{{base_url}}/edit/{{escaped_url_path}}"
class="action-edit-page">Edit</a></li> class="action-edit-page">Edit</a></li>
{{/editable}} {{/editable}}
<li class="minibutton"><a href="{{base_url}}history/{{escaped_url_path}}" <li class="minibutton"><a href="{{base_url}}/history/{{escaped_url_path}}"
class="action-page-history">History</a></li> class="action-page-history">History</a></li>
</ul> </ul>
</div> </div>
@@ -62,7 +69,7 @@
<div id="footer"> <div id="footer">
<p id="last-edit">Last edited by <b>{{author}}</b>, {{date}}</p> <p id="last-edit">Last edited by <b>{{author}}</b>, {{date}}</p>
<p> <p>
<a id="delete-link" href="{{base_url}}{{escaped_url_path}}" data-confirm="Are you sure you want to delete this page?"><span>Delete this Page</span></a> <a id="delete-link" href="{{base_url}}/{{escaped_url_path}}" data-confirm="Are you sure you want to delete this page?"><span>Delete this Page</span></a>
</p> </p>
</div> </div>
</div> </div>
+1 -1
View File
@@ -5,7 +5,7 @@
<li class="minibutton"> <li class="minibutton">
{{>searchbar}} {{>searchbar}}
</li> </li>
<li class="minibutton"><a href="{{base_url}}" <li class="minibutton"><a href="{{base_url}}/"
class="action-edit-page">Home</a></li> class="action-edit-page">Home</a></li>
<li class="minibutton" class="jaws"> <li class="minibutton" class="jaws">
<a href="#" id="minibutton-new-page">New</a> <a href="#" id="minibutton-new-page">New</a>
@@ -5,7 +5,7 @@
<li class="minibutton"> <li class="minibutton">
{{>searchbar}} {{>searchbar}}
</li> </li>
<li class="minibutton"><a href="{{base_url}}" <li class="minibutton"><a href="{{base_url}}/"
class="action-edit-page">Home</a></li> class="action-edit-page">Home</a></li>
</ul> </ul>
</div> </div>
@@ -15,7 +15,7 @@
<ul> <ul>
{{#results}} {{#results}}
<li> <li>
<a href="{{base_url}}{{name}}">{{name}}</a> <a href="{{base_url}}/{{name}}">{{name}}</a>
<span class="count">({{count}} matches)</span> <span class="count">({{count}} matches)</span>
</li> </li>
{{/results}} {{/results}}
@@ -1,5 +1,5 @@
<div id="searchbar"> <div id="searchbar">
<form action="{{base_url}}search" method="get" id="search-form"> <form action="{{base_url}}/search" method="get" id="search-form">
<div id="searchbar-fauxtext"> <div id="searchbar-fauxtext">
<input type="text" name="q" id="search-query" value="Search&hellip;" autocomplete="off"> <input type="text" name="q" id="search-query" value="Search&hellip;" autocomplete="off">
<a href="#" id="search-submit" title="Search this wiki"> <a href="#" id="search-submit" title="Search this wiki">
+10 -2
View File
@@ -1,3 +1,4 @@
# ~*~ encoding: utf-8 ~*~
=begin =begin
Copyright 2006-2008 the V8 project authors. All rights reserved. Copyright 2006-2008 the V8 project authors. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -39,7 +40,12 @@ end
# define charCodeAt on String # define charCodeAt on String
class String class String
def charCodeAt(k) def charCodeAt(k)
return self[k].ord # use scan, nil check, and unpack instead of ord for 1.8
# 1.9 can simply use self[k].ord
# http://stackoverflow.com/questions/7793177/split-utf8-string-regardless-of-ruby-version
c = self.scan(/./mu)[k]
return nil if c.nil?
c.unpack('U')[0]
end end
end end
@@ -147,6 +153,7 @@ def Encode(uri, unescape)
k = -1; k = -1;
while ((k+=1) < uriLength) do while ((k+=1) < uriLength) do
cc1 = uri.charCodeAt(k); cc1 = uri.charCodeAt(k);
next if cc1.nil?
if (self.send(unescape, cc1)) if (self.send(unescape, cc1))
result[index] = cc1; result[index] = cc1;
index += 1 index += 1
@@ -163,10 +170,11 @@ def Encode(uri, unescape)
end end
end end
end end
# use .compact to get rid of nils from charCodeAt
# return %StringFromCharCodeArray(result); # return %StringFromCharCodeArray(result);
# 'c' = 8 bit signed char # 'c' = 8 bit signed char
# http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-pack # http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-pack
return result.pack 'c*' return result.compact.pack 'c*'
end end
end # class << self end # class << self
end # module end # module
+5
View File
@@ -6,6 +6,11 @@ module Precious
attr_reader :page, :content attr_reader :page, :content
# return path set in app.rb not @page.path
def path
@path
end
def title def title
"#{@page.title}" "#{@page.title}"
end end
+4 -4
View File
@@ -12,14 +12,14 @@ module Precious
def breadcrumb def breadcrumb
if @path if @path
path = Pathname.new(@path) path = Pathname.new(@path)
breadcrumb = [%{<a href="#{@base_url}pages/">Home</a>}] breadcrumb = [%{<a href="#{@base_url}/pages/">Home</a>}]
path.descend do |crumb| path.descend do |crumb|
title = crumb.basename title = crumb.basename
if title == path.basename if title == path.basename
breadcrumb << title breadcrumb << title
else else
breadcrumb << %{<a href="#{@base_url}pages/#{crumb}/">#{title}</a>} breadcrumb << %{<a href="#{@base_url}/pages/#{crumb}/">#{title}</a>}
end end
end end
@@ -39,7 +39,7 @@ module Precious
if page_path.include?('/') if page_path.include?('/')
folder = page_path.split('/').first folder = page_path.split('/').first
folder_path = @path ? "#{@path}/#{folder}" : folder folder_path = @path ? "#{@path}/#{folder}" : folder
folder_link = %{<li><a href="#{@base_url}pages/#{folder_path}/" class="folder">#{folder}</a></li>} folder_link = %{<li><a href="#{@base_url}/pages/#{folder_path}/" class="folder">#{folder}</a></li>}
unless folder_links.include?(folder_link) unless folder_links.include?(folder_link)
folder_links << folder_link folder_links << folder_link
@@ -47,7 +47,7 @@ module Precious
folder_link folder_link
end end
elsif page_path != ".gitkeep" elsif page_path != ".gitkeep"
%{<li><a href="#{@base_url}#{page.escaped_url_path}" class="file">#{page.name}</a></li>} %{<li><a href="#{@base_url}/#{page.escaped_url_path}" class="file">#{page.name}</a></li>}
end end
}.compact.join("\n") }.compact.join("\n")
else else
+29 -24
View File
@@ -3,6 +3,9 @@ require 'cgi'
require 'pygments' require 'pygments'
require 'base64' require 'base64'
# initialize Pygments
Pygments.start
module Gollum module Gollum
class Markup class Markup
@@ -84,14 +87,15 @@ module Gollum
def process_headers(doc) def process_headers(doc)
toc = nil toc = nil
doc.css('h1,h2,h3,h4,h5,h6').each do |h| doc.css('h1,h2,h3,h4,h5,h6').each do |h|
id = CGI::escape(h.content.gsub(' ','-')) id = encodeURIComponent(h.content.gsub(' ','-'))
level = h.name.gsub(/[hH]/,'').to_i level = h.name.gsub(/[hH]/,'').to_i
# Add anchors # Add anchors
anchor = Nokogiri::XML::Node.new('a', doc) anchor = Nokogiri::XML::Node.new('a', doc)
anchor['class'] = 'anchor' anchor['class'] = 'anchor'
anchor['id'] = id anchor['id'] = id
anchor['href'] = '#' + id # % -> %25 so anchors work on Firefox. See issue #475
anchor['href'] = '#' + id.gsub('%', '%25')
h.add_child(anchor) h.add_child(anchor)
# Build TOC # Build TOC
@@ -109,7 +113,8 @@ module Gollum
tail_level -= 1 tail_level -= 1
end end
node = Nokogiri::XML::Node.new('li', doc) node = Nokogiri::XML::Node.new('li', doc)
node.add_child("<a href='##{id}'>#{h.content}</a>") # % -> %25 so anchors work on Firefox. See issue #475
node.add_child("<a href='##{id.gsub('%', '%25')}'>#{h.content}</a>")
tail.add_child(node) tail.add_child(node)
end end
toc = toc.to_xhtml if toc != nil toc = toc.to_xhtml if toc != nil
@@ -150,23 +155,7 @@ module Gollum
def process_tex(data) def process_tex(data)
@texmap.each do |id, spec| @texmap.each do |id, spec|
type, tex = *spec type, tex = *spec
data.gsub!(id, Gollum::Tex.to_html(tex, type))
# Obtain the formula with parameters
out = nil
begin
width, height, align, base64 = Gollum::Tex.render_formula(tex, true)
# TODO: Should we load the binary inside the html?
#out = %{<img width="#{width}" height="#{height}" style="vertical-align: #{align}px;" src="data:image/png;base64,\n#{base64}" alt="#{CGI.escapeHTML(tex)}" />}
# Use the alignment values from the formula rendering but still use the call to '_tex.png'. Although it will call render_formula()
# again, it will use the already cached formula and it might have some advantages from the point of view of browser caching (really not sure here).
out = %{<img width="#{width}" height="#{height}" style="vertical-align: #{align}px;" src="#{::File.join(@wiki.base_path, '_tex.png')}?type=#{type}&data=#{Base64.encode64(tex).chomp}" alt="#{CGI.escapeHTML(tex)}" />}
rescue # In case of error
out = CGI.escapeHTML(tex)
end
data.gsub!(id, out)
end end
data data
end end
@@ -223,7 +212,7 @@ module Gollum
if is_preformatted?(data, id) if is_preformatted?(data, id)
data.gsub!(id, "[[#{tag}]]") data.gsub!(id, "[[#{tag}]]")
else else
data.gsub!(id, process_tag(tag)) data.gsub!(id, process_tag(tag).gsub('%2F', '/'))
end end
end end
data data
@@ -436,13 +425,23 @@ module Gollum
# Find a page from a given cname. If the page has an anchor (#) and has # Find a page from a given cname. If the page has an anchor (#) and has
# no match, strip the anchor and try again. # no match, strip the anchor and try again.
# #
# cname - The String canonical page name. # cname - The String canonical page name including path.
# #
# Returns a Gollum::Page instance if a page is found, or an Array of # Returns a Gollum::Page instance if a page is found, or an Array of
# [Gollum::Page, String extra] if a page without the extra anchor data # [Gollum::Page, String extra] if a page without the extra anchor data
# is found. # is found.
def find_page_from_name(cname) def find_page_from_name(cname)
if page = @wiki.page(cname) slash = cname.rindex('/')
unless slash.nil?
name = cname[slash+1..-1]
path = cname[0..slash]
page = @wiki.paged(name, path)
else
page = @wiki.paged(cname, '/')
end
if page
return page return page
end end
if pos = cname.index('#') if pos = cname.index('#')
@@ -576,12 +575,18 @@ module Gollum
######################################################################### #########################################################################
# Extract metadata for data and build metadata table. Metadata # Extract metadata for data and build metadata table. Metadata
# is content found between `<!-- ---` and `-->` markers, and must # is content found between markers, and must
# be a valid YAML mapping. # be a valid YAML mapping.
# #
# Because ri and ruby 1.8.7 are awesome, the markers can't
# be included in this documentation without triggering
# `Unhandled special: Special: type=17`
# Please read the source code for the exact markers
#
# Returns the String of formatted data with metadata removed. # Returns the String of formatted data with metadata removed.
def extract_metadata(data) def extract_metadata(data)
@metadata ||= {} @metadata ||= {}
# The markers are `<!-- ---` and `-->`
data.gsub(/\<\!--+\s+---(.*?)--+\>/m) do data.gsub(/\<\!--+\s+---(.*?)--+\>/m) do
yaml = @wiki.sanitizer.clean($1) yaml = @wiki.sanitizer.clean($1)
hash = YAML.load(yaml) hash = YAML.load(yaml)
+6 -4
View File
@@ -327,7 +327,7 @@ module Gollum
# Returns the String canonical name. # Returns the String canonical name.
def self.cname(name, char_white_sub = '-', char_other_sub = '-') def self.cname(name, char_white_sub = '-', char_other_sub = '-')
name.respond_to?(:gsub) ? 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 end
@@ -372,9 +372,9 @@ module Gollum
# version - The String version ID to find. # version - The String version ID to find.
# #
# Returns a Gollum::Page or nil if the page could not be found. # Returns a Gollum::Page or nil if the page could not be found.
def find(name, version, dir = nil) def find(name, version, dir = nil, exact = false)
map = @wiki.tree_map_for(version.to_s) map = @wiki.tree_map_for(version.to_s)
if page = find_page_in_tree(map, name, dir) if page = find_page_in_tree(map, name, dir, exact)
page.version = version.is_a?(Grit::Commit) ? page.version = version.is_a?(Grit::Commit) ?
version : @wiki.commit_for(version) version : @wiki.commit_for(version)
page.historical = page.version.to_s == version.to_s page.historical = page.version.to_s == version.to_s
@@ -391,12 +391,14 @@ module Gollum
# to be in. The string should # to be in. The string should
# #
# Returns a Gollum::Page or nil if the page could not be found. # Returns a Gollum::Page or nil if the page could not be found.
def find_page_in_tree(map, name, checked_dir = nil) def find_page_in_tree(map, name, checked_dir = nil, exact = false)
return nil if !map || name.to_s.empty? return nil if !map || name.to_s.empty?
if checked_dir = BlobEntry.normalize_dir(checked_dir) if checked_dir = BlobEntry.normalize_dir(checked_dir)
checked_dir.downcase! checked_dir.downcase!
end end
checked_dir = '' if exact && checked_dir.nil?
map.each do |entry| map.each do |entry|
next if entry.name.to_s.empty? next if entry.name.to_s.empty?
next unless checked_dir.nil? || entry.dir.downcase == checked_dir next unless checked_dir.nil? || entry.dir.downcase == checked_dir
+7 -359
View File
@@ -1,366 +1,14 @@
require 'fileutils' require 'escape_utils'
require 'shellwords'
require 'tmpdir'
require 'posix/spawn'
require 'base64'
module Gollum module Gollum
module Tex module Tex
class Error < StandardError; end TEX_URL = "http://www.mathtran.org/cgi-bin/toy/"
TEX_SIZES = { :inline => 2, :block => 4 }
extend POSIX::Spawn def self.to_html(tex, type = :inline)
tex_uri = EscapeUtils.escape_uri(tex)
Template = <<-EOS tex_alt = EscapeUtils.escape_html(tex)
\\documentclass[11pt]{article} %{<img src="#{TEX_URL}?D=#{TEX_SIZES[type]};tex=#{tex}" alt="#{tex_alt}">}
\\pagestyle{empty}
\\setlength{\\topskip}{0pt}
\\setlength{\\parindent}{0pt}
\\setlength{\\abovedisplayskip}{0pt}
\\setlength{\\belowdisplayskip}{0pt}
\\usepackage{geometry}
\\usepackage{amsfonts}
\\usepackage{amsmath}
\\newsavebox{\\snippetbox}
\\newlength{\\snippetwidth}
\\newlength{\\snippetheight}
\\newlength{\\snippetdepth}
\\newlength{\\pagewidth}
\\newlength{\\pageheight}
\\newlength{\\pagemargin}
\\begin{lrbox}{\\snippetbox}%
\$%s\$
\\end{lrbox}
\\settowidth{\\snippetwidth}{\\usebox{\\snippetbox}}
\\settoheight{\\snippetheight}{\\usebox{\\snippetbox}}
\\settodepth{\\snippetdepth}{\\usebox{\\snippetbox}}
\\setlength\\pagemargin{4pt}
\\setlength\\pagewidth\\snippetwidth
\\addtolength\\pagewidth\\pagemargin
\\addtolength\\pagewidth\\pagemargin
\\setlength\\pageheight\\snippetheight
\\addtolength{\\pageheight}{\\snippetdepth}
\\addtolength\\pageheight\\pagemargin
\\addtolength\\pageheight\\pagemargin
\\newwrite\\foo
\\immediate\\openout\\foo=\\jobname.dimensions
\\immediate\\write\\foo{snippetdepth = \\the\\snippetdepth}
\\immediate\\write\\foo{snippetheight = \\the\\snippetheight}
\\immediate\\write\\foo{snippetwidth = \\the\\snippetwidth}
\\immediate\\write\\foo{pagewidth = \\the\\pagewidth}
\\immediate\\write\\foo{pageheight = \\the\\pageheight}
\\immediate\\write\\foo{pagemargin = \\the\\pagemargin}
\\closeout\\foo
\\geometry{paperwidth=\\pagewidth,paperheight=\\pageheight,margin=\\pagemargin}
\\begin{document}%
\\usebox{\\snippetbox}%
\\end{document}
EOS
class << self
attr_accessor :latex_path
end end
self.latex_path = 'pdflatex'
def self.check_dependencies!
return if @dependencies_available
if `which pdflatex` == ""
raise Error, "`pdflatex` command not found"
end
if `which gs` == ""
raise Error, "`gs` command not found"
end
if `which pnmcrop` == ""
raise Error, "`pnmcrop` command not found"
end
if `which pnmpad` == ""
raise Error, "`pnmpad` command not found"
end
if `which pnmscale` == ""
raise Error, "`pnmscale` command not found"
end
if `which ppmtopgm` == ""
raise Error, "`ppmtopgm` command not found"
end
if `which pnmgamma` == ""
raise Error, "`pnmgamma` command not found"
end
if `which pnmtopng` == ""
raise Error, "`pnmtopng` command not found"
end
@dependencies_available = true
end
# Render the formula and calculate the correct alignment
# for the image in the html.
#
# This is a ruby implementation of the Perl version described
# at http://tex.stackexchange.com/questions/44486/pixel-perfect-vertical-alignment-of-image-rendered-tex-snippets
#
# The main caveat is that rendering takes quite a bit of processing power,
# which can make the page load slowly if it has to render each time.
# For this reason, the method caches the rendered formula in `/tmp` for reduced
# loading time in subsequent loads.
#
# @param formula the tex formula to render
# @param with_properties, if true it returns an array with a base64
# string with the image, and the alignment values for the image.
# Otherwise it returns the binary image.
def self.render_formula(formula, with_properties=false)
check_dependencies!
render_antialias_bits = 4
render_oversample = 4
display_oversample = 4
gamma = 0.3
if !with_properties
display_oversample = 1
gamma = 0.5
end
oversample = render_oversample * display_oversample
render_dpi = 96*1.2 * 72.27/72 * oversample # This is 1850.112 dpi.
# Cache rendered formula and returned cached version if it exists
# First look for the .cache directory in the home folder
cache_dir = ::File.expand_path("~/.cache")
if not ::File.exists?(cache_dir) or not ::File.directory?(cache_dir)
::Dir.mkdir(cache_dir)
end
# Check that the gollum directory exists inside the cache dir
cache_dir = ::File.join(cache_dir, "gollum")
if not ::File.exists?(cache_dir) or not ::File.directory?(cache_dir)
::Dir.mkdir(cache_dir)
end
# Check for the formula in the cache dir
hash = Digest::SHA1.hexdigest(formula)
cache_file = ::File.join(cache_dir, "tex-#{hash}")
if ::File.exists?(cache_file)
width, height, align, base64 = ::File.open(cache_file, 'rb') { |io| io.read }.split(",")
if with_properties
return width, height, align, base64
else
return Base64.decode64(base64)
end
end
Dir.mktmpdir('tex') do |path|
file = ::File.join(path, "formula")
# --- Write TeX source and compile to PDF.Write snippet into template
::File.open(file + ".tex", 'w') { |f| f.write(Template % formula) }
result = sh_chdir path, "pdflatex",
"-halt-on-error",
"-output-directory=#{path}",
"-output-format=pdf",
"#{file}.tex",
">#{file}.err 2>&1"
# --- Convert PDF to PNM using Ghostscript.
sh "gs",
"-q -dNOPAUSE -dBATCH",
"-dTextAlphaBits=#{render_antialias_bits}",
"-dGraphicsAlphaBits=#{render_antialias_bits}",
"-r#{render_dpi}",
"-sDEVICE=pnmraw",
"-sOutputFile=#{file}.pnm",
"#{file}.pdf"
img_width, img_height = pnm_width_height(file + ".pnm")
# --- Read dimensions file written by TeX during processing.
#
# Example of file contents:
# snippetdepth = 6.50009pt
# snippetheight = 13.53899pt
# snippetwidth = 145.4777pt
# pagewidth = 153.4777pt
# pageheight = 28.03908pt
# pagemargin = 4.0pt
dimensions = {}
::File.open(file + ".dimensions").readlines.each_with_index do |line, i|
if line =~ /^(\S+)\s+=\s+(-?[0-9\.]+)pt$/
dimensions[$1] = Float($2) / 72.27 * render_dpi
else
raise Error, "#{file}.dimensions: invalid line: #{i}"
end
end
# --- Crop bottom, then measure how much was cropped.
sh "pnmcrop -white -bottom #{file}.pnm >#{file}.bottomcrop.pnm"
#raise Error, "`pnmcrop` command failed: #{result}" unless ::File.exist?(file + ".bottomcrop.pnm")
img_width_bottomcrop, img_height_bottomcrop = pnm_width_height("#{file}.bottomcrop.pnm")
bottomcrop = img_height - img_height_bottomcrop
# --- Crop top and sides, then measure how much was cropped from the top.
sh "pnmcrop -white #{file}.bottomcrop.pnm > #{file}.crop.pnm"
#raise Error, "`pnmcrop` command failed: #{result}" unless ::File.exist?(file + ".crop.pnm")
cropped_img_width, cropped_img_height = pnm_width_height("#{file}.crop.pnm")
topcrop = img_height_bottomcrop - cropped_img_height
# --- Pad image with specific values on all four sides, in preparation for
# downsampling.
# Calculate bottom padding.
snippet_depth = Integer(dimensions["snippetdepth"] + dimensions["pagemargin"] + 0.5) - bottomcrop
padded_snippet_depth = round_up(snippet_depth, oversample)
increase_snippet_depth = padded_snippet_depth - snippet_depth
bottom_padding = increase_snippet_depth
# --- Next calculate top padding, which depends on bottom padding.
padded_img_height = round_up(cropped_img_height + bottom_padding,
oversample)
top_padding = padded_img_height - (cropped_img_height + bottom_padding)
# --- Calculate left and right side padding. Distribute padding evenly.
padded_img_width = round_up(cropped_img_width, oversample)
left_padding = Integer((padded_img_width - cropped_img_width) / 2.0)
right_padding = (padded_img_width - cropped_img_width) - left_padding
# --- Pad the final image.
result = sh "pnmpad",
"-white",
"-bottom=#{bottom_padding}",
"-top=#{top_padding}",
"-left=#{left_padding}",
"-right=#{right_padding}",
"#{file}.crop.pnm",
">#{file}.pad.pnm"
# --- Sanity check of final size.
final_pnm_width, final_pnm_height = pnm_width_height(file + ".pad.pnm")
raise Error, "#{final_pnm_width} is not a multiple of #{oversample}" unless final_pnm_width % oversample == 0
raise "#{final_pnm_height} is not a multiple of #{oversample}" unless final_pnm_height % oversample == 0
# --- Convert PNM to PNG.
final_png_width = final_pnm_width / render_oversample
final_png_height = final_pnm_height / render_oversample
result = sh "cat #{file}.pad.pnm",
"| ppmtopgm",
"| pnmscale -reduce #{render_oversample}",
"| pnmgamma #{gamma}",
"| pnmtopng -compression 9",
"> #{file}.png"
raise Error, "Conversion to png failed: #{result}" unless ::File.exist?(file + ".png")
# Calculate html properties
html_img_width = final_png_width / display_oversample
html_img_height = final_png_height / display_oversample
html_img_vertical_align = sprintf("%.0f", -padded_snippet_depth / oversample)
png_data_base64 = Base64.encode64(::File.open("#{file}.png") { |io| io.read }).chomp
::File.open(cache_file, 'w') { |f| f.write(%{#{html_img_width},#{html_img_height},#{html_img_vertical_align},#{png_data_base64}}) }
if with_properties
return html_img_width, html_img_height, html_img_vertical_align, png_data_base64
else
::File.read(file + ".png")
end
end
end
private
def self.sh_chdir(path, *args)
origcommand = args * " "
return if origcommand == ""
command = origcommand
command.gsub! /(["\\])/, "\\$1"
command = %{/bin/sh -c "(#{command}) 2>&1"}
pid = spawn command, :chdir => path
result = Process::waitpid(pid)
exit_value = Integer($? >> 8), signal_num = Integer($? & 127), dumped_core = Integer($? & 128)
raise Error, "Failed #{result}: #{origcommand}. Exit value = #{exit_value}. Signal Num = #{signal_num}. Dumped core = #{dumped_core}" unless $?.success?
return result
end
def self.sh(*args)
origcommand = args * " "
return if origcommand == ""
command = origcommand
command.gsub! /(["\\])/, "\\$1"
command = %{/bin/sh -c "(#{command}) 2>&1"}
pid = spawn command
#pid = spawn *args
result = Process::waitpid(pid)
exit_value = $? >> 8, signal_num = $? & 127, dumped_core = $? & 128
raise Error, "Failed #{result}: #{origcommand}. Exit value = #{exit_value}. Signal Num = #{signal_num}. Dumped core = #{dumped_core}" unless $?.success?
return result
end
def self.round_up(num, mod)
num + (num % mod == 0 ? 0 : (mod - (num % mod)))
end
def self.pnm_width_height(filename)
raise Error, "#{filename} is not a .pnm file" if filename !~ /\.pnm$/
width = nil, height = nil
::File.open(filename) do |file|
# Read first line
line = file.gets
begin
line = file.gets # Read next line, skipping comments
end while line && line =~ /^#/
if line =~ /^(\d+)\s+(\d+)$/
width = Integer($1)
height = Integer($2)
else
raise Error, "#{filename}: couldn't read image size"
end
end
raise Error, "#{filename}: couldn't read image size" unless width && height
return width, height
end
end end
end end
+5 -5
View File
@@ -179,7 +179,7 @@ module Gollum
self.class.history_sanitization self.class.history_sanitization
@live_preview = options.fetch(:live_preview, true) @live_preview = options.fetch(:live_preview, true)
@universal_toc = options.fetch(:universal_toc, false) @universal_toc = options.fetch(:universal_toc, false)
@mathjax = options[:mathjax] || true @mathjax = options[:mathjax] || false
end end
# Public: check whether the wiki's git repo exists on the filesystem. # Public: check whether the wiki's git repo exists on the filesystem.
@@ -196,9 +196,9 @@ module Gollum
# dir - The directory String relative to the repo. # dir - The directory String relative to the repo.
# #
# Returns a Gollum::Page or nil if no matching page was found. # Returns a Gollum::Page or nil if no matching page was found.
def page(name, version = @ref, dir = nil) def page(name, version = @ref, dir = nil, exact = false)
version = @ref if version.nil? version = @ref if version.nil?
@page_class.new(self).find(name, version, dir) @page_class.new(self).find(name, version, dir, exact)
end end
# Public: Convenience method instead of calling page(name, nil, dir). # Public: Convenience method instead of calling page(name, nil, dir).
@@ -208,8 +208,8 @@ module Gollum
# dir - The directory String relative to the repo. # dir - The directory String relative to the repo.
# #
# Returns a Gollum::Page or nil if no matching page was found. # Returns a Gollum::Page or nil if no matching page was found.
def paged(name, dir = nil, version = @ref) def paged(name, dir = nil, exact = false, version = @ref)
page(name, version, dir) page(name, version, dir, exact)
end end
# Public: Get the static file for a given name. # Public: Get the static file for a given name.
+42 -3
View File
@@ -50,6 +50,14 @@ context "Frontend" do
assert_not_equal page_1.version.sha, page_2.version.sha assert_not_equal page_1.version.sha, page_2.version.sha
end end
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'
follow_redirect!
assert last_response.ok?
end
test "edits page header footer and sidebar" do test "edits page header footer and sidebar" do
commits = @wiki.repo.commits('master').size commits = @wiki.repo.commits('master').size
page_1 = @wiki.page('A') page_1 = @wiki.page('A')
@@ -142,13 +150,14 @@ context "Frontend" do
assert last_response.ok? assert last_response.ok?
end end
test "page create and edit with dash" do test "page create and edit with dash & page rev" do
page = 'c-d-e' page = 'c-d-e'
path = 'a/b/' # path must end with / path = 'a/b/' # path must end with /
post '/create', :content => 'create_msg', :page => page, post '/create', :content => 'create_msg', :page => page,
:path => path, :format => 'markdown', :message => '' :path => path, :format => 'markdown', :message => ''
assert_equal 'create_msg', @wiki.paged(page, path).raw_data page_c = @wiki.paged(page, path)
assert_equal 'create_msg', page_c.raw_data
# must clear or create_msg will be returned # must clear or create_msg will be returned
@wiki.clear_cache @wiki.clear_cache
@@ -156,13 +165,26 @@ context "Frontend" do
# post '/edit' fails. post '/edit/' works. # post '/edit' fails. post '/edit/' works.
post '/edit/', :content => 'edit_msg', post '/edit/', :content => 'edit_msg',
:page => page, :path => path, :message => '' :page => page, :path => path, :message => ''
assert_equal 'edit_msg', @wiki.paged(page, path).raw_data page_e = @wiki.paged(page, path)
assert_equal 'edit_msg', page_e.raw_data
@wiki.clear_cache
# test `get %r{/(.+?)/([0-9a-f]{40})} do` in app.rb
get '/' + page_c.escaped_url_path + '/' + page_c.version.to_s
assert last_response.ok?
assert_match /create_msg/, last_response.body
get '/' + page_e.escaped_url_path + '/' + page_e.version.to_s
assert last_response.ok?
assert_match /edit_msg/, last_response.body
end end
test "guards against creation of existing page" do test "guards against creation of existing page" do
name = "A" name = "A"
post "/create", :content => 'abc', :page => name, post "/create", :content => 'abc', :page => name,
:format => 'markdown', :message => 'def' :format => 'markdown', :message => 'def'
follow_redirect!
assert last_response.ok? assert last_response.ok?
@wiki.clear_cache @wiki.clear_cache
@@ -199,6 +221,8 @@ context "Frontend" do
assert last_response.ok? assert last_response.ok?
end end
=begin
# Grit is broken.
test "reverts single commit" do test "reverts single commit" do
page1 = @wiki.page('B') page1 = @wiki.page('B')
@@ -224,6 +248,7 @@ context "Frontend" do
assert_not_equal page1.version.sha, page2.version.sha assert_not_equal page1.version.sha, page2.version.sha
assert_equal "INITIAL", page2.raw_data.strip assert_equal "INITIAL", page2.raw_data.strip
end end
=end
test "cannot revert conflicting commit" do test "cannot revert conflicting commit" do
page1 = @wiki.page('A') page1 = @wiki.page('A')
@@ -236,6 +261,20 @@ context "Frontend" do
assert_equal page1.version.sha, page2.version.sha assert_equal page1.version.sha, page2.version.sha
end end
test "redirects from 'base_path' or 'base_path/' to 'base_path/Home'" do
Precious::App.set(:wiki_options, {})
get "/"
assert_match "http://example.org/Home", last_response.headers['Location']
Precious::App.set(:wiki_options, { :base_path => '/wiki' })
get "/"
assert_match "http://example.org/wiki/Home", last_response.headers['Location']
Precious::App.set(:wiki_options, { :base_path => '/wiki/' })
get "/"
assert_match "http://example.org/wiki/Home", last_response.headers['Location']
end
def app def app
Precious::App Precious::App
end end
+2 -2
View File
@@ -670,13 +670,13 @@ end
test "TeX block syntax" do test "TeX block syntax" do
content = 'a \[ a^2 \] b' content = 'a \[ a^2 \] b'
output = "<p>a<imgwidth=\"15\"height=\"16\"style=\"vertical-align:-1px;\"src=\"/_tex.png?type=block&data=YV4y\"alt=\"a^2\"/>b</p>" output = "<p>a<imgsrc=\"http://www.mathtran.org/cgi-bin/toy/?D=4;tex=a^2\"alt=\"a^2\">b</p>"
compare(content, output, 'md') compare(content, output, 'md')
end end
test "TeX inline syntax" do test "TeX inline syntax" do
content = 'a \( a^2 \) b' content = 'a \( a^2 \) b'
output = "<p>a<imgwidth=\"15\"height=\"16\"style=\"vertical-align:-1px;\"src=\"/_tex.png?type=inline&data=YV4y\"alt=\"a^2\"/>b</p>" output = "<p>a<imgsrc=\"http://www.mathtran.org/cgi-bin/toy/?D=2;tex=a^2\"alt=\"a^2\">b</p>"
compare(content, output, 'md') compare(content, output, 'md')
end end
+2 -1
View File
@@ -99,7 +99,8 @@ context "Page" do
test "cname" do test "cname" do
assert_equal "Foo", Gollum::Page.cname("Foo") assert_equal "Foo", Gollum::Page.cname("Foo")
assert_equal "Foo-Bar", Gollum::Page.cname("Foo Bar") assert_equal "Foo-Bar", Gollum::Page.cname("Foo Bar")
assert_equal "Foo---Bar", Gollum::Page.cname("Foo / Bar") # / is now a directory delimiter so it must be preserved
assert_equal "Foo-/-Bar", Gollum::Page.cname("Foo / Bar")
assert_equal "José", Gollum::Page.cname("José") assert_equal "José", Gollum::Page.cname("José")
assert_equal "モルドール", Gollum::Page.cname("モルドール") assert_equal "モルドール", Gollum::Page.cname("モルドール")
end end
+11 -2
View File
@@ -19,7 +19,7 @@ context "Precious::Views::Pages" do
test "breadcrumb" do test "breadcrumb" do
@page.instance_variable_set("@path", "Mordor/Eye-Of-Sauron/Saruman") @page.instance_variable_set("@path", "Mordor/Eye-Of-Sauron/Saruman")
@page.instance_variable_set("@base_url", "/") @page.instance_variable_set("@base_url", "")
assert_equal '<a href="/pages/">Home</a> / <a href="/pages/Mordor/">Mordor</a> / <a href="/pages/Mordor/Eye-Of-Sauron/">Eye-Of-Sauron</a> / Saruman', @page.breadcrumb assert_equal '<a href="/pages/">Home</a> / <a href="/pages/Mordor/">Mordor</a> / <a href="/pages/Mordor/Eye-Of-Sauron/">Eye-Of-Sauron</a> / Saruman', @page.breadcrumb
end end
@@ -29,9 +29,18 @@ context "Precious::Views::Pages" do
test "files_folders" do test "files_folders" do
@page.instance_variable_set("@path", "Mordor") @page.instance_variable_set("@path", "Mordor")
@page.instance_variable_set("@base_url", "/") @page.instance_variable_set("@base_url", "")
results = [FakeResult.new("Mordor/Eye-Of-Sauron.md"), FakeResult.new("Mordor/Orc/Saruman.md"), FakeResult.new("Mordor/.gitkeep")] results = [FakeResult.new("Mordor/Eye-Of-Sauron.md"), FakeResult.new("Mordor/Orc/Saruman.md"), FakeResult.new("Mordor/.gitkeep")]
@page.instance_variable_set("@results", results) @page.instance_variable_set("@results", results)
assert_equal %{<li><a href="/Mordor/Eye-Of-Sauron" class="file">Eye Of Sauron</a></li>\n<li><a href="/pages/Mordor/Orc/" class="folder">Orc</a></li>}, @page.files_folders assert_equal %{<li><a href="/Mordor/Eye-Of-Sauron" class="file">Eye Of Sauron</a></li>\n<li><a href="/pages/Mordor/Orc/" class="folder">Orc</a></li>}, @page.files_folders
end end
test "base url" do
# based on test "files_folders"
@page.instance_variable_set("@path", "Mordor")
@page.instance_variable_set("@base_url", "/wiki")
results = [FakeResult.new("Mordor/Eye-Of-Sauron.md"), FakeResult.new("Mordor/Orc/Saruman.md"), FakeResult.new("Mordor/.gitkeep")]
@page.instance_variable_set("@results", results)
assert_equal %{<li><a href="/wiki/Mordor/Eye-Of-Sauron" class="file">Eye Of Sauron</a></li>\n<li><a href="/wiki/pages/Mordor/Orc/" class="folder">Orc</a></li>}, @page.files_folders
end
end end
+22 -1
View File
@@ -15,12 +15,33 @@ context "Unicode Support" do
FileUtils.rm_rf(@path) FileUtils.rm_rf(@path)
end end
test "create and read non-latin page" do test "uri encode" do
c = '한글'
assert_equal '%ED%95%9C%EA%B8%80', encodeURIComponent(c)
assert_equal '%ED%95%9C%EA%B8%80', CGI::escape(c)
end
test "create and read non-latin page with anchor" do
@wiki.write_page("test", :markdown, "# 한글") @wiki.write_page("test", :markdown, "# 한글")
page = @wiki.page("test") page = @wiki.page("test")
assert_equal Gollum::Page, page.class assert_equal Gollum::Page, page.class
assert_equal "# 한글", utf8(page.raw_data) assert_equal "# 한글", utf8(page.raw_data)
# markup.rb
# #简介
# href.gsub('%', '%25') so the anchor works in Firefox.
# <a href="#%25ED%2595%259C%25EA%25B8%2580" id="%ED%95%9C%EA%B8%80" class="anchor"></a>
doc = Nokogiri::HTML page.formatted_data
h1s = doc / :h1
h1 = h1s.first
anchors = h1 / :a
assert_equal 1, h1s.size
assert_equal 1, anchors.size
assert_equal '#%25ED%2595%259C%25EA%25B8%2580', anchors[0]['href']
assert_equal '%ED%95%9C%EA%B8%80', anchors[0]['id']
assert_equal 'anchor', anchors[0]['class']
assert_equal '', anchors[0].text
end end
test "unicode with existing format rules" do test "unicode with existing format rules" do