Skip to content

Make it easy to use Panel with Sphinx-Gallery #5519

@MarcSkovMadsen

Description

@MarcSkovMadsen

In https://discourse.holoviz.org/t/how-to-use-sphinx-gallery-with-panel/6035 pkrull asks for help using Panel with sphinx-gallery.

I think it could be quite powerful to support. It could even be used for the Panel or awesome-panel sites? It builds much faster than the notebooks in Panel !

All it takes to support sphinx-gallery is really a _repr_html_ method on Panel objects. For example something that returns an iframe.

Proof of concept

For example by adding the below to the sphinx conf.py file you will get it working

# Configure sphinx-gallery for panel

import panel as pn
from uuid import uuid4
from io import StringIO
from html import escape
import param

class PanelReprHTML(param.Parameterized):
    max_height=param.Integer(1000, bounds=(0,None))
    embed = param.Boolean(True)

    def __init__(self, object):
        self._object = object

    def _get_html(self):
        out = StringIO()
        self._object.save(out, embed=self.embed)
        out.seek(0)
        return escape(out.read())
    
    def _repr_html_(self):
        html = self._get_html()    
        uid = str(uuid4())       
        return f"""
<script>
function resizeIframe(){{
    setTimeout(() => {{
        var iframe = document.getElementById("{uid}");
        iframe.width = iframe.contentWindow.document.body.scrollWidth + 25;
        iframe.height = Math.min(iframe.contentWindow.document.body.scrollHeight + 10, {self.max_height});
        console.log(iframe.height)
    }}, "100");
    
}}
</script>        
<iframe id="{uid}" srcdoc='{html}' frameBorder='0' onload='resizeIframe(this)'></iframe>
"""

def _repr_html_(self):
    return PanelReprHTML(self)._repr_html_()

def add_repr_html():
    pn.viewable.Viewable._repr_html_=_repr_html_

PanelReprHTML.max_height=600
add_repr_html()

This is how it looks

sphinx-gallery

Repository

A working repository is here https://github.com/MarcSkovMadsen/sphinx-gallery-panel-example

Todo

Some things that could be done to improve things

  • Figure out how to make the resizeIframe more robust. With the Plotly example sometimes the iframe.contentWindow.document.body.scrollHeight is ~500px and sometimes ~1500px. That is why I've introduced the max_height parameter.
  • Enable using either .save or panel convert to pyodide to generate the html
  • Figure out how to use real screenshots of the Panel components in the gallery
  • Add nicer css styling
  • Reset panel before each example https://sphinx-gallery.github.io/stable/advanced.html#resetting-before-each-example
  • Support multiple outputs

Question

How should we support it

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions