Show More
@@ -166,20 +166,6 b' class NotebookHandler(web.RequestHandler):' | |||||
166 | # RST web service handlers |
|
166 | # RST web service handlers | |
167 | #----------------------------------------------------------------------------- |
|
167 | #----------------------------------------------------------------------------- | |
168 |
|
168 | |||
169 | _rst_header = """======== |
|
|||
170 | Heading1 |
|
|||
171 | ======== |
|
|||
172 |
|
||||
173 | Heading2 |
|
|||
174 | ======== |
|
|||
175 |
|
||||
176 | Heading3 |
|
|||
177 | -------- |
|
|||
178 |
|
||||
179 | Heading4 |
|
|||
180 | ^^^^^^^^ |
|
|||
181 |
|
||||
182 | """ |
|
|||
183 |
|
169 | |||
184 | class RSTHandler(web.RequestHandler): |
|
170 | class RSTHandler(web.RequestHandler): | |
185 |
|
171 | |||
@@ -187,15 +173,14 b' class RSTHandler(web.RequestHandler):' | |||||
187 | if publish_string is None: |
|
173 | if publish_string is None: | |
188 | raise web.HTTPError(503) |
|
174 | raise web.HTTPError(503) | |
189 | body = self.request.body.strip() |
|
175 | body = self.request.body.strip() | |
190 |
source = |
|
176 | source = body | |
191 | template_path=os.path.join(os.path.dirname(__file__), u'templates', u'rst_template.html') |
|
177 | # template_path=os.path.join(os.path.dirname(__file__), u'templates', u'rst_template.html') | |
192 | print template_path |
|
178 | print template_path | |
193 | defaults = {'file_insertion_enabled': 0, |
|
179 | defaults = {'file_insertion_enabled': 0, | |
194 | 'raw_enabled': 0, |
|
180 | 'raw_enabled': 0, | |
195 | '_disable_config': 1, |
|
181 | '_disable_config': 1, | |
196 | 'stylesheet_path': 0, |
|
182 | 'stylesheet_path': 0, | |
197 | 'initial_header_level': 3, |
|
183 | # 'template': template_path | |
198 | 'template': template_path |
|
|||
199 | } |
|
184 | } | |
200 | try: |
|
185 | try: | |
201 | html = publish_string(source, writer_name='html', |
|
186 | html = publish_string(source, writer_name='html', | |
@@ -204,8 +189,6 b' class RSTHandler(web.RequestHandler):' | |||||
204 | except: |
|
189 | except: | |
205 | raise web.HTTPError(400) |
|
190 | raise web.HTTPError(400) | |
206 | print html |
|
191 | print html | |
207 | # html = '\n'.join(html.split('\n')[7:-3]) |
|
|||
208 | # print html |
|
|||
209 | self.set_header('Content-Type', 'text/html') |
|
192 | self.set_header('Content-Type', 'text/html') | |
210 | self.finish(html) |
|
193 | self.finish(html) | |
211 |
|
194 |
@@ -204,7 +204,7 b' var IPython = (function (IPython) {' | |||||
204 |
|
204 | |||
205 | CodeCell.prototype.append_pyerr = function (json) { |
|
205 | CodeCell.prototype.append_pyerr = function (json) { | |
206 | var tb = json.traceback; |
|
206 | var tb = json.traceback; | |
207 | if (tb !== undefined) { |
|
207 | if (tb !== undefined && tb.length > 0) { | |
208 | var s = ''; |
|
208 | var s = ''; | |
209 | var len = tb.length; |
|
209 | var len = tb.length; | |
210 | for (var i=0; i<len; i++) { |
|
210 | for (var i=0; i<len; i++) { | |
@@ -262,7 +262,7 b' var IPython = (function (IPython) {' | |||||
262 | CodeCell.prototype.append_text = function (data, element) { |
|
262 | CodeCell.prototype.append_text = function (data, element) { | |
263 | element = element || this.element.find("div.output"); |
|
263 | element = element || this.element.find("div.output"); | |
264 | var toinsert = $("<div/>").addClass("output_stream"); |
|
264 | var toinsert = $("<div/>").addClass("output_stream"); | |
265 |
toinsert.append($("<pre/>").html( |
|
265 | toinsert.append($("<pre/>").html(data)); | |
266 | element.append(toinsert); |
|
266 | element.append(toinsert); | |
267 | return element; |
|
267 | return element; | |
268 | }; |
|
268 | }; |
@@ -520,7 +520,7 b' var IPython = (function (IPython) {' | |||||
520 | var json = {}; |
|
520 | var json = {}; | |
521 | json.output_type = msg_type; |
|
521 | json.output_type = msg_type; | |
522 | if (msg_type === "stream") { |
|
522 | if (msg_type === "stream") { | |
523 | json.text = content.data + '\n'; |
|
523 | json.text = utils.fixConsole(content.data + '\n'); | |
524 | } else if (msg_type === "display_data") { |
|
524 | } else if (msg_type === "display_data") { | |
525 | json = this.convert_mime_types(json, content.data); |
|
525 | json = this.convert_mime_types(json, content.data); | |
526 | } else if (msg_type === "pyout") { |
|
526 | } else if (msg_type === "pyout") { | |
@@ -529,7 +529,11 b' var IPython = (function (IPython) {' | |||||
529 | } else if (msg_type === "pyerr") { |
|
529 | } else if (msg_type === "pyerr") { | |
530 | json.ename = content.ename; |
|
530 | json.ename = content.ename; | |
531 | json.evalue = content.evalue; |
|
531 | json.evalue = content.evalue; | |
532 |
|
|
532 | var traceback = []; | |
|
533 | for (var i=0; i<content.traceback.length; i++) { | |||
|
534 | traceback.push(utils.fixConsole(content.traceback[i])); | |||
|
535 | } | |||
|
536 | json.traceback = traceback; | |||
533 | }; |
|
537 | }; | |
534 | cell.append_output(json); |
|
538 | cell.append_output(json); | |
535 | }; |
|
539 | }; | |
@@ -537,7 +541,7 b' var IPython = (function (IPython) {' | |||||
537 |
|
541 | |||
538 | Notebook.prototype.convert_mime_types = function (json, data) { |
|
542 | Notebook.prototype.convert_mime_types = function (json, data) { | |
539 | if (data['text/plain'] !== undefined) { |
|
543 | if (data['text/plain'] !== undefined) { | |
540 | json.text = data['text/plain']; |
|
544 | json.text = utils.fixConsole(data['text/plain']); | |
541 | }; |
|
545 | }; | |
542 | if (data['text/html'] !== undefined) { |
|
546 | if (data['text/html'] !== undefined) { | |
543 | json.html = data['text/html']; |
|
547 | json.html = data['text/html']; | |
@@ -688,7 +692,6 b' var IPython = (function (IPython) {' | |||||
688 |
|
692 | |||
689 | Notebook.prototype.notebook_saved = function (data, status, xhr) { |
|
693 | Notebook.prototype.notebook_saved = function (data, status, xhr) { | |
690 | setTimeout($.proxy(IPython.save_widget.status_save,IPython.save_widget),500); |
|
694 | setTimeout($.proxy(IPython.save_widget.status_save,IPython.save_widget),500); | |
691 | // IPython.save_widget.status_save(); |
|
|||
692 | } |
|
695 | } | |
693 |
|
696 | |||
694 |
|
697 |
@@ -24,11 +24,14 b' def from_dict(d):' | |||||
24 |
|
24 | |||
25 | def new_output(output_type=None, output_text=None, output_png=None, |
|
25 | def new_output(output_type=None, output_text=None, output_png=None, | |
26 | output_html=None, output_svg=None, output_latex=None, output_json=None, |
|
26 | output_html=None, output_svg=None, output_latex=None, output_json=None, | |
27 |
output_javascript=None, output_jpeg=None, prompt_number=None |
|
27 | output_javascript=None, output_jpeg=None, prompt_number=None, | |
|
28 | etype=None, evalue=None, traceback=None): | |||
28 | """Create a new code cell with input and output""" |
|
29 | """Create a new code cell with input and output""" | |
29 | output = NotebookNode() |
|
30 | output = NotebookNode() | |
30 | if output_type is not None: |
|
31 | if output_type is not None: | |
31 | output.output_type = unicode(output_type) |
|
32 | output.output_type = unicode(output_type) | |
|
33 | ||||
|
34 | if output_type != 'pyerr': | |||
32 | if output_text is not None: |
|
35 | if output_text is not None: | |
33 | output.text = unicode(output_text) |
|
36 | output.text = unicode(output_text) | |
34 | if output_png is not None: |
|
37 | if output_png is not None: | |
@@ -45,8 +48,19 b' def new_output(output_type=None, output_text=None, output_png=None,' | |||||
45 | output.json = unicode(output_json) |
|
48 | output.json = unicode(output_json) | |
46 | if output_javascript is not None: |
|
49 | if output_javascript is not None: | |
47 | output.javascript = unicode(output_javascript) |
|
50 | output.javascript = unicode(output_javascript) | |
|
51 | ||||
|
52 | if output_type == u'pyout': | |||
48 | if prompt_number is not None: |
|
53 | if prompt_number is not None: | |
49 | output.prompt_number = int(prompt_number) |
|
54 | output.prompt_number = int(prompt_number) | |
|
55 | ||||
|
56 | if output_type == u'pyerr': | |||
|
57 | if etype is not None: | |||
|
58 | output.etype = unicode(etype) | |||
|
59 | if evalue is not None: | |||
|
60 | output.evalue = unicode(evalue) | |||
|
61 | if traceback is not None: | |||
|
62 | output.traceback = [unicode(frame) for frame in list(traceback)] | |||
|
63 | ||||
50 | return output |
|
64 | return output | |
51 |
|
65 | |||
52 |
|
66 |
@@ -90,53 +90,64 b' class XMLReader(NotebookReader):' | |||||
90 | return self.to_notebook(root, **kwargs) |
|
90 | return self.to_notebook(root, **kwargs) | |
91 |
|
91 | |||
92 | def to_notebook(self, root, **kwargs): |
|
92 | def to_notebook(self, root, **kwargs): | |
93 | nbname = _get_text(root,'name') |
|
93 | nbname = _get_text(root,u'name') | |
94 | nbid = _get_text(root,'id') |
|
94 | nbid = _get_text(root,u'id') | |
95 | nbauthor = _get_text(root,'author') |
|
95 | nbauthor = _get_text(root,u'author') | |
96 | nbemail = _get_text(root,'email') |
|
96 | nbemail = _get_text(root,u'email') | |
97 | nblicense = _get_text(root,'license') |
|
97 | nblicense = _get_text(root,u'license') | |
98 | nbcreated = _get_text(root,'created') |
|
98 | nbcreated = _get_text(root,u'created') | |
99 | nbsaved = _get_text(root,'saved') |
|
99 | nbsaved = _get_text(root,u'saved') | |
100 |
|
100 | |||
101 | worksheets = [] |
|
101 | worksheets = [] | |
102 | for ws_e in root.find('worksheets').getiterator('worksheet'): |
|
102 | for ws_e in root.find(u'worksheets').getiterator(u'worksheet'): | |
103 | wsname = _get_text(ws_e,'name') |
|
103 | wsname = _get_text(ws_e,u'name') | |
104 | cells = [] |
|
104 | cells = [] | |
105 | for cell_e in ws_e.find('cells').getiterator(): |
|
105 | for cell_e in ws_e.find(u'cells').getiterator(): | |
106 | if cell_e.tag == 'codecell': |
|
106 | if cell_e.tag == u'codecell': | |
107 | input = _get_text(cell_e,'input') |
|
107 | input = _get_text(cell_e,u'input') | |
108 | prompt_number = _get_int(cell_e,'prompt_number') |
|
108 | prompt_number = _get_int(cell_e,u'prompt_number') | |
109 | collapsed = _get_bool(cell_e,'collapsed') |
|
109 | collapsed = _get_bool(cell_e,u'collapsed') | |
110 | language = _get_text(cell_e,'language') |
|
110 | language = _get_text(cell_e,u'language') | |
111 | outputs = [] |
|
111 | outputs = [] | |
112 | for output_e in cell_e.find('outputs').getiterator('output'): |
|
112 | for output_e in cell_e.find(u'outputs').getiterator(u'output'): | |
113 |
out |
|
113 | output_type = _get_text(output_e,u'output_type') | |
114 |
output_t |
|
114 | output_text = _get_text(output_e,u'text') | |
115 |
output_ |
|
115 | output_png = _get_binary(output_e,u'png') | |
116 |
output_ |
|
116 | output_jpeg = _get_binary(output_e,u'jpeg') | |
117 |
output_ |
|
117 | output_svg = _get_text(output_e,u'svg') | |
118 |
output_ |
|
118 | output_html = _get_text(output_e,u'html') | |
119 |
output_ |
|
119 | output_latex = _get_text(output_e,u'latex') | |
120 |
output_ |
|
120 | output_json = _get_text(output_e,u'json') | |
121 |
output_j |
|
121 | output_javascript = _get_text(output_e,u'javascript') | |
122 | output_javascript = _get_text(output_e,'javascript') |
|
122 | ||
|
123 | out_prompt_number = _get_int(output_e,u'prompt_number') | |||
|
124 | etype = _get_text(output_e,u'etype') | |||
|
125 | evalue = _get_text(output_e,u'evalue') | |||
|
126 | traceback = [] | |||
|
127 | traceback_e = output_e.find(u'traceback') | |||
|
128 | if traceback_e is not None: | |||
|
129 | for frame_e in traceback_e.getiterator(u'frame'): | |||
|
130 | traceback.append(frame_e.text) | |||
|
131 | if len(traceback) == 0: | |||
|
132 | traceback = None | |||
123 | output = new_output(output_type=output_type,output_png=output_png, |
|
133 | output = new_output(output_type=output_type,output_png=output_png, | |
124 | output_text=output_text, output_svg=output_svg, |
|
134 | output_text=output_text, output_svg=output_svg, | |
125 | output_html=output_html, output_latex=output_latex, |
|
135 | output_html=output_html, output_latex=output_latex, | |
126 | output_json=output_json, output_javascript=output_javascript, |
|
136 | output_json=output_json, output_javascript=output_javascript, | |
127 | output_jpeg=output_jpeg, prompt_number=out_prompt_number |
|
137 | output_jpeg=output_jpeg, prompt_number=out_prompt_number, | |
|
138 | etype=etype, evalue=evalue, traceback=traceback | |||
128 | ) |
|
139 | ) | |
129 | outputs.append(output) |
|
140 | outputs.append(output) | |
130 | cc = new_code_cell(input=input,prompt_number=prompt_number, |
|
141 | cc = new_code_cell(input=input,prompt_number=prompt_number, | |
131 | language=language,outputs=outputs,collapsed=collapsed) |
|
142 | language=language,outputs=outputs,collapsed=collapsed) | |
132 | cells.append(cc) |
|
143 | cells.append(cc) | |
133 | if cell_e.tag == 'htmlcell': |
|
144 | if cell_e.tag == u'htmlcell': | |
134 | source = _get_text(cell_e,'source') |
|
145 | source = _get_text(cell_e,u'source') | |
135 | rendered = _get_text(cell_e,'rendered') |
|
146 | rendered = _get_text(cell_e,u'rendered') | |
136 | cells.append(new_text_cell(u'html', source=source, rendered=rendered)) |
|
147 | cells.append(new_text_cell(u'html', source=source, rendered=rendered)) | |
137 | if cell_e.tag == 'markdowncell': |
|
148 | if cell_e.tag == u'markdowncell': | |
138 | source = _get_text(cell_e,'source') |
|
149 | source = _get_text(cell_e,u'source') | |
139 | rendered = _get_text(cell_e,'rendered') |
|
150 | rendered = _get_text(cell_e,u'rendered') | |
140 | cells.append(new_text_cell(u'markdown', source=source, rendered=rendered)) |
|
151 | cells.append(new_text_cell(u'markdown', source=source, rendered=rendered)) | |
141 | ws = new_worksheet(name=wsname,cells=cells) |
|
152 | ws = new_worksheet(name=wsname,cells=cells) | |
142 | worksheets.append(ws) |
|
153 | worksheets.append(ws) | |
@@ -149,49 +160,56 b' class XMLReader(NotebookReader):' | |||||
149 | class XMLWriter(NotebookWriter): |
|
160 | class XMLWriter(NotebookWriter): | |
150 |
|
161 | |||
151 | def writes(self, nb, **kwargs): |
|
162 | def writes(self, nb, **kwargs): | |
152 | nb_e = ET.Element('notebook') |
|
163 | nb_e = ET.Element(u'notebook') | |
153 | _set_text(nb,'name',nb_e,'name') |
|
164 | _set_text(nb,u'name',nb_e,u'name') | |
154 | _set_text(nb,'id',nb_e,'id') |
|
165 | _set_text(nb,u'id',nb_e,u'id') | |
155 | _set_text(nb,'author',nb_e,'author') |
|
166 | _set_text(nb,u'author',nb_e,u'author') | |
156 | _set_text(nb,'email',nb_e,'email') |
|
167 | _set_text(nb,u'email',nb_e,u'email') | |
157 | _set_text(nb,'license',nb_e,'license') |
|
168 | _set_text(nb,u'license',nb_e,u'license') | |
158 | _set_text(nb,'created',nb_e,'created') |
|
169 | _set_text(nb,u'created',nb_e,u'created') | |
159 | _set_text(nb,'saved',nb_e,'saved') |
|
170 | _set_text(nb,u'saved',nb_e,u'saved') | |
160 | _set_int(nb,'nbformat',nb_e,'nbformat') |
|
171 | _set_int(nb,u'nbformat',nb_e,u'nbformat') | |
161 | wss_e = ET.SubElement(nb_e,'worksheets') |
|
172 | wss_e = ET.SubElement(nb_e,u'worksheets') | |
162 | for ws in nb.worksheets: |
|
173 | for ws in nb.worksheets: | |
163 | ws_e = ET.SubElement(wss_e, 'worksheet') |
|
174 | ws_e = ET.SubElement(wss_e, u'worksheet') | |
164 | _set_text(ws,'name',ws_e,'name') |
|
175 | _set_text(ws,u'name',ws_e,u'name') | |
165 | cells_e = ET.SubElement(ws_e,'cells') |
|
176 | cells_e = ET.SubElement(ws_e,u'cells') | |
166 | for cell in ws.cells: |
|
177 | for cell in ws.cells: | |
167 | cell_type = cell.cell_type |
|
178 | cell_type = cell.cell_type | |
168 | if cell_type == 'code': |
|
179 | if cell_type == u'code': | |
169 | cell_e = ET.SubElement(cells_e, 'codecell') |
|
180 | cell_e = ET.SubElement(cells_e, u'codecell') | |
170 | _set_text(cell,'input',cell_e,'input') |
|
181 | _set_text(cell,u'input',cell_e,u'input') | |
171 | _set_text(cell,'language',cell_e,'language') |
|
182 | _set_text(cell,u'language',cell_e,u'language') | |
172 | _set_int(cell,'prompt_number',cell_e,'prompt_number') |
|
183 | _set_int(cell,u'prompt_number',cell_e,u'prompt_number') | |
173 | _set_bool(cell,'collapsed',cell_e,'collapsed') |
|
184 | _set_bool(cell,u'collapsed',cell_e,u'collapsed') | |
174 | outputs_e = ET.SubElement(cell_e, 'outputs') |
|
185 | outputs_e = ET.SubElement(cell_e, u'outputs') | |
175 | for output in cell.outputs: |
|
186 | for output in cell.outputs: | |
176 | output_e = ET.SubElement(outputs_e, 'output') |
|
187 | output_e = ET.SubElement(outputs_e, u'output') | |
177 |
_set_ |
|
188 | _set_text(output,u'output_type',output_e,u'output_type') | |
178 |
_set_text(output,' |
|
189 | _set_text(output,u'text',output_e,u'text') | |
179 |
_set_ |
|
190 | _set_binary(output,u'png',output_e,u'png') | |
180 |
_set_binary(output,' |
|
191 | _set_binary(output,u'jpeg',output_e,u'jpeg') | |
181 |
_set_ |
|
192 | _set_text(output,u'html',output_e,u'html') | |
182 |
_set_text(output,' |
|
193 | _set_text(output,u'svg',output_e,u'svg') | |
183 |
_set_text(output,' |
|
194 | _set_text(output,u'latex',output_e,u'latex') | |
184 |
_set_text(output,' |
|
195 | _set_text(output,u'json',output_e,u'json') | |
185 |
_set_text(output,'j |
|
196 | _set_text(output,u'javascript',output_e,u'javascript') | |
186 |
_set_ |
|
197 | _set_int(output,u'prompt_number',output_e,u'prompt_number') | |
187 | elif cell_type == 'html': |
|
198 | _set_text(output,u'etype',output_e,u'etype') | |
188 | cell_e = ET.SubElement(cells_e, 'htmlcell') |
|
199 | _set_text(output,u'evalue',output_e,u'evalue') | |
189 | _set_text(cell,'source',cell_e,'source') |
|
200 | if u'traceback' in output: | |
190 | _set_text(cell,'rendered',cell_e,'rendered') |
|
201 | tb_e = ET.SubElement(output_e, u'traceback') | |
191 | elif cell_type == 'markdown': |
|
202 | for frame in output.traceback: | |
192 |
|
|
203 | frame_e = ET.SubElement(tb_e, u'frame') | |
193 | _set_text(cell,'source',cell_e,'source') |
|
204 | frame_e.text = frame | |
194 | _set_text(cell,'rendered',cell_e,'rendered') |
|
205 | elif cell_type == u'html': | |
|
206 | cell_e = ET.SubElement(cells_e, u'htmlcell') | |||
|
207 | _set_text(cell,u'source',cell_e,u'source') | |||
|
208 | _set_text(cell,u'rendered',cell_e,u'rendered') | |||
|
209 | elif cell_type == u'markdown': | |||
|
210 | cell_e = ET.SubElement(cells_e, u'markdowncell') | |||
|
211 | _set_text(cell,u'source',cell_e,u'source') | |||
|
212 | _set_text(cell,u'rendered',cell_e,u'rendered') | |||
195 |
|
213 | |||
196 | indent(nb_e) |
|
214 | indent(nb_e) | |
197 | txt = ET.tostring(nb_e, encoding="utf-8") |
|
215 | txt = ET.tostring(nb_e, encoding="utf-8") |
@@ -56,8 +56,12 b' ws.cells.append(new_code_cell(' | |||||
56 | output_jpeg=b'data', |
|
56 | output_jpeg=b'data', | |
57 | output_svg=u'<svg>', |
|
57 | output_svg=u'<svg>', | |
58 | output_json=u'json data', |
|
58 | output_json=u'json data', | |
59 |
output_javascript=u'var i=0;' |
|
59 | output_javascript=u'var i=0;' | |
60 | prompt_number=4 |
|
60 | ),new_output( | |
|
61 | output_type=u'pyerr', | |||
|
62 | etype=u'NameError', | |||
|
63 | evalue=u'NameError was here', | |||
|
64 | traceback=[u'frame 0', u'frame 1', u'frame 2'] | |||
61 | )] |
|
65 | )] | |
62 | )) |
|
66 | )) | |
63 |
|
67 | |||
@@ -65,7 +69,7 b' nb0 = new_notebook(' | |||||
65 | name='nb0', |
|
69 | name='nb0', | |
66 | worksheets=[ws, new_worksheet(name='worksheet2')], |
|
70 | worksheets=[ws, new_worksheet(name='worksheet2')], | |
67 | author='Bart Simpson', |
|
71 | author='Bart Simpson', | |
68 |
email='bsimp |
|
72 | email='bsimpson@fox.com', | |
69 | saved='ISO8601_goes_here', |
|
73 | saved='ISO8601_goes_here', | |
70 | created='ISO8601_goes_here', |
|
74 | created='ISO8601_goes_here', | |
71 | license='BSD' |
|
75 | license='BSD' |
@@ -27,6 +27,14 b' class TestCell(TestCase):' | |||||
27 | self.assertEquals(cc.outputs[0].prompt_number, 0) |
|
27 | self.assertEquals(cc.outputs[0].prompt_number, 0) | |
28 | self.assertEquals(cc.collapsed, True) |
|
28 | self.assertEquals(cc.collapsed, True) | |
29 |
|
29 | |||
|
30 | def test_pyerr(self): | |||
|
31 | o = new_output(output_type=u'pyerr', etype=u'NameError', | |||
|
32 | evalue=u'Name not found', traceback=[u'frame 0', u'frame 1', u'frame 2'] | |||
|
33 | ) | |||
|
34 | self.assertEquals(o.output_type, u'pyerr') | |||
|
35 | self.assertEquals(o.etype, u'NameError') | |||
|
36 | self.assertEquals(o.evalue, u'Name not found') | |||
|
37 | self.assertEquals(o.traceback, [u'frame 0', u'frame 1', u'frame 2']) | |||
30 |
|
38 | |||
31 | def test_empty_html_cell(self): |
|
39 | def test_empty_html_cell(self): | |
32 | tc = new_text_cell(u'html') |
|
40 | tc = new_text_cell(u'html') |
General Comments 0
You need to be logged in to leave comments.
Login now