1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
# -*- coding: utf-8 -*-
"""
sphinx.websupport.storage.differ
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A differ for creating an HTML representations of proposal diffs
:copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import re
from cgi import escape
from difflib import Differ
class CombinedHtmlDiff(object):
highlight_regex = re.compile(r'([\+\-\^]+)')
def _highlight_text(self, text, next, tag):
next = next[2:]
new_text = []
start = 0
for match in self.highlight_regex.finditer(next):
new_text.append(text[start:match.start()])
new_text.append('<%s>' % tag)
new_text.append(text[match.start():match.end()])
new_text.append('</%s>' % tag)
start = match.end()
new_text.append(text[start:])
return ''.join(new_text)
def _handle_line(self, line, next=None):
prefix = line[0]
text = line[2:]
if prefix == ' ':
return text
elif prefix == '?':
return ''
if next[0] == '?':
tag = 'ins' if prefix == '+' else 'del'
text = self._highlight_text(text, next, tag)
css_class = 'prop_added' if prefix == '+' else 'prop_removed'
return '<span class="%s">%s</span>\n' % (css_class, text.rstrip())
def make_html(self, source, proposal):
proposal = escape(proposal)
differ = Differ()
diff = list(differ.compare(source.splitlines(1),
proposal.splitlines(1)))
html = []
line = diff.pop(0)
next = diff.pop(0)
while True:
html.append(self._handle_line(line, next))
line = next
try:
next = diff.pop(0)
except IndexError:
self._handle_line(line)
break
return ''.join(html)
|