diff --git a/README.md b/README.md index bcdc39c8..14be837f 100644 --- a/README.md +++ b/README.md @@ -23,8 +23,8 @@ choose. Special footers can be created in `footer files`. Other content ## PAGE FILES Page files may be written in any format supported by -[GitHub-Markup](http://github.com/defunkt/github-markup). The current list of -formats and allowed extensions is: +[GitHub-Markup](http://github.com/defunkt/github-markup) (except roff). The +current list of formats and allowed extensions is: * Markdown: .markdown, .mdown, .mkdn, .mkd, .md * Textile: .textile @@ -34,7 +34,6 @@ formats and allowed extensions is: * ReStructured Text: .rest.txt, .rst.txt, .rest, .rst * ASCIIDoc: .asciidoc * POD: .pod - * Roff: .1, .2, .3, ... Gollum detects the page file format via the extension, so files must have one of the supported extensions in order to be converted. diff --git a/lib/gollum/frontend/app.rb b/lib/gollum/frontend/app.rb index 4b3b0d70..267580a8 100644 --- a/lib/gollum/frontend/app.rb +++ b/lib/gollum/frontend/app.rb @@ -62,12 +62,12 @@ module Precious end post '/create/:name' do - page = params[:name] + name = params[:name] wiki = Gollum::Wiki.new($path) format = params[:format].intern - wiki.write_page(page, format, params[:content], commit_message) + wiki.write_page(name, format, params[:content], commit_message) redirect "/#{name}" end diff --git a/lib/gollum/frontend/public/css/editbar.css b/lib/gollum/frontend/public/css/editbar.css new file mode 100644 index 00000000..8839399e --- /dev/null +++ b/lib/gollum/frontend/public/css/editbar.css @@ -0,0 +1,168 @@ +#editbar { + border-left: 1px solid #888; + border-top: 1px solid #888; + border-right: 1px solid #888; + width: 100%; + overflow: hidden; + font-family: sans-serif; + font-size: 13px; +} + + #editbar .current { + display: block !important; + } + + #editbar .menu { + overflow: hidden; + background: white; + background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#EBF1FF)); + background: -moz-linear-gradient(top, #fff, #EBF1FF); + } + + #editbar .group { + float: left; + height: 26px; + margin: 3px; + padding-right: 6px; + } + + #editbar .group-separator { + border-right: 1px solid #ddd; + } + + #editbar .button { + width: 22px; + height: 22px; + background: url(/images/buttons.png); + text-indent: -100px; + cursor: pointer; + overflow: hidden; + padding: 2px; + display: block; + float: left; + } + + #editbar .bold { + background-position: 2px -142px; + } + + #editbar .italic { + background-position: 2px -862px; + } + + #editbar .link { + background-position: 2px -1654px; + } + + #editbar .image { + background-position: 2px -1438px; + } + + #editbar .ul { + background-position: 2px -1366px; + } + + #editbar .ol { + background-position: 2px -1078px; + } + + #editbar .tab { + float: left; + display: block; + } + + #editbar .tab a { + cursor: pointer; + display: inline-block; + float: left; + height: 26px; + padding-left: 18px; + padding-right: 12px; + line-height: 26px; + text-decoration: none; + background-image: url(/images/twiddle-right.png); + background-position: 0 50%; + background-repeat: no-repeat; + color: blue; + } + + #editbar .tab a.open { + background-image: url(/images/twiddle-down.png); + color: #333; + } + + #editbar .tab a.open:hover { + text-decoration: none; + } + + #editbar .tab a:hover { + text-decoration: underline; + } + + #editbar .sections { + clear: both; + float: left; + width: 100%; + overflow: visible; + border-top: 1px solid #888; + height: 175px; + background-color: #E0EEF7; + display: none; + } + + #editbar .sections .toc { + float: left; + width: 20%; + overflow: auto; + } + + #editbar .sections .toc div { + cursor: pointer; + padding: 4px 4px 4px 6px; + background-color: #E0EEF7; + color: blue; + } + + #editbar .sections .toc div.current { + cursor: default; + background-color: white; + color: #333; + } + + #editbar .sections .pages { + overflow: auto; + background-color: white; + float: right; + width: 80%; + height: 175px; + } + + #editbar .sections .page { + display: none; + } + + #editbar .sections .pages th { + color: #999; + font-weight: bold; + padding: 5px; + text-align: left; + } + + #editbar .sections .pages td { + color: black; + padding: 5px; + border-top: 1px solid #eee; + } + + #editbar .sections .pages span.invisible { + color: #bbb; + padding-left: 1px; + } + + #editbar .sections .pages .shortcodes th { + text-align: center; + } + + #editbar .sections .pages .shortcodes ul { + list-style-type: none; + } \ No newline at end of file diff --git a/lib/gollum/frontend/public/css/screen.css b/lib/gollum/frontend/public/css/screen.css index dd9dd232..bd174078 100644 --- a/lib/gollum/frontend/public/css/screen.css +++ b/lib/gollum/frontend/public/css/screen.css @@ -342,4 +342,29 @@ html {overflow-y: scroll;} .wikistyle pre.console span.command { color: yellow !important; - } \ No newline at end of file + } + +/* Special markup considerations */ + +/* asciidoc */ + +.wikistyle .ulist p, +.wikistyle .olist p { + margin: 0 !important; +} + +.wikistyle .loweralpha { + list-style-type: lower-alpha; +} + +.wikistyle .lowerroman { + list-style-type: lower-roman; +} + +.wikistyle .upperalpha { + list-style-type: upper-alpha; +} + +.wikistyle .upperroman { + list-style-type: upper-roman; +} \ No newline at end of file diff --git a/lib/gollum/frontend/public/images/buttons.png b/lib/gollum/frontend/public/images/buttons.png new file mode 100644 index 00000000..60544992 Binary files /dev/null and b/lib/gollum/frontend/public/images/buttons.png differ diff --git a/lib/gollum/frontend/public/images/example.png b/lib/gollum/frontend/public/images/example.png new file mode 100644 index 00000000..a3853683 Binary files /dev/null and b/lib/gollum/frontend/public/images/example.png differ diff --git a/lib/gollum/frontend/public/images/twiddle-down.png b/lib/gollum/frontend/public/images/twiddle-down.png new file mode 100644 index 00000000..bf2d4fb4 Binary files /dev/null and b/lib/gollum/frontend/public/images/twiddle-down.png differ diff --git a/lib/gollum/frontend/public/images/twiddle-right.png b/lib/gollum/frontend/public/images/twiddle-right.png new file mode 100644 index 00000000..c27c9636 Binary files /dev/null and b/lib/gollum/frontend/public/images/twiddle-right.png differ diff --git a/lib/gollum/frontend/public/javascript/gollum.js b/lib/gollum/frontend/public/javascript/gollum.js new file mode 100644 index 00000000..8a3cb8de --- /dev/null +++ b/lib/gollum/frontend/public/javascript/gollum.js @@ -0,0 +1,187 @@ +Gollum = { + encloseStrategy: function(prefix, content, suffix) { + return { + type: 'enclose', + content: content, + prefix: prefix, + suffix: suffix + } + }, + + prefixStrategy: function(prefix, content, newline) { + return { + type: 'prefixLine', + prefix: prefix, + content: content, + newline: newline + } + }, + + enclose: function(el, format, kind) { + var cfg = Gollum.Formats[format][kind] + var sel = el.getSelectionRange() + if (sel.start == sel.end) { + el.insertText(cfg.prefix + cfg.content + cfg.suffix, sel.start, sel.start, false) + el.setSelectionRange(sel.start + cfg.prefix.length, sel.start + cfg.prefix.length + cfg.content.length) + } else { + el.insertText(cfg.prefix + el.getSelectedText() + cfg.suffix, sel.start, sel.end, false) + } + }, + + prefix: function(el, format, kind) { + var cfg = Gollum.Formats[format][kind] + var sel = el.getSelectionRange() + var cnt = el.getSelectedText() + var prefix = cfg.prefix + if (cfg.newline) { + el.setSelectionRange(sel.start - 1, sel.start) + var before = el.getSelectedText() + if (before != '\n') { + prefix = '\n' + prefix + } + } + if (sel.start == sel.end) { + el.insertText(prefix + cfg.content, sel.start, sel.start, false) + el.setSelectionRange(sel.start + prefix.length, sel.start + prefix.length + cfg.content.length) + } else { + el.insertText(prefix + cnt + '\n', sel.start, sel.end, false) + } + } +} + +Gollum.Formats = { + asciidoc: { + bold: Gollum.encloseStrategy('*', 'bold text', '*'), + italic: Gollum.encloseStrategy('_', 'italic text', '_'), + ul: Gollum.prefixStrategy('* ', 'Bullet list item', true), + ol: Gollum.prefixStrategy('. ', 'Numbered list item', true) + }, + creole: { + bold: Gollum.encloseStrategy('**', 'bold text', '**'), + italic: Gollum.encloseStrategy('//', 'italic text', '//'), + ul: Gollum.prefixStrategy('* ', 'Bullet list item', true), + ol: Gollum.prefixStrategy('# ', 'Numbered list item', true) + }, + gollum: { + link: Gollum.encloseStrategy('[[', 'Page Name', ']]'), + image: Gollum.encloseStrategy('[[', '/path/to/image.png', ']]'), + }, + markdown: { + bold: Gollum.encloseStrategy('**', 'bold text', '**'), + italic: Gollum.encloseStrategy('*', 'italic text', '*'), + ul: Gollum.prefixStrategy('* ', 'Bullet list item', true), + ol: Gollum.prefixStrategy('1. ', 'Numbered list item', true) + }, + org: { + bold: Gollum.encloseStrategy('*', 'bold text', '*'), + italic: Gollum.encloseStrategy('/', 'italic text', '/'), + ul: Gollum.prefixStrategy('- ', 'Bullet list item', true), + ol: Gollum.prefixStrategy('1. ', 'Numbered list item', true) + }, + pod: { + bold: Gollum.encloseStrategy('B<', 'bold text', '>'), + italic: Gollum.encloseStrategy('I<', 'italic text', '>'), + ul: Gollum.prefixStrategy('=item * ', 'Bullet list item', true), + ol: Gollum.prefixStrategy('=item 1. ', 'Numbered list item', true) + }, + rest: { + bold: Gollum.encloseStrategy('**', 'bold text', '**'), + italic: Gollum.encloseStrategy('*', 'italic text', '*'), + ul: Gollum.prefixStrategy('* ', 'Bullet list item', true), + ol: Gollum.prefixStrategy('1. ', 'Numbered list item', true) + }, + rdoc: { + bold: Gollum.encloseStrategy('*', 'bold text', '*'), + italic: Gollum.encloseStrategy('_', 'italic text', '_'), + ul: Gollum.prefixStrategy('* ', 'Bullet list item', true), + ol: Gollum.prefixStrategy('1. ', 'Numbered list item', true) + }, + textile: { + bold: Gollum.encloseStrategy('*', 'bold text', '*'), + italic: Gollum.encloseStrategy('_', 'italic text', '_'), + ul: Gollum.prefixStrategy('* ', 'Bullet list item', true), + ol: Gollum.prefixStrategy('# ', 'Numbered list item', true) + } +} + +$(function(){ + /* Version selector */ + + $('#versions_select').change(function() { + location.href = this.value + }) + + /* EditBar */ + + $('#editbar .link').click(function() { + var el = $('#guides .write textarea') + var format = $('#guides .write select[name=format] option:selected').attr('value') + Gollum.enclose(el, 'gollum', 'link') + }) + + $('#editbar .image').click(function() { + var el = $('#guides .write textarea') + var format = $('#guides .write select[name=format] option:selected').attr('value') + Gollum.enclose(el, 'gollum', 'image') + }) + + $('#editbar .bold').click(function() { + var el = $('#guides .write textarea') + var format = $('#guides .write select[name=format] option:selected').attr('value') + Gollum.enclose(el, format, 'bold') + }) + + $('#editbar .italic').click(function() { + var el = $('#guides .write textarea') + var format = $('#guides .write select[name=format] option:selected').attr('value') + Gollum.enclose(el, format, 'italic') + }) + + $('#editbar .ul').click(function() { + var el = $('#guides .write textarea') + var format = $('#guides .write select[name=format] option:selected').attr('value') + Gollum.prefix(el, format, 'ul') + }) + + $('#editbar .ol').click(function() { + var el = $('#guides .write textarea') + var format = $('#guides .write select[name=format] option:selected').attr('value') + Gollum.prefix(el, format, 'ol') + }) + + $('#editbar .tab.help a').click(function() { + if ($(this).hasClass("open")) { + $(this).removeClass("open") + $('#editbar .sections').slideUp() + } else { + $(this).addClass("open") + if (!$('#editbar .sections .toc .current').get(0)) { + var target = $('#editbar .sections .toc .headers').get(0) + sectionItemClick.call(target) + } + $('#editbar .sections').slideDown() + } + }) + + $('#guides .write select[name=format]').change(function() { + var target = $('#editbar .sections .toc div.current').get(0) + sectionItemClick.call(target) + }) + + var sectionItemClick = function() { + $('#editbar .sections .toc div').removeClass('current') + $(this).addClass('current') + $('#editbar .sections .page').removeClass('current') + var classes = $(this).attr('class').split(' ') + var name = classes[0] + var format = $('#guides .write select[name=format] option:selected').attr('value') + if (classes.indexOf('gollum') == -1) { + $('#editbar .sections .page.' + name + '.' + format).addClass('current') + } else { + $('#editbar .sections .page.' + name).addClass('current') + } + return false; + } + + $('#editbar .sections .toc div').click(sectionItemClick) +}) diff --git a/lib/gollum/frontend/public/javascript/jquery.text_selection-1.0.0.min.js b/lib/gollum/frontend/public/javascript/jquery.text_selection-1.0.0.min.js new file mode 100644 index 00000000..1d161033 --- /dev/null +++ b/lib/gollum/frontend/public/javascript/jquery.text_selection-1.0.0.min.js @@ -0,0 +1 @@ +(function(B){var A=(function(){var C=(typeof document.selection!=="undefined"&&typeof document.selection.createRange!=="undefined");return{getSelectionRange:function(F){var J,D,E,I,H,G;F.focus();if(typeof F.selectionStart!=="undefined"){J=F.selectionStart;D=F.selectionEnd;}else{if(C){E=document.selection.createRange();I=E.text.length;if(E.parentElement()!==F){throw ("Unable to get selection range.");}if(F.type==="textarea"){H=E.duplicate();H.moveToElementText(F);H.setEndPoint("EndToEnd",E);J=H.text.length-I;}else{G=F.createTextRange();G.setEndPoint("EndToStart",E);J=G.text.length;}D=J+I;}else{throw ("Unable to get selection range.");}}return{start:J,end:D};},getSelectionStart:function(D){return this.getSelectionRange(D).start;},getSelectionEnd:function(D){return this.getSelectionRange(D).end;},setSelectionRange:function(F,H,D){var G,E;F.focus();if(typeof D==="undefined"){D=H;}if(typeof F.selectionStart!=="undefined"){F.setSelectionRange(H,D);}else{if(C){G=F.value;E=F.createTextRange();D-=H+G.slice(H+1,D).split("\n").length-1;H-=G.slice(0,H).split("\n").length-1;E.move("character",H);E.moveEnd("character",D);E.select();}else{throw ("Unable to set selection range.");}}},getSelectedText:function(E){var D=this.getSelectionRange(E);return E.value.substring(D.start,D.end);},insertText:function(E,I,D,F,K){F=F||D;var L=I.length,J=D+L,G=E.value.substring(0,D),H=E.value.substr(F);E.value=G+I+H;if(K===true){this.setSelectionRange(E,D,J);}else{this.setSelectionRange(E,J);}},replaceSelectedText:function(E,G,F){var D=this.getSelectionRange(E);this.insertText(E,G,D.start,D.end,F);},wrapSelectedText:function(E,G,D,F){var H=G+this.getSelectedText(E)+D;this.replaceSelectedText(E,H,F);}};})();window.Selection=A;B.fn.extend({getSelectionRange:function(){return A.getSelectionRange(this[0]);},getSelectionStart:function(){return A.getSelectionStart(this[0]);},getSelectionEnd:function(){return A.getSelectionEnd(this[0]);},getSelectedText:function(){return A.getSelectedText(this[0]);},setSelectionRange:function(D,C){return this.each(function(){A.setSelectionRange(this,D,C);});},insertText:function(E,F,C,D){return this.each(function(){A.insertText(this,E,F,C,D);});},replaceSelectedText:function(D,C){return this.each(function(){A.replaceSelectedText(this,D,C);});},wrapSelectedText:function(E,C,D){return this.each(function(){A.wrapSelectedText(this,E,C,D);});}});})(jQuery); \ No newline at end of file diff --git a/lib/gollum/frontend/templates/edit.mustache b/lib/gollum/frontend/templates/edit.mustache index fb3a904b..126816d0 100644 --- a/lib/gollum/frontend/templates/edit.mustache +++ b/lib/gollum/frontend/templates/edit.mustache @@ -12,7 +12,7 @@