~ubuntu-branches/ubuntu/natty/moin/natty-updates

« back to all changes in this revision

Viewing changes to MoinMoin/util/diff_html.py

  • Committer: Bazaar Package Importer
  • Author(s): Jonas Smedegaard
  • Date: 2008-06-22 21:17:13 UTC
  • mto: This revision was merged to the branch mainline in revision 18.
  • Revision ID: james.westby@ubuntu.com-20080622211713-inlv5k4eifxckelr
ImportĀ upstreamĀ versionĀ 1.7.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
 
24
24
 
25
25
# This code originally by Scott Moonen, used with permission.
26
 
def diff(request, old, new, old_top='', new_top='', old_bottom='', new_bottom='', old_top_class='', new_top_class='', old_bottom_class='', new_bottom_class=''):
 
26
def diff(request, old, new):
27
27
    """ Find changes between old and new and return
28
28
        HTML markup visualising them.
29
 
 
30
 
        @param old: old text [unicode]
31
 
        @param new: new text [unicode]
32
 
        @param old_top: Custom html for adding ontop of old revision column (optional)
33
 
        @param old_bottom: Custom html for adding at bottom of old revision column (optional)
34
 
        @param new_top: Custom html for adding ontop of new revision column (optional)
35
 
        @param new_bottom: Custom html for adding at bottom of new revision column (optional)
36
 
        @param old_top_class: Custom class for <td> with old_top content (optional)
37
 
        @param new_top_class: Custom class for <td> with new_top content (optional)
38
 
        @param old_bottom_class: Custom class for <td> with old_bottom content (optional)
39
 
        @param new_bottom_class: Custom class for <td> with new_bottom content (optional)
40
29
    """
41
30
    _ = request.getText
42
31
    t_line = _("Line") + " %d"
47
36
    seqobj = difflib.SequenceMatcher(None, seq1, seq2)
48
37
    linematch = seqobj.get_matching_blocks()
49
38
 
 
39
    if len(seq1) == len(seq2) and linematch[0] == (0, 0, len(seq1)):
 
40
        # No differences.
 
41
        return " - " + _("No differences found!")
 
42
 
 
43
    lastmatch = (0, 0)
 
44
 
50
45
    result = """
51
46
<table class="diff">
52
 
"""
53
 
 
54
 
    if old_top or new_top:
55
 
        result += '<tr><td class="%s">%s</td><td class="%s">%s</td></tr>' % (old_top_class, old_top, new_top_class, new_top)
56
 
 
57
 
    if len(seq1) == len(seq2) and linematch[0] == (0, 0, len(seq1)):
58
 
        # No differences.
59
 
        result += '<tr><td class="diff-same" colspan="2">' + _("No differences found!") + '</td></tr>'
60
 
    else:
61
 
        result += """
62
47
<tr>
63
 
<td class="diff-removed"><span>%s</span></td>
64
 
<td class="diff-added"><span>%s</span></td>
 
48
<td class="diff-removed">
 
49
<span>
 
50
%s
 
51
</span>
 
52
</td>
 
53
<td class="diff-added">
 
54
<span>
 
55
%s
 
56
</span>
 
57
</td>
65
58
</tr>
66
59
""" % (_('Deletions are marked like this.'), _('Additions are marked like this.'), )
67
60
 
68
 
        lastmatch = (0, 0)
69
 
 
70
 
        # Print all differences
71
 
        for match in linematch:
72
 
            # Starts of pages identical?
73
 
            if lastmatch == match[0:2]:
74
 
                lastmatch = (match[0] + match[2], match[1] + match[2])
75
 
                continue
76
 
            llineno, rlineno = lastmatch[0]+1, lastmatch[1]+1
77
 
            result += """
 
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])
 
66
            continue
 
67
        llineno, rlineno = lastmatch[0]+1, lastmatch[1]+1
 
68
        result += """
78
69
<tr class="diff-title">
79
 
<td>%s:</td>
80
 
<td>%s:</td>
 
70
<td>
 
71
%s:
 
72
</td>
 
73
<td>
 
74
%s:
 
