nbxml.py 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. """Read and write notebook files as XML.
  2. Authors:
  3. * Brian Granger
  4. """
  5. #-----------------------------------------------------------------------------
  6. # Copyright (C) 2008-2011 The IPython Development Team
  7. #
  8. # Distributed under the terms of the BSD License. The full license is in
  9. # the file COPYING, distributed as part of this software.
  10. #-----------------------------------------------------------------------------
  11. #-----------------------------------------------------------------------------
  12. # Imports
  13. #-----------------------------------------------------------------------------
  14. from base64 import encodestring, decodestring
  15. import warnings
  16. from xml.etree import ElementTree as ET
  17. from ipython_genutils.py3compat import unicode_type
  18. from .rwbase import NotebookReader, NotebookWriter
  19. from .nbbase import (
  20. new_code_cell, new_text_cell, new_worksheet, new_notebook, new_output,
  21. new_metadata
  22. )
  23. #-----------------------------------------------------------------------------
  24. # Code
  25. #-----------------------------------------------------------------------------
  26. def indent(elem, level=0):
  27. i = "\n" + level*" "
  28. if len(elem):
  29. if not elem.text or not elem.text.strip():
  30. elem.text = i + " "
  31. if not elem.tail or not elem.tail.strip():
  32. elem.tail = i
  33. for elem in elem:
  34. indent(elem, level+1)
  35. if not elem.tail or not elem.tail.strip():
  36. elem.tail = i
  37. else:
  38. if level and (not elem.tail or not elem.tail.strip()):
  39. elem.tail = i
  40. def _get_text(e, tag):
  41. sub_e = e.find(tag)
  42. if sub_e is None:
  43. return None
  44. else:
  45. return sub_e.text
  46. def _set_text(nbnode, attr, parent, tag):
  47. if attr in nbnode:
  48. e = ET.SubElement(parent, tag)
  49. e.text = nbnode[attr]
  50. def _get_int(e, tag):
  51. sub_e = e.find(tag)
  52. if sub_e is None:
  53. return None
  54. else:
  55. return int(sub_e.text)
  56. def _set_int(nbnode, attr, parent, tag):
  57. if attr in nbnode:
  58. e = ET.SubElement(parent, tag)
  59. e.text = unicode_type(nbnode[attr])
  60. def _get_bool(e, tag):
  61. sub_e = e.find(tag)
  62. if sub_e is None:
  63. return None
  64. else:
  65. return bool(int(sub_e.text))
  66. def _set_bool(nbnode, attr, parent, tag):
  67. if attr in nbnode:
  68. e = ET.SubElement(parent, tag)
  69. if nbnode[attr]:
  70. e.text = u'1'
  71. else:
  72. e.text = u'0'
  73. def _get_binary(e, tag):
  74. sub_e = e.find(tag)
  75. if sub_e is None:
  76. return None
  77. else:
  78. return decodestring(sub_e.text)
  79. def _set_binary(nbnode, attr, parent, tag):
  80. if attr in nbnode:
  81. e = ET.SubElement(parent, tag)
  82. e.text = encodestring(nbnode[attr])
  83. class XMLReader(NotebookReader):
  84. def reads(self, s, **kwargs):
  85. root = ET.fromstring(s)
  86. return self.to_notebook(root, **kwargs)
  87. def to_notebook(self, root, **kwargs):
  88. warnings.warn('The XML notebook format is no longer supported, '
  89. 'please convert your notebooks to JSON.', DeprecationWarning)
  90. nbname = _get_text(root,u'name')
  91. nbauthor = _get_text(root,u'author')
  92. nbemail = _get_text(root,u'email')
  93. nblicense = _get_text(root,u'license')
  94. nbcreated = _get_text(root,u'created')
  95. nbsaved = _get_text(root,u'saved')
  96. worksheets = []
  97. for ws_e in root.find(u'worksheets').getiterator(u'worksheet'):
  98. wsname = _get_text(ws_e,u'name')
  99. cells = []
  100. for cell_e in ws_e.find(u'cells').getiterator():
  101. if cell_e.tag == u'codecell':
  102. input = _get_text(cell_e,u'input')
  103. prompt_number = _get_int(cell_e,u'prompt_number')
  104. collapsed = _get_bool(cell_e,u'collapsed')
  105. language = _get_text(cell_e,u'language')
  106. outputs = []
  107. for output_e in cell_e.find(u'outputs').getiterator(u'output'):
  108. output_type = _get_text(output_e,u'output_type')
  109. output_text = _get_text(output_e,u'text')
  110. output_png = _get_binary(output_e,u'png')
  111. output_jpeg = _get_binary(output_e,u'jpeg')
  112. output_svg = _get_text(output_e,u'svg')
  113. output_html = _get_text(output_e,u'html')
  114. output_latex = _get_text(output_e,u'latex')
  115. output_json = _get_text(output_e,u'json')
  116. output_javascript = _get_text(output_e,u'javascript')
  117. out_prompt_number = _get_int(output_e,u'prompt_number')
  118. etype = _get_text(output_e,u'etype')
  119. evalue = _get_text(output_e,u'evalue')
  120. traceback = []
  121. traceback_e = output_e.find(u'traceback')
  122. if traceback_e is not None:
  123. for frame_e in traceback_e.getiterator(u'frame'):
  124. traceback.append(frame_e.text)
  125. if len(traceback) == 0:
  126. traceback = None
  127. output = new_output(output_type=output_type,output_png=output_png,
  128. output_text=output_text, output_svg=output_svg,
  129. output_html=output_html, output_latex=output_latex,
  130. output_json=output_json, output_javascript=output_javascript,
  131. output_jpeg=output_jpeg, prompt_number=out_prompt_number,
  132. etype=etype, evalue=evalue, traceback=traceback
  133. )
  134. outputs.append(output)
  135. cc = new_code_cell(input=input,prompt_number=prompt_number,
  136. language=language,outputs=outputs,collapsed=collapsed)
  137. cells.append(cc)
  138. if cell_e.tag == u'htmlcell':
  139. source = _get_text(cell_e,u'source')
  140. rendered = _get_text(cell_e,u'rendered')
  141. cells.append(new_text_cell(u'html', source=source, rendered=rendered))
  142. if cell_e.tag == u'markdowncell':
  143. source = _get_text(cell_e,u'source')
  144. rendered = _get_text(cell_e,u'rendered')
  145. cells.append(new_text_cell(u'markdown', source=source, rendered=rendered))
  146. ws = new_worksheet(name=wsname,cells=cells)
  147. worksheets.append(ws)
  148. md = new_metadata(name=nbname)
  149. nb = new_notebook(metadata=md,worksheets=worksheets)
  150. return nb
  151. _reader = XMLReader()
  152. reads = _reader.reads
  153. read = _reader.read
  154. to_notebook = _reader.to_notebook