A Jupyter Notebook Sphinx reader built on top of the MyST markdown parser.
—
Flexible rendering system supporting multiple output formats with extensible MIME type handling and customizable renderers. The rendering system converts notebook content into various output formats while preserving formatting and interactive elements.
Core renderer class that handles conversion of notebook elements to output formats.
class NbElementRenderer:
"""
Base notebook element renderer.
Provides the foundation for rendering notebook content
to various output formats with extensible MIME type support.
"""
def render_nb_cell_code(self, cell, **kwargs):
"""Render a code cell."""
pass
def render_nb_cell_code_outputs(self, outputs, **kwargs):
"""Render code cell outputs."""
pass
def render_nb_cell_markdown(self, cell, **kwargs):
"""Render a markdown cell."""
passMixin class that adds markdown-it token rendering capabilities.
class MditRenderMixin:
"""
Mixin for markdown-it token rendering.
Provides methods for rendering markdown-it tokens
in the context of notebook processing.
"""
def render_markdown_it_token(self, token, **kwargs):
"""Render a markdown-it token."""
passContainer for MIME type data and associated metadata.
class MimeData:
"""
Container for MIME type data and metadata.
Attributes:
- mime_type: str - MIME type identifier
- data: Any - Content data
- metadata: dict - Associated metadata
"""
mime_type: str
data: Any
metadata: dict
def __init__(self, mime_type: str, data: Any, metadata: dict = None):
"""
Initialize MIME data container.
Parameters:
- mime_type: MIME type string (e.g., 'text/html', 'image/png')
- data: Content data
- metadata: Optional metadata dictionary
"""Factory function for loading and instantiating renderer plugins.
def load_renderer(name: str) -> type[NbElementRenderer]:
"""
Load renderer plugin by name.
Parameters:
- name: str - Renderer plugin name
Returns:
type[NbElementRenderer]: Renderer class
Loads renderer from entry points or built-in renderers.
"""Function for determining MIME type rendering priorities based on output format.
def get_mime_priority(builder_name: str, overrides: dict = None) -> dict:
"""
Get MIME type priorities for a builder.
Parameters:
- builder_name: str - Output builder name (html, latex, etc.)
- overrides: dict - Priority overrides
Returns:
dict: MIME type to priority mapping
"""Example implementation of a MIME renderer plugin for extending functionality.
class ExampleMimeRenderPlugin:
"""
Example MIME renderer plugin.
Demonstrates how to create custom MIME type renderers
for specialized content types.
"""
def render(self, mime_data: MimeData, **kwargs) -> str:
"""
Render MIME data to output format.
Parameters:
- mime_data: MimeData container
- kwargs: Additional rendering options
Returns:
str: Rendered content
"""MyST-NB supports a wide range of MIME types with configurable priorities:
text/plain, text/html, text/markdown, text/lateximage/png, image/jpeg, image/svg+xml, image/gifapplication/javascript, text/htmlapplication/json, text/csvapplication/vnd.jupyter.widget-view+jsonDefault priorities by output format:
# HTML output priorities
html_priorities = {
"application/vnd.jupyter.widget-view+json": 10,
"text/html": 9,
"image/svg+xml": 8,
"image/png": 7,
"image/jpeg": 6,
"text/markdown": 5,
"text/latex": 4,
"text/plain": 3
}
# LaTeX output priorities
latex_priorities = {
"text/latex": 10,
"image/png": 9,
"image/jpeg": 8,
"text/plain": 7,
"text/html": 1 # Low priority for LaTeX
}from myst_nb.core.render import NbElementRenderer, MimeData
class CustomRenderer(NbElementRenderer):
"""Custom renderer with specialized formatting."""
def render_nb_cell_code(self, cell, **kwargs):
"""Custom code cell rendering."""
source = cell.source
return f'<div class="custom-code">{source}</div>'
def render_nb_cell_code_outputs(self, outputs, **kwargs):
"""Custom output rendering."""
rendered = []
for output in outputs:
if output.output_type == "execute_result":
data = output.data
for mime_type, content in data.items():
mime_data = MimeData(mime_type, content)
rendered.append(self.render_mime_data(mime_data))
return "\n".join(rendered)from myst_nb.core.render import MimeData, get_mime_priority
# Create MIME data
mime_data = MimeData(
mime_type="text/html",
data="<h1>Hello World</h1>",
metadata={"width": 500, "height": 300}
)
# Get priorities for HTML output
priorities = get_mime_priority("html")
print(priorities["text/html"]) # 9
# Custom priority overrides
custom_priorities = get_mime_priority("html", {
"image/svg+xml": 15, # Prefer SVG over other formats
"text/html": 5 # Lower HTML priority
})Register custom renderer as a plugin:
# In setup.py or pyproject.toml
entry_points = {
"myst_nb.renderers": [
"custom = mypackage.renderer:CustomRenderer"
]
}
# Load and use custom renderer
from myst_nb.core.render import load_renderer
CustomRenderer = load_renderer("custom")
renderer = CustomRenderer()class MultiFormatRenderer(NbElementRenderer):
"""Renderer that adapts to different output formats."""
def __init__(self, output_format="html"):
self.output_format = output_format
self.mime_priorities = get_mime_priority(output_format)
def render_nb_cell_code_outputs(self, outputs, **kwargs):
"""Format-specific output rendering."""
if self.output_format == "html":
return self._render_html_outputs(outputs)
elif self.output_format == "latex":
return self._render_latex_outputs(outputs)
else:
return self._render_default_outputs(outputs)
def _render_html_outputs(self, outputs):
"""HTML-specific rendering with interactive elements."""
# Implementation for HTML output
pass
def _render_latex_outputs(self, outputs):
"""LaTeX-specific rendering with math support."""
# Implementation for LaTeX output
passdef filter_by_mime_type(outputs, allowed_types):
"""Filter outputs by allowed MIME types."""
filtered = []
for output in outputs:
if hasattr(output, 'data'):
filtered_data = {}
for mime_type, content in output.data.items():
if mime_type in allowed_types:
filtered_data[mime_type] = content
if filtered_data:
output.data = filtered_data
filtered.append(output)
return filtered
# Usage
web_safe_outputs = filter_by_mime_type(outputs, [
"text/html", "text/plain", "image/png", "image/svg+xml"
])class InteractiveRenderer(NbElementRenderer):
"""Renderer with support for interactive content."""
def render_widget(self, widget_data, **kwargs):
"""Render Jupyter widgets."""
if widget_data.mime_type == "application/vnd.jupyter.widget-view+json":
model_id = widget_data.data.get("model_id")
return f'<div class="jupyter-widget" data-model-id="{model_id}"></div>'
def render_javascript(self, js_data, **kwargs):
"""Render JavaScript content."""
if js_data.mime_type == "application/javascript":
return f'<script>{js_data.data}</script>'The rendering system provides the flexibility to customize how notebook content appears in different output formats while maintaining consistency and supporting the full range of Jupyter notebook features.
Install with Tessl CLI
npx tessl i tessl/pypi-myst-nb