From c467b2efc0e27ad18f137089d32b802acee9ce15 2012-01-30 19:50:03 From: Brian Granger Date: 2012-01-30 19:50:03 Subject: [PATCH] Adding rst and heading cells to the notebook format. --- diff --git a/IPython/nbformat/v2/nbbase.py b/IPython/nbformat/v2/nbbase.py index d4ef94e..00f893e 100644 --- a/IPython/nbformat/v2/nbbase.py +++ b/IPython/nbformat/v2/nbbase.py @@ -119,6 +119,16 @@ def new_text_cell(cell_type, source=None, rendered=None): return cell +def new_heading_cell(source=None, level=1): + """Create a new section cell with a given integer level.""" + cell = NotebookNode() + cell.cell_type = u'heading' + if source is not None: + cell.source = unicode(source) + cell.level = int(level) + return cell + + def new_worksheet(name=None, cells=None): """Create a worksheet by name with with a list of cells.""" ws = NotebookNode() diff --git a/IPython/nbformat/v2/nbpy.py b/IPython/nbformat/v2/nbpy.py index 8d89fc0..2493fcd 100644 --- a/IPython/nbformat/v2/nbpy.py +++ b/IPython/nbformat/v2/nbpy.py @@ -18,7 +18,10 @@ Authors: import re from .rwbase import NotebookReader, NotebookWriter -from .nbbase import new_code_cell, new_text_cell, new_worksheet, new_notebook +from .nbbase import ( + new_code_cell, new_text_cell, new_worksheet, + new_notebook, new_heading_cell +) #----------------------------------------------------------------------------- # Code @@ -39,28 +42,53 @@ class PyReader(NotebookReader): lines = s.splitlines() cells = [] cell_lines = [] + kwargs = {} state = u'codecell' for line in lines: if line.startswith(u'# ') or _encoding_declaration_re.match(line): pass elif line.startswith(u'# '): - cell = self.new_cell(state, cell_lines) + cell = self.new_cell(state, cell_lines, **kwargs) if cell is not None: cells.append(cell) state = u'codecell' cell_lines = [] + kwargs = {} elif line.startswith(u'# '): - cell = self.new_cell(state, cell_lines) + cell = self.new_cell(state, cell_lines, **kwargs) if cell is not None: cells.append(cell) state = u'htmlcell' cell_lines = [] + kwargs = {} elif line.startswith(u'# '): - cell = self.new_cell(state, cell_lines) + cell = self.new_cell(state, cell_lines, **kwargs) if cell is not None: cells.append(cell) state = u'markdowncell' cell_lines = [] + kwargs = {} + elif line.startswith(u'# '): + cell = self.new_cell(state, cell_lines, **kwargs) + if cell is not None: + cells.append(cell) + state = u'rstcell' + cell_lines = [] + kwargs = {} + elif line.startswith(u'# \d)>',line) + if m is not None: + state = u'headingcell' + kwargs = {} + kwargs['level'] = int(m.group('level')) + else: + state = u'codecell' + kwargs = {} + cell_lines = [] else: cell_lines.append(line) if cell_lines and state == u'codecell': @@ -71,7 +99,7 @@ class PyReader(NotebookReader): nb = new_notebook(worksheets=[ws]) return nb - def new_cell(self, state, lines): + def new_cell(self, state, lines, **kwargs): if state == u'codecell': input = u'\n'.join(lines) input = input.strip(u'\n') @@ -85,6 +113,15 @@ class PyReader(NotebookReader): text = self._remove_comments(lines) if text: return new_text_cell(u'markdown',source=text) + elif state == u'rstcell': + text = self._remove_comments(lines) + if text: + return new_text_cell(u'rst',source=text) + elif state == u'headingcell': + text = self._remove_comments(lines) + level = kwargs.get('level',1) + if text: + return new_heading_cell(source=text,level=level) def _remove_comments(self, lines): new_lines = [] @@ -135,6 +172,19 @@ class PyWriter(NotebookWriter): lines.extend([u'# ',u'']) lines.extend([u'# ' + line for line in input.splitlines()]) lines.append(u'') + elif cell.cell_type == u'rst': + input = cell.get(u'source') + if input is not None: + lines.extend([u'# ',u'']) + lines.extend([u'# ' + line for line in input.splitlines()]) + lines.append(u'') + elif cell.cell_type == u'heading': + input = cell.get(u'source') + level = cell.get(u'level',1) + if input is not None: + lines.extend([u'# ' % level,u'']) + lines.extend([u'# ' + line for line in input.splitlines()]) + lines.append(u'') lines.append('') return unicode('\n'.join(lines)) diff --git a/IPython/nbformat/v2/rwbase.py b/IPython/nbformat/v2/rwbase.py index 39d54b2..ae4e53d 100644 --- a/IPython/nbformat/v2/rwbase.py +++ b/IPython/nbformat/v2/rwbase.py @@ -64,6 +64,8 @@ def rejoin_lines(nb): item = output.get(key, None) if isinstance(item, list): output[key] = u'\n'.join(item) + elif cell.cell_type == 'heading': + pass else: # text cell for key in ['source', 'rendered']: item = cell.get(key, None) @@ -90,6 +92,8 @@ def split_lines(nb): item = output.get(key, None) if isinstance(item, basestring): output[key] = item.splitlines() + elif cell.cell_type == 'heading': + pass else: # text cell for key in ['source', 'rendered']: item = cell.get(key, None) diff --git a/IPython/nbformat/v2/tests/nbexamples.py b/IPython/nbformat/v2/tests/nbexamples.py index 3e83e8e..af6a251 100644 --- a/IPython/nbformat/v2/tests/nbexamples.py +++ b/IPython/nbformat/v2/tests/nbexamples.py @@ -4,7 +4,7 @@ from base64 import encodestring from ..nbbase import ( NotebookNode, new_code_cell, new_text_cell, new_worksheet, new_notebook, new_output, - new_metadata, new_author + new_metadata, new_author, new_heading_cell ) # some random base64-encoded *bytes* @@ -32,6 +32,16 @@ ws.cells.append(new_text_cell( rendered='A random array' )) +ws.cells.append(new_text_cell( + u'rst', + source='A random array', +)) + +ws.cells.append(new_heading_cell( + u'My Heading', + level=2 +)) + ws.cells.append(new_code_cell( input='a = numpy.random.rand(100)', prompt_number=2, @@ -96,6 +106,14 @@ import numpy # A random array +# + +# A random array + +# + +# My Heading + # a = numpy.random.rand(100) diff --git a/IPython/nbformat/v2/tests/test_json.py b/IPython/nbformat/v2/tests/test_json.py index d6cc5d3..ecbb2d1 100644 --- a/IPython/nbformat/v2/tests/test_json.py +++ b/IPython/nbformat/v2/tests/test_json.py @@ -9,12 +9,12 @@ class TestJSON(TestCase): def test_roundtrip(self): s = writes(nb0) -# print -# print pprint.pformat(nb0,indent=2) -# print -# print pprint.pformat(reads(s),indent=2) -# print -# print s + # print + # print pprint.pformat(nb0,indent=2) + # print + # print pprint.pformat(reads(s),indent=2) + # print + # print s self.assertEquals(reads(s),nb0) def test_roundtrip_nosplit(self): diff --git a/IPython/nbformat/v2/tests/test_nbbase.py b/IPython/nbformat/v2/tests/test_nbbase.py index d711bcf..5a90d35 100644 --- a/IPython/nbformat/v2/tests/test_nbbase.py +++ b/IPython/nbformat/v2/tests/test_nbbase.py @@ -3,7 +3,7 @@ from unittest import TestCase from ..nbbase import ( NotebookNode, new_code_cell, new_text_cell, new_worksheet, new_notebook, new_output, - new_author, new_metadata + new_author, new_metadata, new_heading_cell ) class TestCell(TestCase): @@ -59,6 +59,27 @@ class TestCell(TestCase): self.assertEquals(tc.source, u'hi') self.assertEquals(tc.rendered, u'hi') + def test_empty_rst_cell(self): + tc = new_text_cell(u'rst') + self.assertEquals(tc.cell_type, u'rst') + self.assertEquals(u'source' not in tc, True) + self.assertEquals(u'rendered' not in tc, True) + + def test_rst_cell(self): + tc = new_text_cell(u'rst', 'hi', 'hi') + self.assertEquals(tc.source, u'hi') + self.assertEquals(tc.rendered, u'hi') + + def test_empty_heading_cell(self): + tc = new_heading_cell() + self.assertEquals(tc.cell_type, u'heading') + self.assertEquals(u'source' not in tc, True) + + def test_heading_cell(self): + tc = new_heading_cell(u'My Heading', level=2) + self.assertEquals(tc.source, u'My Heading') + self.assertEquals(tc.level, 2) + class TestWorksheet(TestCase):