##// END OF EJS Templates
Added a notebook dirty flag that is used when exiting page.
Added a notebook dirty flag that is used when exiting page.

File last commit:

r4540:36699623
r4550:fb55a882
Show More
nbxml.py
228 lines | 9.0 KiB | text/x-python | PythonLexer
"""Read and write notebook files as XML."""
from base64 import encodestring, decodestring
from xml.etree import ElementTree as ET
from .rwbase import NotebookReader, NotebookWriter
from .nbbase import (
new_code_cell, new_text_cell, new_worksheet, new_notebook, new_output
)
def indent(elem, level=0):
i = "\n" + level*" "
if len(elem):
if not elem.text or not elem.text.strip():
elem.text = i + " "
if not elem.tail or not elem.tail.strip():
elem.tail = i
for elem in elem:
indent(elem, level+1)
if not elem.tail or not elem.tail.strip():
elem.tail = i
else:
if level and (not elem.tail or not elem.tail.strip()):
elem.tail = i
def _get_text(e, tag):
sub_e = e.find(tag)
if sub_e is None:
return None
else:
return sub_e.text
def _set_text(nbnode, attr, parent, tag):
if attr in nbnode:
e = ET.SubElement(parent, tag)
e.text = nbnode[attr]
def _get_int(e, tag):
sub_e = e.find(tag)
if sub_e is None:
return None
else:
return int(sub_e.text)
def _set_int(nbnode, attr, parent, tag):
if attr in nbnode:
e = ET.SubElement(parent, tag)
e.text = unicode(nbnode[attr])
def _get_bool(e, tag):
sub_e = e.find(tag)
if sub_e is None:
return None
else:
return bool(int(sub_e.text))
def _set_bool(nbnode, attr, parent, tag):
if attr in nbnode:
e = ET.SubElement(parent, tag)
if nbnode[attr]:
e.text = u'1'
else:
e.text = u'0'
def _get_binary(e, tag):
sub_e = e.find(tag)
if sub_e is None:
return None
else:
return decodestring(sub_e.text)
def _set_binary(nbnode, attr, parent, tag):
if attr in nbnode:
e = ET.SubElement(parent, tag)
e.text = encodestring(nbnode[attr])
class XMLReader(NotebookReader):
def reads(self, s, **kwargs):
root = ET.fromstring(s)
return self.to_notebook(root, **kwargs)
def to_notebook(self, root, **kwargs):
nbname = _get_text(root,u'name')
nbid = _get_text(root,u'id')
nbauthor = _get_text(root,u'author')
nbemail = _get_text(root,u'email')
nblicense = _get_text(root,u'license')
nbcreated = _get_text(root,u'created')
nbsaved = _get_text(root,u'saved')
worksheets = []
for ws_e in root.find(u'worksheets').getiterator(u'worksheet'):
wsname = _get_text(ws_e,u'name')
cells = []
for cell_e in ws_e.find(u'cells').getiterator():
if cell_e.tag == u'codecell':
input = _get_text(cell_e,u'input')
prompt_number = _get_int(cell_e,u'prompt_number')
collapsed = _get_bool(cell_e,u'collapsed')
language = _get_text(cell_e,u'language')
outputs = []
for output_e in cell_e.find(u'outputs').getiterator(u'output'):
output_type = _get_text(output_e,u'output_type')
output_text = _get_text(output_e,u'text')
output_png = _get_binary(output_e,u'png')
output_jpeg = _get_binary(output_e,u'jpeg')
output_svg = _get_text(output_e,u'svg')
output_html = _get_text(output_e,u'html')
output_latex = _get_text(output_e,u'latex')
output_json = _get_text(output_e,u'json')
output_javascript = _get_text(output_e,u'javascript')
out_prompt_number = _get_int(output_e,u'prompt_number')
etype = _get_text(output_e,u'etype')
evalue = _get_text(output_e,u'evalue')
traceback = []
traceback_e = output_e.find(u'traceback')
if traceback_e is not None:
for frame_e in traceback_e.getiterator(u'frame'):
traceback.append(frame_e.text)
if len(traceback) == 0:
traceback = None
output = new_output(output_type=output_type,output_png=output_png,
output_text=output_text, output_svg=output_svg,
output_html=output_html, output_latex=output_latex,
output_json=output_json, output_javascript=output_javascript,
output_jpeg=output_jpeg, prompt_number=out_prompt_number,
etype=etype, evalue=evalue, traceback=traceback
)
outputs.append(output)
cc = new_code_cell(input=input,prompt_number=prompt_number,
language=language,outputs=outputs,collapsed=collapsed)
cells.append(cc)
if cell_e.tag == u'htmlcell':
source = _get_text(cell_e,u'source')
rendered = _get_text(cell_e,u'rendered')
cells.append(new_text_cell(u'html', source=source, rendered=rendered))
if cell_e.tag == u'markdowncell':
source = _get_text(cell_e,u'source')
rendered = _get_text(cell_e,u'rendered')
cells.append(new_text_cell(u'markdown', source=source, rendered=rendered))
ws = new_worksheet(name=wsname,cells=cells)
worksheets.append(ws)
nb = new_notebook(name=nbname,id=nbid,worksheets=worksheets,author=nbauthor,
email=nbemail,license=nblicense,saved=nbsaved,created=nbcreated)
return nb
class XMLWriter(NotebookWriter):
def writes(self, nb, **kwargs):
nb_e = ET.Element(u'notebook')
_set_text(nb,u'name',nb_e,u'name')
_set_text(nb,u'id',nb_e,u'id')
_set_text(nb,u'author',nb_e,u'author')
_set_text(nb,u'email',nb_e,u'email')
_set_text(nb,u'license',nb_e,u'license')
_set_text(nb,u'created',nb_e,u'created')
_set_text(nb,u'saved',nb_e,u'saved')
_set_int(nb,u'nbformat',nb_e,u'nbformat')
wss_e = ET.SubElement(nb_e,u'worksheets')
for ws in nb.worksheets:
ws_e = ET.SubElement(wss_e, u'worksheet')
_set_text(ws,u'name',ws_e,u'name')
cells_e = ET.SubElement(ws_e,u'cells')
for cell in ws.cells:
cell_type = cell.cell_type
if cell_type == u'code':
cell_e = ET.SubElement(cells_e, u'codecell')
_set_text(cell,u'input',cell_e,u'input')
_set_text(cell,u'language',cell_e,u'language')
_set_int(cell,u'prompt_number',cell_e,u'prompt_number')
_set_bool(cell,u'collapsed',cell_e,u'collapsed')
outputs_e = ET.SubElement(cell_e, u'outputs')
for output in cell.outputs:
output_e = ET.SubElement(outputs_e, u'output')
_set_text(output,u'output_type',output_e,u'output_type')
_set_text(output,u'text',output_e,u'text')
_set_binary(output,u'png',output_e,u'png')
_set_binary(output,u'jpeg',output_e,u'jpeg')
_set_text(output,u'html',output_e,u'html')
_set_text(output,u'svg',output_e,u'svg')
_set_text(output,u'latex',output_e,u'latex')
_set_text(output,u'json',output_e,u'json')
_set_text(output,u'javascript',output_e,u'javascript')
_set_int(output,u'prompt_number',output_e,u'prompt_number')
_set_text(output,u'etype',output_e,u'etype')
_set_text(output,u'evalue',output_e,u'evalue')
if u'traceback' in output:
tb_e = ET.SubElement(output_e, u'traceback')
for frame in output.traceback:
frame_e = ET.SubElement(tb_e, u'frame')
frame_e.text = frame
elif cell_type == u'html':
cell_e = ET.SubElement(cells_e, u'htmlcell')
_set_text(cell,u'source',cell_e,u'source')
_set_text(cell,u'rendered',cell_e,u'rendered')
elif cell_type == u'markdown':
cell_e = ET.SubElement(cells_e, u'markdowncell')
_set_text(cell,u'source',cell_e,u'source')
_set_text(cell,u'rendered',cell_e,u'rendered')
indent(nb_e)
txt = ET.tostring(nb_e, encoding="utf-8")
txt = '<?xml version="1.0" encoding="utf-8"?>\n' + txt
return txt
_reader = XMLReader()
_writer = XMLWriter()
reads = _reader.reads
read = _reader.read
to_notebook = _reader.to_notebook
write = _writer.write
writes = _writer.writes