diff -uNr wikit-orig.vfs/lib/rskdiff/pkgIndex.tcl wikit-revs-9rsk.vfs/lib/rskdiff/pkgIndex.tcl
--- wikit-orig.vfs/lib/rskdiff/pkgIndex.tcl	1969-12-31 18:00:00.000000000 -0600
+++ wikit-revs-9rsk.vfs/lib/rskdiff/pkgIndex.tcl	2008-04-06 00:18:08.000000000 -0500
@@ -0,0 +1,11 @@
+# Tcl package index file, version 1.1
+# This file is generated by the "pkg_mkIndex" command
+# and sourced either when an application starts up or
+# by a "package unknown" script.  It invokes the
+# "package ifneeded" command to set up package-related
+# information so that packages will be loaded automatically
+# in response to "package require" commands.  When this
+# script is sourced, the variable $dir must contain the
+# full path name of this file's directory.
+
+package ifneeded rskdiff 0.1 [list source [file join $dir rskdiff.tcl]]
diff -uNr wikit-orig.vfs/lib/rskdiff/rskdiff.tcl wikit-revs-9rsk.vfs/lib/rskdiff/rskdiff.tcl
--- wikit-orig.vfs/lib/rskdiff/rskdiff.tcl	1969-12-31 18:00:00.000000000 -0600
+++ wikit-revs-9rsk.vfs/lib/rskdiff/rskdiff.tcl	2008-04-06 00:18:08.000000000 -0500
@@ -0,0 +1,148 @@
+proc _perform_diff_isMinimalMatch {a b} {
+	set a [string trim [string tolower $a]]
+	set b [string trim [string tolower $b]]
+
+	# If either line is blank, then never consider it a match
+	if {$a eq "" || $b eq ""} {
+		return 0
+	}
+
+	# Check for match discounting non-alphabetic chars
+	set minA [string tolower [regsub -all {[^a-z]} $a {}]]
+	set minB [string tolower [regsub -all {[^a-z]} $b {}]]
+	if {$minA eq $minB} {
+		return 1
+	}
+
+	# Check compositing
+	if {[string first $minA $minB] != -1} {
+		return 1
+	}
+	if {[string first $minB $minA] != -1} {
+		return 1
+	}
+
+	return 0
+}
+
+# RET:
+#   List of:
+#      = LINE (unchanged)
+#      + LINE (in dest, but not source)
+#      - LINE (in source, but not dest)
+#      M LINE (Minor modification on line)
+proc perform_diff {source dest {splitchar \r\n}} {
+	set source [split $source $splitchar]
+	set dest [split $dest $splitchar]
+
+	set sourceLen [llength $source]
+	set destLen [llength $dest]
+
+        set lookAheadLines 15
+
+	set ret [list]
+	for {set idxSrcLine 0; set idxDstLine 0} {$idxSrcLine < $sourceLen && $idxDstLine < $destLen} {incr idxSrcLine; incr idxDstLine} {
+		set srcLine [lindex $source $idxSrcLine]
+		set dstLine [lindex $dest $idxDstLine]
+
+		# Check for exact equality
+		if {$srcLine eq $dstLine} {
+			lappend ret [list = $dstLine]
+			continue
+		}
+
+		# Check for close equality
+		if {[_perform_diff_isMinimalMatch $srcLine $dstLine]} {
+			lappend ret [list M $srcLine $dstLine]
+			continue
+		}
+
+		# Look ahead to see if this srcLine occurs in the near future in the output
+		set foundInLookAhead 0
+		for {set idxFwdLine 1} {$idxFwdLine < $lookAheadLines} {incr idxFwdLine} {
+			set tryIdx [expr $idxDstLine + $idxFwdLine]
+			if {$tryIdx >= $destLen} {
+				break
+			}
+
+			set tmpDstLine [lindex $dest $tryIdx]
+			if {[_perform_diff_isMinimalMatch $srcLine $tmpDstLine]} {
+				# We have found a match, so all the intervening lines are in DEST, but not in SOURCE
+				for {set idxCaptured 0} {$idxCaptured < $idxFwdLine} {incr idxCaptured} {
+					set capturedLine [lindex $dest [expr $idxDstLine + $idxCaptured]]
+				
+					lappend ret [list + "" $capturedLine]
+				}
+
+				# Move past captured lines
+				incr idxDstLine $idxFwdLine
+
+				# Note that we have found a match.
+				set foundInLookAhead 1
+				break
+			}
+		}
+		if {$foundInLookAhead} {
+			# Reprocess the current line
+			incr idxDstLine -1
+			incr idxSrcLine -1
+			continue
+		}
+
+		# Look ahead to see if this srcLine occurs in the near future in the input (try to resync)
+		set foundInLookAhead 0
+		for {set idxFwdLine 1} {$idxFwdLine < $lookAheadLines} {incr idxFwdLine} {
+			set tryIdx [expr $idxSrcLine + $idxFwdLine]
+			if {$tryIdx >= $sourceLen} {
+				break
+			}
+
+			set tmpSrcLine [lindex $source $tryIdx]
+			if {[_perform_diff_isMinimalMatch $srcLine $tmpSrcLine]} {
+				# We have found a match, so all the intervening lines are in DEST, but not in SOURCE
+				for {set idxCaptured 0} {$idxCaptured < $idxFwdLine} {incr idxCaptured} {
+					set capturedLine [lindex $source [expr $idxSrcLine + $idxCaptured]]
+
+					lappend ret [list - $capturedLine ""]
+				}
+
+				# Move past captured lines
+				incr idxSrcLine $idxFwdLine
+
+				# Note that we have found a match.
+				set foundInLookAhead 1
+				break
+			}
+		}
+		if {$foundInLookAhead} {
+			# Reprocess the current line
+			incr idxDstLine -1
+			incr idxSrcLine -1
+			continue
+		}
+
+		# Not found in look-ahead, this line was probably deleted
+		lappend ret [list - $srcLine]
+		incr idxDstLine -1
+	}
+
+	set remSrcLines [expr $sourceLen - $idxSrcLine]
+	set remDstLines [expr $destLen - $idxDstLine]
+        if {$remSrcLines != 0 || $remDstLines != 0} {
+		if {$remSrcLines > $remDstLines} {
+			for {set idx $idxSrcLine} {$idx < $sourceLen} {incr idx} {
+				set srcLine [lindex $source $idx]
+				lappend ret [list - $srcLine ""]
+			}
+		} else {
+			for {set idx $idxDstLine} {$idx < $destLen} {incr idx} {
+				set dstLine [lindex $dest $idx]
+				lappend ret [list + "" $dstLine]
+			}
+		}
+	}
+
+	return $ret
+}
+
+package provide rskdiff 0.1
diff -uNr wikit-orig.vfs/lib/wikit/db.tcl wikit-revs-9rsk.vfs/lib/wikit/db.tcl
--- wikit-orig.vfs/lib/wikit/db.tcl	2007-04-10 06:44:06.000000000 -0500
+++ wikit-revs-9rsk.vfs/lib/wikit/db.tcl	2008-04-06 00:18:08.000000000 -0500
@@ -109,6 +109,10 @@
     
     mk::view layout $db.pages	{name page date:I who}
     mk::view layout $db.refs	{from:I to:I}
