Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

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 html, js = create_visual_diff_through_html_files( 

83 args.f1, args.f2, encoding=args.encoding, notebook=True, 

84 context_size=None if args.context in [ 

85 None, ""] else int(args.context), 

86 inline_view=args.inline) 

87 display_html(html) 

88 return js 

89 return None # pragma: no cover 

90 

91 @staticmethod 

92 def strdiff_parser(): 

93 """ 

94 Defines the way to parse the magic command ``%strdiff``. 

95 """ 

96 parser = MagicCommandParser(prog="strdiff", 

97 description='show the differences between two strings') 

98 parser.add_argument('s1', type=str, help='first file or text or url') 

99 parser.add_argument('s2', type=str, help='second file or text or url') 

100 return parser 

101 

102 @line_magic 

103 def strdiff(self, line): 

104 """ 

105 .. nbref:: 

106 :title: %strdiff 

107 :tag: nb 

108 

109 It displays differences between two strings assuming they contains 

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

111 

112 from IPython.core.display import display_html 

113 from pyquickhelper.texthelper.text_diff import html_diffs 

114 html = html_diffs(<s1>, <s2>) 

115 display_html(html) 

116 

117 """ 

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

119 args = self.get_args(line, parser) 

120 

121 if args is not None: 

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

123 return HTML(html) 

124 return None # pragma: no cover 

125 

126 @line_magic 

127 def difftext(self, line): 

128 """ 

129 Defines ``%difftext`` which calls :meth:`textdiff 

130 <pyquickhelper.ipythonhelper.magic_class_diff.MagicDiff.textdiff>`. 

131 but should be easier to remember 

132 """ 

133 return self.textdiff(line) 

134 

135 @staticmethod 

136 def codediff_parser(): 

137 """ 

138 Defines the way to parse the magic command ``%codediff``. 

139 """ 

140 parser = MagicCommandParser(prog="codediff", 

141 description='show the differences between two strings') 

142 parser.add_argument('c1', type=str, help='first file or text or url') 

143 parser.add_argument('c2', type=str, help='second file or text or url') 

144 parser.add_argument( 

145 '--threshold', type=float, default=0.5, 

146 help='two lines can match if the edit ' 

147 'distance is not too big, a low threshold means no match') 

148 parser.add_argument( 

149 '--verbose', type=bool, default=False, 

150 help='display progress if True') 

151 parser.add_argument( 

152 '--two', type=bool, default=False, 

153 help='display on two columns') 

154 return parser 

155 

156 @line_magic 

157 def codediff(self, line): 

158 """ 

159 .. nbref:: 

160 :title: %codediff 

161 :tag: nb 

162 

163 It displays differences between two strings assuming they contains 

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

165 

166 from IPython.core.display import display_html 

167 from pyquickhelper.texthelper.edit_text_diff ( 

168 import edit_distance_text, diff2html) 

169 _, aligned, final = edit_distance_text( 

170 args.c1, args.c2, threshold=args.threshold, 

171 verbose=args.verbose) 

172 ht = diff2html(args.c1, args.c2, aligned, final) 

173 display_html(ht) 

174 

175 """ 

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

177 args = self.get_args(line, parser) 

178 

179 if args is not None: 

180 _, aligned, final = edit_distance_text( # pylint: disable=W0632 

181 args.c1, args.c2, threshold=args.threshold, 

182 verbose=args.verbose) 

183 ht = diff2html(args.c1, args.c2, aligned, 

184 final, two_columns=args.two) 

185 return HTML(ht) 

186 return None # pragma: no cover 

187 

188 

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

190 """ 

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

192 

193 @param ip from ``get_ipython()`` 

194 """ 

195 if ip is None: 

196 from IPython import get_ipython 

197 ip = get_ipython() 

198 ip.register_magics(MagicDiff)