Contents

transclusion of data with jinja2/templates

    import pidgy.base, jinja2.meta, IPython, sys, traitlets, functools
import pidgy.base, jinja2.meta, IPython, sys, traitlets, functools
    minify = lambda x: __import__('htmlmin').minify(x, False, True, True, True, True, True, True)
minify = lambda x: __import__('htmlmin').minify(x, False, True, True, True, True, True, True)
    def active_types(shell=None):
        shell = shell or IPython.get_ipython()
        if shell:
            object = list(shell.display_formatter.active_types)
            object.insert(object.index('text/html'), object.pop(object.index('text/latex')))
            return reversed(object)
        return []
def active_types(shell=None):
    shell = shell or IPython.get_ipython()
    if shell:
        object = list(shell.display_formatter.active_types)
        object.insert(object.index('text/html'), object.pop(object.index('text/latex')))
        return reversed(object)
    return []
    def environment(shell=None):        
        environment = __import__('nbconvert').exporters.TemplateExporter().environment
        environment.loader.loaders.append(jinja2.FileSystemLoader('.'))
        environment.display_manager = DisplayManager()
        environment.finalize = Finalize(parent=shell or IPython.get_ipython())
        return environment
def environment(shell=None):        
    environment = __import__('nbconvert').exporters.TemplateExporter().environment
    environment.loader.loaders.append(jinja2.FileSystemLoader('.'))
    environment.display_manager = DisplayManager()
    environment.finalize = Finalize(parent=shell or IPython.get_ipython())
    return environment
    class MarkdownDisplay(pidgy.base.Display):
        body = traitlets.Unicode()
        
        vars = traitlets.Set()
        template = traitlets.Any()
        _display = traitlets.Any()
        @traitlets.default('template')
        def _default_template(self):
            return self.environment.from_string(self.body)
        @traitlets.default('vars')
        def _default_vars(self):
            return jinja2.meta.find_undeclared_variables(self.template.environment.parse(self.body))
            
        def render(self, **kwargs):
            return IPython.display.Markdown(self.template.render(**kwargs))
class MarkdownDisplay(pidgy.base.Display):
    body = traitlets.Unicode()
    
    vars = traitlets.Set()
    template = traitlets.Any()
    _display = traitlets.Any()
    @traitlets.default('template')
    def _default_template(self):
        return self.environment.from_string(self.body)
    @traitlets.default('vars')
    def _default_vars(self):
        return jinja2.meta.find_undeclared_variables(self.template.environment.parse(self.body))
        
    def render(self, **kwargs):
        return IPython.display.Markdown(self.template.render(**kwargs))
    class DisplayManager(pidgy.base.Trait):
        display = traitlets.Dict()
        state = traitlets.Dict()
        widgets = traitlets.List()
        def pre_execute(self):
                deleted = getattr(self.parent, '_last_parent', {}).get('metadata', {}).get('deletedCells', [])
                for key, displays in self.display.items() if deleted else []:
                    self.display[key] = [
                        x for x in displays if x._display and x._display.display_id not in deleted
                    ]
                
        def append(self, object):
            for key in object.vars:
                self.display[key] = self.display.get(key, [])
                self.display[key].append(object)
                self.state[key] = self.parent.user_ns.get(key, None)
                
        def pop(self, object):
            for key, values in self.display.items():
                self.display[key] = [x for x in values if x is not object]                
        
        def _post_execute_widget(self, object, change):
            with object.hold_trait_notifications():
                self.post_execute()
                
        def post_execute(self):
            if not self.enabled: return
            update = {
                x: self.parent.user_ns.get(x, None) for x in self.display 
                if isinteractive(self.parent.user_ns.get(x, None)) or
                self.parent.user_ns.get(x, None) is not self.state.get(x, None)
            }
            for key, object in update.items():
                if isinteractive(object) and object not in self.widgets:
                    object.observe(functools.partial(self._post_execute_widget, object))
                    self.widgets += [object]
            self.state.update(update)
            for object in set(
                sum([self.display[x] for x in update], [])
            ): 
                try:
                    object.update(**self.state)
                except Exception as e: 
                    self.pop(object)
                    sys.stderr.writelines(str(self.state))
                    sys.stderr.writelines(str(e).splitlines())