+    # Versioning attempt: <wiki@rkeene.org>
+    mk::view layout $db.revs    {id:I}
+    mk::view layout $db.history {name page date:I who}
+    # Versioning attempt (end)
     
     # if there are no references, probably it's the first time, so recalc
     if {!$readonly && [mk::view size $db.refs] == 0} {
@@ -147,6 +151,22 @@
   }
 
   proc GetTitle {id {db wdb}} {
+    # Versioning attempt: <wiki@rkeene.org>
+    if {[string match "*.*" $id]} {
+      set work [split $id .]
+      set id [lindex $work 0]
+      set rev [lindex $work 1]
+      set chk_id [mk::get $db.revs!$rev id]
+      if {$chk_id != $id} {
+        # XXX: What do we do here ?
+        return -code error "ID Mismatch for Revision $rev.  Expected \"$chk_id\", got \"$id\""
+      }
+
+      set title [mk::get $db.history!$rev name]
+      return $title
+    }
+    # Versioning attempt (end)
+
     set title [mk::get $db.pages!$id name]
     return $title
   }
@@ -155,7 +175,24 @@
     switch $id {
       2		{ SearchResults [SearchList] }
       4		{ RecentChanges $db}
-      default	{ return [mk::get $db.pages!$id page] }
+      default	{
+        # Versioning attempt: <wiki@rkeene.org>
+        if {[string match "*.*" $id]} {
+          set work [split $id .]
+          set id [lindex $work 0]
+          set rev [lindex $work 1]
+          set chk_id [mk::get $db.revs!$rev id]
+          if {$chk_id != $id} {
+            # XXX: What do we do here ?
+            return -code error "ID Mismatch for Revision $rev.  Expected \"$chk_id\", got \"$id\""
+          }
+
+          return [mk::get $db.history!$rev page]
+        }
+        # Versioning attempt (end)
+
+        return [mk::get $db.pages!$id page]
+      }
     }
   }
   
