Coverage for pyquickhelper/ipythonhelper/magic_class_diff.py: 98%
64 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-03 02:21 +0200
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-03 02:21 +0200
1# -*- coding: utf-8 -*-
2"""
3@file
4@brief Magic command to handle files
5"""
6from IPython.core.magic import magics_class, line_magic
7from IPython.core.display import display_html, HTML
9from .magic_class import MagicClassWithHelpers
10from .magic_parser import MagicCommandParser
11from ..filehelper import create_visual_diff_through_html_files
12from ..texthelper.text_diff import html_diffs
13from ..texthelper.edit_text_diff import edit_distance_text, diff2html
16@magics_class
17class MagicDiff(MagicClassWithHelpers):
19 """
20 Defines magic commands to visualize differences between files.
21 """
23 @staticmethod
24 def textdiff_parser():
25 """
26 Defines the way to parse the magic command ``%textdiff``.
27 """
28 parser = MagicCommandParser(
29 prog="textdiff",
30 description='show the differences between two files, two text')
31 parser.add_argument('f1', type=str, help='first file or text or url')
32 parser.add_argument('f2', type=str, help='second file or text or url')
33 parser.add_argument(
34 '-c',
35 '--context',
36 default="",
37 help='context view, empty to see everything, > 0 to see '
38 'only a couple of lines around the changes')
39 parser.add_argument(
40 '-i',
41 '--inline',
42 action="store_true",
43 default=False,
44 help='True=one column (inline) or False=two columns')
45 parser.add_argument(
46 '-e',
47 '--encoding',
48 default="utf8",
49 help='file encoding')
50 return parser
52 @line_magic
53 def textdiff(self, line):
54 """
55 .. nbref::
56 :title: %textdiff
57 :tag: nb
59 It displays differences between two text files, two strings, two urls,
60 it is based on :func:`create_visual_diff_through_html_files
61 <pyquickhelper.filehelper.visual_sync.create_visual_diff_through_html_files>`.
62 Check blog post :ref:`Visualize differences between two files in a notebook <b-diffview>`
63 to see an example. See also
64 `A magic command to visualize differences between two files in a notebook
65 <http://www.xavierdupre.fr/app/pyensae/helpsphinx/blog/2015/2015-04-23_textdiff.html>`_.
66 The magic command is equivalent to::
68 from IPython.core.display import display_html, display_javascript
69 from pyquickhelper import docstring2html, create_visual_diff_through_html_files
70 html, js = create_visual_diff_through_html_files(<f1>, <f2>,
71 encoding=<encoding>, notebook=True,
72 context_size=None if <context> in [None, ""] else int(<context>),
73 inline_view=<inline>)
74 display_html(html)
75 display_javascript(js)
77 """
78 parser = self.get_parser(MagicDiff.textdiff_parser, "textdiff")
79 args = self.get_args(line, parser)
81 if args is not None:
82 import IPython.core.display as ipydisplay
83 html, js = create_visual_diff_through_html_files(
84 args.f1, args.f2, encoding=args.encoding, notebook=True,
85 context_size=None if args.context in [
86 None, ""] else int(args.context),
87 inline_view=args.inline)
88 if 'display' not in dir(ipydisplay):
89 # Weird bug introduced in IPython 8.0.0
90 import IPython.core.display_functions
91 ipydisplay.display = IPython.core.display_functions.display
92 display_html(html)
93 return js
94 return None # pragma: no cover
96 @staticmethod
97 def strdiff_parser():
98 """
99 Defines the way to parse the magic command ``%strdiff``.
100 """
101 parser = MagicCommandParser(prog="strdiff",
102 description='show the differences between two strings')
103 parser.add_argument('s1', type=str, help='first file or text or url')
104 parser.add_argument('s2', type=str, help='second file or text or url')
105 return parser
107 @line_magic
108 def strdiff(self, line):
109 """
110 .. nbref::
111 :title: %strdiff
112 :tag: nb
114 It displays differences between two strings assuming they contains
115 multiple lines. The magic command is equivalent to::
117 from IPython.core.display import display_html
118 from pyquickhelper.texthelper.text_diff import html_diffs
119 html = html_diffs(<s1>, <s2>)
120 display_html(html)
122 """
123 parser = self.get_parser(MagicDiff.strdiff_parser, "strdiff")
124 args = self.get_args(line, parser)
126 if args is not None:
127 html = html_diffs(args.s1, args.s2)
128 return HTML(html)
129 return None # pragma: no cover
131 @line_magic
132 def difftext(self, line):
133 """
134 Defines ``%difftext`` which calls :meth:`textdiff
135 <pyquickhelper.ipythonhelper.magic_class_diff.MagicDiff.textdiff>`.
136 but should be easier to remember
137 """
138 return self.textdiff(line)
140 @staticmethod
141 def codediff_parser():
142 """
143 Defines the way to parse the magic command ``%codediff``.
144 """
145 parser = MagicCommandParser(prog="codediff",
146 description='show the differences between two strings')
147 parser.add_argument('c1', type=str, help='first file or text or url')
148 parser.add_argument('c2', type=str, help='second file or text or url')
149 parser.add_argument(
150 '--threshold', type=float, default=0.5,
151 help='two lines can match if the edit '
152 'distance is not too big, a low threshold means no match')
153 parser.add_argument(
154 '--verbose', type=bool, default=False,
155 help='display progress if True')
156 parser.add_argument(
157 '--two', type=bool, default=False,
158 help='display on two columns')
159 return parser
161 @line_magic
162 def codediff(self, line):
163 """
164 .. nbref::
165 :title: %codediff
166 :tag: nb
168 It displays differences between two strings assuming they contains
169 multiple lines. The magic command is equivalent to::
171 from IPython.core.display import display_html
172 from pyquickhelper.texthelper.edit_text_diff (
173 import edit_distance_text, diff2html)
174 _, aligned, final = edit_distance_text(
175 args.c1, args.c2, threshold=args.threshold,
176 verbose=args.verbose)
177 ht = diff2html(args.c1, args.c2, aligned, final)
178 display_html(ht)
180 """
181 parser = self.get_parser(MagicDiff.codediff_parser, "codediff")
182 args = self.get_args(line, parser)
184 if args is not None:
185 _, aligned, final = edit_distance_text( # pylint: disable=W0632
186 args.c1, args.c2, threshold=args.threshold,
187 verbose=args.verbose)
188 ht = diff2html(args.c1, args.c2, aligned,
189 final, two_columns=args.two)
190 return HTML(ht)
191 return None # pragma: no cover
194def register_file_magics(ip=None): # pragma: no cover
195 """
196 Register magics function, can be called from a notebook.
198 @param ip from ``get_ipython()``
199 """
200 if ip is None:
201 from IPython import get_ipython
202 ip = get_ipython()
203 ip.register_magics(MagicDiff)