Added NDIFF_DIFF option.
diff --git a/Doc/lib/libdoctest.tex b/Doc/lib/libdoctest.tex
index c0bdf6d..0741aa0 100644
--- a/Doc/lib/libdoctest.tex
+++ b/Doc/lib/libdoctest.tex
@@ -356,6 +356,15 @@
     actual outputs will be displayed using a context diff.
 \end{datadesc}
 
+\begin{datadesc}{NDIFF_DIFF}
+    When specified, differences are computed by \code{difflib.Differ},
+    using the same algorithm as the popular \file{ndiff.py} utility.
+    This is the only method that marks differences within lines as
+    well as across lines.  For example, if a line of expected output
+    contains digit \code{1} where actual output contains letter \code{l},
+    a line is inserted with a caret marking the mismatching column
+    positions.
+\end{datadesc}
 
 A "doctest directive" is a trailing Python comment on a line of a doctest
 example:
@@ -414,7 +423,8 @@
 
 \versionchanged[Constants \constant{DONT_ACCEPT_BLANKLINE},
     \constant{NORMALIZE_WHITESPACE}, \constant{ELLIPSIS},
-    \constant{UNIFIED_DIFF}, and \constant{CONTEXT_DIFF}
+    \constant{UNIFIED_DIFF}, \constant{CONTEXT_DIFF}, and
+    \constant{NDIFF_DIFF}
     were added; by default \code{<BLANKLINE>} in expected output
     matches an empty line in actual output; and doctest directives
     were added]{2.4}
diff --git a/Lib/doctest.py b/Lib/doctest.py
index 74714c5..0cafac6 100644
--- a/Lib/doctest.py
+++ b/Lib/doctest.py
@@ -178,6 +178,7 @@
     'ELLIPSIS',
     'UNIFIED_DIFF',
     'CONTEXT_DIFF',
+    'NDIFF_DIFF',
     # 1. Utility Functions
     'is_private',
     # 2. Example & DocTest
@@ -253,6 +254,7 @@
 ELLIPSIS = register_optionflag('ELLIPSIS')
 UNIFIED_DIFF = register_optionflag('UNIFIED_DIFF')
 CONTEXT_DIFF = register_optionflag('CONTEXT_DIFF')
+NDIFF_DIFF = register_optionflag('NDIFF_DIFF')
 
 # Special string markers for use in `want` strings:
 BLANKLINE_MARKER = '<BLANKLINE>'
@@ -1569,6 +1571,24 @@
         # We didn't find any match; return false.
         return False
 
+    # Should we do a fancy diff?
+    def _do_a_fancy_diff(self, want, got, optionflags):
+        # Not unless they asked for a fancy diff.
+        if not optionflags & (UNIFIED_DIFF |
+                              CONTEXT_DIFF |
+                              NDIFF_DIFF):
+            return False
+        # If expected output uses ellipsis, a meaningful fancy diff is
+        # too hard.
+        if optionflags & ELLIPSIS and ELLIPSIS_MARKER in want:
+            return False
+        # ndiff does intraline difference marking, so can be useful even
+        # for 1-line inputs.
+        if optionflags & NDIFF_DIFF:
+            return True
+        # The other diff types need at least a few lines to be helpful.
+        return want.count('\n') > 2 and got.count('\n') > 2
+
     def output_difference(self, want, got, optionflags):
         """
         Return a string describing the differences between the
@@ -1586,9 +1606,7 @@
         # Check if we should use diff.  Don't use diff if the actual
         # or expected outputs are too short, or if the expected output
         # contains an ellipsis marker.
-        if ((optionflags & (UNIFIED_DIFF | CONTEXT_DIFF)) and
-            want.count('\n') > 2 and got.count('\n') > 2 and
-            not (optionflags & ELLIPSIS and '...' in want)):
+        if self._do_a_fancy_diff(want, got, optionflags):
             # Split want & got into lines.
             want_lines = [l+'\n' for l in want.split('\n')]
             got_lines = [l+'\n' for l in got.split('\n')]
@@ -1596,16 +1614,20 @@
             if optionflags & UNIFIED_DIFF:
                 diff = difflib.unified_diff(want_lines, got_lines, n=2,
                                             fromfile='Expected', tofile='Got')
-                kind = 'unified'
+                kind = 'unified diff'
             elif optionflags & CONTEXT_DIFF:
                 diff = difflib.context_diff(want_lines, got_lines, n=2,
                                             fromfile='Expected', tofile='Got')
-                kind = 'context'
+                kind = 'context diff'
+            elif optionflags & NDIFF_DIFF:
+                engine = difflib.Differ(charjunk=difflib.IS_CHARACTER_JUNK)
+                diff = list(engine.compare(want_lines, got_lines))
+                kind = 'ndiff with -expected +actual'
             else:
                 assert 0, 'Bad diff option'
             # Remove trailing whitespace on diff output.
             diff = [line.rstrip() + '\n' for line in diff]
-            return _tag_msg("Differences (" + kind + " diff)",
+            return _tag_msg("Differences (" + kind + ")",
                             ''.join(diff))
 
         # If we're not using diff, then simply list the expected
diff --git a/Lib/test/test_doctest.py b/Lib/test/test_doctest.py
index 6d9d745..969ee17 100644
--- a/Lib/test/test_doctest.py
+++ b/Lib/test/test_doctest.py
@@ -283,7 +283,7 @@
     'test_doctest.py'
 
     >>> test.test_doctest.__file__ = old
-    
+
 
     >>> e = tests[0].examples[0]
     >>> (e.source, e.want, e.lineno)
@@ -931,7 +931,33 @@
           g
     <BLANKLINE>
     (1, 1)
-"""
+
+
+The NDIFF_DIFF flag causes failures to use the difflib.Differ algorithm
+used by the popular ndiff.py utility.  This does intraline difference
+marking, as well as interline differences.
+
+    >>> def f(x):
+    ...     r'''
+    ...     >>> print "a b  c d e f g h i   j k l m"
+    ...     a b c d e f g h i j k 1 m
+    ...     '''
+    >>> test = doctest.DocTestFinder().find(f)[0]
+    >>> flags = doctest.NDIFF_DIFF
+    >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test)
+    **********************************************************************
+    Line 2, in f
+    Failed example:
+        print "a b  c d e f g h i   j k l m"
+    Differences (ndiff with -expected +actual):
+        - a b c d e f g h i j k 1 m
+        ?                       ^
+        + a b  c d e f g h i   j k l m
+        ?     +              ++    ^
+    <BLANKLINE>
+    (1, 1)
+    """
+
     def option_directives(): r"""
 Tests of `DocTestRunner`'s option directive mechanism.
 
@@ -1468,7 +1494,7 @@
 def test_trailing_space_in_test():
     """
     Trailing spaces in expcted output are significant:
-    
+
       >>> x, y = 'foo', ''
       >>> print x, y
       foo \n