Version 25 of There is a huge need for a diffs module!

Updated 2003-11-07 11:45:07

This Wikit is an excellent Wiki and it is certainly one of the very best.

Please see what I wrote here here: http://c2.com/cgi/wiki?InnovativeWikiFeatures . # 18. You guys have the best reverse links module of all the Wikis!. I also discuss your free links and your number for files system. (# 7 and # 8). But there is more to come: I like the system where a page returns to the saved page after 2 or 3 seconds. I will also discuss this feature.

Well done Jean-Claude!

But IMHO there is a huge lack here: a good diffs module. This is to inform the user of the changes between the last version and the new so that he/she does not have to read the whole page to see what has changed since the last version.

NEM - Have a look at wikidiff. It's hosted externally, but does a decent job.

RA Thanks NEM! But this module needs to be integrated here and we should be able to view diffs for each page. See C2.com to see how they do it (click on the date at the bottom of each page).

Andstuff.org has another way of doing it. The Diffs is simply the act of comparing a page version and the one before it. Look at the history module. In the history module you have 3 functions: a possibility to view different versions for each page; a comparison of different versions and a diffs (a comparing of the last and the new version). Usermod.com has the same system. So does OddMuse. This is what you need here. A good history module. TCL Can do a real good job for it.

Come on you guys you are so many gifted programmers! Go for it!. If you want I can give you the code for a diffs module written in Python so that you could get good inspiration! Robert Abitbol

Is saying it once not enough? How many pages are you going to fill with the same message? -jcw

T'as raison Jean Claude. Desole! je pensais pas que l'on avait lu ma page. Bon alors enchante de te connaitre quand meme! :-)

Je peux te demander. Pour installer Wikit localement sur mon ordi, ca prend quoi comme programme? (je suis sur Windows 98). Un grand merci.

Salut/hi. Depends on whether you want a server or a local Tk mode. The server uses the command-line tclkitsh [L1 ], for a local GUI, use [L2 ]. Plus wikit.kit [L3 ]. The wikit docs are not very good, nor easy to find. Best is probably to start here [L4 ]. -jcw

In English: sorry! I didn't know you guys actually read pages entirely so I took the liberty to repeat the same message twice just in case its reading was skipped! No offence I hope! :-) Robert Abitbol

LV Well, many people read the wikidiff highlights, as well as the Recent Changes page religiously. However, if you will pardon me saying this, your perceived need is just one of many perceived needs by people, and in this case, one which has been addressed out of band for this particular web site. If you browse the archives of the tclers wiki mailing list, you will see that people have in fact worked on this need. I don't know what the status of any of that work is though.

Addressed out of band? If it's "out of band" which I suppose means unneeded, then why would some people have worked on it? Doesn't make sense. Unless I don't understand what you're saying! :-) Perceived need! You are kidding! Who wants to read whole pages all the time to see what the changes are compared to the last version? A diffs is a huge need like the title says. It's not just another fancy feature! RobertAbitbol


Dialogue with a teen-ager

MR I think you've made your point, and people have heard it, now shut up already! :-) It's obviously not that big a deal to most of the users of this Wiki, and more importantly, given this Wiki is a free resource, there's little incentive to add this feature. So if its not pissing off the people running this site or most of its users, there's no reason to expect any big changes should be made. Yeah there are more feature-rich Wiki implementations, even in Tcl, but this site serves its purpose well already IMO.

You know when I read comments like yours it reminds me of the bad old days when I was spending too much time on forums inhabited by impolite, ignorant and arrogant teenagers like you. By your choice of words and your lack of manners, you sound like you are coming straight from a tennie-bopper forum and not from a wiki where the level of discussion is much higher than street level.

So in my estimate you should either return to the teenie bopper forum where you are coming from or polish your vocabulary, your manners and your perspective. This being said in all friendship! You ain't in elementary school Sonny boy! This is high-school! Now if you are an adult and you still talk like that, you have reasons to worry! Asta la Vista babe! And please do me a favour don't come too often on the pages where I post. Unless you grow up and quickly! Robert Abitbol


NEM This is all getting a bit heated. The features that RA mentions are some which I have thought might be useful. An in-built diff function, with more fine-grained versioning (rather than the daily wikidiff) would be useful. As would being able to add a brief description of changes made when editing a page (a quick one-liner which shows up on Recent Changes). However, typically, few changes are made to an individual page in a day, and so wikidiff (or a quick manual scan of the page) is usually sufficient. Also, most people tend to add new content at the bottom of pages (as I am doing here), making it pretty easy to see what's been added.

I'm glad RA is making constructive comments (although, in future it might be best to add them to Suggestions for Wikit rather than creating new pages). Ultimately, though, like much in life and free software --- if you aren't prepared to do the actual coding, then it is unlikely to get done. The wiki isn't perfect, but it works.

MR See ProjectForum for an example of a Wiki that does fine-grained versioning and highlight of diffs. So yeah, I agree its useful!

Another example of a very nice, professional looking wiki: http://www.wikitravel.org/article/Main_Page

Try also: http://www.andstuff.org and http://www.usemod.com Robert Abitbol


male - 2003-11-07:

