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 Helpers around JSON 

5""" 

6import os 

7import shutil 

8import uuid 

9import json 

10from IPython.display import display_html, display_javascript 

11 

12 

13class RenderJSONRaw: 

14 """ 

15 Renders :epkg:`JSON` in a :epkg:`notebook` 

16 using :epkg:`renderjson`. 

17 """ 

18 

19 def __init__(self, json_data, width="100%", height="100%", divid=None, 

20 show_to_level=None, local=False): 

21 """ 

22 Initialize with a :epkg:`JSON` data. 

23 

24 @param json_data dictionary or string 

25 @param width (str) width 

26 @param height (str) height 

27 @param divid (str|None) id of the div 

28 @param show_to_level (int|None) show first level 

29 @param local (bool|False) use local javascript files 

30 

31 If *local*, local javascript files are copied in the current folder. 

32 """ 

33 if isinstance(json_data, (dict, list)): 

34 self.json_str = json.dumps(json_data) 

35 else: 

36 self.json_str = json 

37 self.uuid = divid if divid else str(uuid.uuid4()) 

38 self.width = width 

39 self.height = height 

40 self.show_to_level = show_to_level 

41 self.local = local 

42 self._copy_local(local) 

43 

44 def _copy_local(self, local): 

45 """ 

46 If *self.local*, copies javascript dependencies in the local folder. 

47 """ 

48 if not self.local: 

49 return 

50 if os.path.exists('renderjson.js'): 

51 # Already done. 

52 return 

53 this = os.path.dirname(__file__) 

54 js = os.path.join(this, '..', 'js', 'renderjson', 'renderjson.js') 

55 if not os.path.exists(js): 

56 raise FileNotFoundError("Unable to find '{0}'".format(js)) 

57 dest = local if isinstance(local, str) else os.getcwd() 

58 shutil.copy(js, dest) 

59 

60 def generate_html(self): 

61 """ 

62 Overloads method 

63 `_ipython_display_ <http://ipython.readthedocs.io/en/stable/config/integrating.html?highlight=Integrating%20>`_. 

64 """ 

65 level = " show_to_level={}".format( 

66 self.show_to_level) if self.show_to_level is not None else '' 

67 ht = '<div id="{}" style="height: {}; width:{};"{}></div>'.format( 

68 self.uuid, self.width, self.height, level) 

69 lib = 'renderjson.js' if self.local else 'https://rawgit.com/caldwell/renderjson/master/renderjson.js' 

70 js = """ 

71 require(["%s"], function() { 

72 document.getElementById('%s').appendChild(renderjson(%s)) 

73 }); """ % (lib, self.uuid, self.json_str) 

74 return ht, js 

75 

76 

77class RenderJSONObj(RenderJSONRaw): 

78 """ 

79 Renders :epkg:`JSON` using :epkg:`javascript`. 

80 """ 

81 

82 def _ipython_display_(self): 

83 ht, js = self.generate_html() 

84 display_html(ht, raw=True) 

85 display_javascript(js, raw=True) 

86 

87 

88class RenderJSON(RenderJSONRaw): 

89 """ 

90 Renders :epkg:`JSON` using :epkg:`javascript`, outputs only :epkg:`HTML`. 

91 """ 

92 

93 def _repr_html_(self): 

94 ht, js = self.generate_html() 

95 ht += "\n<script>\n{0}\n</script>\n".format(js) 

96 return ht 

97 

98 

99def JSONJS(data, only_html=True, show_to_level=None, local=False): 

100 """ 

101 Inspired from `Pretty JSON Formatting in IPython Notebook 

102 <http://stackoverflow.com/questions/18873066/pretty-json-formatting-in-ipython-notebook>`_. 

103 

104 @param data dictionary or json string 

105 @param show_to_level show first level 

106 @param local use local files 

107 @return @see cl RenderJSON 

108 

109 The function uses library 

110 `renderjson <https://github.com/caldwell/renderjson>`_. 

111 It returns an object with overwrite method 

112 `_ipython_display_ <http://ipython.readthedocs.io/en/stable/config/integrating.html?highlight=Integrating%20>`_. 

113 If *local* is true, javascript dependency are copied in the local folder. 

114 

115 .. faqref:: 

116 :title: Persistent javascript in a conververted notebook 

117 

118 After a couple of tries, it appears that it is more efficient to 

119 render the javascript inside a section ``<script>...</script>`` 

120 when the notebook is converted to RST (*only_html=True*). 

121 """ 

122 if only_html: 

123 return RenderJSON(data, show_to_level=show_to_level, local=local) 

124 return RenderJSONObj(data, show_to_level=show_to_level, local=local)