Issue #1134 resolved

A diff parameter for literalinclude

Richard Wall
created an issue

Some of the Twisted tutorials / howto documents contain a narrative that refers to multiple versions of an example Python script. eg *

The example may start as a simple hello world and each step of the tutorial may introduce a new class / function or modify part of the earlier script.

It would be nice if Sphinx had some way of highlighting only the changes between successive examples.

The most obvious solution that comes to mind, is to add a new "diff" parameter to literalinclude which references an earlier example script.

Then use difflib to produce a unified diff and pygments diff highlighting to color code the output eg

--- a/sphinx/directives/ Sun Mar 17 10:58:28 2013 +0900
+++ b/sphinx/directives/ Wed Mar 27 18:38:29 2013 +0000
@@ -105,9 +105,11 @@
         'prepend': directives.unchanged_required,
         'append': directives.unchanged_required,
         'emphasize-lines': directives.unchanged_required,
+        'diff': directives.unchanged_required,

     def run(self):
         document = self.state.document
         if not document.settings.file_insertion_enabled:
             return [document.reporter.warning('File insertion disabled',
@@ -152,6 +154,25 @@
                 lines = lines[tags[objectname][1]-1 : tags[objectname][2]-1]

+        diffsource = self.options.get('diff')
+        if diffsource is not None:
+            from difflib import unified_diff
+            diff = unified_diff(
+                open(diffsource).readlines(),
+                open(filename).readlines(),
+                diffsource,
+                rel_filename)
+            lines = list(diff)

The trouble with this is that the Python syntax highlighting is lost. It would be even nicer if the files were first syntax highlighted for eg python then the differences computed and only the changed portions displayed with the line numbers from the original files.

Comments (6)

  1. Richard Wall reporter

    Some further discussion and ideas from #twisted-dev

    18:48 < rwall> tomprince: At Pycon we talked briefly about displaying only the diffs between successive examples in the howtos.
    18:48 < rwall> I created a sphinx ticket for it
    18:49 < rwall> I guess there's no point in attempting it in lore.
    18:49 < exarkun> rwall: literally unified diffs?
    18:49 < rwall> Well maybe something better than that. But as a start yes.
    18:50 < rwall> Or a wiget that allows you to see the current/previous/diff of the examples.
    18:50 < exarkun> Hm. :/
    18:50 < rwall> exarkun: You're not convinced?
    18:50 < exarkun> It is an interesting idea.
    18:51 < dreid> The problem is you may never have seen a diff before.
    18:51 < exarkun> I would quite like to watch someone trying to learn Twisted read such a document and observe their reaction.
    18:52 < rwall> It doesn't have to be a raw diff. It could for example work out which classes, functions have been added and only show those.
    18:53 < exarkun> That would probably be better.  Or the interestingly changed parts could be highlighted (preserving context, which is often 
    18:53 < rwall> yep
    18:53 < exarkun> But I seriously would like to watch someone trying to consume documentation using any of these ideas.  I'm not sure how you predict 
                     whether a technique will actually be understood by the audience or not.
    18:56 < rwall> I find the repeated long examples in the finger tutorial make the changes quite hard to follow.
    18:57 < rwall> It would be nice if it could show the complete examples but just highlight the changed lines.
  2. Log in to comment