@@ -264,6 +264,30 @@ def html(self):
264
264
load = '' , widget_views = '' , json_data = json .dumps (self ['state' ]))
265
265
266
266
267
+ class ThebeSourceNode (docutils .nodes .container ):
268
+ """Container that holds the cell source when thebelab is enabled"""
269
+
270
+ def __init__ (self , hide_code ):
271
+ super ().__init__ ('' , hide_code = hide_code )
272
+
273
+ def html (self ):
274
+ code_class = 'thebelab-code'
275
+ if self ['hide_code' ]:
276
+ code_class += ' thebelab-hidden'
277
+ code = self .astext ()
278
+ return f'<pre class="{ code_class } " data-executable="true" data-language="python">{ code } </pre>'
279
+
280
+
281
+ class ThebeOutputNode (docutils .nodes .container ):
282
+ """Container that holds all the output nodes when thebelab is enabled"""
283
+
284
+ def visit_html (self ):
285
+ return '<div class="thebelab-output" data-output="true">'
286
+
287
+ def depart_html (self ):
288
+ return '</div>'
289
+
290
+
267
291
class ThebeButtonNode (docutils .nodes .Element ):
268
292
"""Appended to the doctree by the ThebeButton directive
269
293
@@ -513,32 +537,18 @@ def cell_output_to_nodes(cell, data_priority, dir, thebe_config):
513
537
514
538
def attach_outputs (output_nodes , node , thebe_config ):
515
539
if thebe_config and not node .attributes ['no_thebelab' ]:
516
- code_class = 'thebelab-code'
517
- if node .attributes ['hide_code' ]:
518
- code_class += ' thebelab-hidden'
540
+ source = node .children [0 ]
519
541
520
- code = node .astext ()
542
+ thebe_source = ThebeSourceNode (hide_code = node .attributes ['hide_code' ])
543
+ thebe_source .children = [source ]
521
544
522
- node .children = [docutils .nodes .raw (
523
- text = '<pre class="{code_class}" data-executable="true" data-language="python">' \
524
- '{data}' \
525
- '</pre>' .format (data = code , code_class = code_class ),
526
- format = 'html' ,
527
- )]
545
+ node .children = [thebe_source ]
528
546
529
547
if not node .attributes ['hide_output' ]:
530
548
# We ignore the code_below attribute since this is not supported with thebelab
531
- node .children .append (docutils .nodes .raw (
532
- text = '<div class="thebelab-output" data-output="true">' ,
533
- format = 'html' ,
534
- ))
535
-
536
- node .children += output_nodes
537
-
538
- node .children .append (docutils .nodes .raw (
539
- text = '</div>' ,
540
- format = 'html'
541
- ))
549
+ thebe_output = ThebeOutputNode ()
550
+ thebe_output .children = output_nodes
551
+ node .children .append (thebe_output )
542
552
else :
543
553
if node .attributes ['hide_code' ]:
544
554
node .children = []
@@ -773,6 +783,14 @@ def visit_widget_html(self, node):
773
783
self .body .append (node .html ())
774
784
raise docutils .nodes .SkipNode
775
785
786
+ def visit_container_html (self , node ):
787
+ self .body .append (node .visit_html ())
788
+ self .visit_container (node )
789
+
790
+ def depart_container_html (self , node ):
791
+ self .depart_container (node )
792
+ self .body .append (node .depart_html ())
793
+
776
794
app .add_node (
777
795
JupyterWidgetViewNode ,
778
796
html = (visit_widget_html , None ),
@@ -792,6 +810,24 @@ def visit_widget_html(self, node):
792
810
man = (skip , None ),
793
811
)
794
812
813
+ app .add_node (
814
+ ThebeSourceNode ,
815
+ html = (visit_widget_html , None ),
816
+ latex = render_container ,
817
+ textinfo = render_container ,
818
+ text = render_container ,
819
+ man = render_container ,
820
+ )
821
+
822
+ app .add_node (
823
+ ThebeOutputNode ,
824
+ html = (visit_container_html , depart_container_html ),
825
+ latex = render_container ,
826
+ textinfo = render_container ,
827
+ text = render_container ,
828
+ man = render_container ,
829
+ )
830
+
795
831
app .add_node (
796
832
ThebeButtonNode ,
797
833
html = (visit_widget_html , None ),
0 commit comments