Skip to content

Commit b48b260

Browse files
committed
Add the option to open JupyterLite window in new tab
1 parent 86bdf60 commit b48b260

File tree

2 files changed

+80
-0
lines changed

2 files changed

+80
-0
lines changed

docs/directives/jupyterlite.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,18 @@ You can also pass a Notebook file to open automatically:
3636
:prompt_color: #00aa42
3737
```
3838

39+
If you use the `:new_tab:` option in the directive, the Notebook will be opened in a new browser tab.
40+
41+
```rst
42+
.. jupyterlite:: my_notebook.ipynb
43+
:new_tab: True
44+
```
45+
46+
```{eval-rst}
47+
.. jupyterlite:: my_notebook.ipynb
48+
:new_tab: True
49+
```
50+
3951
The directive `search_params` allows to transfer some search parameters from the documentation URL to the Jupyterlite URL.\
4052
Jupyterlite will then be able to fetch these parameters from its own URL.\
4153
For example `:search_params: ["param1", "param2"]` will transfer the parameters *param1* and *param2*.

jupyterlite_sphinx/jupyterlite_sphinx.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,40 @@ def html(self):
106106
f'width="{self["width"]}" height="{self["height"]}" class="jupyterlite_sphinx_raw_iframe"></iframe>'
107107
)
108108

109+
class _InTab(Element):
110+
def __init__(
111+
self,
112+
rawsource="",
113+
*children,
114+
prefix=JUPYTERLITE_DIR,
115+
notebook=None,
116+
lite_options={},
117+
**attributes,
118+
):
119+
app_path = self.lite_app
120+
if notebook is not None:
121+
lite_options["path"] = notebook
122+
app_path = f"{self.lite_app}{self.notebooks_path}"
123+
124+
options = "&".join(
125+
[f"{key}={quote(value)}" for key, value in lite_options.items()]
126+
)
127+
self.lab_src = (
128+
f'{prefix}/{app_path}{f"?{options}" if options else ""}'
129+
)
130+
131+
super().__init__(
132+
"",
133+
**attributes,
134+
)
135+
136+
def html(self):
137+
return (
138+
'<button class="try_examples_button" '
139+
f"onclick=\"window.open('{self.lab_src}')\">"
140+
"Open as a notebook</button>"
141+
)
142+
109143

110144
class _LiteIframe(_PromptedIframe):
111145
def __init__(
@@ -164,6 +198,14 @@ class JupyterLiteIframe(_LiteIframe):
164198
lite_app = "lab/"
165199
notebooks_path = ""
166200

201+
class JupyterLiteTab(_InTab):
202+
"""Appended to the doctree by the JupyterliteDirective directive
203+
204+
Renders a button that opens a Notebook with JupyterLite in a new tab.
205+
"""
206+
207+
lite_app = "lab/"
208+
notebooks_path = ""
167209

168210
class NotebookLiteIframe(_LiteIframe):
169211
"""Appended to the doctree by the NotebookliteDirective directive
@@ -262,6 +304,7 @@ class _LiteDirective(SphinxDirective):
262304
"prompt": directives.unchanged,
263305
"prompt_color": directives.unchanged,
264306
"search_params": directives.unchanged,
307+
"new_tab": directives.unchanged,
265308
}
266309

267310
def run(self):
@@ -273,6 +316,8 @@ def run(self):
273316

274317
search_params = search_params_parser(self.options.pop("search_params", False))
275318

319+
new_tab = self.options.pop("new_tab", False)
320+
276321
source_location = os.path.dirname(self.get_source_info()[0])
277322

278323
prefix = os.path.relpath(
@@ -299,6 +344,20 @@ def run(self):
299344
else:
300345
notebook_name = None
301346

347+
if new_tab:
348+
return [
349+
self.newtab_cls(
350+
prefix=prefix,
351+
notebook=notebook_name,
352+
width=width,
353+
height=height,
354+
prompt=prompt,
355+
prompt_color=prompt_color,
356+
search_params=search_params,
357+
lite_options=self.options,
358+
)
359+
]
360+
302361
return [
303362
self.iframe_cls(
304363
prefix=prefix,
@@ -320,6 +379,7 @@ class JupyterLiteDirective(_LiteDirective):
320379
"""
321380

322381
iframe_cls = JupyterLiteIframe
382+
newtab_cls = JupyterLiteTab
323383

324384

325385
class NotebookLiteDirective(_LiteDirective):
@@ -694,6 +754,14 @@ def setup(app):
694754
text=(skip, None),
695755
man=(skip, None),
696756
)
757+
app.add_node(
758+
JupyterLiteTab,
759+
html=(visit_element_html, None),
760+
latex=(skip, None),
761+
textinfo=(skip, None),
762+
text=(skip, None),
763+
man=(skip, None),
764+
)
697765
app.add_directive("jupyterlite", JupyterLiteDirective)
698766

699767
# Initialize Replite directive

0 commit comments

Comments
 (0)