0
# Rendering
1
2
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.
3
4
## Capabilities
5
6
### Base Element Renderer
7
8
Core renderer class that handles conversion of notebook elements to output formats.
9
10
```python { .api }
11
class NbElementRenderer:
12
"""
13
Base notebook element renderer.
14
15
Provides the foundation for rendering notebook content
16
to various output formats with extensible MIME type support.
17
"""
18
19
def render_nb_cell_code(self, cell, **kwargs):
20
"""Render a code cell."""
21
pass
22
23
def render_nb_cell_code_outputs(self, outputs, **kwargs):
24
"""Render code cell outputs."""
25
pass
26
27
def render_nb_cell_markdown(self, cell, **kwargs):
28
"""Render a markdown cell."""
29
pass
30
```
31
32
### Rendering Mixin
33
34
Mixin class that adds markdown-it token rendering capabilities.
35
36
```python { .api }
37
class MditRenderMixin:
38
"""
39
Mixin for markdown-it token rendering.
40
41
Provides methods for rendering markdown-it tokens
42
in the context of notebook processing.
43
"""
44
45
def render_markdown_it_token(self, token, **kwargs):
46
"""Render a markdown-it token."""
47
pass
48
```
49
50
### MIME Data Container
51
52
Container for MIME type data and associated metadata.
53
54
```python { .api }
55
class MimeData:
56
"""
57
Container for MIME type data and metadata.
58
59
Attributes:
60
- mime_type: str - MIME type identifier
61
- data: Any - Content data
62
- metadata: dict - Associated metadata
63
"""
64
mime_type: str
65
data: Any
66
metadata: dict
67
68
def __init__(self, mime_type: str, data: Any, metadata: dict = None):
69
"""
70
Initialize MIME data container.
71
72
Parameters:
73
- mime_type: MIME type string (e.g., 'text/html', 'image/png')
74
- data: Content data
75
- metadata: Optional metadata dictionary
76
"""
77
```
78
79
### Renderer Loading
80
81
Factory function for loading and instantiating renderer plugins.
82
83
```python { .api }
84
def load_renderer(name: str) -> type[NbElementRenderer]:
85
"""
86
Load renderer plugin by name.
87
88
Parameters:
89
- name: str - Renderer plugin name
90
91
Returns:
92
type[NbElementRenderer]: Renderer class
93
94
Loads renderer from entry points or built-in renderers.
95
"""
96
```
97
98
### MIME Priority Management
99
100
Function for determining MIME type rendering priorities based on output format.
101
102
```python { .api }
103
def get_mime_priority(builder_name: str, overrides: dict = None) -> dict:
104
"""
105
Get MIME type priorities for a builder.
106
107
Parameters:
108
- builder_name: str - Output builder name (html, latex, etc.)
109
- overrides: dict - Priority overrides
110
111
Returns:
112
dict: MIME type to priority mapping
113
"""
114
```
115
116
### Example MIME Renderer Plugin
117
118
Example implementation of a MIME renderer plugin for extending functionality.
119
120
```python { .api }
121
class ExampleMimeRenderPlugin:
122
"""
123
Example MIME renderer plugin.
124
125
Demonstrates how to create custom MIME type renderers
126
for specialized content types.
127
"""
128
129
def render(self, mime_data: MimeData, **kwargs) -> str:
130
"""
131
Render MIME data to output format.
132
133
Parameters:
134
- mime_data: MimeData container
135
- kwargs: Additional rendering options
136
137
Returns:
138
str: Rendered content
139
"""
140
```
141
142
## MIME Type Support
143
144
### Supported MIME Types
145
146
MyST-NB supports a wide range of MIME types with configurable priorities:
147
148
- **Text formats**: `text/plain`, `text/html`, `text/markdown`, `text/latex`
149
- **Images**: `image/png`, `image/jpeg`, `image/svg+xml`, `image/gif`
150
- **Interactive**: `application/javascript`, `text/html`
151
- **Data formats**: `application/json`, `text/csv`
152
- **Specialized**: `application/vnd.jupyter.widget-view+json`
153
154
### MIME Priority Configuration
155
156
Default priorities by output format:
157
158
```python
159
# HTML output priorities
160
html_priorities = {
161
"application/vnd.jupyter.widget-view+json": 10,
162
"text/html": 9,
163
"image/svg+xml": 8,
164
"image/png": 7,
165
"image/jpeg": 6,
166
"text/markdown": 5,
167
"text/latex": 4,
168
"text/plain": 3
169
}
170
171
# LaTeX output priorities
172
latex_priorities = {
173
"text/latex": 10,
174
"image/png": 9,
175
"image/jpeg": 8,
176
"text/plain": 7,
177
"text/html": 1 # Low priority for LaTeX
178
}
179
```
180
181
## Usage Examples
182
183
### Custom Renderer Implementation
184
185
```python
186
from myst_nb.core.render import NbElementRenderer, MimeData
187
188
class CustomRenderer(NbElementRenderer):
189
"""Custom renderer with specialized formatting."""
190
191
def render_nb_cell_code(self, cell, **kwargs):
192
"""Custom code cell rendering."""
193
source = cell.source
194
return f'<div class="custom-code">{source}</div>'
195
196
def render_nb_cell_code_outputs(self, outputs, **kwargs):
197
"""Custom output rendering."""
198
rendered = []
199
for output in outputs:
200
if output.output_type == "execute_result":
201
data = output.data
202
for mime_type, content in data.items():
203
mime_data = MimeData(mime_type, content)
204
rendered.append(self.render_mime_data(mime_data))
205
return "\n".join(rendered)
206
```
207
208
### MIME Data Processing
209
210
```python
211
from myst_nb.core.render import MimeData, get_mime_priority
212
213
# Create MIME data
214
mime_data = MimeData(
215
mime_type="text/html",
216
data="<h1>Hello World</h1>",
217
metadata={"width": 500, "height": 300}
218
)
219
220
# Get priorities for HTML output
221
priorities = get_mime_priority("html")
222
print(priorities["text/html"]) # 9
223
224
# Custom priority overrides
225
custom_priorities = get_mime_priority("html", {
226
"image/svg+xml": 15, # Prefer SVG over other formats
227
"text/html": 5 # Lower HTML priority
228
})
229
```
230
231
### Plugin Registration
232
233
Register custom renderer as a plugin:
234
235
```python
236
# In setup.py or pyproject.toml
237
entry_points = {
238
"myst_nb.renderers": [
239
"custom = mypackage.renderer:CustomRenderer"
240
]
241
}
242
243
# Load and use custom renderer
244
from myst_nb.core.render import load_renderer
245
246
CustomRenderer = load_renderer("custom")
247
renderer = CustomRenderer()
248
```
249
250
### Output Format Specialization
251
252
```python
253
class MultiFormatRenderer(NbElementRenderer):
254
"""Renderer that adapts to different output formats."""
255
256
def __init__(self, output_format="html"):
257
self.output_format = output_format
258
self.mime_priorities = get_mime_priority(output_format)
259
260
def render_nb_cell_code_outputs(self, outputs, **kwargs):
261
"""Format-specific output rendering."""
262
if self.output_format == "html":
263
return self._render_html_outputs(outputs)
264
elif self.output_format == "latex":
265
return self._render_latex_outputs(outputs)
266
else:
267
return self._render_default_outputs(outputs)
268
269
def _render_html_outputs(self, outputs):
270
"""HTML-specific rendering with interactive elements."""
271
# Implementation for HTML output
272
pass
273
274
def _render_latex_outputs(self, outputs):
275
"""LaTeX-specific rendering with math support."""
276
# Implementation for LaTeX output
277
pass
278
```
279
280
### MIME Type Filtering
281
282
```python
283
def filter_by_mime_type(outputs, allowed_types):
284
"""Filter outputs by allowed MIME types."""
285
filtered = []
286
for output in outputs:
287
if hasattr(output, 'data'):
288
filtered_data = {}
289
for mime_type, content in output.data.items():
290
if mime_type in allowed_types:
291
filtered_data[mime_type] = content
292
if filtered_data:
293
output.data = filtered_data
294
filtered.append(output)
295
return filtered
296
297
# Usage
298
web_safe_outputs = filter_by_mime_type(outputs, [
299
"text/html", "text/plain", "image/png", "image/svg+xml"
300
])
301
```
302
303
### Interactive Content Handling
304
305
```python
306
class InteractiveRenderer(NbElementRenderer):
307
"""Renderer with support for interactive content."""
308
309
def render_widget(self, widget_data, **kwargs):
310
"""Render Jupyter widgets."""
311
if widget_data.mime_type == "application/vnd.jupyter.widget-view+json":
312
model_id = widget_data.data.get("model_id")
313
return f'<div class="jupyter-widget" data-model-id="{model_id}"></div>'
314
315
def render_javascript(self, js_data, **kwargs):
316
"""Render JavaScript content."""
317
if js_data.mime_type == "application/javascript":
318
return f'<script>{js_data.data}</script>'
319
```
320
321
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.