| Index: third_party/WebKit/Tools/Scripts/webkitpy/common/html_diff.py
|
| diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/html_diff.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/html_diff.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..56000331a30f5b48371ea12bf125b26ee06aa709
|
| --- /dev/null
|
| +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/html_diff.py
|
| @@ -0,0 +1,64 @@
|
| +# Copyright 2016 The Chromium Authors. All rights reserved.
|
| +# Use of this source code is governed by a BSD-style license that can be
|
| +# found in the LICENSE file.
|
| +
|
| +"""Utility for outputting a HTML diff of two multi-line strings.
|
| +
|
| +The main purpose of this utility is to show the difference between
|
| +text baselines (-expected.txt files) and actual text results.
|
| +
|
| +Note, in the standard library module difflib, there is also a HtmlDiff class,
|
| +although it outputs a larger and more complex HTML table than we need.
|
| +"""
|
| +
|
| +import difflib
|
| +
|
| +_TEMPLATE = """<html>
|
| +<head>
|
| +<style>.del { background: #faa; } .add { background: #afa; }</style>
|
| +</head>
|
| +<body>
|
| +<pre>%s</pre>
|
| +</body>
|
| +</html>
|
| +"""
|
| +
|
| +
|
| +def html_diff(a_text, b_text):
|
| + """Returns a diff between two strings as HTML."""
|
| + # Diffs can be between multiple text files of different encodings
|
| + # so we always want to deal with them as byte arrays, not unicode strings.
|
| + assert isinstance(a_text, str)
|
| + assert isinstance(b_text, str)
|
| + a_lines = a_text.splitlines(True)
|
| + b_lines = b_text.splitlines(True)
|
| + return _TEMPLATE % html_diff_body(a_lines, b_lines)
|
| +
|
| +
|
| +def html_diff_body(a_lines, b_lines):
|
| + matcher = difflib.SequenceMatcher(None, a_lines, b_lines)
|
| + output = []
|
| + for tag, a_start, a_end, b_start, b_end in matcher.get_opcodes():
|
| + a_chunk = ''.join(a_lines[a_start:a_end])
|
| + b_chunk = ''.join(b_lines[b_start:b_end])
|
| + output.append(_format_chunk(tag, a_chunk, b_chunk))
|
| + return ''.join(output)
|
| +
|
| +
|
| +def _format_chunk(tag, a_chunk, b_chunk):
|
| + if tag == 'delete':
|
| + return _format_delete(a_chunk)
|
| + if tag == 'insert':
|
| + return _format_insert(b_chunk)
|
| + if tag == 'replace':
|
| + return _format_delete(a_chunk) + _format_insert(b_chunk)
|
| + assert tag == 'equal'
|
| + return a_chunk
|
| +
|
| +
|
| +def _format_insert(chunk):
|
| + return '<span class="add">%s</span>' % chunk
|
| +
|
| +
|
| +def _format_delete(chunk):
|
| + return '<span class="del">%s</span>' % chunk
|
|
|