@@ -109,6 +109,39 @@ def html(self):
109109 )
110110
111111
112+ class _InTab (Element ):
113+ def __init__ (
114+ self ,
115+ rawsource = "" ,
116+ * children ,
117+ prefix = JUPYTERLITE_DIR ,
118+ notebook = None ,
119+ lite_options = {},
120+ ** attributes ,
121+ ):
122+ app_path = self .lite_app
123+ if notebook is not None :
124+ lite_options ["path" ] = notebook
125+ app_path = f"{ self .lite_app } { self .notebooks_path } "
126+
127+ options = "&" .join (
128+ [f"{ key } ={ quote (value )} " for key , value in lite_options .items ()]
129+ )
130+ self .lab_src = f'{ prefix } /{ app_path } { f"?{ options } " if options else "" } '
131+
132+ super ().__init__ (
133+ rawsource ,
134+ ** attributes ,
135+ )
136+
137+ def html (self ):
138+ return (
139+ '<button class="try_examples_button" '
140+ f"onclick=\" window.open('{ self .lab_src } ')\" >"
141+ "Open as a notebook</button>"
142+ )
143+
144+
112145class _LiteIframe (_PromptedIframe ):
113146 def __init__ (
114147 self ,
@@ -167,6 +200,16 @@ class JupyterLiteIframe(_LiteIframe):
167200 notebooks_path = ""
168201
169202
203+ class JupyterLiteTab (_InTab ):
204+ """Appended to the doctree by the JupyterliteDirective directive
205+
206+ Renders a button that opens a Notebook with JupyterLite in a new tab.
207+ """
208+
209+ lite_app = "lab/"
210+ notebooks_path = ""
211+
212+
170213class NotebookLiteIframe (_LiteIframe ):
171214 """Appended to the doctree by the NotebookliteDirective directive
172215
@@ -264,6 +307,7 @@ class _LiteDirective(SphinxDirective):
264307 "prompt" : directives .unchanged ,
265308 "prompt_color" : directives .unchanged ,
266309 "search_params" : directives .unchanged ,
310+ "new_tab" : directives .unchanged ,
267311 }
268312
269313 def run (self ):
@@ -275,6 +319,8 @@ def run(self):
275319
276320 search_params = search_params_parser (self .options .pop ("search_params" , False ))
277321
322+ new_tab = self .options .pop ("new_tab" , False )
323+
278324 source_location = os .path .dirname (self .get_source_info ()[0 ])
279325
280326 prefix = os .path .relpath (
@@ -301,6 +347,20 @@ def run(self):
301347 else :
302348 notebook_name = None
303349
350+ if new_tab :
351+ return [
352+ self .newtab_cls (
353+ prefix = prefix ,
354+ notebook = notebook_name ,
355+ width = width ,
356+ height = height ,
357+ prompt = prompt ,
358+ prompt_color = prompt_color ,
359+ search_params = search_params ,
360+ lite_options = self .options ,
361+ )
362+ ]
363+
304364 return [
305365 self .iframe_cls (
306366 prefix = prefix ,
@@ -322,6 +382,7 @@ class JupyterLiteDirective(_LiteDirective):
322382 """
323383
324384 iframe_cls = JupyterLiteIframe
385+ newtab_cls = JupyterLiteTab
325386
326387
327388class NotebookLiteDirective (_LiteDirective ):
@@ -721,6 +782,14 @@ def setup(app):
721782 text = (skip , None ),
722783 man = (skip , None ),
723784 )
785+ app .add_node (
786+ JupyterLiteTab ,
787+ html = (visit_element_html , None ),
788+ latex = (skip , None ),
789+ textinfo = (skip , None ),
790+ text = (skip , None ),
791+ man = (skip , None ),
792+ )
724793 app .add_directive ("jupyterlite" , JupyterLiteDirective )
725794
726795 # Initialize Replite directive
0 commit comments