##// END OF EJS Templates
Initial draft of more formal notebook format....
Initial draft of more formal notebook format. * Basic Python notebook uses a simple Struct subclass, NotebookNode for representing the notebook components. * XML and JSON readers/writers work in full round trip manner. * Python reader/writter works for code cells. * Everything is tested.

File last commit:

r4401:f3a5072f
r4401:f3a5072f
Show More
nbxml.py
141 lines | 5.3 KiB | text/x-python | PythonLexer
"""Read and write notebook files as XML."""
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
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
class XMLReader(NotebookReader):
def reads(self, s, **kwargs):
root = ET.fromstring(s)
nbname = _get_text(root,'name')
nbid = _get_text(root,'id')
worksheets = []
for ws_e in root.getiterator('worksheet'):
wsname = _get_text(ws_e,'name')
cells = []
for cell_e in ws_e.getiterator():
if cell_e.tag == 'codecell':
input = _get_text(cell_e,'input')
output_e = cell_e.find('output')
if output_e is not None:
output_text = _get_text(output_e,'text')
output_png = _get_text(output_e,'png')
output_svg = _get_text(output_e,'svg')
output_html = _get_text(output_e,'html')
output_latex = _get_text(output_e,'latex')
output_json = _get_text(output_e,'json')
output_javascript = _get_text(output_e,'javascript')
cc = new_code_cell(input=input,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
)
cells.append(cc)
if cell_e.tag == 'textcell':
text = _get_text(cell_e,'text')
cells.append(new_text_cell(text=text))
ws = new_worksheet(name=wsname,cells=cells)
worksheets.append(ws)
nb = new_notebook(name=nbname,id=nbid,worksheets=worksheets)
return nb
class XMLWriter(NotebookWriter):
def writes(self, nb, **kwargs):
nb_e = ET.Element('notebook')
if 'name' in nb:
name_e = ET.SubElement(nb_e, 'name')
name_e.text = nb.name
if 'id' in nb:
id_e = ET.SubElement(nb_e, 'id')
id_e.text = nb.id
for ws in nb.worksheets:
ws_e = ET.SubElement(nb_e, 'worksheet')
if 'name' in ws:
ws_name_e = ET.SubElement(ws_e, 'name')
ws_name_e.text = ws.name
for cell in ws.cells:
cell_type = cell.cell_type
if cell_type == 'code':
output = cell.output
cell_e = ET.SubElement(ws_e, 'codecell')
output_e = ET.SubElement(cell_e, 'output')
if 'input' in cell:
input_e = ET.SubElement(cell_e, 'input')
input_e.text = cell.input
if 'prompt_number' in cell:
prompt_number_e = ET.SubElement(cell_e, 'prompt_number')
input_e.text = cell.prompt_number
if 'text' in output:
text_e = ET.SubElement(output_e, 'text')
text_e.text = output.text
if 'png' in output:
png_e = ET.SubElement(output_e, 'png')
png_e.text = output.png
if 'html' in output:
html_e = ET.SubElement(output_e, 'html')
html_e.text = output.html
if 'svg' in output:
svg_e = ET.SubElement(output_e, 'svg')
svg_e.text = output.svg
if 'latex' in output:
latex_e = ET.SubElement(output_e, 'latex')
latex_e.text = output.latex
if 'json' in output:
json_e = ET.SubElement(output_e, 'json')
json_e.text = output.json
if 'javascript' in output:
javascript_e = ET.SubElement(output_e, 'javascript')
javascript_e.text = output.javascript
elif cell_type == 'text':
cell_e = ET.SubElement(ws_e, 'textcell')
if 'text' in cell:
cell_text_e = ET.SubElement(cell_e, 'text')
cell_text_e.text = cell.text
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
write = _writer.write
writes = _writer.writes