ghdiff-0.4/0000755000076500000240000000000012346572641013376 5ustar patrickstaff00000000000000ghdiff-0.4/LICENSE.txt0000644000076500000240000000204612231573557015223 0ustar patrickstaff00000000000000Copyright (c) 2011 Patrick Strawderman Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.ghdiff-0.4/MANIFEST.in0000644000076500000240000000010312231574772015126 0ustar patrickstaff00000000000000include LICENSE.txt README.rst setup.py src/ghdiff.py src/tests.py ghdiff-0.4/PKG-INFO0000644000076500000240000001275212346572640014501 0ustar patrickstaff00000000000000Metadata-Version: 1.1 Name: ghdiff Version: 0.4 Summary: Generate Github-style HTML for unified diffs. Home-page: https://github.com/kilink/ghdiff Author: Patrick Strawderman Author-email: patrick@kilink.net License: MIT Description: .. image:: https://secure.travis-ci.org/kilink/ghdiff.png?branch=master :target: http://travis-ci.org/kilink/ghdiff .. image:: https://coveralls.io/repos/kilink/ghdiff/badge.png :target: https://coveralls.io/r/kilink/ghdiff ghdiff ====== Generate Github-style HTML for unified diffs. Changes ------- 0.4 (2014-06-13) ~~~~~~~~~~~~~~~~ * Add iPython magic (mgaitan) 0.3 (2014-04-06) ~~~~~~~~~~~~~~~~ * Fix Python 3 issue when running as a command-line script. 0.2 ~~~ * Detect character encoding when reading files (Nyoroon) * PEP-8 clean up (laulaz) * Fix display problem when text line is too long (laulaz) 0.1 ~~~ * initial release. diff ==== Generate a diff and output Github-style HTML for it. .. code-block:: pycon >>> import ghdiff >>> from six import print_ >>> print_(ghdiff.diff("a\nb", "b\nb"))
@@ -1,2 +1,2 @@
-a
 b
+b
The css option controls whether or not the output includes CSS. .. code-block:: pycon >>> print_(ghdiff.diff("blah blah blah\nb", "blah zxqq blah\nb", css=False))
@@ -1,2 +1,2 @@
-blah blah blah
+blah zxqq blah
 b
diff accepts lists of strings representing lines as well. .. code-block:: pycon >>> print_(ghdiff.diff(["blah blah blah", "b"], ["blah zxqq blah", "b"]))
@@ -1,2 +1,2 @@
-blah blah blah
+blah zxqq blah
 b
