Merged in r_rudi/sphinx (pull request #267)

add 'diff' parameter to literalinclude.
This commit is contained in:
Takayuki Shimizukawa 2014-08-13 13:17:47 +09:00
commit b8c2619858
4 changed files with 75 additions and 18 deletions

View File

@ -180,6 +180,16 @@ Includes
``prepend`` and ``append`` option, respectively. This is useful e.g. for ``prepend`` and ``append`` option, respectively. This is useful e.g. for
highlighting PHP code that doesn't include the ``<?php``/``?>`` markers. highlighting PHP code that doesn't include the ``<?php``/``?>`` markers.
If you want to show the diff of the code, you can specify the old
file by giving a ``diff`` option::
.. literalinclude:: example.py
:diff: example.py.orig
This shows the diff between example.py and example.py.orig with unified diff format.
.. versionadded:: 0.4.3 .. versionadded:: 0.4.3
The ``encoding`` option. The ``encoding`` option.
.. versionadded:: 0.6 .. versionadded:: 0.6
@ -187,6 +197,8 @@ Includes
as well as support for absolute filenames. as well as support for absolute filenames.
.. versionadded:: 1.0 .. versionadded:: 1.0
The ``prepend`` and ``append`` options, as well as ``tab-width``. The ``prepend`` and ``append`` options, as well as ``tab-width``.
.. versionadded:: 1.3
The ``diff`` option.
Showing a file name Showing a file name

View File

@ -9,10 +9,13 @@
import sys import sys
import codecs import codecs
from difflib import unified_diff
from docutils import nodes from docutils import nodes
from docutils.parsers.rst import Directive, directives from docutils.parsers.rst import Directive, directives
from six import string_types
from sphinx import addnodes from sphinx import addnodes
from sphinx.util import parselinenos from sphinx.util import parselinenos
from sphinx.util.nodes import set_source_info from sphinx.util.nodes import set_source_info
@ -138,8 +141,30 @@ class LiteralInclude(Directive):
'append': directives.unchanged_required, 'append': directives.unchanged_required,
'emphasize-lines': directives.unchanged_required, 'emphasize-lines': directives.unchanged_required,
'filename': directives.unchanged, 'filename': directives.unchanged,
'diff': directives.unchanged_required,
} }
def read_with_encoding(self, filename, document, codec_info, encoding):
f = None
try:
f = codecs.StreamReaderWriter(open(filename, 'rb'),
codec_info[2], codec_info[3], 'strict')
lines = f.readlines()
lines = dedent_lines(lines, self.options.get('dedent'))
return lines
except (IOError, OSError):
return [document.reporter.warning(
'Include file %r not found or reading it failed' % filename,
line=self.lineno)]
except UnicodeError:
return [document.reporter.warning(
'Encoding %r used for reading included file %r seems to '
'be wrong, try giving an :encoding: option' %
(encoding, filename))]
finally:
if f is not None:
f.close()
def run(self): def run(self):
document = self.state.document document = self.state.document
if not document.settings.file_insertion_enabled: if not document.settings.file_insertion_enabled:
@ -155,24 +180,26 @@ class LiteralInclude(Directive):
encoding = self.options.get('encoding', env.config.source_encoding) encoding = self.options.get('encoding', env.config.source_encoding)
codec_info = codecs.lookup(encoding) codec_info = codecs.lookup(encoding)
f = None
try: lines = self.read_with_encoding(filename, document,
f = codecs.StreamReaderWriter(open(filename, 'rb'), codec_info, encoding)
codec_info[2], codec_info[3], 'strict') if not isinstance(lines[0], string_types):
lines = f.readlines() return lines
lines = dedent_lines(lines, self.options.get('dedent'))
except (IOError, OSError): diffsource = self.options.get('diff')
return [document.reporter.warning( if diffsource is not None:
'Include file %r not found or reading it failed' % filename, tmp, fulldiffsource = env.relfn2path(diffsource)
line=self.lineno)]
except UnicodeError: difflines = self.read_with_encoding(fulldiffsource, document,
return [document.reporter.warning( codec_info, encoding)
'Encoding %r used for reading included file %r seems to ' if not isinstance(difflines[0], string_types):
'be wrong, try giving an :encoding: option' % return difflines
(encoding, filename))] diff = unified_diff(
finally: difflines,
if f is not None: lines,
f.close() diffsource,
self.arguments[0])
lines = list(diff)
objectname = self.options.get('pyobject') objectname = self.options.get('pyobject')
if objectname is not None: if objectname is not None:
@ -236,6 +263,8 @@ class LiteralInclude(Directive):
text = text.expandtabs(self.options['tab-width']) text = text.expandtabs(self.options['tab-width'])
retnode = nodes.literal_block(text, text, source=filename) retnode = nodes.literal_block(text, text, source=filename)
set_source_info(self, retnode) set_source_info(self, retnode)
if diffsource is not None: # if diff is set, set udiff
retnode['language'] = 'udiff'
if self.options.get('language', ''): if self.options.get('language', ''):
retnode['language'] = self.options['language'] retnode['language'] = self.options['language']
retnode['linenos'] = 'linenos' in self.options or \ retnode['linenos'] = 'linenos' in self.options or \

View File

@ -58,6 +58,9 @@ Literalinclude options
.. literalinclude:: literal.inc .. literalinclude:: literal.inc
:end-before: class Foo :end-before: class Foo
.. literalinclude:: literal.inc
:diff: literal.inc.orig
.. cssclass:: inc-tab3 .. cssclass:: inc-tab3
.. literalinclude:: tabs.inc .. literalinclude:: tabs.inc
:tab-width: 3 :tab-width: 3

View File

@ -0,0 +1,13 @@
# Literally included file using Python highlighting
# -*- coding: utf-8 -*-
foo = "Including Unicode characters: üöä" # This will be changed
class FooOrig:
pass
class BarOrig:
def baz():
pass
def bar(): pass