diff --git a/lib/gollum.rb b/lib/gollum.rb
index 390b778e..1d82b261 100644
--- a/lib/gollum.rb
+++ b/lib/gollum.rb
@@ -1,3 +1,6 @@
+# stdlib
+require 'digest/md5'
+
# external
require 'grit'
require 'github/markup'
diff --git a/lib/gollum/frontend/app.rb b/lib/gollum/frontend/app.rb
index 3724fd0e..6c0621f4 100644
--- a/lib/gollum/frontend/app.rb
+++ b/lib/gollum/frontend/app.rb
@@ -78,6 +78,23 @@ module Precious
wiki.preview_page("Preview", data, format).formatted_data
end
+ get '/history/:name' do
+ @name = params[:name]
+ wiki = Gollum::Wiki.new($path)
+ @page = wiki.page(@name)
+ mustache :history
+ end
+
+ post '/compare/:name' do
+ @name = params[:name]
+ @versions = params[:versions]
+ wiki = Gollum::Wiki.new($path)
+ @page = wiki.page(@name)
+ diffs = wiki.repo.diff(@versions[1], @versions[0], @page.path)
+ @diff = diffs.first
+ mustache :compare
+ end
+
get %r{/(.+?)/([0-9a-f]{40})} do
name = params[:captures][0]
wiki = Gollum::Wiki.new($path)
diff --git a/lib/gollum/frontend/public/css/screen.css b/lib/gollum/frontend/public/css/screen.css
index 617f963d..8f152b8d 100644
--- a/lib/gollum/frontend/public/css/screen.css
+++ b/lib/gollum/frontend/public/css/screen.css
@@ -487,4 +487,236 @@ label.wiki-label {
.comment-form .comment{
margin:5px 0 0 0;
-}
\ No newline at end of file
+}
+
+/****************************************************************************/
+/* History
+/****************************************************************************/
+
+table.commits {
+ width: 100%;
+ border-left: 1px solid #ccc;
+ border-right: 1px solid #ccc;
+ border-top: 1px solid #ccc;
+ margin-bottom: 2em;
+}
+
+ table.commits tr td {
+ background-color: #eaf2f5;
+ }
+
+ table.commits th {
+ font-weight: normal;
+ border-bottom: 1px solid #ccc;
+ padding: .3em .6em;
+ background-color: #eee;
+ font-size: 95%;
+ text-align:left;
+ }
+
+ table.commits td {
+ border-bottom: 1px solid #ccc;
+ padding: .3em .6em;
+ }
+
+ table.commits td.sha,
+ table.commits td.message {
+ font-family: Monaco, "Courier New", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", monospace;
+ font-size: 80%;
+ }
+
+ table.commits td.checkbox {
+ width: 3%;
+ }
+
+ table.commits td.sha {
+ width: 6%;
+ }
+
+ table.commits td.human {
+ font-family: Monaco, "Courier New", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", monospace;
+ font-size: 80%;
+ width: 4%;
+ color: #888;
+ }
+
+ table.commits td.author {
+ width: 15%;
+ font-weight: bold;
+ }
+
+ table.commits td.author img {
+ vertical-align: middle;
+ border: 1px solid #ccc;
+ padding: 1px;
+ background-color: white;
+ }
+
+ table.commits td.message a {
+ color: black;
+ }
+
+ table.commits td.message a:hover {
+ text-decoration: underline;
+ }
+
+ table.commits td.date {
+ width: 12%;
+ text-align: right;
+ }
+
+/****************************************************************************/
+/* Files
+/****************************************************************************/
+
+#files {
+
+}
+
+ #files .file {
+ border: 1px solid #ccc;
+ margin-bottom: 1em;
+ }
+
+ #files .file .syntax{
+ border:none;
+ padding:0;
+ }
+
+ #files .file .meta {
+ padding:0 5px;
+ height:33px;
+ line-height:33px;
+ font-size:12px;
+ color:#333;
+ background:url(/images/modules/commit/file_head.gif) 0 0 repeat-x #eee;
+ text-shadow:1px 1px 0 rgba(255, 255, 255, 0.5);
+ border-bottom: 1px solid #ccc;
+ overflow: hidden;
+ }
+
+ #files .file .meta .info {
+ float: left;
+ height:33px;
+ line-height:33px;
+ font-family: Monaco, "Courier New", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", monospace;
+ }
+
+ #files .file .meta .info span{
+ padding-left:9px;
+ margin-left:5px;
+ background:url(/images/modules/commit/action_separator.png) 0 50% no-repeat;
+ }
+
+ #files .file .meta .info span:first-child, #files .file .meta .info .icon + span{
+ background:transparent;
+ margin-left:0;
+ padding-left:0;
+ }
+
+ #files .file .meta .info span.icon{
+ float:left;
+ margin:5px 5px 0 0;
+ padding:3px;
+ background:#f7f7f7;
+ border:1px solid #ccc;
+ border-right-color:#e5e5e5;
+ border-bottom-color:#e5e5e5;
+ -webkit-border-radius:3px;
+ -moz-border-radius:3px;
+ border-radius:3px;
+ line-height: 1em;
+ }
+
+ #files .file .meta .actions {
+ float: right;
+ height:33px;
+ line-height:33px;
+ }
+
+ #files .file .meta .actions li{
+ list-style-type:none;
+ float:left;
+ margin:0 0 0 7px;
+ height:33px;
+ line-height:33px;
+ padding-left:9px;
+ font-size:11px;
+ background:url(/images/modules/commit/action_separator.png) 0 50% no-repeat;
+ }
+
+ #files .file .meta .actions li:first-child{
+ background:transparent;
+ margin-left:0;
+ padding-left:0;
+ }
+
+ #files .file .meta .actions li a{
+ font-weight:bold;
+ }
+
+ #files .file .meta .actions li code{
+ font-size:11px;
+ }
+
+ #files .file .meta .actions li label input{
+ position:relative;
+ top:1px;
+ }
+
+ #files .file .data {
+ font-size: 80%;
+ overflow: auto;
+ background-color: #f8f8ff;
+ }
+
+ #files .file .data.empty {
+ font-size: 90%;
+ padding:5px 10px;
+ color:#777;
+ }
+
+ #files .image {
+ padding: 1.2em;
+ text-align: center;
+ }
+
+ #files .image img {
+ max-width: 60em;
+ }
+
+ #files .file .data pre, #files .file .line-data, #files .file .line-number {
+ font-family: 'Bitstream Vera Sans Mono', 'Courier', monospace;
+ font-size: 115%;
+ }
+
+ #files .file .data .highlight {
+ padding: 1em 0;
+ }
+
+ #files .file .data .highlight div {
+ padding-left: 1em;
+ }
+
+ #files .file .data .line_numbers {
+ background-color: #ececec;
+ color: #aaa;
+ padding: 1em .5em;
+ border-right: 1px solid #ddd;
+ text-align: right;
+ }
+
+ #files .file .data td.line_numbers{
+ padding:0 0.5em;
+ font-family: 'Bitstream Vera Sans Mono', 'Courier', monospace;
+ font-size: 115%;
+ -moz-user-select:none;
+ -khtml-user-select:none;
+ user-select:none;
+ }
+
+ #files .file .data .line_numbers span,
+ #files .file .data .line_numbers a {
+ color: #aaa;
+ cursor: pointer;
+ }
\ No newline at end of file
diff --git a/lib/gollum/frontend/public/css/syntax.css b/lib/gollum/frontend/public/css/syntax.css
index 2774b764..d84c0612 100644
--- a/lib/gollum/frontend/public/css/syntax.css
+++ b/lib/gollum/frontend/public/css/syntax.css
@@ -14,6 +14,7 @@
.highlight .gh { color: #999999 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
+.highlight .gc { color: #999; background-color: #EAF2F5 }
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
diff --git a/lib/gollum/frontend/public/images/txt.png b/lib/gollum/frontend/public/images/txt.png
new file mode 100644
index 00000000..f3638cb4
Binary files /dev/null and b/lib/gollum/frontend/public/images/txt.png differ
diff --git a/lib/gollum/frontend/templates/compare.mustache b/lib/gollum/frontend/templates/compare.mustache
new file mode 100644
index 00000000..02b42593
--- /dev/null
+++ b/lib/gollum/frontend/templates/compare.mustache
@@ -0,0 +1,33 @@
+
+
+
+
Comparison of {{human_name}}: {{before}} → {{after}}
+
+
+
+
+
+ {{#lines}}
+
+ {{ldln}}
+ {{rdln}}
+
+ {{line}}
+
+
+ {{/lines}}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/lib/gollum/frontend/templates/history.mustache b/lib/gollum/frontend/templates/history.mustache
new file mode 100644
index 00000000..7a7ee653
--- /dev/null
+++ b/lib/gollum/frontend/templates/history.mustache
@@ -0,0 +1,32 @@
+
+
+
+
History of {{human_name}}
+
+
+
\ No newline at end of file
diff --git a/lib/gollum/frontend/templates/page.mustache b/lib/gollum/frontend/templates/page.mustache
index 321814dc..ce799d27 100644
--- a/lib/gollum/frontend/templates/page.mustache
+++ b/lib/gollum/frontend/templates/page.mustache
@@ -22,11 +22,6 @@
-
Versions:
-
- {{#versions}}
- Version {{num}} ({{id7}}) by {{author}}
- {{/versions}}
-
+
View Revision History
diff --git a/lib/gollum/frontend/views/compare.rb b/lib/gollum/frontend/views/compare.rb
new file mode 100644
index 00000000..a23ec182
--- /dev/null
+++ b/lib/gollum/frontend/views/compare.rb
@@ -0,0 +1,94 @@
+module Precious
+ module Views
+ class Compare < Layout
+ attr_reader :page, :diff, :versions
+
+ def human_name
+ @page.title
+ end
+
+ def title
+ "A Page"
+ end
+
+ def path
+ @page.path
+ end
+
+ def before
+ @versions[1][0..6]
+ end
+
+ def after
+ @versions[0][0..6]
+ end
+
+ def lines
+ lines = []
+ @diff.diff.split("\n")[2..-1].each_with_index do |line, line_index|
+ lines << { :line => line,
+ :class => line_class(line),
+ :ldln => left_diff_line_number(0, line),
+ :rdln => right_diff_line_number(0, line) }
+ end
+ lines
+ end
+
+ # private
+
+ def line_class(line)
+ if line =~ /^@@/
+ 'gc'
+ elsif line =~ /^\+/
+ 'gi'
+ elsif line =~ /^\-/
+ 'gd'
+ else
+ ''
+ end
+ end
+
+ @left_diff_line_number = nil
+ def left_diff_line_number(id, line)
+ if line =~ /^@@/
+ m, li = *line.match(/\-(\d+)/)
+ @left_diff_line_number = li.to_i
+ @current_line_number = @left_diff_line_number
+ ret = '...'
+ elsif line[0] == ?-
+ ret = @left_diff_line_number.to_s
+ @left_diff_line_number += 1
+ @current_line_number = @left_diff_line_number - 1
+ elsif line[0] == ?+
+ ret = ' '
+ else
+ ret = @left_diff_line_number.to_s
+ @left_diff_line_number += 1
+ @current_line_number = @left_diff_line_number - 1
+ end
+ ret
+ end
+
+ @right_diff_line_number = nil
+ def right_diff_line_number(id, line)
+ if line =~ /^@@/
+ m, ri = *line.match(/\+(\d+)/)
+ @right_diff_line_number = ri.to_i
+ @current_line_number = @right_diff_line_number
+ ret = '...'
+ elsif line[0] == ?-
+ ret = ' '
+ elsif line[0] == ?+
+ ret = @right_diff_line_number.to_s
+ @right_diff_line_number += 1
+ @current_line_number = @right_diff_line_number - 1
+ else
+ ret = @right_diff_line_number.to_s
+ @right_diff_line_number += 1
+ @current_line_number = @right_diff_line_number - 1
+ end
+ ret
+ end
+ end
+ end
+end
diff --git a/lib/gollum/frontend/views/history.rb b/lib/gollum/frontend/views/history.rb
new file mode 100644
index 00000000..648db01b
--- /dev/null
+++ b/lib/gollum/frontend/views/history.rb
@@ -0,0 +1,30 @@
+module Precious
+ module Views
+ class History < Layout
+ attr_reader :page
+
+ def human_name
+ @page.title
+ end
+
+ def title
+ "A Page"
+ end
+
+ def versions
+ i = @page.versions.size + 1
+ @page.versions.map do |v|
+ i -= 1
+ { :id => v.id,
+ :id7 => v.id[0..6],
+ :num => i,
+ :selected => @page.version.id == v.id,
+ :author => v.author.name,
+ :message => v.message,
+ :date => v.committed_date.strftime("%B %d, %Y"),
+ :gravatar => Digest::MD5.hexdigest(v.author.email) }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gollum/frontend/views/page.rb b/lib/gollum/frontend/views/page.rb
index d3681288..e2211da5 100644
--- a/lib/gollum/frontend/views/page.rb
+++ b/lib/gollum/frontend/views/page.rb
@@ -37,18 +37,6 @@ module Precious
@footer ||= @page.footer
@footer.format.to_s
end
-
- def versions
- i = @page.versions.size + 1
- @page.versions.map do |v|
- i -= 1
- { :id => v.id,
- :id7 => v.id[0..6],
- :num => i,
- :selected => @page.version.id == v.id,
- :author => v.author.name }
- end
- end
end
end
end