Skip to content

Commit f70e404

Browse files
committed
Added a --clean notebook option to save .clean files w/o output.
- This exactly mimics the behaviour of the --script option and should probably be removed once a method for hooking into the save command is established.
1 parent b1976c9 commit f70e404

File tree

3 files changed

+65
-1
lines changed

3 files changed

+65
-1
lines changed

‎IPython/html/notebookapp.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -236,10 +236,15 @@ def init_handlers(self, settings):
236236
'Auto-save a .py script everytime the .ipynb notebook is saved',
237237
'Do not auto-save .py scripts for every notebook'))
238238

239+
flags.update(boolean_flag('clean', 'FileNotebookManager.save_clean',
240+
'Save a ".clean" (no output) version when the notebook is saved.',
241+
'Do auto-save a ".clean" (no output) version'))
242+
239243
# the flags that are specific to the frontend
240244
# these must be scrubbed before being passed to the kernel,
241245
# or it will raise an error on unrecognized flags
242-
notebook_flags = ['no-browser', 'no-mathjax', 'script', 'no-script']
246+
notebook_flags = ['no-browser', 'no-mathjax', 'script', 'no-script',
247+
'clean', 'no-clean']
243248

244249
aliases = dict(kernel_aliases)
245250

‎IPython/html/services/notebooks/filenbmanager.py

+40
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,19 @@
3030
from IPython.utils.traitlets import Unicode, Dict, Bool, TraitError
3131
from 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

‎IPython/html/services/notebooks/tests/test_nbmanager.py

+19
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,25 @@ def test_save_notebook_with_script(self):
215215
py_path = os.path.join(td, os.path.splitext(name)[0]+'.py')
216216
assert os.path.exists(py_path), py_path
217217

218+
def test_save_notebook_with_clean(self):
219+
with TemporaryDirectory() as td:
220+
# Create a notebook
221+
nm = FileNotebookManager(notebook_dir=td)
222+
nm.save_clean = True
223+
model = nm.create_notebook_model()
224+
name = model['name']
225+
path = model['path']
226+
227+
# Get the model with 'content'
228+
full_model = nm.get_notebook_model(name, path)
229+
230+
# Save the notebook
231+
model = nm.save_notebook_model(full_model, name, path)
232+
233+
# Check that the script was created
234+
py_path = os.path.join(td, name+'.clean')
235+
assert os.path.exists(py_path), py_path
236+
218237
def test_delete_notebook_model(self):
219238
with TemporaryDirectory() as td:
220239
# Test in the root directory

0 commit comments

Comments
 (0)