class DisplayManager(pidgy.base.Trait):
    display = traitlets.Dict()
    state = traitlets.Dict()
    widgets = traitlets.List()
    def pre_execute(self):
            deleted = getattr(self.parent, '_last_parent', {}).get('metadata', {}).get('deletedCells', [])
            for key, displays in self.display.items() if deleted else []:
                self.display[key] = [
                    x for x in displays if x._display and x._display.display_id not in deleted
                ]
            
    def append(self, object):
        for key in object.vars:
            self.display[key] = self.display.get(key, [])
            self.display[key].append(object)
            self.state[key] = self.parent.user_ns.get(key, None)
            
    def pop(self, object):
        for key, values in self.display.items():
            self.display[key] = [x for x in values if x is not object]                
    
    def _post_execute_widget(self, object, change):
        with object.hold_trait_notifications():
            self.post_execute()
            
    def post_execute(self):
        if not self.enabled: return
        update = {
            x: self.parent.user_ns.get(x, None) for x in self.display 
            if isinteractive(self.parent.user_ns.get(x, None)) or
            self.parent.user_ns.get(x, None) is not self.state.get(x, None)
        }
        for key, object in update.items():
            if isinteractive(object) and object not in self.widgets:
                object.observe(functools.partial(self._post_execute_widget, object))
                self.widgets += [object]
        self.state.update(update)
        for object in set(
            sum([self.display[x] for x in update], [])
        ): 
            try:
                object.update(**self.state)
            except Exception as e: 
                self.pop(object)
                sys.stderr.writelines(str(self.state))
                sys.stderr.writelines(str(e).splitlines())
    class Finalize(pidgy.base.Trait):
        def normalize(self, key, object, metadata):            
            if key.startswith('image'):
                if 'svg' in key: return minify(object)
                width, height = metadata.get(key, {}).get('width'), metadata.get(key, {}).get('height')
                if isinstance(object, bytes):
                    object = __import__('base64').b64encode(object).decode('utf-8')
                object = F"""<img src="data:image/{key.partition('/')[2]};base64,{object}"/>"""
            if key == 'text/html': object = minify(object)
            return object
        
        def __call__(self, object):
            datum = self.parent.display_formatter.format(object)
            data, metadata = datum if isinstance(datum, tuple) else (datum, {})
            try: key = next(filter(data.__contains__, active_types(self.parent)))
            except StopIteration: return str(object)
            if key == 'text/plain': return str(object)
            return self.normalize(key, data[key], metadata)
class Finalize(pidgy.base.Trait):
    def normalize(self, key, object, metadata):            
        if key.startswith('image'):
            if 'svg' in key: return minify(object)
            width, height = metadata.get(key, {}).get('width'), metadata.get(key, {}).get('height')
            if isinstance(object, bytes):
                object = __import__('base64').b64encode(object).decode('utf-8')
            object = F"""<img src="data:image/{key.partition('/')[2]};base64,{object}"/>"""
        if key == 'text/html': object = minify(object)
        return object
    
    def __call__(self, object):
        datum = self.parent.display_formatter.format(object)
        data, metadata = datum if isinstance(datum, tuple) else (datum, {})
        try: key = next(filter(data.__contains__, active_types(self.parent)))
        except StopIteration: return str(object)
        if key == 'text/plain': return str(object)
        return self.normalize(key, data[key], metadata)
    def iswidget(object):
        if 'ipywidgets' in sys.modules:
            if isinstance(object, __import__('ipywidgets').Widget):
                return True
        return False

    def ispanel(object):
        if 'param' in sys.modules:
            if isinstance(object, __import__('param').Parameterized):
                return True
        return False

    def isinteractive(object):
        return iswidget(object) | ispanel(object)
def iswidget(object):
    if 'ipywidgets' in sys.modules:
        if isinstance(object, __import__('ipywidgets').Widget):
            return True
    return False

def ispanel(object):
    if 'param' in sys.modules:
        if isinstance(object, __import__('param').Parameterized):
            return True
    return False

def isinteractive(object):
    return iswidget(object) | ispanel(object)