3030from IPython .utils .traitlets import Unicode , Dict , Bool , TraitError
3131from IPython .utils import tz
3232
33+ def clean_nb (nb ):
34+ """Return a clean copy of the notebook nb with all output removed."""
35+ clean_nb = nb .copy ()
36+
37+ # Strip out all of the output and prompt_number sections
38+ for worksheet in clean_nb ["worksheets" ]:
39+ for cell in worksheet ["cells" ]:
40+ if "outputs" in cell :
41+ del cell .outputs [:]
42+ if "prompt_number" in cell :
43+ del cell ["prompt_number" ]
44+ return clean_nb
45+
3346#-----------------------------------------------------------------------------
3447# Classes
3548#-----------------------------------------------------------------------------
@@ -46,6 +59,13 @@ class FileNotebookManager(NotebookManager):
4659 """
4760 )
4861
62+ save_clean = Bool (False , config = True ,
63+ help = """Save a clean (output removed) version when saving the notebook.
64+
65+ This can also be set with the short `--clean` flag.
66+ """
67+ )
68+
4969 checkpoint_dir = Unicode (config = True ,
5070 help = """The location in which to keep notebook checkpoints
5171
@@ -255,6 +275,16 @@ def save_notebook_model(self, model, name='', path=''):
255275 except Exception as e :
256276 raise web .HTTPError (400 , u'Unexpected error while saving notebook as script: %s %s' % (py_path , e ))
257277
278+ # Save .ipynb.clean as well.
279+ if self .save_clean :
280+ py_path = os_path + '.clean'
281+ self .log .debug ("Writing clean file %s" , py_path )
282+ try :
283+ with io .open (py_path , 'w' , encoding = 'utf-8' ) as f :
284+ current .write (clean_nb (nb ), f , u'ipynb' )
285+ except Exception as e :
286+ raise web .HTTPError (400 , u'Unexpected error while saving clean notebook: %s %s' % (py_path , e ))
287+
258288 model = self .get_notebook_model (new_name , new_path , content = False )
259289 return model
260290
@@ -305,6 +335,12 @@ def rename_notebook(self, old_name, old_path, new_name, new_path):
305335 if os .path .isfile (new_py_path ):
306336 raise web .HTTPError (409 , u'Python script with name already exists: %s' % new_py_path )
307337
338+ if self .save_clean :
339+ old_clean_path = old_os_path + '.clean'
340+ new_clean_path = new_os_path + '.clean'
341+ if os .path .isfile (new_py_path ):
342+ raise web .HTTPError (409 , u'Clean notebook with name already exists: %s' % new_py_path )
343+
308344 # Move the notebook file
309345 try :
310346 os .rename (old_os_path , new_os_path )
@@ -324,6 +360,10 @@ def rename_notebook(self, old_name, old_path, new_name, new_path):
324360 # Move the .py script
325361 if self .save_script :
326362 os .rename (old_py_path , new_py_path )
363+
364+ # Move the .clean file
365+ if self .save_clean :
366+ os .rename (old_clean_path , new_clean_path )
327367
328368 # Checkpoint-related utilities
329369
0 commit comments