From f1eb008cc727370e1bd0dc32fdf301f62d9ff981 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 8 May 2012 23:41:41 +0200 Subject: [PATCH] Add hb-diff-colorize Accepts --format=html now. --- test/shaping/Makefile.am | 1 + test/shaping/hb-diff | 4 +- test/shaping/hb-diff-colorize | 7 ++ test/shaping/hb_test_tools.py | 158 +++++++++++++++++++++++++----------------- 4 files changed, 106 insertions(+), 64 deletions(-) create mode 100755 test/shaping/hb-diff-colorize diff --git a/test/shaping/Makefile.am b/test/shaping/Makefile.am index 1694eca..f216c5d 100644 --- a/test/shaping/Makefile.am +++ b/test/shaping/Makefile.am @@ -11,6 +11,7 @@ manifests: EXTRA_DIST += \ hb-diff \ + hb-diff-colorize \ hb-diff-filter-failures \ hb-manifest-read \ hb-manifest-update \ diff --git a/test/shaping/hb-diff b/test/shaping/hb-diff index eac3ff6..6a13fa2 100755 --- a/test/shaping/hb-diff +++ b/test/shaping/hb-diff @@ -3,8 +3,8 @@ from hb_test_tools import * import sys, os -if len (sys.argv) < 3: - print "usage: %s file1 file2..." % sys.argv[0] +if len (sys.argv) < 2: + print "usage: %s FILES..." % sys.argv[0] sys.exit (1) ZipDiffer.diff_files (FileHelpers.open_file_or_stdin (f) for f in sys.argv[1:]) diff --git a/test/shaping/hb-diff-colorize b/test/shaping/hb-diff-colorize new file mode 100755 index 0000000..4e045d2 --- /dev/null +++ b/test/shaping/hb-diff-colorize @@ -0,0 +1,7 @@ +#!/usr/bin/python + +from hb_test_tools import * + +formatter = ColorFormatter.Auto (sys.argv) +colorizer = DiffColorizer (formatter=formatter) +UtilMains.process_multiple_files (FilterHelpers.filter_printer_function_no_newline (colorizer.colorize_diff)) diff --git a/test/shaping/hb_test_tools.py b/test/shaping/hb_test_tools.py index 65640bc..03a7710 100644 --- a/test/shaping/hb_test_tools.py +++ b/test/shaping/hb_test_tools.py @@ -1,65 +1,81 @@ #!/usr/bin/python -import sys, os, re, difflib, unicodedata, errno +import sys, os, re, difflib, unicodedata, errno, cgi from itertools import * diff_symbols = "-+=*&^%$#@!~/" diff_colors = ['red', 'green', 'blue'] -class Colors: +class ColorFormatter: + class Null: - red = '' - green = '' - end = '' + @staticmethod + def start_color (c): return '' + @staticmethod + def end_color (): return '' + @staticmethod + def escape (s): return s + @staticmethod + def newline (): return '\n' + class ANSI: - red = '\033[41;37;1m' - green = '\033[42;37;1m' - end = '\033[m' + @staticmethod + def start_color (c): + return { + 'red': '\033[41;37;1m', + 'green': '\033[42;37;1m', + 'blue': '\033[44;37;1m', + }[c] + @staticmethod + def end_color (): + return '\033[m' + @staticmethod + def escape (s): return s + @staticmethod + def newline (): return '\n' + class HTML: - red = '' - green = '' - end = '' + @staticmethod + def start_color (c): + return '' % c + @staticmethod + def end_color (): + return '' + @staticmethod + def escape (s): return cgi.escape (s) + @staticmethod + def newline (): return '
\n' @staticmethod def Auto (argv = [], out = sys.stdout): - if os.isatty (out.fileno ()): - color = Colors.ANSI - else: - color = Colors.Null - if "--color" in argv: - argv.remove ("--color") - color = Colors.ANSI - if "--color=ansi" in argv: - argv.remove ("--color=ansi") - color = Colors.ANSI - if "--color=html" in argv: - argv.remove ("--color=html") - color = Colors.HTML - if "--no-color" in argv: - argv.remove ("--no-color") - color = Colors.Null - return color - - - @staticmethod - def Default (argv = []): - return Colors.ANSI - - -class FancyDiffer: + format = ColorFormatter.ANSI + if "--format" in argv: + argv.remove ("--format") + format = ColorFormatter.ANSI + if "--format=ansi" in argv: + argv.remove ("--format=ansi") + format = ColorFormatter.ANSI + if "--format=html" in argv: + argv.remove ("--format=html") + format = ColorFormatter.HTML + if "--no-format" in argv: + argv.remove ("--no-format") + format = ColorFormatter.Null + return format + + +class DiffColorizer: diff_regex = re.compile ('([a-za-z0-9_]*)([^a-za-z0-9_]?)') - @staticmethod - def diff_lines (l1, l2, colors=Colors.Null): - - # Easy without colors - if colors == Colors.Null: - if l1 == l2: - return [' ', l1] - return ['-', l1, '+', l2] + def __init__ (self, formatter, colors=diff_colors, symbols=diff_symbols): + self.formatter = formatter + self.colors = colors + self.symbols = symbols - ss = [FancyDiffer.diff_regex.sub (r'\1\n\2\n', l).splitlines (True) for l in (l1, l2)] + def colorize_lines (self, lines): + lines = (l if l else '' for l in lines) + ss = [self.diff_regex.sub (r'\1\n\2\n', l).splitlines (True) for l in lines] oo = ["",""] st = [False, False] for l in difflib.Differ().compare (*ss): @@ -68,29 +84,47 @@ class FancyDiffer: if l[0] == ' ': for i in range(2): if st[i]: - oo[i] += colors.end + oo[i] += self.formatter.end_color () st[i] = False - oo = [o + l[2:] for o in oo] + oo = [o + self.formatter.escape (l[2:]) for o in oo] continue - if l[0] == '-': - if not st[0]: - oo[0] += colors.red - st[0] = True - oo[0] += l[2:] + if l[0] in self.symbols: + i = self.symbols.index (l[0]) + if not st[i]: + oo[i] += self.formatter.start_color (self.colors[i]) + st[i] = True + oo[i] += self.formatter.escape (l[2:]) continue - if l[0] == '+': - if not st[1]: - oo[1] += colors.green - st[1] = True - oo[1] += l[2:] for i in range(2): if st[i]: - oo[i] += colors.end - st[i] = 0 + oo[i] += self.formatter.end_color () + st[i] = False oo = [o.replace ('\n', '') for o in oo] - if oo[0] == oo[1]: - return [' ', oo[0], '\n'] - return ['-', oo[0], '\n', '+', oo[1], '\n'] + return [s1+s2+self.formatter.newline () for (s1,s2) in zip (self.symbols, oo) if s2] + + def colorize_diff (self, f): + lines = [None, None] + for l in f: + if l[0] not in self.symbols: + yield self.formatter.escape (l).replace ('\n', self.formatter.newline ()) + continue + i = self.symbols.index (l[0]) + if lines[i]: + # Flush + for line in self.colorize_lines (lines): + yield line + lines = [None, None] + lines[i] = l[1:] + if (all (lines)): + # Flush + for line in self.colorize_lines (lines): + yield line + lines = [None, None] + if (any (lines)): + # Flush + for line in self.colorize_lines (lines): + yield line + class ZipDiffer: -- 2.7.4