75
</td>
81
76
</tr>
82
77
""" % (request.formatter.line_anchorlink(1, llineno) + request.formatter.text(t_line % llineno) + request.formatter.line_anchorlink(0),
83
 
           request.formatter.line_anchorlink(1, rlineno) + request.formatter.text(t_line % rlineno) + request.formatter.line_anchorlink(0))
84
 
 
85
 
            leftpane = ''
86
 
            rightpane = ''
87
 
            linecount = max(match[0] - lastmatch[0], match[1] - lastmatch[1])
88
 
            for line in range(linecount):
89
 
                if line < match[0] - lastmatch[0]:
90
 
                    if line > 0:
91
 
                        leftpane += '\n'
92
 
                    leftpane += seq1[lastmatch[0] + line]
93
 
                if line < match[1] - lastmatch[1]:
94
 
                    if line > 0:
95
 
                        rightpane += '\n'
96
 
                    rightpane += seq2[lastmatch[1] + line]
97
 
 
98
 
            charobj = difflib.SequenceMatcher(None, leftpane, rightpane)
99
 
            charmatch = charobj.get_matching_blocks()
100
 
 
101
 
            if charobj.ratio() < 0.5:
102
 
                # Insufficient similarity.
103
 
                if leftpane:
104
 
                    leftresult = """<span>%s</span>""" % indent(escape(leftpane))
105
 
                else:
106
 
                    leftresult = ''
107
 
 
108
 
                if rightpane:
109
 
                    rightresult = """<span>%s</span>""" % indent(escape(rightpane))
110
 
                else:
111
 
                    rightresult = ''
 
78
       request.formatter.line_anchorlink(1, rlineno) + request.formatter.text(t_line % rlineno) + request.formatter.line_anchorlink(0))
 
79
 
 
80
        leftpane = ''
 
81
        rightpane = ''
 
82
        linecount = max(match[0] - lastmatch[0], match[1] - lastmatch[1])
 
83
        for line in range(linecount):
 
84
            if line < match[0] - lastmatch[0]:
 
85
                if line > 0:
 
86
                    leftpane += '\n'
 
87
                leftpane += seq1[lastmatch[0] + line]
 
88
            if line < match[1] - lastmatch[1]:
 
89
                if line > 0:
 
90
                    rightpane += '\n'
 
91
                rightpane += seq2[lastmatch[1] + line]
 
92
 
 
93
        charobj = difflib.SequenceMatcher(None, leftpane, rightpane)
 
94
        charmatch = charobj.get_matching_blocks()
 
95
 
 
96
        if charobj.ratio() < 0.5:
 
97
            # Insufficient similarity.
 
98
            if leftpane:
 
99
                leftresult = """<span>%s</span>""" % indent(escape(leftpane))
112
100
            else:
113
 
                # Some similarities; markup changes.
114
 
                charlast = (0, 0)
115
 
 
116
101
                leftresult = ''
 
102
 
 
103
            if rightpane:
 
104
                rightresult = """<span>%s</span>""" % indent(escape(rightpane))
 
105
            else:
117
106
                rightresult = ''
118
 
                for thismatch in charmatch:
119
 
                    if thismatch[0] - charlast[0] != 0:
120
 
                        leftresult += """<span>%s</span>""" % indent(
121
 
                            escape(leftpane[charlast[0]:thismatch[0]]))
122
 
                    if thismatch[1] - charlast[1] != 0:
123
 
                        rightresult += """<span>%s</span>""" % indent(
124
 
                            escape(rightpane[charlast[1]:thismatch[1]]))
125
 
                    leftresult += escape(leftpane[thismatch[0]:thismatch[0] + thismatch[2]])
126
 
                    rightresult += escape(rightpane[thismatch[1]:thismatch[1] + thismatch[2]])
127
 
                    charlast = (thismatch[0] + thismatch[2], thismatch[1] + thismatch[2])
128
 
 
129
 
            leftpane = '<br>'.join([indent(x) for x in leftresult.splitlines()])
130
 
            rightpane = '<br>'.join([indent(x) for x in rightresult.splitlines()])
131
 
 
132
 
            # removed width="50%%"
133
 
            result += """
 
107
        else:
 
108
            # Some similarities; markup changes.
 
109
            charlast = (0, 0)
 
110
 
 
111
            leftresult = ''
 
112
            rightresult = ''
 
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])
 
123
 
 
124
        leftpane = '<br>\n'.join([indent(x) for x in leftresult.splitlines()])
 
125
        rightpane = '<br>\n'.join([indent(x) for x in rightresult.splitlines()])
 
126
 
 
127
        # removed width="50%%"
 
128
        result += """
134
129
<tr>
135
 
<td class="diff-removed">%s</td>
136
 
<td class="diff-added">%s</td>
 
130
<td class="diff-removed">
 
131
%s
 
132
</td>
 
133
<td class="diff-added">
 
134
%s
 
135
</td>
137
136
</tr>
138
137
""" % (leftpane, rightpane)
139
138
 
140
 
            lastmatch = (match[0] + match[2], match[1] + match[2])
141
 
 
142
 
    if old_bottom or new_bottom:
143
 
        result += '<tr><td class="%s">%s</td><td class="%s">%s</td></tr>' % (old_top_class, old_top, new_top_class, new_top)
 
139
        lastmatch = (match[0] + match[2], match[1] + match[2])
144
140
 
145
141
    result += '</table>\n'
146
142
    return result