diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 00000000..c2d147d2
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "public/s/js/jquery/plugins/jquery-form2xml"]
+ path = public/s/js/jquery/plugins/jquery-form2xml
+ url = git@github.com:docunext/jquery-form2xml.git
diff --git a/README.markdown b/README.markdown
index aadc5555..154e3b28 100644
--- a/README.markdown
+++ b/README.markdown
@@ -1,31 +1,133 @@
+<<<<<<< .merge_file_YFuwYZ
+git-wiki
+========
+=======
+# git-wiki fork:
+
+## added features
+- nested pages
+- double click page to edit
+- instant preview while editing
+- save and continue editing
+
+## notable changes
+- /pagename/edit is not /pagename?edit=1
+
+## future features
+- deleting pages
+- restoring deleted pages
+- moving pages
+- shared sub-wiki's using submodules
+- log / history / diff view
+
git-wiki: because who needs cool names when you use git?
========================================================
+>>>>>>> .merge_file_6bMFZW
+
+git-wiki is a wiki that relies on git to keep pages' history and
+[Sinatra][] to serve them. This geek brain overlay system aims to
+replace trac (wiki and ticket system), a CMS and sticky notes.
+
+Features of this fork (by geekQ)
+---------------------
+
+### Support for images
+
+You can add images to `/img` folder of your git repository. Subfolders
+are also supported. At least gif, png and jpg supported - content type
+is set automatically by Sinatra. You can reference the images then from
+your wiki pages like ``
+
+No web interface at this time - use `git commit`.
+
+
+### Custom h1 header
+
+If your wiki page contains a markdown h1 header, then this one is used
+on the page. If not, then h1 is created out of the file name (as in
+original git-wiki).
+
+
+### Integrated TODO list(s)
+
+Just write TODO or DONE at the beginning of a line with task you would
+like to remember.
+
+
+#### Inclusion
-git-wiki is a wiki that relies on git to keep pages' history
-and [Sinatra][] to serve them.
+You can include tasks from other wiki pages. So it is possible to have
+one separate page per project, e.g. ProjectGitWiki, ProjectWorkflow and
+to aggregate all coding tasks on one, say ContextCoding page with
+`INCLUDE project:GitWiki`, `INCLUDE project:Workflow`.
-I wrote git-wiki as a quick and dirty hack, mostly to play with Sinatra.
-It turned out that Sinatra is an awesome little web framework and that this
-hack isn't as useless as I first though since I now use it daily.
+You can also reference other contexts with `INCLUDE context:AtHome`.
-However, it is definitely not feature rich and will probably never be because
-I mostly use it as a web frontend for `git`, `ls` and `vim`.
+Recursion can be turned on with `INCLUDE context:AtHome recursive:true`.
+It is off by default.
+
+You can also reference a source on the web. I prefer to manage my tasks
+related to git-wiki development in this README file. So on my
+ContextCoding page I have following reference: `INCLUDE
+http://github.com/geekq/git-wiki/raw/master/README.markdown`
+
+* DONE: include via http
+* DONE: recursive inclusion
+* DONE: mark included tasks in special way
+* DONE: switch recursion on or off
+* DONE: avoid endless recursion by saving a list of visited nodes
+* TODO: include a task list filtered by tagged value, e.g. `TASKS context:home` should list all the tasks for the specified context.
+* DONE: allow optional asterisk in front of TODO
+* TODO: group included lists by project
+* TODO: merge and resort tasks from subsequent INCLUDE statements
+* DONE: gather all tasks from all pages with `INCLUDE wiki:all`
+* TODO: gather all the remaining (not referenced) tasks into `task inventory` page
+
+### No wiki words
+
+For a hacker the wiki words is more a distraction than a help. Example:
+if I mention ActiveRecord, than it should not link to the wiki article
+ActiveRecord but appear as it is.
+
+* DONE: do not rely on wiki words
+
+### Other plans
+
+* TODO: keyboard short cuts for edit and saving
+* TODO: check dead links
+* TODO: search engine
+* IDEA: presentation system - markdown + my S5 alternative
+* IDEA: support for attachments
+* IDEA: support for deeper Wiki page folder structure
+* IDEA: support for special programmed pages - via haml or liquid template engine
-If you want history, search, etc. you should look at other people's [forks][],
-especially [al3x][]'s one.
Install
-------
-The fellowing [gems][] are required to run git-wiki:
+The following [gems][] are required to run git-wiki:
- [Sinatra][]
- [mojombo-grit][]
- [HAML][]
- [RDiscount][]
+- [RestClient][]
-Run with `mkdir ~/wiki && (cd ~/wiki && git init) && ./run.ru -sthin -p4567`
-and point your browser at
'+stdout+'' + haml :publish end - get "/:page" do - @page = Page.find(params[:page]) - haml :show + + #get "/:page/history" do + # @page = Page.history + # haml :history + #end + + get "/*" do + path = params[:splat].join('/') + if not params[:edit].nil? + @page = Page.find_or_create(path) + haml :edit + else + @page = Page.find(path) + haml :show + end end - post "/:page" do - @page = Page.find_or_create(params[:page]) + post "/*" do + path = params[:splat].join('/') + @page = Page.find_or_create(path) @page.update_content(params[:body]) redirect "/#{@page}" end + private def title(title=nil) - @title = title.to_s unless title.nil? + @title = title.to_s.gsub('_',' ').gsub(/\b\w+/){$&.capitalize} unless title.nil? @title end + def breadcrumbs(title=nil) + #@title = title.to_s.gsub('_',' ').gsub(/\b\w+/){$&.capitalize} unless title.nil? + unless title.nil? + @bc = title.to_s + if @bc.include?('/') + @breadc = '' + @bc = @bc.split('/').map! do |path| + folder_name = path.gsub('_',' ').gsub(/\b\w+/){$&.capitalize} + if @breadc.empty? + path = path + '/index' + else + @breadc.gsub!('/index','') + end + @breadc << '/' << path + %Q{#{folder_name}} + end.join('/') + end + end + @bc + end def list_item(page) - %Q{#{page.name}} + title = page.name.gsub('_',' ').gsub(/\b\w+/){$&.capitalize} + %Q{#{title}} end end end - -__END__ -@@ layout -!!! -%html - %head - %title= title - %body - %ul - %li - %a{ :href => "/#{GitWiki.homepage}" } Home - %li - %a{ :href => "/pages" } All pages - #content= yield - -@@ show -- title @page.name -#edit - %a{:href => "/#{@page}/edit"} Edit this page -%h1= title -#content - ~"#{@page.to_html}" - -@@ edit -- title "Editing #{@page.name}" -%h1= title -%form{:method => 'POST', :action => "/#{@page}"} - %p - %textarea{:name => 'body', :rows => 30, :style => "width: 100%"}= @page.content - %p - %input.submit{:type => :submit, :value => "Save as the newest version"} - or - %a.cancel{:href=>"/#{@page}"} cancel - -@@ list -- title "Listing pages" -%h1 All pages -- if @pages.empty? - %p No pages found. -- else - %ul#list - - @pages.each do |page| - %li= list_item(page) diff --git a/git_wiki/app.rb b/git_wiki/app.rb new file mode 100644 index 00000000..f1399e4c --- /dev/null +++ b/git_wiki/app.rb @@ -0,0 +1,56 @@ +module GitWiki + class App < Sinatra::Base + enable :static + set :public, Proc.new { File.join(root, "public") } + set :app_file, __FILE__ + set :haml, { :format => :html5, + :attr_wrapper => '"' } + + error PageNotFound do + page = request.env["sinatra.error"].name + redirect "/#{page}?edit=1" + end + + before do + content_type "text/html", :charset => "utf-8" + @page_class = []; + end + + get "/stylesheets/application.css" do + content_type "text/css; charset=utf-8", :charset => "utf-8" + sass :"application" + end + + post "/preview" do + RDiscount.new(params[:body]).to_html + end + + get "/" do + redirect "/" + GitWiki.homepage + end + + get "/pages" do + @pages = Page.find_all + haml :list + end + + get "/*" do + path = params[:splat].join('/') + if not params[:edit].nil? + @page = Page.find_or_create(path) + haml :edit + else + @page = Page.find(path) + haml :show + end + end + + post "/*" do + path = params[:splat].join('/') + @page = Page.find_or_create(path) + @page.update_content(params[:body]) + redirect "/#{@page}" + end + + end +end \ No newline at end of file diff --git a/git_wiki/page.rb b/git_wiki/page.rb new file mode 100644 index 00000000..c9ff2d95 --- /dev/null +++ b/git_wiki/page.rb @@ -0,0 +1,164 @@ +module GitWiki + class Page + def self.find_all + return [] if repository.tree.contents.empty? + + all_blobs = collect_blobs_from_tree(repository.tree) + + all_blobs.flatten.collect do |blob| + new(blob) + end + end + + def self.collect_blobs_from_tree(tree, path=nil) + path = (path.nil? || tree.name.nil?) ? '' : path+'/'+tree.name + tree.contents.inject([]) do |blobs, file| + if file.is_a? Grit::Blob + add_path_to_blob(file, path+'/'+file.name) + blobs.push file + elsif file.is_a? Grit::Tree + blobs.concat collect_blobs_from_tree(file, path) + end + blobs + end + end + + def self.find(name) + page_blob = find_blob(name) + raise PageNotFound.new(name) unless page_blob + new(page_blob) + end + + def self.find_or_create(name) + find(name) + rescue PageNotFound + new(create_blob_for(name)) + end + + def self.css_class_for(name) + find(name) + "exists" + rescue PageNotFound + "unknown" + end + + def self.history + repository.commits + end + + def self.repository + GitWiki.repository || raise + end + + def self.extension + GitWiki.extension || raise + end + + def self.find_blob(page_name) + blob = repository.tree/(page_name + extension) + add_path_to_blob(blob, page_name + extension) if blob + blob + end + private_class_method :find_blob + + def self.add_path_to_blob(blob, path) + blob.instance_eval do + def path + @path + end + def path=(new_path) + @path = new_path + end + end + blob.path = path + end + private_class_method :add_path_to_blob + + def self.create_blob_for(page_name) + blob = Grit::Blob.create(repository, { + :name => page_name + extension, + :data => "" + }) + add_path_to_blob(blob, page_name + extension) if blob + blob + end + private_class_method :create_blob_for + + def initialize(blob) + @blob = blob + end + + def to_html + RDiscount.new(wiki_link(content)).to_html + end + + def to_s + name + end + + def new? + @blob.id.nil? + end + + def name + @blob.path.gsub(/#{File.extname(@blob.name)}$/, '').gsub(/^\//,'') + end + + def short_name + File.basename(@blob.name).gsub(/#{File.extname(@blob.name)}$/, '') + end + + def parent_directories + File.dirname(name).split(/\//).inject([[],[]]){ |collection, dirname| + parents, paths = collection + parents.push(dirname) + paths.push(parents.join('/')) + [parents, paths] + }[1] + end + + def content + @blob.data + end + + def update_content(new_content) + return if new_content == content + system("mkdir -p '#{File.dirname(file_name)}'"); + File.open(file_name, "w") { |f| f << new_content } + add_to_index_and_commit! + end + + private + def add_to_index_and_commit! + Dir.chdir(self.class.repository.working_dir) { + self.class.repository.add(@blob.path) + } + self.class.repository.commit_index(commit_message) + end + + def file_name + File.join(self.class.repository.working_dir, name + self.class.extension) + end + + def commit_message + new? ? "Created #{name}" : "Updated #{name}" + end + + def wiki_link(str) + str.gsub(/\[\[([^\]]+\]\])/) { |page| + filename = page.downcase.gsub('[','').gsub(']','').gsub(/[^a-z0-9:\/\.]/,'_') + if filename =~ /^\// + wiki = file_name.gsub(self.class.repository.working_dir,'').split('/')[1] + file = wiki + filename + filename = '/' + file + else + file = File.expand_path(File.dirname(file_name) + '/' + filename) + file.gsub!(self.class.repository.working_dir+'/','') + end + linktext = page.gsub('[','').gsub(']','').split('/').pop().capitalize(); + %Q{#{linktext}} + } + end + end +end \ No newline at end of file diff --git a/git_wiki/page_not_found.rb b/git_wiki/page_not_found.rb new file mode 100644 index 00000000..d63cbffa --- /dev/null +++ b/git_wiki/page_not_found.rb @@ -0,0 +1,9 @@ +module GitWiki + class PageNotFound < Sinatra::NotFound + attr_reader :name + + def initialize(name) + @name = name + end + end +end \ No newline at end of file diff --git a/ikiwikis.ru b/ikiwikis.ru new file mode 100755 index 00000000..bb828151 --- /dev/null +++ b/ikiwikis.ru @@ -0,0 +1,5 @@ +#!/home/albertlash/.rbenv/versions/1.9.3-rc1/bin/rackup +require "./git-wiki" + +run GitWiki.new("/home/albertlash/savonix/wikis", + ARGV[2] || ".mdwn", ARGV[3] || "index") diff --git a/public/s/css/yui.reset.css b/public/s/css/yui.reset.css new file mode 100644 index 00000000..47844f75 --- /dev/null +++ b/public/s/css/yui.reset.css @@ -0,0 +1,7 @@ +/* +Copyright (c) 2009, Yahoo! Inc. All rights reserved. +Code licensed under the BSD License: +http://developer.yahoo.net/yui/license.txt +version: 2.8.0r4 +*/ +html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var,optgroup{font-style:inherit;font-weight:inherit;}del,ins{text-decoration:none;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym{border:0;font-variant:normal;}sup{vertical-align:baseline;}sub{vertical-align:baseline;}legend{color:#000;}input,button,textarea,select,optgroup,option{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;}input,button,textarea,select{*font-size:100%;} diff --git a/run.ru b/run.ru index 664eb858..53c09e2a 100755 --- a/run.ru +++ b/run.ru @@ -1,5 +1,5 @@ -#!/usr/bin/env rackup +#!/usr/bin/rackup1.8 require File.dirname(__FILE__) + "/git-wiki" -run GitWiki.new(File.expand_path(ARGV[1] || "~/wiki"), - ARGV[2] || ".markdown", ARGV[3] || "Home") +run GitWiki.new(File.expand_path("~/nudocs/mntdocs/"), + ARGV[2] || ".mdwn", ARGV[3] || "Home") diff --git a/views/commits.haml b/views/commits.haml new file mode 100644 index 00000000..f868062e --- /dev/null +++ b/views/commits.haml @@ -0,0 +1,8 @@ +- title "Listing commits" +%h1 All commits +- if @commits.empty? + %p No commits found. +- else + %ul#list + - @commits.each do |commit| + %li= commit.id << " " << commit.authored_date.to_s diff --git a/views/edit.haml b/views/edit.haml new file mode 100644 index 00000000..b3e5704b --- /dev/null +++ b/views/edit.haml @@ -0,0 +1,9 @@ +- title "Editing #{@page.name}" +%h1= title +%form{:method => 'POST', :action => "/#{@page}"} + %p + %textarea{:name => 'body', :rows => 30, :style => "width: 100%"}= @page.content + %p + %input.submit{:type => :submit, :value => "Save as the newest version"} + or + %a.cancel{:href=>"/#{@page}"} cancel diff --git a/views/layout.haml b/views/layout.haml new file mode 100644 index 00000000..549f577d --- /dev/null +++ b/views/layout.haml @@ -0,0 +1,16 @@ +!!! +%html + %head + %title= title + %script{ :type=> "text/javascript", :src=> "http://www-01.evenserver.com/s/js/jquery/jquery-1.4.2.min.js" } + %link{ :rel=> "stylesheet", :type=> "text/css", :href=> "/s/css/yui.reset.css" } + %link{ :href=> "/styles.css", :media=> 'all', :type=> "text/css", :rel=> "stylesheet" } + %body + %ul{:id=> 'header-menu'} + %li + %a{ :href => "/#{GitWiki.homepage}" } Home + %li + %a{ :href => "/pages" } All pages + %li + %a{ :href => "/commits" } Commits + #container= yield \ No newline at end of file diff --git a/views/list.haml b/views/list.haml new file mode 100644 index 00000000..d8813524 --- /dev/null +++ b/views/list.haml @@ -0,0 +1,9 @@ +- title "Listing pages" +%h1 All #{@pages.count} pages +- if @pages.empty? + %p No pages found. +- else + %ul#list + - @pages.each do |page| + %li= list_item(page) + %p #{@pages.count} pages \ No newline at end of file diff --git a/views/publish.haml b/views/publish.haml new file mode 100644 index 00000000..5808f75c --- /dev/null +++ b/views/publish.haml @@ -0,0 +1,3 @@ +- title "Publish" +#content + ~"#{@publish}" \ No newline at end of file diff --git a/views/show.haml b/views/show.haml new file mode 100644 index 00000000..a6bfd22f --- /dev/null +++ b/views/show.haml @@ -0,0 +1,10 @@ +- title @page.name +#page-controls + %ul + %li + %a{:href => "/#{@page}?edit=1"} Edit this page + %li + %a{:href => "/#{@page}/history"} History +%h1= breadcrumbs(@page.name) +#content + ~"#{@page.to_html}" \ No newline at end of file diff --git a/views/styles.sass b/views/styles.sass new file mode 100644 index 00000000..db289097 --- /dev/null +++ b/views/styles.sass @@ -0,0 +1,31 @@ +h1 + :font-size 120% + :margin-top 1em + +h2 + :font-size 110% + :margin-top 1em + +h3 + :font-size 105% + :margin-top 1em + + +div + :padding 10px !important + +#header-menu li, #page-controls li + :display inline + +#content ul li + :list-style-type disc + +#content ul + :margin 2em + +.unknown + :color red + +ol li + :margin-left 2em + :list-style-type decimal