Sorry to say - there is IMO a big need to diff wiki pages!

Why? Just because, many people work on many pages adding, changing, removing much text, but it is very often very difficult to realize what was changed, added, removed, ...! Many wiki pages grow, but grow to be confusing more and more.

So - people authoring wiki pages should claim and then keep standards to allow pages to be reviewed much better, or we need a diff system to allow a much better review.

One standard could be to begin a page new content with the author name, authoring date (and perhabs time) and to seperate this new content with horizontal lines from older contents.

Sometimes I desperate trying to analyse what's new on a wiki page, what's changed, ... .

So please claim and keep standards or extend wiki's functionality with a diff module.


Many people agree! But the problem is there are not many people who would like to program it. I am sure this is not an easy task to do! I'll be putting on the code I have for diffs in Python. Maybe some people could understand it. it is public domain; written by Scott Moonen of And Stuff.org

Here it is:

 #!/home/andstuff/py/bin/python

 def diff(s1, s2) :
  from difflib import SequenceMatcher

  s1 = s1.replace('&', '&')
  s1 = s1.replace('<', '&lt;')
  s2 = s2.replace('&', '&amp;')
  s2 = s2.replace('<', '&lt;')

  seq1 = s1.splitlines()
  seq2 = s2.splitlines()

  seqobj = SequenceMatcher(None, seq1, seq2)

  linematch = seqobj.get_matching_blocks()

  if len(seq1) == len(seq2) \
and linematch0 == (0, 0, len(seq1))
# No differences.
    return '<strong>No differences.</strong>'

  lastmatch = (0, 0)
  end       = (len(seq1), len(seq2))

  result = "<table class='diff'>\n"

  for match in linematch :              # Print all differences.
if lastmatch == match0:2
# Starts of pages identical.
      lastmatch = (match[0] + match[2], match[1] + match[2])
      continue

    result = result \
             + "<tr><td colspan='2' class='diff-title'><strong>" \
             + "Line " + str(lastmatch[0] + 1) + ", removed:" \
             + "</strong></td><td colspan='2' class='diff-title'><strong>" \
             + "Line " + str(lastmatch[1] + 1) + ", added:" \
             + "</strong></td></tr>\n"

    leftpane  = ''
    rightpane = ''
    linecount = max(match[0] - lastmatch[0], match[1] - lastmatch[1])
    for line in range(linecount) :
      if line < match[0] - lastmatch[0] :
        if line > 0 :
          leftpane += '\n'
        leftpane += seq1[lastmatch[0] + line]
      if line < match[1] - lastmatch[1] :
        if line > 0 :
          rightpane += '\n'
        rightpane += seq2[lastmatch[1] + line]

    charobj   = SequenceMatcher(None, leftpane, rightpane)
    charmatch = charobj.get_matching_blocks()

    if leftpane == '' and rightpane == '' :
      ratio = 1.0
    else :
      ratio = charobj.ratio()
if ratio < 0.5
# Insufficient similarity.
      if len(leftpane) != 0 :
        leftresult = "<span class='diff-removed'>" + leftpane + "</span>"
      else :
        leftresult = ''

      if len(rightpane) != 0 :
        rightresult = "<span class='diff-added'>" + rightpane + "</span>"
      else :
        rightresult = ''
else
# Some similarities; markup changes.
      charlast = (0, 0)
      charend  = (len(leftpane), len(rightpane))

      leftresult  = ''
      rightresult = ''
      for thismatch in charmatch :
        if thismatch[0] - charlast[0] != 0 :
          leftresult = leftresult \
                       + "<span class='diff-removed'>" \
                       + leftpane[charlast[0]:thismatch[0]] \
                       + "</span>"
        if thismatch[1] - charlast[1] != 0 :
          rightresult = rightresult \
                        + "<span class='diff-added'>" \
                        + rightpane[charlast[1]:thismatch[1]] \
                        + "</span>"
        leftresult = leftresult \
                     + leftpane[thismatch[0]:thismatch[0] + thismatch[2]]
        rightresult = rightresult \
                      + rightpane[thismatch[1]:thismatch[1] + thismatch[2]]
        charlast = (thismatch[0] + thismatch[2], thismatch[1] + thismatch[2])

    leftpane  = leftresult.replace('\n', '<br />\n')
    rightpane = rightresult.replace('\n', '<br />\n')

    result = result \
             + "<tr><td colspan='2' class='diff-removed'>" \
             + leftpane \
             + "</td><td colspan='2' class='diff-added'>" \
             + rightpane \
             + "</td></tr>\n"

    lastmatch = (match[0] + match[2], match[1] + match[2])

  result = result + '</table>\n'

  return result

 import sys

 file1 = file(sys.argv[1])
 file2 = file(sys.argv[2])

 str1 = file1.read()
 str2 = file2.read()

 file1.close()
 file2.close()

 print diff(str1, str2)

The best thing to do would be to try to understand the algorithm and we could try to write it in TCL right here on this page. I don't program but I am pretty good at algorithms. I can already see we are comparing too files! Pretty good start! --

So let's do the algorith first.

Robert Abitbol


Category Wikit