Ticket #11459: trac11459_rst2notebook_sagenb-sl.patch
File trac11459_rst2notebook_sagenb-sl.patch, 59.3 KB (added by , 11 years ago) |
---|
-
flask_version/worksheet_listing.py
# HG changeset patch # User Sebastien Labbe <slabqc at gmail.com> # Date 1308369592 25200 # Node ID ef51b01fd7bc9fb4dbfeefada98cfd73c50366c2 # Parent b732dafbff2259938b55873e247213f9a82fe9e3 #11459: ReST -> Sage worksheet diff --git a/flask_version/worksheet_listing.py b/flask_version/worksheet_listing.py
a b def upload_worksheet(): 232 232 # to a temporary file with the same extension 233 233 path = urlparse.urlparse(url).path 234 234 extension = os.path.splitext(path)[1].lower() 235 if extension not in [".txt", ".sws", ".zip", ".html" ]:235 if extension not in [".txt", ".sws", ".zip", ".html", ".rst"]: 236 236 # Or shall we try to import the document as an sws in doubt? 237 237 return current_app.message("Unknown worksheet extension: %s. %s" % (extension, backlinks)) 238 238 filename = tmp_filename()+extension … … def upload_worksheet(): 268 268 W = g.notebook.import_worksheet(filename, g.username) 269 269 270 270 except Exception, msg: 271 print "Error: %s" % msg 271 272 s = 'There was an error uploading the worksheet. It could be an old unsupported format or worse. If you desperately need its contents contact the <a href="http://groups.google.com/group/sage-support">sage-support group</a> and post a link to your worksheet. Alternatively, an sws file is just a bzip2 tarball; take a look inside!%s' % backlinks 272 273 return current_app.message(s, url_for('home', username=g.username)) 273 274 finally: -
sagenb/data/sage/html/upload.html
diff --git a/sagenb/data/sage/html/upload.html b/sagenb/data/sage/html/upload.html
a b 8 8 9 9 <div> 10 10 <h2>Upload worksheet to the Sage Notebook</h2> 11 <p>Supported file formats: sws, html, or txt, or zip archive of such.</p> 12 11 <p>Supported file formats:</p> 12 <ul class="simple"> 13 <li><tt>.sws</tt> - a Sage worksheet</li> 14 <li><tt>.html</tt> or <tt>.txt</tt> - a worksheet text file with html code and cells surrounded by <tt>{{{</tt> and <tt>}}}</tt> that defines a worksheet</li> 15 <li><tt>.html</tt> - the URL of a page of the Sage Documentation, for example the URL of <a class="reference external" href="http://www.sagemath.org/doc/reference/sage/rings/integer.html">this page</a></li> 16 <li><tt>.html</tt> - an HTML page generated by docutils from a ReStructuredText file</li> 17 <li><tt>.rst</tt> - a ReStructuredText file (Add "<tt>.. escape-backslashes</tt>" as a line in the file if you want backslashes to be escaped. Put latex code inside backticks "<tt>`</tt>" or dollar signs "<tt>$</tt>" or "<tt>$$</tt>". Math role is not supported for now.)</li> 18 <li><tt>.zip</tt> - a zip archive of any of the above</li> 19 </ul> 13 20 <form method="POST" action="upload_worksheet" 14 21 name="upload" enctype="multipart/form-data"> 15 22 <div> 16 <label for="file">Browse your computer to select a worksheetfile to upload:</label>23 <label for="file">Browse your computer to select a file to upload:</label> 17 24 <input size="50" type="file" name="file" /> 18 25 </div> 19 26 <div> 20 <label for="url">Or enter the URL of a worksheetfile on the web:</label>27 <label for="url">Or enter the URL of a file on the web:</label> 21 28 <input size="50" type="text" name="url" /> 22 29 </div> 23 30 <div> -
sagenb/notebook/docHTMLProcessor.py
diff --git a/sagenb/notebook/docHTMLProcessor.py b/sagenb/notebook/docHTMLProcessor.py
a b 2 2 """ 3 3 Live Documentation in the Notebook 4 4 5 Processes Sage documentation into notebook worksheet format with 6 evaluable examples.5 Conversion of HTML (output by Sphinx or docutils) to Sage worksheet txt 6 file. 7 7 8 This takes in any HTML document, i.e., Sage documentation, and returns9 it in the editable format (like the notebook edit window). It also 10 returns a string representing the CSS link for the document. The SGML11 parser is setup to return only the body of the HTML documentation page 12 andto re-format Sage examples and type-setting.8 This takes an HTML document, i.e., Sage documentation, and returns it in 9 the editable format (notebook worksheet format with evaluable examples). It 10 also returns a string representing the CSS link for the document. The SGML 11 parser is setup to return only the body of the HTML documentation page and 12 to re-format Sage examples and type-setting. 13 13 14 Note: This extension of sgmllib.SGMLParser was partly inspired by Mark 15 Pilgrim's 'Dive Into Python' examples. 14 This module contains three classes: 16 15 17 Author: 16 - :class:``sagenb.notebook.docHTMLProcessor.genericHTMLProcessor`` : 17 gathers all the common methods of the other two classes. 18 19 - :class:``sagenb.notebook.docHTMLProcessor.SphinxHTMLProcessor`` : 20 translates HTML file generated by Sphinx into a worksheet text file 21 22 - :class:``sagenb.notebook.docHTMLProcessor.docutilsHTMLProcessor`` 23 translates HTML file generated by docutils ``rst2html`` command into a 24 worksheet text file 25 26 .. NOTE:: 27 28 This extension of sgmllib.SGMLParser was partly inspired by Mark 29 Pilgrim's 'Dive Into Python' examples. 30 31 AUTHORS: 18 32 19 33 - Dorian Raymer (2006): first version 20 34 21 35 - William Stein (2007-06-10): rewrite to work with twisted Sage notebook 22 36 23 37 - Mike Hansen (2008-09-27): Rewrite to work with Sphinx HTML documentation 38 39 - Sebastien Labbe (2011-01-15): Added a new class named 40 docutilsHTMLProcessor used for translating the html output of the 41 rst2html docutils command run on a rst file into worksheet text file. 42 Also added a new class named genericHTMLProcessor which gathers the 43 common methods of both docutilsHTMLProcessor and SphinxHTMLProcessor 44 classes. Added lots of doctests to make its coverage 100% doctested. 45 46 EXAMPLES: 47 48 Process the output of docutils ``rst2html`` command:: 49 50 sage: rst = "" 51 sage: rst += "Additions in Sage\n" 52 sage: rst += "-----------------\n" 53 sage: rst += "\n" 54 sage: rst += "Let's do easy computations with Sage::\n" 55 sage: rst += "\n" 56 sage: rst += " s" + "age: 4 + 3\n" 57 sage: rst += " 7\n" 58 sage: rst += " s" + "age: 1 - 2\n" 59 sage: rst += " -1\n" 60 sage: rst += "\n" 61 sage: rst += "Let's do `x^2`::\n" 62 sage: rst += "\n" 63 sage: rst += " s" + "age: x^2\n" 64 sage: rst += " x^2\n" 65 sage: from docutils.core import publish_string 66 sage: html = publish_string(rst, writer_name='html') 67 sage: from sagenb.notebook.docHTMLProcessor import docutilsHTMLProcessor 68 sage: p = docutilsHTMLProcessor() 69 sage: txt = p.process_doc_html(html) 70 sage: len(txt) 71 191 72 sage: print txt 73 <h1 class="title">Additions in Sage</h1> 74 <BLANKLINE> 75 <BLANKLINE> 76 <BLANKLINE> 77 <p>Let's do easy computations with Sage:</p> 78 <BLANKLINE> 79 {{{id=0| 80 4 + 3 81 /// 82 7 83 }}} 84 <BLANKLINE> 85 {{{id=1| 86 1 - 2 87 /// 88 -1 89 }}} 90 <BLANKLINE> 91 <p>Let's do $x^2$:</p> 92 <BLANKLINE> 93 {{{id=2| 94 x^2 95 /// 96 x^2 97 }}} 98 <BLANKLINE> 99 <BLANKLINE> 24 100 """ 25 101 ############################################################################# 26 102 # Copyright (C) 2007 William Stein <wstein@gmail.com> and Dorian Raimer 103 # Copyright (C) 2011 Sebastien Labbe <slabqc at gmail.com> 27 104 # Distributed under the terms of the GNU General Public License (GPL) 28 105 # The full text of the GPL is available at: 29 106 # http://www.gnu.org/licenses/ … … from sgmllib import SGMLParser 33 110 from urllib import splittag 34 111 from htmlentitydefs import entitydefs 35 112 36 class SphinxHTMLProcessor(SGMLParser): 37 def reset(self): 38 """ 39 Initialize necessary variables. Called by 40 :meth:`SGMLParser.__init__`. 41 42 EXAMPLES:: 43 44 sage: from sagenb.notebook.docHTMLProcessor import SphinxHTMLProcessor 45 sage: d = SphinxHTMLProcessor() 46 sage: d.bodyQ 47 False 48 sage: d.in_highlight_div 49 False 50 sage: d.temp_pieces 51 [] 52 sage: d.all_pieces 53 '' 54 sage: d.cellcount 55 0 56 """ 57 # flags 58 self.bodyQ = False #don't keep anything before the <body> tag 59 self.in_highlight_div = False 60 61 # lists of what the parser keeps 62 self.temp_pieces = [] 63 self.all_pieces = '' 64 65 # counters 66 self.cellcount = 0 67 68 SGMLParser.reset(self) 69 113 class genericHTMLProcessor(SGMLParser): 114 r""" 115 This class gathers the methods that are common to both classes 116 :class:`sagenb.notebook.SphinxHTMLProcessor` and 117 :class:`sagenb.notebook.docutilsHTMLProcessor` . 118 """ 70 119 def process_doc_html(self, doc_in): 71 120 """ 72 121 Returns processed HTML input as HTML output. This is the only … … class SphinxHTMLProcessor(SGMLParser): 79 128 OUTPUT: 80 129 81 130 - a string; the processed HTML 131 132 EXAMPLES:: 133 134 sage: rst = "" 135 sage: rst += "Title\n" 136 sage: rst += "-----\n" 137 sage: rst += "n" 138 sage: rst += "Some text\n" 139 sage: from docutils.core import publish_string 140 sage: html = publish_string(rst, writer_name='html') 141 sage: from sagenb.notebook.docHTMLProcessor import docutilsHTMLProcessor 142 sage: p = docutilsHTMLProcessor() 143 sage: txt = p.process_doc_html(html) 144 sage: len(txt) 145 51 146 sage: txt 147 '<h1 class="title">Title</h1>\n\n<p>nSome text</p>\n\n\n\n' 148 82 149 """ 83 150 # self.feed() is a SGMLParser method and starts everything 84 151 # off; Most of the functions here are extensions to … … class SphinxHTMLProcessor(SGMLParser): 86 153 self.feed(doc_in) #SGMLParser call 87 154 self.close() #SGMLParser call 88 155 self.hand_off_temp_pieces('to_doc_pieces') 89 self.all_pieces = self.all_pieces[:-16] # drop </body></html>90 156 return self.all_pieces 91 157 92 158 93 159 def hand_off_temp_pieces(self, piece_type): 94 160 """ 95 161 To separate the documentation's content from the Sage … … class SphinxHTMLProcessor(SGMLParser): 100 166 INPUT: 101 167 102 168 - ``piece_type`` - a string; indicates the type of and how to 103 process the current ``self.temp_pieces`` 169 process the current ``self.temp_pieces``. It can be one of the 170 following: 171 172 - ``"to_doc_pieces"`` - put temp_pieces in all_pieces 173 - ``"ignore"`` - delete temp_pieces 174 - ``"to_cell_pieces"`` - translate temp_pieces into cells and put 175 it in all_pieces 176 177 EXAMPLES: 178 179 Move temporary pieces to all pieces:: 180 181 sage: from sagenb.notebook.docHTMLProcessor import docutilsHTMLProcessor 182 sage: p = docutilsHTMLProcessor() 183 sage: p.all_pieces = 'a lot of stuff done ' 184 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 185 sage: p.hand_off_temp_pieces('to_doc_pieces') 186 sage: p.all_pieces 187 'a lot of stuff done bunch of tmp strings' 188 sage: p.temp_pieces 189 [] 190 191 Ignore temporary pieces:: 192 193 sage: p = docutilsHTMLProcessor() 194 sage: p.all_pieces = 'a lot of stuff done ' 195 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 196 sage: p.hand_off_temp_pieces('ignore') 197 sage: p.all_pieces 198 'a lot of stuff done ' 199 sage: p.temp_pieces 200 [] 201 202 Translate temporary pieces (starting with sage prompt) into cells:: 203 204 sage: p = docutilsHTMLProcessor() 205 sage: p.all_pieces = 'a lot of stuff done ' 206 sage: p.temp_pieces = ['sage'+': 4+4\n', '8\n', 'sage'+': 9-4\n', '5\n'] 207 sage: p.hand_off_temp_pieces('to_cell_pieces') 208 sage: print p.all_pieces 209 a lot of stuff done 210 {{{id=0| 211 4+4 212 /// 213 8 214 }}} 215 <BLANKLINE> 216 {{{id=1| 217 9-4 218 /// 219 5 220 }}} 221 sage: p.temp_pieces 222 [] 223 224 Translate temporary pieces (not starting with sage prompt) into cells:: 225 226 sage: p = docutilsHTMLProcessor() 227 sage: p.all_pieces = 'a lot of stuff done ' 228 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 229 sage: p.hand_off_temp_pieces('to_cell_pieces') 230 sage: print p.all_pieces 231 a lot of stuff done <pre class="literal-block"> 232 bunch of tmp strings 233 </pre> 234 sage: p.temp_pieces 235 [] 236 104 237 """ 105 238 pieces = "".join(self.temp_pieces) 106 239 pieces = pieces.lstrip() … … class SphinxHTMLProcessor(SGMLParser): 109 242 self.temp_pieces = [] 110 243 elif piece_type == 'ignore': 111 244 self.temp_pieces = [] 112 el se:245 elif piece_type == 'to_cell_pieces': 113 246 pieces = self.process_cell_input_output(pieces) 114 247 self.all_pieces += pieces 115 248 self.temp_pieces = [] 249 else: 250 raise ValueError('unknown piece_type(=%s)' % piece_type) 116 251 117 252 def get_cellcount(self): 118 253 """ … … class SphinxHTMLProcessor(SGMLParser): 124 259 125 260 EXAMPLES:: 126 261 262 sage: from sagenb.notebook.docHTMLProcessor import docutilsHTMLProcessor 263 sage: d = docutilsHTMLProcessor() 264 sage: d.get_cellcount() 265 0 266 sage: d.get_cellcount() 267 1 268 269 :: 270 127 271 sage: from sagenb.notebook.docHTMLProcessor import SphinxHTMLProcessor 128 272 sage: d = SphinxHTMLProcessor() 129 273 sage: d.get_cellcount() … … class SphinxHTMLProcessor(SGMLParser): 138 282 """ 139 283 Process and return a ``cell_piece``. 140 284 141 All divs with CSS class="highlight" contain code examples. 142 They include 285 All divs with CSS class="highlight" (if generated with Sphinx) or 286 class="literal-block" (if generated with docutils) contain code 287 examples. They include 143 288 144 289 - Models of how the function works. These begin with, e.g., 145 290 'INPUT:' and are re-styled as divs with … … class SphinxHTMLProcessor(SGMLParser): 156 301 OUTPUT: 157 302 158 303 - a string; the processed cell piece 304 305 EXAMPLES:: 306 307 sage: from sagenb.notebook.docHTMLProcessor import docutilsHTMLProcessor 308 sage: p = docutilsHTMLProcessor() 309 sage: s = "s" + "age: 4 + 4\n8" # avoid the doctest script to parse "sage:" 310 sage: p.process_cell_input_output(s) 311 '\n{{{id=0|\n4 + 4\n///\n8\n}}}\n\n' 312 sage: print p.process_cell_input_output(s) 313 {{{id=1| 314 4 + 4 315 /// 316 8 317 }}} 318 319 :: 320 321 sage: s = "age: 4 + 4\n8" 322 sage: print p.process_cell_input_output(s) 323 <pre class="literal-block"> 324 age: 4 + 4 325 8 326 </pre> 327 328 :: 329 330 sage: s = '>'*3 + " 4 + 4\n8" 331 sage: print p.process_cell_input_output(s) 332 {{{id=2| 333 4 + 4 334 /// 335 8 336 }}} 337 338 :: 339 340 sage: s = "s" + "age: 4 + 4\n8\ns" + "age: 2 + 2\n4" 341 sage: print p.process_cell_input_output(s) 342 {{{id=3| 343 4 + 4 344 /// 345 8 346 }}} 347 <BLANKLINE> 348 {{{id=4| 349 2 + 2 350 /// 351 4 352 }}} 159 353 """ 160 354 if cell_piece[:5] != 'sage:' and cell_piece[:12] != '>'*3: 161 piece = '<div class="highlight"><pre>' 162 piece += cell_piece 163 piece = piece.replace('{','{ ') 164 piece = piece.replace('}','} ') 165 piece += '</pre></div>' 355 piece = self.false_positive_input_output_cell(cell_piece) 166 356 else: 167 357 # group and format inputs and outputs 168 358 pieces = cell_piece.split('\n') 169 359 output_flag = False 170 piece = ' {{{id=%s|\n'%self.get_cellcount()360 piece = '\n{{{id=%s|\n'%self.get_cellcount() 171 361 for p in pieces: 172 362 173 363 if p[:5] == 'sage:' and not output_flag: 174 364 piece += p[5:].lstrip() + '\n' 175 365 elif p[:5] == 'sage:' and output_flag: 176 piece += ' }}}\n{{{id=%s|\n'%self.get_cellcount() + p[5:].lstrip() + '\n'366 piece += '\n}}}\n\n{{{id=%s|\n'%self.get_cellcount() + p[5:].lstrip() + '\n' 177 367 output_flag = False 178 368 elif p[:12] == '>'*3 and not output_flag: 179 369 piece += p[12:].lstrip() + '\n' 180 370 elif p[:12] == '>'*3 and output_flag: 181 piece += ' }}}\n{{{id=%s|\n'%self.get_cellcount() + p[12:].lstrip() + '\n'371 piece += '\n}}}\n\n{{{id=%s|\n'%self.get_cellcount() + p[12:].lstrip() + '\n' 182 372 output_flag = False 183 373 elif p[:3] == '...': 184 374 piece += p[3:] + '\n' … … class SphinxHTMLProcessor(SGMLParser): 192 382 # first occurrence of an output string 193 383 # write /// denoting output 194 384 if output_flag == False: 195 piece += '///\n' 196 piece += p + '\n' 385 piece += '///' 386 if p: 387 piece += '\n' + p 197 388 output_flag = True 198 389 # multiple output lines exist, don't need /// repeated 199 390 else: 200 piece += p + '\n'201 piece += ' }}}\n'391 piece += p 392 piece += '\n}}}\n\n' 202 393 return piece 203 394 204 395 ############################################## 205 396 ## General tag handlers 206 ## These just append their HTML to 207 ## self.temp_pieces. 208 397 ## These just append their HTML to self.temp_pieces. 209 398 def unknown_starttag(self, tag, attrs): 210 if self.bodyQ: 399 r""" 400 INPUT: 401 402 - ``tag`` - string 403 - ``attrs`` - list of tuples 404 405 EXAMPLES:: 406 407 sage: from sagenb.notebook.docHTMLProcessor import docutilsHTMLProcessor 408 sage: p = docutilsHTMLProcessor() 409 sage: p.all_pieces = 'a lot of stuff done ' 410 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 411 sage: p.keep_data = True 412 sage: tag = 'style' 413 sage: attrs = [('type', 'text/css')] 414 sage: p.unknown_starttag(tag, attrs) 415 sage: p.all_pieces 416 'a lot of stuff done ' 417 sage: p.temp_pieces 418 ['bunch ', 'of ', 'tmp ', 'strings', '<style type="text/css">'] 419 """ 420 if self.keep_data: 211 421 strattrs = "".join([' %s="%s"' % (key, value) for key, value in attrs]) 212 422 self.temp_pieces.append("<%(tag)s%(strattrs)s>" % locals()) 213 423 214 424 def unknown_endtag(self, tag): 215 if self.bodyQ: 425 r""" 426 INPUT: 427 428 - ``tag`` - string 429 430 EXAMPLES:: 431 432 sage: from sagenb.notebook.docHTMLProcessor import docutilsHTMLProcessor 433 sage: p = docutilsHTMLProcessor() 434 sage: p.all_pieces = 'a lot of stuff done ' 435 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 436 sage: p.keep_data = True 437 sage: p.unknown_endtag('head') 438 sage: p.all_pieces 439 'a lot of stuff done ' 440 sage: p.temp_pieces 441 ['bunch ', 'of ', 'tmp ', 'strings', '</head>'] 442 """ 443 if self.keep_data: 216 444 self.temp_pieces.append("</%(tag)s>" % locals()) 217 445 218 446 def handle_data(self, data): 219 if self.bodyQ: 447 r""" 448 INPUT: 449 450 - ``data`` - string 451 452 EXAMPLES:: 453 454 sage: from sagenb.notebook.docHTMLProcessor import docutilsHTMLProcessor 455 sage: p = docutilsHTMLProcessor() 456 sage: p.all_pieces = 'a lot of stuff done ' 457 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 458 sage: p.keep_data = True 459 sage: p.handle_data('some important data') 460 sage: p.all_pieces 461 'a lot of stuff done ' 462 sage: p.temp_pieces 463 ['bunch ', 'of ', 'tmp ', 'strings', 'some important data'] 464 """ 465 if self.keep_data: 220 466 self.temp_pieces.append(data) 221 222 467 def handle_charref(self, ref): 223 if self.bodyQ: 468 r""" 469 INPUT: 470 471 - ``ref`` - string 472 473 EXAMPLES:: 474 475 sage: from sagenb.notebook.docHTMLProcessor import docutilsHTMLProcessor 476 sage: p = docutilsHTMLProcessor() 477 sage: p.all_pieces = 'a lot of stuff done ' 478 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 479 sage: p.keep_data = True 480 sage: p.handle_charref('160') 481 sage: p.all_pieces 482 'a lot of stuff done ' 483 sage: p.temp_pieces 484 ['bunch ', 'of ', 'tmp ', 'strings', ' '] 485 """ 486 if self.keep_data: 224 487 self.temp_pieces.append("&#%(ref)s;" % locals()) 225 488 226 489 def handle_entityref(self, ref): 227 if self.bodyQ: 490 r""" 491 INPUT: 492 493 - ``ref`` - string 494 495 EXAMPLES:: 496 497 sage: from sagenb.notebook.docHTMLProcessor import docutilsHTMLProcessor 498 sage: p = docutilsHTMLProcessor() 499 sage: p.all_pieces = 'a lot of stuff done ' 500 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 501 sage: p.keep_data = True 502 sage: p.handle_entityref('160') 503 sage: p.all_pieces 504 'a lot of stuff done ' 505 sage: p.temp_pieces 506 ['bunch ', 'of ', 'tmp ', 'strings', '&160'] 507 """ 508 if self.keep_data: 228 509 self.temp_pieces.append("&%(ref)s" % locals()) 229 510 if entitydefs.has_key(ref): 230 511 self.temp_pieces.append(';') 231 232 512 def handle_comment(self, data): 233 if self.bodyQ: 513 r""" 514 INPUT: 515 516 - ``data`` - string 517 518 EXAMPLES:: 519 520 sage: from sagenb.notebook.docHTMLProcessor import docutilsHTMLProcessor 521 sage: p = docutilsHTMLProcessor() 522 sage: p.all_pieces = 'a lot of stuff done ' 523 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 524 sage: p.keep_data = True 525 sage: p.handle_comment('important comment') 526 sage: p.all_pieces 527 'a lot of stuff done ' 528 sage: p.temp_pieces 529 ['bunch ', 'of ', 'tmp ', 'strings', '<!--important comment-->'] 530 """ 531 if self.keep_data: 234 532 self.temp_pieces.append("<!--%(data)s-->" % locals()) 235 236 533 def handle_pi(self, text): 237 if self.bodyQ: 534 r""" 535 Handle processing instructions 536 537 INPUT: 538 539 - ``text`` - string 540 541 EXAMPLES:: 542 543 sage: from sagenb.notebook.docHTMLProcessor import docutilsHTMLProcessor 544 sage: p = docutilsHTMLProcessor() 545 sage: p.all_pieces = 'a lot of stuff done ' 546 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 547 sage: p.keep_data = True 548 sage: p.handle_pi('instructions') 549 sage: p.all_pieces 550 'a lot of stuff done ' 551 sage: p.temp_pieces 552 ['bunch ', 'of ', 'tmp ', 'strings', '<?instructions>'] 553 """ 554 if self.keep_data: 238 555 self.temp_pieces.append("<?%(text)s>" % locals()) 239 556 240 557 def handle_decl(self, text): 241 if self.bodyQ: 558 r""" 559 INPUT: 560 561 - ``data`` - string 562 563 EXAMPLES:: 564 565 sage: from sagenb.notebook.docHTMLProcessor import docutilsHTMLProcessor 566 sage: p = docutilsHTMLProcessor() 567 sage: p.all_pieces = 'a lot of stuff done ' 568 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 569 sage: p.keep_data = True 570 sage: p.handle_decl('declaration') 571 sage: p.all_pieces 572 'a lot of stuff done ' 573 sage: p.temp_pieces 574 ['bunch ', 'of ', 'tmp ', 'strings', '<!declaration>'] 575 """ 576 if self.keep_data: 242 577 self.temp_pieces.append("<!%(text)s>" % locals()) 243 578 244 245 ############################################# 579 ############################################## 246 580 ## Specific tag handlers 247 ##248 581 def start_body(self, attrs): 249 582 """ 250 Set ``self. bodyQ`` to True upon finding the opening body tag.583 Set ``self.keep_data`` to True upon finding the opening body tag. 251 584 252 585 INPUT: 253 586 … … class SphinxHTMLProcessor(SGMLParser): 258 591 259 592 sage: from sagenb.notebook.docHTMLProcessor import SphinxHTMLProcessor 260 593 sage: d = SphinxHTMLProcessor() 261 sage: d. bodyQ594 sage: d.keep_data 262 595 False 263 596 sage: d.start_body(None) 264 sage: d.bodyQ 597 sage: d.keep_data 598 True 599 600 :: 601 602 sage: from sagenb.notebook.docHTMLProcessor import docutilsHTMLProcessor 603 sage: d = docutilsHTMLProcessor() 604 sage: d.keep_data 605 False 606 sage: d.start_body(None) 607 sage: d.keep_data 265 608 True 266 609 """ 267 self. bodyQ= True610 self.keep_data = True 268 611 612 def end_body(self): 613 r""" 614 EXAMPLES:: 615 616 sage: from sagenb.notebook.docHTMLProcessor import docutilsHTMLProcessor 617 sage: p = docutilsHTMLProcessor() 618 sage: p.all_pieces = 'a lot of stuff done ' 619 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 620 sage: p.end_body() 621 sage: p.all_pieces 622 'a lot of stuff done ' 623 sage: p.temp_pieces 624 ['bunch ', 'of ', 'tmp ', 'strings'] 625 """ 626 pass 627 def end_html(self): 628 r""" 629 INPUT: 630 631 - ``data`` - string 632 633 EXAMPLES:: 634 635 sage: from sagenb.notebook.docHTMLProcessor import docutilsHTMLProcessor 636 sage: p = docutilsHTMLProcessor() 637 sage: p.all_pieces = 'a lot of stuff done ' 638 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 639 sage: p.end_html() 640 sage: p.all_pieces 641 'a lot of stuff done ' 642 sage: p.temp_pieces 643 ['bunch ', 'of ', 'tmp ', 'strings'] 644 """ 645 pass 646 647 class SphinxHTMLProcessor(genericHTMLProcessor): 648 def reset(self): 649 """ 650 Initialize necessary variables. Called by 651 :meth:`SGMLParser.__init__`. 652 653 EXAMPLES:: 654 655 sage: from sagenb.notebook.docHTMLProcessor import SphinxHTMLProcessor 656 sage: d = SphinxHTMLProcessor() #indirect doctest 657 sage: d.keep_data 658 False 659 sage: d.in_highlight_div 660 False 661 sage: d.temp_pieces 662 [] 663 sage: d.all_pieces 664 '' 665 sage: d.cellcount 666 0 667 """ 668 # flags 669 self.keep_data = False #don't keep anything before the <body> tag 670 self.in_highlight_div = False 671 672 # lists of what the parser keeps 673 self.temp_pieces = [] 674 self.all_pieces = '' 675 676 # counters 677 self.cellcount = 0 678 679 SGMLParser.reset(self) 680 681 def false_positive_input_output_cell(self, cell_piece): 682 r""" 683 Return the untouched html string of a false positive input output 684 cell. 685 686 A false positive input-output cell come from a block of code which 687 doesn't start with the sage prompt string 'sage:' or the Python 688 prompt '>>>'. 689 690 INPUT: 691 692 - ``cell_piece`` - string, a cell piece 693 694 OUPUT: 695 696 string 697 698 EXAMPLES:: 699 700 sage: from sagenb.notebook.docHTMLProcessor import SphinxHTMLProcessor 701 sage: p = SphinxHTMLProcessor() 702 sage: s = "sage -rst2html -h" 703 sage: print p.false_positive_input_output_cell(s) 704 <div class="highlight"><pre> 705 sage -rst2html -h 706 </pre></div> 707 708 """ 709 piece = '<div class="highlight"><pre>\n' 710 piece += cell_piece 711 piece = piece.replace('{','{ ') 712 piece = piece.replace('}','} ') 713 piece += '\n</pre></div>' 714 return piece 715 716 ############################################# 717 ## Specific tag handlers 718 ## 269 719 def start_div(self, attrs): 270 #Find out if we are starting a highlighted div 720 r""" 721 Find out if we are starting a highlighted div. 722 723 Once we hit the <div> tag in a highlighted block, 724 hand of all of the pieces we've encountered so far 725 and ignore the tag. 726 727 INPUT: 728 729 - ``attrs`` - list of tuple 730 731 EXAMPLES:: 732 733 sage: from sagenb.notebook.docHTMLProcessor import SphinxHTMLProcessor 734 sage: p = SphinxHTMLProcessor() 735 sage: p.all_pieces = 'a lot of stuff done ' 736 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 737 sage: attrs = [('class', 'highlight')] 738 sage: p.start_div(attrs) 739 sage: p.all_pieces 740 'a lot of stuff done bunch of tmp strings' 741 sage: p.temp_pieces 742 [] 743 sage: p.in_highlight_div 744 True 745 746 :: 747 748 sage: p = SphinxHTMLProcessor() 749 sage: p.all_pieces = 'a lot of stuff done ' 750 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 751 sage: p.keep_data = True 752 sage: attrs = [('class', 'something-else')] 753 sage: p.start_div(attrs) 754 sage: p.all_pieces 755 'a lot of stuff done ' 756 sage: p.temp_pieces 757 ['bunch ', 'of ', 'tmp ', 'strings', '<div class="something-else">'] 758 sage: p.in_highlight_div 759 False 760 """ 271 761 for name, value in attrs: 272 762 if name.lower()=='class' and value.lower()=='highlight': 273 763 self.in_highlight_div = True 764 self.hand_off_temp_pieces('to_doc_pieces') 274 765 return 275 766 self.unknown_starttag('div', attrs) 276 767 277 768 def end_div(self): 278 #Once we end the highlighted div, convert all of the pieces 279 #to cells 769 r""" 770 Once we end the highlighted div, convert all of the pieces 771 to cells. 772 773 EXAMPLES:: 774 775 sage: from sagenb.notebook.docHTMLProcessor import SphinxHTMLProcessor 776 sage: p = SphinxHTMLProcessor() 777 sage: p.all_pieces = 'a lot of stuff done ' 778 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings\n'] 779 sage: p.keep_data = True 780 sage: attrs = [('class', 'highlight')] 781 sage: p.start_div(attrs) 782 sage: p.start_pre([]) 783 sage: sprompt = 'sa' + 'ge' + ': ' # to avoid problems with doctest script 784 sage: p.handle_data('%s4+4\n8\n%sx^2\nx^2\n' % (sprompt, sprompt)) 785 sage: p.end_pre() 786 sage: p.end_div() 787 sage: print p.all_pieces 788 a lot of stuff done bunch of tmp strings 789 {{{id=0| 790 4+4 791 /// 792 8 793 }}} 794 <BLANKLINE> 795 {{{id=1| 796 x^2 797 /// 798 x^2 799 }}} 800 sage: p.temp_pieces 801 [] 802 sage: p.in_highlight_div 803 False 804 805 :: 806 807 sage: p = SphinxHTMLProcessor() 808 sage: p.all_pieces = 'a lot of stuff done ' 809 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 810 sage: p.keep_data = True 811 sage: attrs = [('class', 'something-else')] 812 sage: p.start_div(attrs) 813 sage: p.handle_data('some data') 814 sage: p.end_div() 815 sage: print p.all_pieces 816 a lot of stuff done 817 sage: p.temp_pieces 818 ['bunch ', 'of ', 'tmp ', 'strings', '<div class="something-else">', 'some data', '</div>'] 819 sage: p.in_highlight_div 820 False 821 822 """ 280 823 if self.in_highlight_div: 281 824 self.in_highlight_div = False 282 825 self.hand_off_temp_pieces('to_cell_pieces') … … class SphinxHTMLProcessor(SGMLParser): 284 827 self.temp_pieces.append("</div>") 285 828 286 829 def start_pre(self, attrs): 287 #Once we hit the <pre> tag in a highlighted block, 288 #hand of all of the pieces we've encountered so far 289 #and ignore the tag. 830 r""" 831 Ignore tag <pre> when inside highligh div. 832 833 INPUT: 834 835 - ``attrs`` - list of tuple 836 837 EXAMPLES:: 838 839 sage: from sagenb.notebook.docHTMLProcessor import SphinxHTMLProcessor 840 sage: p = SphinxHTMLProcessor() 841 sage: p.all_pieces = 'a lot of stuff done ' 842 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 843 sage: p.keep_data = True 844 sage: p.in_highlight_div = True 845 sage: attrs = [] 846 sage: p.start_pre(attrs) 847 sage: p.all_pieces 848 'a lot of stuff done ' 849 sage: p.temp_pieces 850 ['bunch ', 'of ', 'tmp ', 'strings'] 851 852 :: 853 854 sage: from sagenb.notebook.docHTMLProcessor import SphinxHTMLProcessor 855 sage: p = SphinxHTMLProcessor() 856 sage: p.all_pieces = 'a lot of stuff done ' 857 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 858 sage: p.keep_data = True 859 sage: p.in_highlight_div = False 860 sage: attrs = [] 861 sage: p.start_pre(attrs) 862 sage: p.all_pieces 863 'a lot of stuff done ' 864 sage: p.temp_pieces 865 ['bunch ', 'of ', 'tmp ', 'strings', '<pre>'] 866 """ 290 867 if self.in_highlight_div: 291 self.hand_off_temp_pieces('to_doc_pieces')292 868 return 293 869 self.unknown_starttag('pre',attrs) 294 870 295 871 def end_pre(self): 296 #Ignore the pre tags in highlighted blocks 872 r""" 873 Ignore tag </pre> when inside highligh div. 874 875 EXAMPLES:: 876 877 sage: from sagenb.notebook.docHTMLProcessor import SphinxHTMLProcessor 878 sage: p = SphinxHTMLProcessor() 879 sage: p.all_pieces = 'a lot of stuff done ' 880 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 881 sage: p.keep_data = True 882 sage: p.in_highlight_div = True 883 sage: p.end_pre() 884 sage: p.all_pieces 885 'a lot of stuff done ' 886 sage: p.temp_pieces 887 ['bunch ', 'of ', 'tmp ', 'strings'] 888 889 :: 890 891 sage: p.all_pieces = 'a lot of stuff done ' 892 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 893 sage: p.keep_data = True 894 sage: p.in_highlight_div = False 895 sage: p.end_pre() 896 sage: p.all_pieces 897 'a lot of stuff done ' 898 sage: p.temp_pieces 899 ['bunch ', 'of ', 'tmp ', 'strings', '</pre>'] 900 """ 297 901 if self.in_highlight_div: 298 902 return 299 903 self.unknown_endtag('pre') 300 904 301 905 #Ignore forms 302 906 def start_form(self, attrs): 303 #Hand of everything we've accumulated so far 907 r""" 908 Hand of everything we've accumulated so far. 909 910 Forms are ignored. 911 912 INPUT: 913 914 - ``attrs`` - list of tuple 915 916 EXAMPLES:: 917 918 sage: from sagenb.notebook.docHTMLProcessor import SphinxHTMLProcessor 919 sage: p = SphinxHTMLProcessor() 920 sage: p.all_pieces = 'a lot of stuff done ' 921 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 922 sage: attrs = [] 923 sage: p.start_form(attrs) 924 sage: p.all_pieces 925 'a lot of stuff done bunch of tmp strings' 926 sage: p.temp_pieces 927 [] 928 """ 304 929 self.hand_off_temp_pieces('to_doc_pieces') 305 930 return 306 931 307 932 def end_form(self): 308 #Ignore all of the pieces since we started 309 #the form. 933 r""" 934 Ignore all of the pieces since we started 935 the form. 936 937 EXAMPLES:: 938 939 sage: from sagenb.notebook.docHTMLProcessor import SphinxHTMLProcessor 940 sage: p = SphinxHTMLProcessor() 941 sage: p.all_pieces = 'a lot of stuff done ' 942 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 943 sage: p.end_form() 944 sage: p.all_pieces 945 'a lot of stuff done ' 946 sage: p.temp_pieces 947 [] 948 """ 310 949 self.hand_off_temp_pieces('ignore') 311 950 return 312 951 313 952 def start_span(self, attrs): 314 #Ignore all spans that occur within highlighted blocks 953 r""" 954 Ignore all spans that occur within highlighted blocks 955 956 INPUT: 957 958 - ``attrs`` - list of tuple 959 960 EXAMPLES:: 961 962 sage: from sagenb.notebook.docHTMLProcessor import SphinxHTMLProcessor 963 sage: p = SphinxHTMLProcessor() 964 sage: p.all_pieces = 'a lot of stuff done ' 965 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 966 sage: p.keep_data = True 967 sage: p.in_highlight_div = True 968 sage: attrs = [] 969 sage: p.start_span(attrs) 970 sage: p.all_pieces 971 'a lot of stuff done ' 972 sage: p.temp_pieces 973 ['bunch ', 'of ', 'tmp ', 'strings'] 974 975 :: 976 977 sage: from sagenb.notebook.docHTMLProcessor import SphinxHTMLProcessor 978 sage: p = SphinxHTMLProcessor() 979 sage: p.all_pieces = 'a lot of stuff done ' 980 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 981 sage: p.keep_data = True 982 sage: p.in_highlight_div = False 983 sage: attrs = [] 984 sage: p.start_span(attrs) 985 sage: p.all_pieces 986 'a lot of stuff done ' 987 sage: p.temp_pieces 988 ['bunch ', 'of ', 'tmp ', 'strings', '<span>'] 989 """ 315 990 if self.in_highlight_div: 316 991 return 317 992 self.unknown_starttag('span', attrs) 318 319 993 def end_span(self): 320 #Ignore all spans that occur within highlighted blocks 994 r""" 995 Ignore all spans that occur within highlighted blocks 996 997 EXAMPLES:: 998 999 sage: from sagenb.notebook.docHTMLProcessor import SphinxHTMLProcessor 1000 sage: p = SphinxHTMLProcessor() 1001 sage: p.all_pieces = 'a lot of stuff done ' 1002 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 1003 sage: p.keep_data = True 1004 sage: p.in_highlight_div = True 1005 sage: p.end_span() 1006 sage: p.all_pieces 1007 'a lot of stuff done ' 1008 sage: p.temp_pieces 1009 ['bunch ', 'of ', 'tmp ', 'strings'] 1010 1011 :: 1012 1013 sage: p.all_pieces = 'a lot of stuff done ' 1014 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 1015 sage: p.keep_data = True 1016 sage: p.in_highlight_div = False 1017 sage: p.end_span() 1018 sage: p.all_pieces 1019 'a lot of stuff done ' 1020 sage: p.temp_pieces 1021 ['bunch ', 'of ', 'tmp ', 'strings', '</span>'] 1022 """ 321 1023 if self.in_highlight_div: 322 1024 return 323 1025 self.unknown_endtag('span') 1026 1027 class docutilsHTMLProcessor(genericHTMLProcessor): 1028 r""" 1029 Translates output of the docutils parser rst2html into notebook text. 1030 1031 EXAMPLES:: 1032 1033 sage: rst = "" 1034 sage: rst += "Additions in Sage\n" 1035 sage: rst += "-----------------\n" 1036 sage: rst += "\n" 1037 sage: rst += "Let's do easy computations with Sage::\n" 1038 sage: rst += "\n" 1039 sage: rst += " s" + "age: 4 + 3\n" 1040 sage: rst += " 7\n" 1041 sage: rst += " s" + "age: 1 - 2\n" 1042 sage: rst += " -1\n" 1043 sage: rst += "\n" 1044 sage: rst += "Let's do `x^2`::\n" 1045 sage: rst += "\n" 1046 sage: rst += " s" + "age: x^2\n" 1047 sage: rst += " x^2\n" 1048 sage: from docutils.core import publish_string 1049 sage: html = publish_string(rst, writer_name='html') 1050 sage: from sagenb.notebook.docHTMLProcessor import docutilsHTMLProcessor 1051 sage: p = docutilsHTMLProcessor() 1052 sage: txt = p.process_doc_html(html) 1053 sage: len(txt) 1054 191 1055 sage: print txt 1056 <h1 class="title">Additions in Sage</h1> 1057 <BLANKLINE> 1058 <BLANKLINE> 1059 <BLANKLINE> 1060 <p>Let's do easy computations with Sage:</p> 1061 <BLANKLINE> 1062 {{{id=0| 1063 4 + 3 1064 /// 1065 7 1066 }}} 1067 <BLANKLINE> 1068 {{{id=1| 1069 1 - 2 1070 /// 1071 -1 1072 }}} 1073 <BLANKLINE> 1074 <p>Let's do $x^2$:</p> 1075 <BLANKLINE> 1076 {{{id=2| 1077 x^2 1078 /// 1079 x^2 1080 }}} 1081 <BLANKLINE> 1082 <BLANKLINE> 1083 1084 """ 1085 def reset(self): 1086 """ 1087 Initialize necessary variables. Called by 1088 :meth:`SGMLParser.__init__`. 1089 1090 EXAMPLES:: 1091 1092 sage: from sagenb.notebook.docHTMLProcessor import docutilsHTMLProcessor 1093 sage: d = docutilsHTMLProcessor() #indirect doctest 1094 sage: d.keep_data 1095 False 1096 sage: d.in_pre_litteral_block 1097 False 1098 sage: d.in_div_footer_block 1099 False 1100 sage: d.temp_pieces 1101 [] 1102 sage: d.all_pieces 1103 '' 1104 sage: d.cellcount 1105 0 1106 """ 1107 # flags 1108 self.keep_data = False #don't keep anything before the <body> tag 1109 self.in_pre_litteral_block = False 1110 self.in_div_footer_block = False 1111 1112 # lists of what the parser keeps 1113 self.temp_pieces = [] 1114 self.all_pieces = '' 1115 1116 # counters 1117 self.cellcount = 0 1118 1119 SGMLParser.reset(self) 1120 1121 def false_positive_input_output_cell(self, cell_piece): 1122 r""" 1123 Return the untouched html string of a false positive input output 1124 cell. 1125 1126 A false positive input-output cell come from a block of code which 1127 doesn't start with the sage prompt string 'sage:' or the Python 1128 prompt '>>>'. 1129 1130 INPUT: 1131 1132 - ``cell_piece`` - string, a cell piece 1133 1134 OUPUT: 1135 1136 string 1137 1138 EXAMPLES:: 1139 1140 sage: from sagenb.notebook.docHTMLProcessor import docutilsHTMLProcessor 1141 sage: p = docutilsHTMLProcessor() 1142 sage: s = "sage -rst2html -h" 1143 sage: print p.false_positive_input_output_cell(s) 1144 <pre class="literal-block"> 1145 sage -rst2html -h 1146 </pre> 1147 1148 """ 1149 piece = '<pre class="literal-block">\n' 1150 piece += cell_piece 1151 piece = piece.replace('{','{ ') 1152 piece = piece.replace('}','} ') 1153 piece += '\n</pre>' 1154 return piece 1155 1156 ############################################# 1157 ## Specific tag handlers 1158 ## 1159 # sage blocks 1160 def start_pre(self, attrs): 1161 r""" 1162 INPUT: 1163 1164 - ``attrs`` - list of tuple 1165 1166 EXAMPLES:: 1167 1168 sage: from sagenb.notebook.docHTMLProcessor import docutilsHTMLProcessor 1169 sage: p = docutilsHTMLProcessor() 1170 sage: p.all_pieces = 'a lot of stuff done ' 1171 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 1172 sage: attrs = [('class', 'literal-block')] 1173 sage: p.start_pre(attrs) 1174 sage: p.all_pieces 1175 'a lot of stuff done bunch of tmp strings' 1176 sage: p.temp_pieces 1177 [] 1178 sage: p.in_pre_litteral_block 1179 True 1180 1181 :: 1182 1183 sage: p = docutilsHTMLProcessor() 1184 sage: p.all_pieces = 'a lot of stuff done ' 1185 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 1186 sage: p.keep_data = True 1187 sage: attrs = [('class', 'something-else')] 1188 sage: p.start_pre(attrs) 1189 sage: p.all_pieces 1190 'a lot of stuff done ' 1191 sage: p.temp_pieces 1192 ['bunch ', 'of ', 'tmp ', 'strings', '<pre class="something-else">'] 1193 sage: p.in_pre_litteral_block 1194 False 1195 """ 1196 #Find out if we are starting a pre litteral-block 1197 for name, value in attrs: 1198 if name.lower()=='class' and value.lower()=='literal-block': 1199 self.in_pre_litteral_block = True 1200 self.hand_off_temp_pieces('to_doc_pieces') 1201 return 1202 self.unknown_starttag('pre',attrs) 1203 1204 def end_pre(self): 1205 r""" 1206 EXAMPLES:: 1207 1208 sage: from sagenb.notebook.docHTMLProcessor import docutilsHTMLProcessor 1209 sage: p = docutilsHTMLProcessor() 1210 sage: p.all_pieces = 'a lot of stuff done ' 1211 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 1212 sage: p.keep_data = True 1213 sage: attrs = [('class', 'literal-block')] 1214 sage: p.start_pre(attrs) 1215 sage: sprompt = 'sa' + 'ge' + ': ' # to avoid problems with doctest script 1216 sage: p.handle_data('%s4+4\n8\n%sx^2\nx^2\n' % (sprompt, sprompt)) 1217 sage: p.end_pre() 1218 sage: print p.all_pieces 1219 a lot of stuff done bunch of tmp strings 1220 {{{id=0| 1221 4+4 1222 /// 1223 8 1224 }}} 1225 <BLANKLINE> 1226 {{{id=1| 1227 x^2 1228 /// 1229 x^2 1230 }}} 1231 sage: p.temp_pieces 1232 [] 1233 sage: p.in_pre_litteral_block 1234 False 1235 1236 :: 1237 1238 sage: from sagenb.notebook.docHTMLProcessor import docutilsHTMLProcessor 1239 sage: p = docutilsHTMLProcessor() 1240 sage: p.all_pieces = 'a lot of stuff done ' 1241 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 1242 sage: p.keep_data = True 1243 sage: attrs = [('class', 'something-else')] 1244 sage: p.start_pre(attrs) 1245 sage: p.handle_data('some data') 1246 sage: p.end_pre() 1247 sage: print p.all_pieces 1248 a lot of stuff done 1249 sage: p.temp_pieces 1250 ['bunch ', 'of ', 'tmp ', 'strings', '<pre class="something-else">', 'some data', '</pre>'] 1251 sage: p.in_pre_litteral_block 1252 False 1253 """ 1254 if self.in_pre_litteral_block: 1255 self.in_pre_litteral_block = False 1256 self.hand_off_temp_pieces('to_cell_pieces') 1257 return 1258 self.unknown_endtag('pre') 1259 1260 # Ignore div 1261 def start_div(self, attrs): 1262 r""" 1263 INPUT: 1264 1265 - ``attrs`` - list of tuple 1266 1267 EXAMPLES:: 1268 1269 sage: from sagenb.notebook.docHTMLProcessor import docutilsHTMLProcessor 1270 sage: p = docutilsHTMLProcessor() 1271 sage: p.all_pieces = 'a lot of stuff done ' 1272 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 1273 sage: attrs = [('class', 'document'), ('id', 'title')] 1274 sage: p.start_div(attrs) 1275 sage: p.all_pieces 1276 'a lot of stuff done ' 1277 sage: p.temp_pieces 1278 ['bunch ', 'of ', 'tmp ', 'strings'] 1279 """ 1280 #Find out if we are starting a div footer block 1281 for name, value in attrs: 1282 if name.lower()=='class' and value.lower()=='footer': 1283 self.hand_off_temp_pieces('to_doc_pieces') 1284 self.keep_data = False 1285 self.in_div_footer_block = True 1286 return 1287 return 1288 1289 def end_div(self): 1290 r""" 1291 EXAMPLES:: 1292 1293 sage: from sagenb.notebook.docHTMLProcessor import docutilsHTMLProcessor 1294 sage: p = docutilsHTMLProcessor() 1295 sage: p.all_pieces = 'a lot of stuff done ' 1296 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 1297 sage: p.end_div() 1298 sage: p.all_pieces 1299 'a lot of stuff done ' 1300 sage: p.temp_pieces 1301 ['bunch ', 'of ', 'tmp ', 'strings'] 1302 """ 1303 if self.in_div_footer_block: 1304 self.in_div_footer_block = False 1305 self.keep_data = True 1306 return 1307 1308 # latex role 1309 def start_cite(self, attrs): 1310 r""" 1311 INPUT: 1312 1313 - ``attrs`` - list of tuple 1314 1315 EXAMPLES:: 1316 1317 sage: from sagenb.notebook.docHTMLProcessor import docutilsHTMLProcessor 1318 sage: p = docutilsHTMLProcessor() 1319 sage: p.all_pieces = 'a lot of stuff done ' 1320 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 1321 sage: p.keep_data = True 1322 sage: attrs = [] 1323 sage: p.start_cite(attrs) 1324 sage: p.all_pieces 1325 'a lot of stuff done ' 1326 sage: p.temp_pieces 1327 ['bunch ', 'of ', 'tmp ', 'strings', '$'] 1328 """ 1329 self.temp_pieces.append("$") 1330 return 1331 1332 def end_cite(self): 1333 r""" 1334 EXAMPLES:: 1335 1336 sage: from sagenb.notebook.docHTMLProcessor import docutilsHTMLProcessor 1337 sage: p = docutilsHTMLProcessor() 1338 sage: p.all_pieces = 'a lot of stuff done ' 1339 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 1340 sage: p.keep_data = True 1341 sage: p.start_cite([]) 1342 sage: p.handle_data('x^2') 1343 sage: p.end_cite() 1344 sage: p.all_pieces 1345 'a lot of stuff done ' 1346 sage: p.temp_pieces 1347 ['bunch ', 'of ', 'tmp ', 'strings', '$', 'x^2', '$'] 1348 """ 1349 self.temp_pieces.append("$") 1350 return 1351 1352 # script (for example for mathjax) 1353 def start_script(self, attrs): 1354 r""" 1355 INPUT: 1356 1357 - ``attrs`` - list of tuple 1358 1359 EXAMPLES:: 1360 1361 sage: from sagenb.notebook.docHTMLProcessor import docutilsHTMLProcessor 1362 sage: p = docutilsHTMLProcessor() 1363 sage: p.all_pieces = 'a lot of stuff done ' 1364 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 1365 sage: attrs = [('type', 'text/x-mathjax-config')] 1366 sage: p.start_script(attrs) 1367 sage: p.all_pieces 1368 'a lot of stuff done ' 1369 sage: p.temp_pieces 1370 ['bunch ', 'of ', 'tmp ', 'strings'] 1371 sage: p.keep_data 1372 False 1373 """ 1374 self.keep_data = False 1375 return 1376 1377 def end_script(self): 1378 r""" 1379 EXAMPLES:: 1380 1381 sage: from sagenb.notebook.docHTMLProcessor import docutilsHTMLProcessor 1382 sage: p = docutilsHTMLProcessor() 1383 sage: p.all_pieces = 'a lot of stuff done ' 1384 sage: p.temp_pieces = ['bunch ', 'of ', 'tmp ', 'strings'] 1385 sage: p.end_script() 1386 sage: p.all_pieces 1387 'a lot of stuff done ' 1388 sage: p.temp_pieces 1389 ['bunch ', 'of ', 'tmp ', 'strings'] 1390 sage: p.keep_data 1391 True 1392 """ 1393 self.keep_data = True 1394 return 1395 -
sagenb/notebook/notebook.py
diff --git a/sagenb/notebook/notebook.py b/sagenb/notebook/notebook.py
a b class Notebook(object): 700 700 elif ext.lower() == '.html': 701 701 # An html file, which should contain the static version of 702 702 # a sage help page, as generated by Sphinx 703 W = self._import_worksheet_html(filename, owner) 703 html = open(filename).read() 704 705 cell_pattern = r"""{{{id=.*?///.*?}}}""" 706 docutils_pattern = r"""<meta name="generator" content="Docutils \S+: http://docutils\.sourceforge\.net/" />""" 707 sphinx_pattern = r"""Created using <a href="http://sphinx\.pocoo\.org/">Sphinx</a>""" 708 709 if re.search(cell_pattern, html, re.DOTALL) is not None: 710 W = self._import_worksheet_txt(filename, owner) 711 elif re.search(docutils_pattern, html) is not None: 712 W = self._import_worksheet_docutils_html(filename, owner) 713 elif re.search(sphinx_pattern, html) is not None: 714 W = self._import_worksheet_html(filename, owner) 715 else: 716 # Unrecognized html file 717 # We do the default behavior, i.e. we import as if it was generated 718 # by Sphinx web page 719 W = self._import_worksheet_html(filename, owner) 720 elif ext.lower() == '.rst': 721 # A ReStructuredText file 722 W = self._import_worksheet_rst(filename, owner) 704 723 else: 705 # We only support txt, sws, and htmlfiles724 # We only support txt, sws, html and rst files 706 725 raise ValueError, "unknown extension '%s'"%ext 707 726 self.__worksheets[W.filename()] = W 708 727 return W … … class Notebook(object): 800 819 801 820 INPUT: 802 821 803 - ``filename`` - a string; a filename that ends in . txt822 - ``filename`` - a string; a filename that ends in .html 804 823 805 824 - ``owner`` - a string; the imported worksheet's owner 806 825 … … class Notebook(object): 853 872 <p>Here are some computations:</p> 854 873 <BLANKLINE> 855 874 <div class="highlight-python">, Cell 0; in=1+1, out= 856 2 857 , TextCell 2: </div> 875 2, TextCell 2: </div> 858 876 <BLANKLINE> 859 </div></div></div></div ]877 </div></div></div></div>] 860 878 sage: cell = W.cell_list()[1] 861 879 sage: cell.input_text() 862 880 u'1+1' … … class Notebook(object): 883 901 884 902 return worksheet 885 903 904 def _import_worksheet_rst(self, filename, owner): 905 r""" 906 Import a ReStructuredText file as a new worksheet. 907 908 INPUT: 909 910 - ``filename`` - a string; a filename that ends in .rst 911 912 - ``owner`` - a string; the imported worksheet's owner 913 914 OUTPUT: 915 916 - a new instance of Worksheet 917 918 EXAMPLES: 919 920 sage: sprompt = 'sage' + ':' 921 sage: rst = '\n'.join(['=============', 922 ... 'Test Notebook', 923 ... '=============', 924 ... '', 925 ... 'Let\'s do some computations::', 926 ... '', 927 ... ' %s 2+2' % sprompt, 928 ... ' 4', 929 ... '', 930 ... '::', 931 ... '', 932 ... ' %s x^2' % sprompt, 933 ... ' x^2']) 934 sage: name = tmp_filename() + '.rst' 935 sage: fd = open(name,'w') 936 sage: fd.write(rst) 937 sage: fd.close() 938 sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb') 939 sage: W = nb._import_worksheet_rst(name, 'admin') 940 sage: W.name() 941 u'Test Notebook' 942 sage: W.owner() 943 'admin' 944 sage: W.cell_list() 945 [TextCell 2: <h1 class="title">Test Notebook</h1> 946 <BLANKLINE> 947 <p>Let's do some computations:</p>, Cell 0; in=2+2, out= 948 4, Cell 1; in=x^2, out= 949 x^2] 950 sage: cell = W.cell_list()[1] 951 sage: cell.input_text() 952 u'2+2' 953 sage: cell.output_text() 954 u'<pre class="shrunk">4</pre>' 955 956 """ 957 rst = open(filename).read() 958 959 # docutils removes the backslashes if they are not escaped This is 960 # not practical because backslashes are almost never escaped in 961 # Sage docstrings written in ReST. So if the user wants the 962 # backslashes to be escaped automatically, he adds the comment 963 # ".. escape-backslashes" in the input file 964 if re.search(r'^\.\.[ \t]+escape-backslashes', rst, re.MULTILINE) is not None: 965 rst = rst.replace('\\','\\\\') 966 967 # Do the translation rst -> html (using docutils) 968 from docutils.core import publish_parts 969 D = publish_parts(rst, writer_name='html') 970 title = D['title'] 971 html = D['whole'] 972 973 # Do the translation html -> txt 974 from docHTMLProcessor import docutilsHTMLProcessor 975 translator = docutilsHTMLProcessor() 976 worksheet_txt = translator.process_doc_html(html) 977 978 # Create worksheet 979 worksheet = self.create_new_worksheet(title, owner) 980 worksheet.edit_save(worksheet_txt) 981 982 return worksheet 983 984 def _import_worksheet_docutils_html(self, filename, owner): 985 r""" 986 Import a static html help page generated by docutils as a new 987 worksheet. 988 989 INPUT: 990 991 - ``filename`` - a string; a filename that ends in .html 992 993 - ``owner`` - a string; the imported worksheet's owner 994 995 OUTPUT: 996 997 - a new instance of Worksheet 998 999 EXAMPLES: 1000 1001 sage: sprompt = 'sage' + ':' 1002 sage: rst = '\n'.join(['=============', 1003 ... 'Test Notebook', 1004 ... '=============', 1005 ... '', 1006 ... 'Let\'s do some computations::', 1007 ... '', 1008 ... ' %s 2+2' % sprompt, 1009 ... ' 4', 1010 ... '', 1011 ... '::', 1012 ... '', 1013 ... ' %s x^2' % sprompt, 1014 ... ' x^2']) 1015 sage: from docutils.core import publish_string 1016 sage: html = publish_string(rst, writer_name='html') 1017 sage: name = tmp_filename() + '.html' 1018 sage: fd = open(name,'w') 1019 sage: fd.write(html) 1020 sage: fd.close() 1021 sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb') 1022 sage: W = nb._import_worksheet_docutils_html(name, 'admin') 1023 sage: W.name() 1024 u'Test Notebook' 1025 sage: W.owner() 1026 'admin' 1027 sage: W.cell_list() 1028 [TextCell 2: <h1 class="title">Test Notebook</h1> 1029 <BLANKLINE> 1030 <p>Let's do some computations:</p>, Cell 0; in=2+2, out= 1031 4, Cell 1; in=x^2, out= 1032 x^2] 1033 sage: cell = W.cell_list()[1] 1034 sage: cell.input_text() 1035 u'2+2' 1036 sage: cell.output_text() 1037 u'<pre class="shrunk">4</pre>' 1038 1039 """ 1040 html = open(filename).read() 1041 1042 # Do the translation html -> txt 1043 from docHTMLProcessor import docutilsHTMLProcessor 1044 translator = docutilsHTMLProcessor() 1045 worksheet_txt = translator.process_doc_html(html) 1046 1047 # Extract title 1048 from worksheet import extract_name 1049 title, _ = extract_name(worksheet_txt) 1050 if title.startswith('<h1 class="title">'): 1051 title = title[18:] 1052 if title.endswith('</h1>'): 1053 title = title[:-5] 1054 1055 # Create worksheet 1056 worksheet = self.create_new_worksheet(title, owner) 1057 worksheet.edit_save(worksheet_txt) 1058 1059 return worksheet 1060 886 1061 def change_worksheet_name_to_avoid_collision(self, worksheet): 887 1062 """ 888 1063 Change the display name of the worksheet if there is already a