28
\$\begingroup\$

When I see code-golf entries that knock a few characters off, whittling down the code, I go look at the edit history for a side-by-side diff. See and learn :)

This challenge is to make a program that produces the prettiest animated diffs.

  • The input will be any ordered series of text versions.
  • The program may be written in any programming language.
  • It is allowed that the program limit itself to input data in some specific programming languages.
  • The program should not be tuned to the specific input data; the program should be generic and work for any ordered series of text versions.
  • For each version in the input there must be a corresponding time in the output animation where the full text of the version is displayed. You must animate the diff between version stages, and all version stages must be present and in order in the output. On these key frames, the version size must be shown and the viewer should understand this is a complete version they are seeing at that point.
  • The program may not use any third party code to compute the diffs.
  • Syntax highlighting output is optional. If the program colours syntax, it may not use any third party code to do so.
  • The output will be an animated GIF.
  • The program may use a third party library to author the GIF.
  • This is a , so as per the definition of popularity-contest on this site, the entry with the most votes wins.

Here's a simple example script that uses Python's ndiff and Pillow's rudimentary animated GIF support and animates each add and remove step:

Personally, I think this a pretty poor job. It doesn't do syntax highlighting, it doesn't try and move code chunks that get rearranged, it doesn't feel like someone is live editing it, and so on. It also breaks the rules regards showing the size of the input in bytes on key frames, and it uses a third party library to do the diffing. Lots of room for improvement!

And hopefully the popular entries will become useful fun tools for the codegolf.stackexchange.com community too. So its appreciated if the programs are easy for others to get running and use.

\$\endgroup\$
  • 1
    \$\begingroup\$ Comments purged as the extended conversation here seems to be coming to a stop. Discussion about this post can be found on this meta question. \$\endgroup\$ – Doorknob Sep 18 '14 at 23:34
11
\$\begingroup\$

(OP)

enter image description here

This is based on the example Python script in the question.

I used the simplest edit distance rather than a cleverer patience diff.

For aligning genomes there's Multi Sequence Alignment algorithms and they could well make an even better job than just considering each pair of adjacent frames?

I was pleasantly surprised how straightforward it was to implement edit distance for the diff, and made it compatible with Python's difflib.ndiff format. There are plenty of Python implementations of edit distance to be found on the web, but I think my formulation is that little bit tidier and deals with the tricky but essential part of actually determining the path in the table too; in our context, we need to know the steps to turn one into another and not just how many steps there are.

I introduced syntax highlighting using a very simple tokenizer that ought to be able to cope with most c-like languages including, by its laxity, Python and such. It splits the source into punctuation, whitespace, strings (with escape support) and everything else is an identifier and checked against a list of keywords. The colouring is also easy to change.

It was easy to integrate the syntax highlighting into a dynamic language; the highlighter outputs a list of character and colour pairs, and the differ is agnostic to whether its diffing strings or any arbitrary iterables of comparables! An interesting - and deliberate - effect of highlighting first and then diffing is that characters that remain unchanged but change colour get animated. I didn't want to compute the highlight each frame as that would mean that as you delete a closing string you'd suddenly flash a big chunk of text up as string.

Python's support for authoring GIF is rather limited. PIL doesn't do it, and Pillow does it rather badly. I use Pillow, but then have to run through gifsicle to compress and add looping etc; Pillow doesn't correctly write frame timing and doesn't let you manage disposal methods etc, which is a shame as the differ has so much better understanding of the scene than a post-processing step dealing with flattened frames :(

Sourcecode

\$\endgroup\$
  • 1
    \$\begingroup\$ I implemented the same diff algorithm. Later I rewrote it using Cython and gained a 100x speedup. \$\endgroup\$ – Ray Sep 19 '14 at 11:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.