import sys import difflib import argparse import StringIO import pygments from pygments.lexers import guess_lexer_for_filename from pygments.lexer import RegexLexer from pygments.formatters import HtmlFormatter from pygments.token import * class DefaultLexer(RegexLexer): """ Simply lex each line as a token. """ name = 'Default' aliases = ['default'] filenames = ['*'] tokens = { 'root': [ (r'.*\n', Text), ] } class DiffHtmlFormatter(HtmlFormatter): """ Formats a single source file with pygments and adds diff highlights based on the diff details given. """ isLeft = False diffs = None def __init__(self, isLeft, diffs, *args, **kwargs): self.isLeft = isLeft self.diffs = diffs super(DiffHtmlFormatter, self).__init__(*args, **kwargs) def wrap(self, source, outfile): return self._wrap_code(source) def getDiffLineNos(self): retlinenos = [] for idx, ((left_no, left_line),(right_no, right_line),change) in enumerate(self.diffs): no = None if self.isLeft: if change: if isinstance(left_no, int) and isinstance(right_no, int): no = '' + str(left_no) + "" elif isinstance(left_no, int) and not isinstance(right_no, int): no = '' + str(left_no) + "" elif not isinstance(left_no, int) and isinstance(right_no, int): no = ' ' else: no = '' + str(left_no) + "" else: if change: if isinstance(left_no, int) and isinstance(right_no, int): no = '' + str(right_no) + "" elif isinstance(left_no, int) and not isinstance(right_no, int): no = ' ' elif not isinstance(left_no, int) and isinstance(right_no, int): no = '' + str(right_no) + "" else: no = '' + str(right_no) + "" retlinenos.append(no) return retlinenos def _wrap_code(self, source): source = list(source) yield 0, '
'
for idx, ((left_no, left_line),(right_no, right_line),change) in enumerate(self.diffs):
#print idx, ((left_no, left_line),(right_no, right_line),change)
try:
if self.isLeft:
if change:
if isinstance(left_no, int) and isinstance(right_no, int) and left_no <= len(source):
i,t = source[left_no-1]
t = '' + t + ""
elif isinstance(left_no, int) and not isinstance(right_no, int) and left_no <= len(source):
i,t = source[left_no-1]
t = '' + t + ""
elif not isinstance(left_no, int) and isinstance(right_no, int):
i,t = 1, left_line
t = '' + t + ""
else:
raise
else:
if left_no <= len(source):
i,t = source[left_no-1]
else:
i = 1
t = left_line
else:
if change:
if isinstance(left_no, int) and isinstance(right_no, int) and right_no <= len(source):
i,t = source[right_no-1]
t = '' + t + ""
elif isinstance(left_no, int) and not isinstance(right_no, int):
i,t = 1, right_line
t = '' + t + ""
elif not isinstance(left_no, int) and isinstance(right_no, int) and right_no <= len(source):
i,t = source[right_no-1]
t = '' + t + ""
else:
raise
else:
if right_no <= len(source):
i,t = source[right_no-1]
else:
i = 1
t = right_line
yield i, t
except:
#print "WARNING! failed to enumerate diffs fully!"
pass # this is expected sometimes
yield 0, '\n'
def _wrap_tablelinenos(self, inner):
dummyoutfile = StringIO.StringIO()
lncount = 0
for t, line in inner:
if t:
lncount += 1
dummyoutfile.write(line)
fl = self.linenostart
mw = len(str(lncount + fl - 1))
sp = self.linenospecial
st = self.linenostep
la = self.lineanchors
aln = self.anchorlinenos
nocls = self.noclasses
lines = []
for i in self.getDiffLineNos():
lines.append('%s' % (i,))
ls = ''.join(lines)
# in case you wonder about the seemingly redundant '
' ' +
ls + ' | ')
else:
yield 0, ('
|