# -*- coding: iso-8859-1 -*- """ MoinMoin - Side by side diffs @copyright: 2002 by Jürgen Hermann @copyright: 2002 by Scott Moonen @license: GNU GPL, see COPYING for details. """ from MoinMoin.support import difflib from MoinMoin.wikiutil import escape def indent(line): eol = '' while line and line[0] == '\n': eol += '\n' line = line[1:] stripped = line.lstrip() if len(line) - len(stripped): line = " " * (len(line) - len(stripped)) + stripped #return "%d / %d / %s" % (len(line), len(stripped), line) return eol + line # This code originally by Scott Moonen, used with permission. def diff(request, old, new): """ Find changes between old and new and return HTML markup visualising them. """ _ = request.getText t_line = _("Line") + " %d" seq1 = old.splitlines() seq2 = new.splitlines() seqobj = difflib.SequenceMatcher(None, seq1, seq2) linematch = seqobj.get_matching_blocks() if len(seq1) == len(seq2) and linematch[0] == (0, 0, len(seq1)): # No differences. return _("No differences found!") lastmatch = (0, 0) result = """ """ % (_('Deletions are marked like this.'), _('Additions are marked like this.'),) # Print all differences for match in linematch: # Starts of pages identical? if lastmatch == match[0:2]: lastmatch = (match[0] + match[2], match[1] + match[2]) continue llineno, rlineno = lastmatch[0]+1, lastmatch[1]+1 result += """ """ % ( request.formatter.line_anchorlink(1, llineno) + request.formatter.text(t_line % llineno) + request.formatter.line_anchorlink(0), request.formatter.line_anchorlink(1, rlineno) + request.formatter.text(t_line % rlineno) + request.formatter.line_anchorlink(0)) 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 = difflib.SequenceMatcher(None, leftpane, rightpane) charmatch = charobj.get_matching_blocks() if charobj.ratio() < 0.5: # Insufficient similarity. if leftpane: leftresult = """%s""" % indent(escape(leftpane)) else: leftresult = '' if rightpane: rightresult = """%s""" % indent(escape(rightpane)) else: rightresult = '' else: # Some similarities; markup changes. charlast = (0, 0) leftresult = '' rightresult = '' for thismatch in charmatch: if thismatch[0] - charlast[0] != 0: leftresult += """%s""" % indent( escape(leftpane[charlast[0]:thismatch[0]])) if thismatch[1] - charlast[1] != 0: rightresult += """%s""" % indent( escape(rightpane[charlast[1]:thismatch[1]])) leftresult += escape(leftpane[thismatch[0]:thismatch[0] + thismatch[2]]) rightresult += escape(rightpane[thismatch[1]:thismatch[1] + thismatch[2]]) charlast = (thismatch[0] + thismatch[2], thismatch[1] + thismatch[2]) leftpane = '
\n'.join(map(indent, leftresult.splitlines())) rightpane = '
\n'.join(map(indent, rightresult.splitlines())) # removed width="50%%" result += """ """ % (leftpane, rightpane) lastmatch = (match[0] + match[2], match[1] + match[2]) result += '
%s %s
%s: %s:
%s %s
\n' return result