1
# -*- coding: iso-8859-1 -*-
3
MoinMoin - Side by side diffs
5
@copyright: 2002 Juergen Hermann <jh@web.de>,
6
2002 Scott Moonen <smoonen@andstuff.org>
7
@license: GNU GPL, see COPYING for details.
10
from MoinMoin.support import difflib
11
from MoinMoin.wikiutil import escape
15
while line and line[0] == '\n':
18
stripped = line.lstrip()
19
if len(line) - len(stripped):
20
line = " " * (len(line) - len(stripped)) + stripped
21
#return "%d / %d / %s" % (len(line), len(stripped), line)
25
# This code originally by Scott Moonen, used with permission.
26
def diff(request, old, new):
27
""" Find changes between old and new and return
28
HTML markup visualising them.
31
t_line = _("Line") + " %d"
33
seq1 = old.splitlines()
34
seq2 = new.splitlines()
36
seqobj = difflib.SequenceMatcher(None, seq1, seq2)
37
linematch = seqobj.get_matching_blocks()
39
if len(seq1) == len(seq2) and linematch[0] == (0, 0, len(seq1)):
41
return " - " + _("No differences found!")
48
<td class="diff-removed">
53
<td class="diff-added">
59
""" % (_('Deletions are marked like this.'), _('Additions are marked like this.'), )
61
# Print all differences
62
for match in linematch:
63
# Starts of pages identical?
64
if lastmatch == match[0:2]:
65
lastmatch = (match[0] + match[2], match[1] + match[2])
67
llineno, rlineno = lastmatch[0]+1, lastmatch[1]+1
69
<tr class="diff-title">
77
""" % (request.formatter.line_anchorlink(1, llineno) + request.formatter.text(t_line % llineno) + request.formatter.line_anchorlink(0),
78
request.formatter.line_anchorlink(1, rlineno) + request.formatter.text(t_line % rlineno) + request.formatter.line_anchorlink(0))
82
linecount = max(match[0] - lastmatch[0], match[1] - lastmatch[1])
83
for line in range(linecount):
84
if line < match[0] - lastmatch[0]:
87
leftpane += seq1[lastmatch[0] + line]
88
if line < match[1] - lastmatch[1]:
91
rightpane += seq2[lastmatch[1] + line]
93
charobj = difflib.SequenceMatcher(None, leftpane, rightpane)
94
charmatch = charobj.get_matching_blocks()
96
if charobj.ratio() < 0.5:
97
# Insufficient similarity.
99
leftresult = """<span>%s</span>""" % indent(escape(leftpane))
104
rightresult = """<span>%s</span>""" % indent(escape(rightpane))
108
# Some similarities; markup changes.
113
for thismatch in charmatch:
114
if thismatch[0] - charlast[0] != 0:
115
leftresult += """<span>%s</span>""" % indent(
116
escape(leftpane[charlast[0]:thismatch[0]]))
117
if thismatch[1] - charlast[1] != 0:
118
rightresult += """<span>%s</span>""" % indent(
119
escape(rightpane[charlast[1]:thismatch[1]]))
120
leftresult += escape(leftpane[thismatch[0]:thismatch[0] + thismatch[2]])
121
rightresult += escape(rightpane[thismatch[1]:thismatch[1] + thismatch[2]])
122
charlast = (thismatch[0] + thismatch[2], thismatch[1] + thismatch[2])
124
leftpane = '<br>\n'.join([indent(x) for x in leftresult.splitlines()])
125
rightpane = '<br>\n'.join([indent(x) for x in rightresult.splitlines()])
127
# removed width="50%%"
130
<td class="diff-removed">
133
<td class="diff-added">
137
""" % (leftpane, rightpane)
139
lastmatch = (match[0] + match[2], match[1] + match[2])
141
result += '</table>\n'