@@ -225,9 +262,13 @@
   # SavePageDB - store page $id ($who, $text, $newdate)
   proc SavePageDB {db id text who newName {newdate ""}} {
     set changed 0
-    
-    pagevarsDB $db $id name page
 
+    # Versioning attempt: <wiki@rkeene.org>
+    set id [lindex [split $id .] 0]
+    # Versioning attempt (end)
+
+    pagevarsDB $db $id name page
+    
     if {$newName != $name} {
       set changed 1
       
@@ -253,6 +294,12 @@
     # avoid creating a log entry and committing if nothing changed
     set text [string trimright $text]
     if {!$changed && $text == $page} return
+
+    # Versioning attempt: <wiki@rkeene.org>
+    set newRev [mk::view size $db.revs]
+    mk::set $db.history!$newRev page $text who $who date [clock seconds] name $newName
+    mk::set $db.revs!$newRev id $id
+    # Versioning attempt (end)
     
     # make sure it parses before deleting old references
     set newRefs [StreamToRefs [TextToStream $text] [list ::Wikit::InfoProc $db]]
@@ -264,7 +311,7 @@
     }
     
     mk::set $db.pages!$id page $text who $who
-    
+
     if {$newdate == ""} {
       mk::set $db.pages!$id date [clock seconds]
       AddLogEntry $id $db
diff -uNr wikit-orig.vfs/lib/wikit/web.tcl wikit-revs-9rsk.vfs/lib/wikit/web.tcl
--- wikit-orig.vfs/lib/wikit/web.tcl	2007-04-10 06:44:06.000000000 -0500
+++ wikit-revs-9rsk.vfs/lib/wikit/web.tcl	2008-04-06 01:01:53.000000000 -0500
@@ -6,6 +6,7 @@
 package require cgi
 package require Wikit::Db
 package require Wikit::Search
+package require rskdiff
 
 # dump CGI env to file for debugging purposes
 if {[catch {
@@ -163,7 +164,7 @@
     set section ""
       # Updated 3Mar03, edit and references are now subdirs to allow
       # for site indexing. 
-      if {![regexp {^/(edit/|references/)?([0-9]+)(.*)$} $path x section N cmd] || $N >= [mk::view size wdb.pages]} {
+      if {![regexp {^/(revs/|diff/|edit/|references/)?([0-9\.]+)(.*)$} $path x section N cmd] || [lindex [split $N .] 0] >= [mk::view size wdb.pages]} {
       set N 0
     
         # try to locate a page by name, using various search heuristics
@@ -195,7 +196,7 @@
     #tclLog "path $path query $query N $N"
 
     # prevent DoS via way too large integers
-    if {$query eq "" && [string length $N] > 9} { set query $N }
+    if {$query eq "" && [string length [lindex [split $N .] 0]] > 9} { set query $N }
 
     if {$query != ""} {
       set N 2
@@ -205,10 +206,12 @@
       set searchLong [regexp {^(.*)\*$} $searchKey x searchKey]
       set query "?$query"
     }
-    
+
     pagevars $N name date who
     set origtag [list $date $who]
-    set refs [mk::select wdb.refs to $N]
+    # Versioning attempt: <wiki@rkeene.org>
+    set refs [mk::select wdb.refs to [lindex [split $N .] 0]]
+    # Versioning attempt (end)
     
     # added 2004-05-17 wru cookie identification
     catch {source $::env(WIKIT_WRU)}
@@ -298,6 +301,11 @@
     
     # set up a few standard URLs an strings
     
+    if {$section eq ""} {
+      set backRef references/[lindex [split $N .] 0]!
+    } else {
+      set backRef ../references/[lindex [split $N .] 0]!
+    }
     switch [llength $refs] {
       0 {
 	set backRef ""
@@ -308,18 +316,24 @@
         # 03-06-2003 generate page with back ref request, so cached
 	# copy stays valid when more page references are added later
 	#set backRef [mk::get wdb.refs!$refs from]
-	set backRef references/$N!
         set Refs "[Wiki Reference $backRef] - " 
         set Title [Wiki $name $backRef]
       }
       default {
-	set backRef references/$N!
         set Refs "[llength $refs] [Wiki References $backRef] - "
         set Title [Wiki $name $backRef]
       }
     }
     
-    set Edit "Edit [Wiki - edit/$N@]"
+    # Versioning attempt: <wiki@rkeene.org>
+    if {$section eq ""} {
+      set Edit "Edit [Wiki - edit/$N@]"
+      set Revisions "[link - Revisions revs/[lindex [split $N .] 0]|] - "
+    } else {
+      set Edit "Edit [Wiki - ../edit/$N@]"
+      set Revisions "[link - Revisions ../revs/[lindex [split $N .] 0]|] - "
+    }
+    # Versioning attempt (end)
 
     if { $section eq "" } {
 	set Home "Go to [Wiki - 0]"
@@ -338,7 +352,6 @@
 	set Help " - [Wiki - ../3]"
     }
 
-    if {$N == 1} { set About "" }
     if {$N == 2} { set Search "" }
     if {$N == 3} { set Help "" }
     if {$N == 4} { set Changes "" }
@@ -357,18 +370,19 @@
     if {[lsearch -exact $::ProtectedPages $N] >= 0} {
       set menu ""
     } elseif {$roflag >= 0 || $readonly} {
-      set menu "$updated[nl]"
+      set menu "$updated"
+      append menu [nl]
     } else {
-      set menu "$updated [nbspace]-[nbspace] $Edit"
-      # 2004-05-29 add optional link to history
-      if {[info exists ::env(WIKIT_REVS)] && $::env(WIKIT_REVS) ne ""} {
-      append menu " [nbspace]-[nbspace]\
-        [link - Revisions $::env(WIKIT_REVS)/$N]"
+      # Versioning attempt: <wiki@rkeene.org>
+      set menu "$updated"
+      if { $section eq "" || $section eq "revs/" } {
+        append menu " [nbspace]-[nbspace] $Edit"
       }
       append menu [nl]
+      # Versioning attempt (end)
     }
     
-    append menu "$Search$Changes$Refs$About$Home$Help"
+    append menu "$Search$Changes$Refs$Revisions$Home$Help"
     
     cgi_http_head {
       cgi_content_type
@@ -380,7 +394,151 @@
     cgi_html {
 
       switch -- $cmd {
+        = {
+          # Versioning attempt: <wiki@rkeene.org>
+
+          set work [split $N .]
+          set N [lindex $work 0]
+          set destRev [lindex $work 1]
+          set destFakeRev [lindex $work 2]
+          set sourceRev [lindex $work 3]
+          set sourceFakeRev [lindex $work 4]
+
+          set sourceWho [mk::get wdb.history!$sourceRev who]
+          set destWho [mk::get wdb.history!$destRev who]
+          set sourceDate [mk::get wdb.history!$sourceRev date]
+          set destDate [mk::get wdb.history!$destRev date]
+
+          set source [mk::get wdb.history!$sourceRev page]
+          set dest [mk::get wdb.history!$destRev page]
+
+          set revDiff [perform_diff $source $dest]
+
+	  cgi_head {
+	    cgi_http_equiv Content-type "text/html; charset=utf-8"
+	    cgi_title "Changes to \"$name\" between r$sourceFakeRev and r$destFakeRev"
+	    cgi_meta name=robots content=noindex,nofollow
+	    cgi_http_equiv Pragma no-cache
+	    cgi_http_equiv Expire "Mon, 04 Dec 1999 21:29:02 GMT"
+            cgi_puts {<style type="text/css">}
+            cgi_puts {<!--}
+            cgi_puts {.diffOld { background-color: #f4aaaa; text-decoration: line-through; }}
+            cgi_puts {.diffNew { background-color: #aaf4aa; }}
+            cgi_puts {.diffModifiedOld { background-color: #effaaa; text-decoration: line-through; }}
+            cgi_puts {.diffModifiedNew { background-color: #faefaa; }}
+            cgi_puts {.diffModifiedConnector { font-style: italic; font-weight: bold; }}
+            cgi_puts {#diffLegend { border: solid 1px #000000; padding: 2px; margin: 3px auto 3px auto; }}
+            cgi_puts {#diffLegendHeader { border: solid 1px #000000; text-align: center; background: #dedede; margin-bottom: 2px; }}
+            cgi_puts {-->}
+            cgi_puts {</style>}
+	    stylesheet
+	    if {$N != "2" && [info exists ::env(WIKIT_BASE)]} {
+	      cgi_base href=$::env(WIKIT_BASE)revs/
+	    }
+	  }
+
+          set diffLegend "<strike>[cgi_span class=diffOld [nbspace][nbspace][nbspace][nbspace]]</strike>  Only in r$sourceFakeRev[nl]"
+          append diffLegend "[cgi_span class=diffNew [nbspace][nbspace][nbspace][nbspace]]  Only in r$destFakeRev[nl]"
+          set diffModLineOutput <strike>[cgi_span class=diffModifiedOld [nbspace][nbspace][nbspace][nbspace]]</strike>
+          append diffModLineOutput [cgi_span class=diffModifiedConnector " --> "] 
+          append diffModLineOutput [cgi_span class=diffModifiedNew [nbspace][nbspace][nbspace][nbspace]]
+          append diffLegend [cgi_span class=diffModified "$diffModLineOutput  Modified slightly between r$sourceFakeRev and r$destFakeRev"][nl]
+
+          set htmlifymap [list "&" "&amp;" "\"" "&quot;" "<" "&lt;" ">" "&gt;" "  " [cgi_nbspace][cgi_nbspace]]
+          cgi_body bgcolor=#ffffff {
+            cgi_h2 "Changes to [Wiki - ../$N] between [link - r$sourceFakeRev ../$N.$sourceRev.$sourceFakeRev] and [link - r$destFakeRev ../$N.$destRev.$destFakeRev]"
+
+            cgi_puts "<p id=\"diffPage\">"
+            foreach diffInfo $revDiff {
+              set diffType [lindex $diffInfo 0]
+              set diffOldLine [string map $htmlifymap [lindex [string trim $diffInfo] 1]]
+              set diffNewLine [string map $htmlifymap [lindex [string trim $diffInfo] 2]]
+              if {$diffType != "="} {
+                if {$diffOldLine == ""} {
+                   set diffOldLine "<i>(blank line)</i>"
+                }
+                if {$diffNewLine == ""} {
+                  set diffNewLine "<i>(blank line)</i>"
+                }
+              }
+              switch -- $diffType {
+                "=" {
+                  cgi_puts [cgi_span class=diffSame "$diffOldLine"][nl]
+                }
+                "M" {
+                  set diffModLineOutput <strike>[cgi_span class=diffModifiedOld "$diffOldLine"]</strike>
+                  append diffModLineOutput [cgi_span class=diffModifiedConnector " --> "] 
+                  append diffModLineOutput [cgi_span class=diffModifiedNew "$diffNewLine"][nl]
+                  cgi_puts [cgi_span class=diffModified $diffModLineOutput]
+                }
+                "+" {
+                  cgi_puts [cgi_span class=diffNew "$diffNewLine"][nl]
+                }
+                "-" {
+                  cgi_puts <strike>[cgi_span class=diffOld "$diffOldLine"]</strike>[nl]
+                }
+              }
+            }
+            cgi_puts "</p>"
+
+            cgi_puts "<div id=\"diffLegend\"><div id=\"diffLegendHeader\">Legend</div><p>$diffLegend</p></div>"
 
+	    hr noshade id=footerSeperator
+
+            cgi_puts "<p id='footer'>$menu</p>"
+          }
+          # Versioning attempt (end)
+        }
+        | {
+          # Versioning attempt: <wiki@rkeene.org>
+	  cgi_head {
+	    cgi_http_equiv Content-type "text/html; charset=utf-8"
+	    cgi_title "Revisions for $name"
+	    cgi_meta name=robots content=noindex,nofollow
+	    cgi_http_equiv Pragma no-cache
+	    cgi_http_equiv Expire "Mon, 04 Dec 1999 21:29:02 GMT"
+	    stylesheet
+	    if {$N != "2" && [info exists ::env(WIKIT_BASE)]} {
+	      cgi_base href=$::env(WIKIT_BASE)revs/
+	    }
+	  }
+
+          cgi_body bgcolor=#ffffff {
+            cgi_h2 "Revisions for [Wiki - ../$N]"
+            cgi_puts "<p id=\"revsPage\">Older versions of this page:[nl]"
+            set fakeRev 0
+            set prevRev ""
+            set revs [mk::select wdb.revs -exact id $N]
+            set currRev [lindex $revs end]
+            foreach rev $revs {
+              set revEditDate [mk::get wdb.history!$rev date]
+              set revEditDate [clock format $revEditDate -gmt 1 -format {%e %b %Y, %R GMT}]
+              set revEditWho [mk::get wdb.history!$rev who]
+
+              if {$prevRev == ""} {
+                set prevDiff "(prev)"
+              } else {
+                set prevDiff [link - {(prev)} "../diff/$N.$rev.$fakeRev.$prevRev.[expr $fakeRev - 1]="]
+              }
+
+              if {$rev == $currRev} {
+                set currDiff "(curr)"
+              } else {
+                set currDiff [link - {(curr)} "../diff/$N.$currRev.[expr [llength $revs] - 1].$rev.$fakeRev="]
+              }
+
+              cgi_puts "[nbspace] [nbspace] Revision [link - "r$fakeRev" ../$N.$rev.$fakeRev] on $revEditDate by $revEditWho ([cgi_span id=difflinks "$prevDiff $currDiff"])[nl]"
+
+              incr fakeRev
+              set prevRev $rev
+            }
+            cgi_puts "</p>"
+
+	    hr noshade id=footerSeperator
+            cgi_puts "<p id='footer'>$menu</p>"
+          }
+          # Versioning attempt (end)
+        }
 	@ { # called to generate an edit page
 	  cgi_head {
 	    cgi_http_equiv Content-type "text/html; charset=utf-8"
@@ -437,6 +595,9 @@
 	}
 	      
 	! { # called to generate a page with references
+          # Versioning attempt: <wiki@rkeene.org>
+          set N [lindex [split $N .] 0]
+          # Versioning attempt (end)
 	  cgi_head {
 	    cgi_http_equiv Content-type "text/html; charset=utf-8"
 	    cgi_title "References to $name"
@@ -493,7 +654,17 @@
 	    foreach {C U} [Expand_HTML $C] break
 	    set noTitle [regsub {^<p>(<img src=".*?")>} $C \
 					[link - {\1 border=0>} $backRef] C]
-	    if {!$noTitle} { h2 $Title }
+	    if {!$noTitle} {
+              # Versioning attempt: <wiki@rkeene.org>
+              if {[string match "*.*" $N]} {
+                set work [split $N .]
+                set rev [lindex $work 2]
+                set HEAD [lindex $work 0]
+                append Title " r$rev (See the [link - {current copy} $HEAD])"
+              }
+              # Versioning attempt (end)
+              h2 $Title
+            }
 	
 	    if {$N == 2} {
 	      # thx Alistair Grant, see http://mini.net/tcl/9748
