def text_history_compare(request, key, v1_version_key, v2_version_key, mode=''): text = get_text_by_keys_or_404(key) v1 = get_textversion_by_keys_or_404(v1_version_key, key=key) v2 = get_textversion_by_keys_or_404(v2_version_key, key=key) content = get_uniffied_inner_diff_table(v1.title, v2.title, _("by %(author)s") %{'author' : v1.get_name()}, _("by %(author)s") %{'author' : v2.get_name()}, v1.content, v2.content) if mode=='1': # alternate diff #from cm.utils.diff import text_diff from cm.utils.diff import diff_match_patch2 dif = diff_match_patch2() content = dif.diff_prettyHtml_one_way(dif.diff_main(v1.get_content(), v2.get_content()), mode='ins_del') text_versions = text.get_versions() first_version = text_versions[len(text_versions) - 1] template_dict = { 'text' : text, 'v1': v1, 'v2': v2, 'content' : content.strip(), 'empty' : '<table class="diff"><tbody></tbody></table>'==content, 'first_version':first_version, } return render_to_response('site/text_history_compare.html', template_dict, context_instance=RequestContext(request))
def get_uniffied_inner_diff_table(title1, title2, author1, author2, text1, text2): """ Return the inner of the html table for text1 vs text2 diff """ gen = unified_diff(text1.replace('\r\n','\n').split('\n'), text2.replace('\r\n','\n').split('\n'), n=3) index = 0 res = ['<table class="diff"><col class="diff-marker"/><col class="diff-content"/><col class="diff-separator"/><col class="diff-marker"/><col class="diff-content"/><tbody>'] res.append('<tr><td></td><td class="diff-title">%s</td><td></td><td></td><td class="diff-title">%s</td></tr>' %(title1, title2)) res.append('<tr><td></td><td class="diff-author">%s</td><td></td><td></td><td class="diff-author">%s</td></tr>' %(author1, author2)) res.append('<tr><td colspan="5"></td></tr>') #res.append('<tr><td width="50%" colspan="2"></td><td width="50%" colspan="2"></td></tr>') for g in gen: if index > 1: col_in = None if g.startswith('@@'): line_number = g.split(' ')[1][1:].split(',')[0] if index != 2: res.append('<tr><td></td> <td></td><td></td><td> </td></tr>') res.append('<tr><td class="diff-lineno" colspan="2">Line %s</td><td class="diff-separator"></td><td class="diff-lineno" colspan="2">Line %s</td></tr>' % (line_number, line_number)) if g.startswith(' '): res.append('<tr><td class="diff-marker"></td><td class="diff-context">%s</td><td class="diff-separator"></td><td class="diff-marker"></td><td class="diff-context">%s</td></tr>' % (g, g)) if g.startswith('-') or g.startswith('+'): plus = [] minus = [] while g.startswith('-') or g.startswith('+'): if g.startswith('-'): minus.append(g[1:]) else: plus.append(g[1:]) try: g = gen.next() except StopIteration: break minus, plus = diff_decorate(minus, plus) minus, plus = '<br />'.join(minus), '<br />'.join(plus) from cm.utils.diff import diff_match_patch2 dif = diff_match_patch2() res_diff1 = dif.diff_main(minus, plus) dif.diff_cleanupSemantic(res_diff1) p = dif.diff_prettyHtml_one_way(res_diff1, 1) minus = dif.diff_prettyHtml_one_way(res_diff1, 2) plus = p res.append('<tr><td class="diff-marker">-</td><td class="diff-deletedline"><div>%s</div></td><td class="diff-separator"></td><td class="diff-marker">+</td><td class="diff-addedline"><div>%s</div></td></tr>' % (minus, plus)) index += 1 res.append('</tbody></table>') return ''.join(res)