Source code for jyquickhelper.jspy.render_nb_json

# -*- coding: utf-8 -*-
"""
Helpers around JSON


:githublink:`%|py|6`
"""
import os
import shutil
import uuid
import json
from IPython.display import display_html, display_javascript


[docs]class RenderJSONRaw: """ Renders :epkg:`JSON` in a :epkg:`notebook` using :epkg:`renderjson`. :githublink:`%|py|17` """
[docs] def __init__(self, json_data, width="100%", height="100%", divid=None, show_to_level=None, local=False): """ Initialize with a :epkg:`JSON` data. :param json_data: dictionary or string :param width: (str) width :param height: (str) height :param divid: (str|None) id of the div :param show_to_level: (int|None) show first level :param local: (bool|False) use local javascript files If *local*, local javascript files are copied in the current folder. :githublink:`%|py|32` """ if isinstance(json_data, (dict, list)): self.json_str = json.dumps(json_data) else: self.json_str = json self.uuid = divid if divid else str(uuid.uuid4()) self.width = width self.height = height self.show_to_level = show_to_level self.local = local self._copy_local(local)
[docs] def _copy_local(self, local): """ If *self.local*, copies javascript dependencies in the local folder. :githublink:`%|py|47` """ if not self.local: return if os.path.exists('renderjson.js'): # Already done. return this = os.path.dirname(__file__) js = os.path.join(this, '..', 'js', 'renderjson', 'renderjson.js') if not os.path.exists(js): raise FileNotFoundError("Unable to find '{0}'".format(js)) dest = local if isinstance(local, str) else os.getcwd() shutil.copy(js, dest)
[docs] def generate_html(self): """ Overloads method `_ipython_display_ <http://ipython.readthedocs.io/en/stable/config/integrating.html?highlight=Integrating%20>`_. :githublink:`%|py|64` """ level = " show_to_level={}".format( self.show_to_level) if self.show_to_level is not None else '' ht = '<div id="{}" style="height: {}; width:{};"{}></div>'.format( self.uuid, self.width, self.height, level) lib = 'renderjson.js' if self.local else 'https://rawgit.com/caldwell/renderjson/master/renderjson.js' js = """ require(["%s"], function() { document.getElementById('%s').appendChild(renderjson(%s)) }); """ % (lib, self.uuid, self.json_str) return ht, js
[docs]class RenderJSONObj(RenderJSONRaw): """ Renders :epkg:`JSON` using :epkg:`javascript`. :githublink:`%|py|80` """
[docs] def _ipython_display_(self): ht, js = self.generate_html() display_html(ht, raw=True) display_javascript(js, raw=True)
[docs]class RenderJSON(RenderJSONRaw): """ Renders :epkg:`JSON` using :epkg:`javascript`, outputs only :epkg:`HTML`. :githublink:`%|py|91` """
[docs] def _repr_html_(self): ht, js = self.generate_html() ht += "\n<script>\n{0}\n</script>\n".format(js) return ht
[docs]def JSONJS(data, only_html=True, show_to_level=None, local=False): """ Inspired from `Pretty JSON Formatting in IPython Notebook <http://stackoverflow.com/questions/18873066/pretty-json-formatting-in-ipython-notebook>`_. :param data: dictionary or json string :param show_to_level: show first level :param local: use local files :return: :class:`RenderJSON <jyquickhelper.jspy.render_nb_json.RenderJSON>` The function uses library `renderjson <https://github.com/caldwell/renderjson>`_. It returns an object with overwrite method `_ipython_display_ <http://ipython.readthedocs.io/en/stable/config/integrating.html?highlight=Integrating%20>`_. If *local* is true, javascript dependency are copied in the local folder. .. faqref:: :title: Persistent javascript in a conververted notebook After a couple of tries, it appears that it is more efficient to render the javascript inside a section ``<script>...</script>`` when the notebook is converted to RST (*only_html=True*). :githublink:`%|py|121` """ if only_html: return RenderJSON(data, show_to_level=show_to_level, local=local) return RenderJSONObj(data, show_to_level=show_to_level, local=local)