You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by br...@apache.org on 2012/12/19 17:25:53 UTC
[19/48] git commit: [#5389] ticket:229 use own side-by-side diff
generator
[#5389] ticket:229 use own side-by-side diff generator
Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/ba6c028f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/ba6c028f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/ba6c028f
Branch: refs/heads/db/4790
Commit: ba6c028fda9e6d8b048faf11cfa4e339c866eaf0
Parents: b09028b
Author: Igor Bondarenko <je...@gmail.com>
Authored: Fri Dec 7 12:56:02 2012 +0000
Committer: Cory Johns <jo...@geek.net>
Committed: Mon Dec 17 22:21:16 2012 +0000
----------------------------------------------------------------------
Allura/allura/controllers/repository.py | 5 +-
Allura/allura/lib/diff.py | 96 ++++++++++++++++++++++++++
2 files changed, 99 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ba6c028f/Allura/allura/controllers/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/repository.py b/Allura/allura/controllers/repository.py
index d93fe1d..853fda9 100644
--- a/Allura/allura/controllers/repository.py
+++ b/Allura/allura/controllers/repository.py
@@ -31,6 +31,7 @@ from allura.lib.widgets.subscriptions import SubscribeForm
from allura import model as M
from allura.lib.widgets import form_fields as ffw
from allura.controllers.base import DispatchIndex
+from allura.lib.diff import HtmlSideBySideDiff
from .base import BaseController
@@ -586,8 +587,8 @@ class FileBrowser(BaseController):
web_session['diformat'] = fmt
web_session.save()
if fmt == 'sidebyside':
- hd = difflib.HtmlDiff(tabsize=4)
- diff = hd.make_table(la, lb, adesc, bdesc, context=True)
+ hd = HtmlSideBySideDiff()
+ diff = hd.make_table(la, lb, adesc, bdesc)
diff = diff.replace(' ', ' ')
else:
diff = ''.join(difflib.unified_diff(la, lb, adesc, bdesc))
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ba6c028f/Allura/allura/lib/diff.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/diff.py b/Allura/allura/lib/diff.py
new file mode 100644
index 0000000..78a736b
--- /dev/null
+++ b/Allura/allura/lib/diff.py
@@ -0,0 +1,96 @@
+import difflib
+
+
+class HtmlSideBySideDiff(object):
+
+ table_tmpl = '''
+<table class="side-by-side-diff">
+ <thead>
+ <th colspan="2">%s</th>
+ <th colspan="2">%s</th>
+ </thead>
+ %s
+</table>
+'''.strip()
+
+ line_tmpl = '''
+<tr>
+ <td class="lineno">%s</td>
+ <td%s><pre>%s</pre></td>
+ <td class="lineno">%s</td>
+ <td%s><pre>%s</pre></td>
+</tr>'''.strip()
+
+ def __init__(self, tabsize=4):
+ self._tabsize = 4
+
+ def _render_change(self, aline, bline, anum=None, bnum=None, astyle=None, bstyle=None):
+ astyle = (' class="%s"' % astyle) if astyle else ''
+ bstyle = (' class="%s"' % bstyle) if bstyle else ''
+ anum = anum if anum is not None else ''
+ bnum = bnum if bnum is not None else ''
+ return self.line_tmpl % (anum, astyle, aline, bnum, bstyle, bline)
+
+ def _preprocess(self, line):
+ if not line:
+ return line
+ line = line.expandtabs(self._tabsize)
+ return line.replace('&', '&').replace('<', '<').replace('>', '>')
+
+ def _replace_marks(self, line):
+ # if entire line was added/removed/changed
+ # we strip first mark and return corresponding flag
+ # this is needed to be able to highlight entire <td> in the table,
+ # rather then highlighting only chunk inside the <span>
+ flag = ''
+ if line.startswith('\0+'):
+ line = line.lstrip('\0+').rstrip('\1')
+ flag = 'diff-add'
+ elif line.startswith('\0-'):
+ line = line.lstrip('\0-').rstrip('\1')
+ flag = 'diff-rem'
+ elif '\0^' in line:
+ flag = 'diff-chg'
+
+ # replace all other marks with <span>'s
+ span = '<span class="%s">'
+ line = line.replace('\0+', span % 'diff-add')
+ line = line.replace('\0-', span % 'diff-rem')
+ line = line.replace('\0^', span % 'diff-chg')
+ line = line.replace('\1', '</span>')
+ return line, flag
+
+ def _make_line(self, diff):
+ aline, bline, changed = diff
+ if changed is None:
+ # context separation
+ return self._render_change('...', '...', '', '', 'diff-gap', 'diff-gap')
+ anum, aline = aline
+ bnum, bline = bline
+ aline = self._preprocess(aline)
+ bline = self._preprocess(bline)
+ if not changed:
+ # line doesn't changed - render with default style
+ return self._render_change(aline, bline, anum, bnum)
+
+ aline, aflag = self._replace_marks(aline)
+ bline, bflag = self._replace_marks(bline)
+ return self._render_change(aline, bline, anum, bnum, aflag, bflag)
+
+ def make_table(self, a, b, adesc=None, bdesc=None, context=5):
+ """Make html table that displays side-by-side diff
+
+ Arguments:
+ - a -- list of text lines to be compared to b
+ - b -- list of text lines to be compared to a
+ - adesc -- description of the 'a' lines (e.g. filename)
+ - bdesc -- description of the 'b' lines (e.g. filename)
+ - context -- number of context lines to display
+
+ Uses difflib._mdiff function to generate diff.
+ """
+ adesc = adesc or ''
+ bdesc = bdesc or ''
+ diff = difflib._mdiff(a, b, context=context)
+ lines = [self._make_line(d) for d in diff]
+ return self.table_tmpl % (adesc, bdesc, '\n'.join(lines))