This Notebook is an attempt to make a downgrader for IPython Notebooks written using IPython 3.0 dev to Notebooks that run under version 2.3 of IPython. It has worked on my test cases but I make no guarantee that it will work. The original notebook remains intact and the name of the downgraded version has "_downgraded" added to it which may be a problem on Windows in a deeply nested directory if the total path exceeds 256 characters.
import json
from collections import namedtuple
import re
def cell_downgrade(cell, language):
"Attempts to convert a dev 3 cell to version 2.3"
d_graded = {} # create downgraded cell dictionary
source = cell['source']
if cell['cell_type'] != "code":
# Check to see if it should be a heading
if cell['cell_type'] == "markdown":
try:
pat = re.compile('#+')
line = source[0]
result = pat.match(line)
if result != None:
level = result.span()[1]
line = line[level:]
line = line.strip()
if len(source)==1:
d_graded['cell_type'] = "heading"
d_graded['level'] = level
source[0] = line
d_graded['metadata'] = {}
else:
d_graded['cell_type'] = "markdown"
else:
d_graded['cell_type'] = "markdown"
except:
d_graded['cell_type'] = "markdown"
else:
d_graded['cell_type'] = cell['cell_type']
d_graded['source'] = source
else:
d_graded['cell_type'] = "code"
d_graded['input'] = source
d_graded['language'] = language
outputs = []
try:
for output in cell['outputs']:
out_dict = {}
for key, item in output.items():
if key == 'name':
out_dict['stream'] = item
else:
out_dict[key] = item
outputs.append(out_dict)
d_graded['outputs'] = outputs
except:
pass
try:
if cell['execution_count'] != None:
prompt = cell['execution_count']
d_graded['prompt_number'] = prompt
except:
pass
# Convert cell metadata
try:
m_data = {}
for key, item in cell['metadata'].items():
if key == 'collapsed':
# Headings do not have a value for 'collapsed'
if d_graded['cell_type'] != "heading":
d_graded[key] = item
continue
else:
m_data[key] = item
d_graded['metadata'] = m_data
except:
print("Error with cell metadata:")
key = 'metadata'
m_data = cell.__getitem__(key) if cell.__contains__(key) else None
print(m_data)
pass
return d_graded
def meta_downgrade(metadata):
d_meta = {}
d_meta['signature'] = metadata['signature']
try:
d_meta['celltoolbar'] = metadata['celltoolbar']
except:
pass
d_meta['name'] = ''
language = metadata['language_info']['name']
Meta = namedtuple('Meta','metadata language')
output = Meta(d_meta,language)
return output
def downgrade(notebook):
d_grade = {}
d_grade['nbformat'] = 3
d_grade['nbformat_minor'] = notebook['nbformat_minor']
m_d_grade = meta_downgrade(notebook['metadata'])
d_grade['metadata'] = m_d_grade.metadata
language = m_d_grade.language
cells = []
for cell in notebook['cells']:
d_cell = cell_downgrade(cell,language)
cells.append(d_cell)
d_grade['worksheets'] = [{'cells':cells, 'metadata':{}}]
return d_grade
def convert2old(filename):
"Trys to convert a Dev 3 version of an IPython Notebook to version 2.3"
with open(filename,'r') as f:
json_data = json.load(f)
d_graded = downgrade(json_data)
name = filename.strip('.ipynb')
outputname = name + "_downgraded.ipynb"
# print(pr.pformat(d_graded))
with open(outputname,'w') as f:
json.dump(d_graded, f, indent=1, sort_keys=True)
print("Downgrade complete.")
convert2old("EMPTY_3.ipynb")
# convert2old("Examples.ipynb")
Downgrade complete.