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

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 

8 

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 

14 

15 

16@magics_class 

17class MagicDiff(MagicClassWithHelpers): 

18 

19 """ 

20 Defines magic commands to visualize differences between files. 

21 """ 

22 

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 

51 

52 @line_magic 

53 def textdiff(self, line): 

54 """ 

55 .. nbref:: 

56 :title: %textdiff 

57 :tag: nb 

58 

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:: 

67 

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) 

76 

77 """ 

78 parser = self.get_parser(MagicDiff.textdiff_parser, "textdiff") 

79 args = self.get_args(line, parser) 

80 

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 

95 

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 

106 

107 @line_magic 

108 def strdiff(self, line): 

109 """ 

110 .. nbref:: 

111 :title: %strdiff 

112 :tag: nb 

113 

114 It displays differences between two strings assuming they contains 

115 multiple lines. The magic command is equivalent to:: 

116 

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) 

121 

122 """ 

123 parser = self.get_parser(MagicDiff.strdiff_parser, "strdiff") 

124 args = self.get_args(line, parser) 

125 

126 if args is not None: 

127 html = html_diffs(args.s1, args.s2) 

128 return HTML(html) 

129 return None # pragma: no cover 

130 

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) 

139 

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 

160 

161 @line_magic 

162 def codediff(self, line): 

163 """ 

164 .. nbref:: 

165 :title: %codediff 

166 :tag: nb 

167 

168 It displays differences between two strings assuming they contains 

169 multiple lines. The magic command is equivalent to:: 

170 

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) 

179 

180 """ 

181 parser = self.get_parser(MagicDiff.codediff_parser, "codediff") 

182 args = self.get_args(line, parser) 

183 

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 

192 

193 

194def register_file_magics(ip=None): # pragma: no cover 

195 """ 

196 Register magics function, can be called from a notebook. 

197 

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)