IPython magic ============= ghdiff also works as an IPython magic: .. code-block:: python In[1]: %load_ext ghdiff In[2]: %ghdiff var1 var2 See a `notebook example `_ colorize ======== colorize takes an existing unified diff and outputs Github-style markup. .. code-block:: python >>> print_(ghdiff.colorize("""\ ... index 921100e..8b177e1 100755 ... --- a/src/ghdiff.py ... +++ b/src/ghdiff.py ... @@ -10,20 +10,24 @@ def escape(text): ... default_css = \"\"\"\ ... \"\"\" % (open(os.path.join(os.path.dirname(__file__), "default.css")).read(),) ... + ... +\"\"\" % (open(os.path.join(os.path.dirname(__file__), "default.css")).read(),) ... +"""))
@@ -10,20 +10,24 @@ def escape(text):
 default_css = """ <style type="text/css">
 %s
-</style>""" % (open(os.path.join(os.path.dirname(__file__), "default.css")).read(),)
+</style>
+""" % (open(os.path.join(os.path.dirname(__file__), "default.css")).read(),)
+
Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Console Classifier: Intended Audience :: Developers Classifier: Natural Language :: English Classifier: License :: OSI Approved :: MIT License Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.3 Classifier: Programming Language :: Python :: 3.4 Classifier: Framework :: IPython Classifier: Topic :: Software Development Classifier: Topic :: Utilities ghdiff-0.4/README.rst0000644000076500000240000000705612346572541015074 0ustar patrickstaff00000000000000.. image:: https://secure.travis-ci.org/kilink/ghdiff.png?branch=master :target: http://travis-ci.org/kilink/ghdiff .. image:: https://coveralls.io/repos/kilink/ghdiff/badge.png :target: https://coveralls.io/r/kilink/ghdiff ghdiff ====== Generate Github-style HTML for unified diffs. Changes ------- 0.4 (2014-06-13) ~~~~~~~~~~~~~~~~ * Add iPython magic (mgaitan) 0.3 (2014-04-06) ~~~~~~~~~~~~~~~~ * Fix Python 3 issue when running as a command-line script. 0.2 ~~~ * Detect character encoding when reading files (Nyoroon) * PEP-8 clean up (laulaz) * Fix display problem when text line is too long (laulaz) 0.1 ~~~ * initial release. diff ==== Generate a diff and output Github-style HTML for it. .. code-block:: pycon >>> import ghdiff >>> from six import print_ >>> print_(ghdiff.diff("a\nb", "b\nb"))
@@ -1,2 +1,2 @@
-a
 b
+b
The css option controls whether or not the output includes CSS. .. code-block:: pycon >>> print_(ghdiff.diff("blah blah blah\nb", "blah zxqq blah\nb", css=False))
@@ -1,2 +1,2 @@
-blah blah blah
+blah zxqq blah
 b
diff accepts lists of strings representing lines as well. .. code-block:: pycon >>> print_(ghdiff.diff(["blah blah blah", "b"], ["blah zxqq blah", "b"]))
@@ -1,2 +1,2 @@
-blah blah blah
+blah zxqq blah
 b
IPython magic ============= ghdiff also works as an IPython magic: .. code-block:: python In[1]: %load_ext ghdiff In[2]: %ghdiff var1 var2 See a `notebook example `_ colorize ======== colorize takes an existing unified diff and outputs Github-style markup. .. code-block:: python >>> print_(ghdiff.colorize("""\ ... index 921100e..8b177e1 100755 ... --- a/src/ghdiff.py ... +++ b/src/ghdiff.py ... @@ -10,20 +10,24 @@ def escape(text): ... default_css = \"\"\"\ ... \"\"\" % (open(os.path.join(os.path.dirname(__file__), "default.css")).read(),) ... + ... +\"\"\" % (open(os.path.join(os.path.dirname(__file__), "default.css")).read(),) ... +"""))
@@ -10,20 +10,24 @@ def escape(text):
 default_css = """ <style type="text/css">
 %s
-</style>""" % (open(os.path.join(os.path.dirname(__file__), "default.css")).read(),)
+</style>
+""" % (open(os.path.join(os.path.dirname(__file__), "default.css")).read(),)
+
ghdiff-0.4/setup.cfg0000644000076500000240000000007312346572641015217 0ustar patrickstaff00000000000000[egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 ghdiff-0.4/setup.py0000644000076500000240000000300112346572550015101 0ustar patrickstaff00000000000000from setuptools import setup setup( name="ghdiff", version="0.4", description="Generate Github-style HTML for unified diffs.", long_description=open("README.rst").read(), author="Patrick Strawderman", author_email="patrick@kilink.net", url="https://github.com/kilink/ghdiff", license="MIT", package_data={"": ["*.py", "*.txt", "*.css"]}, include_package_data=True, package_dir={"": "src"}, py_modules=["ghdiff", "ipython_magic"], tests_require=["zope.testrunner"], install_requires=["six", "chardet"], test_suite="tests.test_suite", entry_points={ 'console_scripts': [ "ghdiff = ghdiff:main" ] }, classifiers=['Development Status :: 5 - Production/Stable', 'Environment :: Console', 'Intended Audience :: Developers', 'Natural Language :: English', 'License :: OSI Approved :: MIT License', 'Programming Language :: Python', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', 'Framework :: IPython', 'Topic :: Software Development', 'Topic :: Utilities', ], ) ghdiff-0.4/src/0000755000076500000240000000000012346572640014164 5ustar patrickstaff00000000000000ghdiff-0.4/src/ghdiff.egg-info/0000755000076500000240000000000012346572640017105 5ustar patrickstaff00000000000000ghdiff-0.4/src/ghdiff.egg-info/dependency_links.txt0000644000076500000240000000000112346572640023153 0ustar patrickstaff00000000000000 ghdiff-0.4/src/ghdiff.egg-info/entry_points.txt0000644000076500000240000000005012346572640022376 0ustar patrickstaff00000000000000[console_scripts] ghdiff = ghdiff:main ghdiff-0.4/src/ghdiff.egg-info/PKG-INFO0000644000076500000240000001275212346572640020211 0ustar patrickstaff00000000000000Metadata-Version: 1.1 Name: ghdiff Version: 0.4 Summary: Generate Github-style HTML for unified diffs. Home-page: https://github.com/kilink/ghdiff Author: Patrick Strawderman Author-email: patrick@kilink.net License: MIT Description: .. image:: https://secure.travis-ci.org/kilink/ghdiff.png?branch=master :target: http://travis-ci.org/kilink/ghdiff .. image:: https://coveralls.io/repos/kilink/ghdiff/badge.png :target: https://coveralls.io/r/kilink/ghdiff ghdiff ====== Generate Github-style HTML for unified diffs. Changes ------- 0.4 (2014-06-13) ~~~~~~~~~~~~~~~~ * Add iPython magic (mgaitan) 0.3 (2014-04-06) ~~~~~~~~~~~~~~~~ * Fix Python 3 issue when running as a command-line script. 0.2 ~~~ * Detect character encoding when reading files (Nyoroon) * PEP-8 clean up (laulaz) * Fix display problem when text line is too long (laulaz) 0.1 ~~~ * initial release. diff ==== Generate a diff and output Github-style HTML for it. .. code-block:: pycon >>> import ghdiff >>> from six import print_ >>> print_(ghdiff.diff("a\nb", "b\nb"))
@@ -1,2 +1,2 @@
-a
 b
+b
The css option controls whether or not the output includes CSS. .. code-block:: pycon >>> print_(ghdiff.diff("blah blah blah\nb", "blah zxqq blah\nb", css=False))
@@ -1,2 +1,2 @@
-blah blah blah
+blah zxqq blah
 b
diff accepts lists of strings representing lines as well. .. code-block:: pycon >>> print_(ghdiff.diff(["blah blah blah", "b"], ["blah zxqq blah", "b"]))
@@ -1,2 +1,2 @@
-blah blah blah
+blah zxqq blah
 b
IPython magic ============= ghdiff also works as an IPython magic: .. code-block:: python In[1]: %load_ext ghdiff In[2]: %ghdiff var1 var2 See a `notebook example `_ colorize ======== colorize takes an existing unified diff and outputs Github-style markup. .. code-block:: python >>> print_(ghdiff.colorize("""\ ... index 921100e..8b177e1 100755 ... --- a/src/ghdiff.py ... +++ b/src/ghdiff.py ... @@ -10,20 +10,24 @@ def escape(text): ... default_css = \"\"\"\ ... \"\"\" % (open(os.path.join(os.path.dirname(__file__), "default.css")).read(),) ... + ... +\"\"\" % (open(os.path.join(os.path.dirname(__file__), "default.css")).read(),) ... +"""))
@@ -10,20 +10,24 @@ def escape(text):
 default_css = """ <style type="text/css">
 %s
-</style>""" % (open(os.path.join(os.path.dirname(__file__), "default.css")).read(),)
+</style>
+""" % (open(os.path.join(os.path.dirname(__file__), "default.css")).read(),)
+
Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Console Classifier: Intended Audience :: Developers Classifier: Natural Language :: English Classifier: License :: OSI Approved :: MIT License Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.3 Classifier: Programming Language :: Python :: 3.4 Classifier: Framework :: IPython Classifier: Topic :: Software Development Classifier: Topic :: Utilities ghdiff-0.4/src/ghdiff.egg-info/requires.txt0000644000076500000240000000001312346572640021477 0ustar patrickstaff00000000000000six chardetghdiff-0.4/src/ghdiff.egg-info/SOURCES.txt0000644000076500000240000000045112346572640020771 0ustar patrickstaff00000000000000LICENSE.txt MANIFEST.in README.rst setup.py src/ghdiff.py src/ipython_magic.py src/tests.py src/ghdiff.egg-info/PKG-INFO src/ghdiff.egg-info/SOURCES.txt src/ghdiff.egg-info/dependency_links.txt src/ghdiff.egg-info/entry_points.txt src/ghdiff.egg-info/requires.txt src/ghdiff.egg-info/top_level.txtghdiff-0.4/src/ghdiff.egg-info/top_level.txt0000644000076500000240000000002512346572640021634 0ustar patrickstaff00000000000000ghdiff ipython_magic ghdiff-0.4/src/ghdiff.py0000755000076500000240000001007212346572426015772 0ustar patrickstaff00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- import chardet import difflib import optparse import six import sys import xml.sax.saxutils __version__ = "0.3" default_css = """\ """ def escape(text): return xml.sax.saxutils.escape(text, {" ": " "}) def diff(a, b, n=3, css=True): if isinstance(a, six.string_types): a = a.splitlines() if isinstance(b, six.string_types): b = b.splitlines() return colorize(list(difflib.unified_diff(a, b, n=n)), css=css) def colorize(diff, css=True): css = default_css if css else "" return css + "\n".join(_colorize(diff)) def _colorize(diff): if isinstance(diff, six.string_types): lines = diff.splitlines() else: lines = diff lines.reverse() while lines and not lines[-1].startswith("@@"): lines.pop() yield '
' while lines: line = lines.pop() klass = "" if line.startswith("@@"): klass = "control" elif line.startswith("-"): klass = "delete" if lines: _next = [] while lines and len(_next) < 2: _next.append(lines.pop()) if _next[0].startswith("+") and ( len(_next) == 1 or _next[1][0] not in ("+", "-")): aline, bline = _line_diff(line[1:], _next.pop(0)[1:]) yield '
-%s
' % (aline,) yield '
+%s
' % (bline,) if _next: lines.append(_next.pop()) continue lines.extend(reversed(_next)) elif line.startswith("+"): klass = "insert" yield '
%s
' % (klass, escape(line),) yield "
" def _line_diff(a, b): aline = [] bline = [] for tag, i1, i2, j1, j2 in difflib.SequenceMatcher(a=a, b=b).get_opcodes(): if tag == "equal": aline.append(escape(a[i1:i2])) bline.append(escape(b[j1:j2])) continue aline.append('%s' % (escape(a[i1:i2]),)) bline.append('%s' % (escape(b[j1:j2]),)) return "".join(aline), "".join(bline) def main(args=None, stdout=sys.stdout): if args is None: args = sys.argv[1:] parser = optparse.OptionParser(usage="%prog [options] file1 file2", version="%prog " + __version__) parser.add_option("--no-css", action="store_false", dest="css", help="Don't include CSS in output", default=True) options, args = parser.parse_args(args) if (len(args) != 2): parser.print_help(stdout) sys.exit(-1) def read_file(filename): with open(filename, "rb") as f: text = f.read() codepage = chardet.detect(text)['encoding'] return text.decode(codepage).splitlines() a = read_file(args[0]) b = read_file(args[1]) stdout.write(diff(a, b, css=options.css).encode("utf-8")) def load_ipython_extension(ip): """Load the extension in IPython.""" from ipython_magic import GHDiffMagics ip.register_magics(GHDiffMagics) if __name__ == "__main__": main(sys.argv[1:]) ghdiff-0.4/src/ipython_magic.py0000644000076500000240000000174612346572426017402 0ustar patrickstaff00000000000000from IPython.core.magic import Magics, line_magic, magics_class from IPython.core import magic_arguments from IPython.core.error import UsageError from IPython.core.display import HTML import ghdiff @magics_class class GHDiffMagics(Magics): @magic_arguments.magic_arguments() @magic_arguments.argument( "var1", help="first variable" ) @magic_arguments.argument( "var2", help="second variable" ) @line_magic def ghdiff(self, line): """ Generate Github-style HTML for unified diffs """ args = magic_arguments.parse_argstring(self.ghdiff, line) try: a = self.shell.user_ns[args.var1] except KeyError: raise UsageError("Unknown variable %s" % args.var1) try: b = self.shell.user_ns[args.var2] except KeyError: raise UsageError("Unknown variable %s" % args.var2) return HTML(ghdiff.diff(a, b)) ghdiff-0.4/src/tests.py0000644000076500000240000000267712320314537015703 0ustar patrickstaff00000000000000import doctest import ghdiff import io import os import os.path import sys import tempfile import unittest class GhDiffTest(unittest.TestCase): def write_file(self, text): fd, path = tempfile.mkstemp() self._tempfiles.append(path) with os.fdopen(fd, "w") as f: f.write(text) return path def setUp(self): self._tempfiles = [] self._stdout = sys.stdout def tearDown(self): for path in self._tempfiles: os.remove(path) del self._tempfiles[:] def test_script(self): """Simple exercise of the commandline mode""" f1 = self.write_file("foobar") f2 = self.write_file("foobarbaz") out = io.BytesIO() ghdiff.main([f1, f2], stdout=out) output = out.getvalue() self.assertTrue(b"-foobar" in output) self.assertTrue(b'+foobarbaz' in output) def test_no_css_option(self): """Simple test for --no-css option""" f1 = self.write_file("foobar") f2 = self.write_file("foobarbaz") out = io.BytesIO() ghdiff.main([f1, f2, "--no-css"], stdout=out) output = out.getvalue() self.assertFalse(b"