749
749
"""
750
750
751
751
752
+ class Writer (nbconvert .preprocessors .Preprocessor ):
753
+ def preprocess (self , nb , resources ):
754
+ if 'nbsphinx_save_notebook' in resources :
755
+ # Save *executed* notebook *before* the Exporter can change it:
756
+ nbformat .write (nb , resources ['nbsphinx_save_notebook' ])
757
+ return nb , resources
758
+
752
759
class Exporter (nbconvert .RSTExporter ):
753
760
"""Convert Jupyter notebooks to reStructuredText.
754
761
@@ -760,8 +767,6 @@ class Exporter(nbconvert.RSTExporter):
760
767
761
768
"""
762
769
763
- # TODO: define default preprocessors to include our one to write out notebook just after execution
764
-
765
770
def __init__ (self , execute = 'auto' , kernel_name = '' , execute_arguments = [],
766
771
allow_errors = False , timeout = None , codecell_lexer = 'none' ,
767
772
nbconvert_config = None ):
@@ -804,7 +809,6 @@ def replace_attachments(text):
804
809
# Work around https://github.com/jupyter/nbconvert/issues/720:
805
810
'RegexRemovePreprocessor' : {'enabled' : False },
806
811
}
807
-
808
812
super (Exporter , self ).__init__ (
809
813
template_file = 'nbsphinx-rst.tpl' , extra_loaders = [loader ],
810
814
config = traitlets .config .Config (nbconvert_config ),
@@ -848,23 +852,29 @@ def from_notebook_node(self, nb, resources=None, **kw):
848
852
not any (c .get ('outputs' ) or c .get ('execution_count' )
849
853
for c in nb .cells if c .cell_type == 'code' )
850
854
)
855
+ preprocessors = []
851
856
if auto_execute or execute == 'always' :
852
857
allow_errors = nbsphinx_metadata .get (
853
858
'allow_errors' , self ._allow_errors )
854
859
timeout = nbsphinx_metadata .get ('timeout' , self ._timeout )
855
- # TODO: Here, just add the execute preprocessor to the exporter list of preprocessors
856
- # rather than executing directly. We can still pass appropriate config values in
857
- # and that way the tag remove preprocessor is run *before* execution rather than after.
858
- pp = nbconvert .preprocessors .ExecutePreprocessor (
860
+ preprocessors .append (nbconvert .preprocessors .ExecutePreprocessor (
859
861
kernel_name = self ._kernel_name ,
860
862
extra_arguments = self ._execute_arguments ,
861
- allow_errors = allow_errors , timeout = timeout )
862
- nb , resources = pp .preprocess (nb , resources )
863
-
864
- if 'nbsphinx_save_notebook' in resources :
865
- # TODO: maybe we write our *own* preprocessor to hook into this stage, right after the execute preprocessor, to save the notebook
866
- # Save *executed* notebook *before* the Exporter can change it:
867
- nbformat .write (nb , resources ['nbsphinx_save_notebook' ])
863
+ allow_errors = allow_errors , timeout = timeout ))
864
+ # pp = nbconvert.preprocessors.ExecutePreprocessor(
865
+ # kernel_name=self._kernel_name,
866
+ # extra_arguments=self._execute_arguments,
867
+ # allow_errors=allow_errors, timeout=timeout)
868
+ # nb, resources = pp.preprocess(nb, resources)
869
+
870
+ # if 'nbsphinx_save_notebook' in resources:
871
+ # # Save *executed* notebook *before* the Exporter can change it:
872
+ # nbformat.write(nb, resources['nbsphinx_save_notebook'])
873
+
874
+ preprocessors .append (Writer ())
875
+ # Find the existing execute preprocessor and replace it
876
+ i = next ((i for i ,p in enumerate (self ._preprocessors ) if isinstance (p , nbconvert .preprocessors .ExecutePreprocessor )), len (self ._preprocessors ))
877
+ self ._preprocessors [i :i + 1 ] = preprocessors
868
878
869
879
# Call into RSTExporter
870
880
rststr , resources = super (Exporter , self ).from_notebook_node (
0 commit comments