Ticket #6568: trac_6568-jinja_migration_v2.patch
File trac_6568-jinja_migration_v2.patch, 137.4 KB (added by , 12 years ago) |
---|
-
sage/server/notebook/notebook.py
# HG changeset patch # User Mitesh Patel <qed777@gmail.com> # Date 1250300225 25200 # Node ID b9893319d0926141a5e3c8e5f4973c3bb48c69e4 # Parent 4a994d18ceef6dadc9419b812d5a9aacb45e1b62 #6568, notebook Jinja migration, combined Tim Dumol's patches * * * * Migrated notebook.py from HTML to Jinja. ** notebook._html_body ** notebook._html_head ** notebook.html_topbar ** notebook.html_banner_and_control ** notebook.html_user_control ** notebook.html_banner ** notebook.html_debug_window ** notebook.plain_text_worksheet_html ** notebook.worksheet_html ** notebook.html_worksheet_revision_list ** html_specific_revision ** history_html ** html_worksheet_revision_list ** html_specific_revision ** html_share ** html_download_or_delete_datafile ** html_slide_controls ** html_debug_window ** html_edit_window ** html_beforepublish_window ** html_afterpublish_window ** html_upload_data_window ** html ** html_settings ** html_doc * Created a template to replace html_worksheet_page_template * * * * Completed migration of worksheet.py to Jinja and added doctests ** worksheet.html ** worksheet.html_title ** worksheet.html_share_publish_buttons ** worksheet.html_menu ** worksheet.html_worksheet_body ** worksheet.time_since_last_edited ** worksheet.attached_html ** worksheet.format_completions_as_html * Changed template directory scheme from a flat to nested tree * Removed unused functions: ** notebook.html_system_select_form_element ** notebook.html_pretty_print_check_form_element ** notebook.html_slide_controls ** notebook.html_worksheet_page_template ** notebook._html_head ** notebook.html_worksheet_topbar ** notebook._html_body * * * * Fixed various bugs in the templates. ** Fixed bug in `published_worksheet.html` and `worksheet_body.html` that allowed editing of published worksheets. ** Fixed bug in `afterpublish_window.html` that caused the "re-publish" and "stop publishing" buttons not to work. ** Fixed bug in various templates that caused ``main.css`` not to load. ** Fixed bug in print representation of a worksheet that caused ``main.css`` not to load. ** Fixed typo: 'reviisions' to 'revisions' * * * * Fixed bug in styling of documentation pages * * * * Fixed a few bugs in templating. ** Fixed bug where `worksheet.html` was not passed the do_print argument. ** Fixed typo in `beforepublish_window.html` diff --git a/sage/server/notebook/notebook.py b/sage/server/notebook/notebook.py
a b from sage.misc.misc import (alar 24 24 tmp_dir, pad_zeros, cputime) 25 25 from sage.misc.package import is_package_installed 26 26 from sage.version import version 27 27 28 # Sage Notebook 28 29 import css # style 29 30 import js # javascript … … import keyboards # keyboard layouts 33 34 import server_conf # server configuration 34 35 import user_conf # user configuration 35 36 import user # users 37 from template import template 36 38 37 39 from cgi import escape 38 40 … … class Notebook(SageObject): 167 169 # quickly, etc. 168 170 shutil.rmtree(dir, ignore_errors=True) 169 171 172 def systems(self): 173 return SYSTEMS 174 175 def system_names(self): 176 return SYSTEM_NAMES 170 177 ########################################################## 171 178 # Users 172 179 ########################################################## … … class Notebook(SageObject): 908 915 return MAX_HISTORY_LENGTH 909 916 910 917 def history_html(self): 911 t = self.history_text() 912 t = escape(t) 913 s = '<head>\n' 914 s += '<title>Command History</title>\n' 915 s += '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">' 916 s += '</head>\n' 917 s += '<body>\n' 918 s += '<pre>' + t + '</pre>\n' 919 s += '<a name="bottom"></a>\n' 920 s += '<script type="text/javascript"> window.location="#bottom"</script>\n' 921 s += '</body>\n' 922 return s 918 return template("notebook/command_history.html", history_text = escape(self.history_text())) 923 919 924 920 925 921 def history_with_start(self, start): … … class Notebook(SageObject): 1169 1165 # Importing and exporting worksheets to a plain text format 1170 1166 ########################################################## 1171 1167 1172 def plain_text_worksheet_html(self, name, prompts=True): 1173 W = self.get_worksheet_with_filename(name) 1174 t = W.plain_text(prompts = prompts) 1175 t = escape(t) 1176 s = '<head>\n' 1177 s += '<title>Sage Worksheet: %s</title>\n'%W.name() 1178 s += '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">' 1179 s += '</head>\n' 1180 s += '<body>\n' 1181 s += '<h1><a href=".">Sage Worksheet: %s</a></h1>\n'%W.name() 1182 s += '<pre>' + t + '</pre>' 1183 s += '</body>\n' 1184 return s 1168 def plain_text_worksheet_html(self, filename, prompts=True): 1169 """ 1170 Outputs html containing the plain text version of a worksheet 1171 1172 INPUT: 1173 - ``filename`` - filename of a worksheet 1174 - ``prompts`` - boolean 1175 1176 OUTPUT: 1177 - A string containing the html for the plain text version 1178 """ 1179 worksheet = self.get_worksheet_with_filename(filename) 1180 text = escape(worksheet.plain_text(prompts = prompts)) 1181 return template("notebook/plain_text_worksheet.html", 1182 worksheet_name = worksheet.name(), 1183 worksheet_plain_text = text) 1185 1184 1186 1185 ########################################################## 1187 1186 # Directories for worksheets, etc. … … class Notebook(SageObject): 1310 1309 return s 1311 1310 1312 1311 def worksheet_html(self, filename, do_print=False): 1313 W = self.get_worksheet_with_filename(filename) 1314 s = '<head>\n' 1315 s += '<title>Sage Worksheet: %s</title>\n'%W.name() 1316 s += '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">' 1317 s += '<script type="text/javascript" src="/javascript_local/jquery/jquery.js"></script>' 1318 s += '<script type="text/javascript" src="/javascript/main.js"></script>\n' 1319 if do_print: 1320 s += '<script type="text/javascript" src="/javascript_local/jsmath/jsMath.js"></script>\n' 1321 s += '<link rel=stylesheet href="/css/main.css">\n' 1322 s += '</head>\n' 1323 if do_print: 1324 s += '<body>\n' 1325 s += '<div class="worksheet_print_title">%s</div>'%W.name() 1326 else: 1327 s += '<body class="worksheet-online" onLoad="initialize_the_notebook();">\n' 1328 s += W.html(include_title=False, do_print=do_print) 1329 if do_print: 1330 s += '<script type="text/javascript">jsMath.Process();</script>\n' 1331 s += '\n</body>\n' 1332 return s 1312 """ 1313 Returns the HTML for the worksheet. 1314 1315 INPUT: 1316 - ``username`` - a string 1317 - ``worksheet`` - an instance of Worksheet 1318 1319 OUTPUT: 1320 - a string containing the HTML 1321 1322 EXAMPLES:: 1323 1324 sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir()) 1325 sage: W = nb.create_new_worksheet('Test', 'admin') 1326 sage: nb.worksheet_html(W.filename()) 1327 '\n<!D...ript type="text/javascript">cell_id_list=[0];</script>\n\n\n\n\n\n </body>\n</html>' 1328 """ 1329 worksheet = self.get_worksheet_with_filename(filename) 1330 return template("notebook/worksheet.html", worksheet_name = worksheet.name(), 1331 worksheet_html = worksheet.html(include_title=False, do_print=do_print), 1332 do_print = do_print) 1333 1333 1334 1334 1335 1335 … … class Notebook(SageObject): 1355 1355 sort_worksheet_list(W, sort, reverse) # changed W in place 1356 1356 return W 1357 1357 1358 def html_topbar(self, user, pub=False):1359 s = ''1360 entries = []1361 1362 if self.user_is_guest(user):1363 entries.append(('/', 'Log in', 'Please log in to the Sage notebook'))1364 else:1365 entries.append(('/home/%s'%user, 'Home', 'Back to your personal worksheet list'))1366 entries.append(('/pub', 'Published', 'Browse the published worksheets'))1367 entries.append(('help()', 'Help', 'Documentation'))1368 1369 ## TODO -- settings1370 #if self.user(user).is_admin():1371 # entries.insert(1, ('/notebook_settings', 'Server', 'Change general Sage notebook server configuration'))1372 if not pub:1373 entries.insert(2, ('history_window()', 'Log', 'View a log of recent computations'))1374 if not self.user_is_guest(user):1375 entries.append(('/settings', 'Settings', 'Change account settings including password'))1376 entries.append(('/logout', 'Sign out', 'Log out of the Sage notebook'))1377 1378 s += self.html_banner_and_control(user, entries)1379 s += '<hr class="usercontrol">'1380 return s1381 1382 def html_banner_and_control(self, user, entries):1383 return """1384 <table width="100%%"><tr><td>1385 %s1386 </td><td align=right>1387 %s1388 </td></tr>1389 </table>1390 """%(self.html_banner(),1391 self.html_user_control(user, entries))1392 1393 1394 def html_user_control(self, user, entries):1395 s = ''1396 s += '<span class="username">%s</span>'%user1397 for href, name, title in entries:1398 if '(' in href:1399 action = 'onClick="%s"'%href1400 else:1401 action = 'href="%s"'%href1402 x = '<a title="%s" class="usercontrol" %s>%s</a>\n'%(title, action, name)1403 s += vbar + x1404 return s1405 1406 def html_banner(self):1407 ver=version1408 s = """1409 <div class="banner">1410 <table width="100%%"><tr><td>1411 <a class="banner" href="http://www.sagemath.org"><img align="top" src="/images/sagelogo.png" alt="Sage"> Notebook</a></td><td><span class="ping" id="ping">Searching for Sage server...</span></td>1412 </tr><tr><td style="font-size:xx-small; text-indent:13px; color:black">Version %s</td><td></td></tr></table>1413 </div>1414 """%ver1415 return s1416 1417 1418 1358 ########################################################## 1419 1359 # Revision history for a worksheet 1420 1360 ########################################################## 1421 1361 def html_worksheet_revision_list(self, username, worksheet): 1422 head, body = self.html_worksheet_page_template(worksheet, username, "Revision history", select="revisions") 1362 """ 1363 Returns the HTML for the revision list of a worksheet. 1364 1365 INPUT: 1366 - ``username`` - a string 1367 - ``worksheet`` - an instance of Worksheet 1368 1369 OUTPUT: 1370 - a string containing the HTML 1371 1372 EXAMPLES:: 1373 1374 sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir()) 1375 sage: W = nb.create_new_worksheet('Test', 'admin') 1376 sage: nb.html_worksheet_revision_list('admin', W) 1377 '\n<!D...seconds ago</span></td>\n </tr>\n\n</table>\n\n\n </body>\n</html>' 1378 """ 1423 1379 data = worksheet.snapshot_data() # pairs ('how long ago', key) 1424 rows = []1425 i = 01426 for i in range(len(data)):1427 desc, key = data[i]1428 rows.append('<tr><td></td><td><a href="revisions?rev=%s">Revision %s</a></td><td><span class="revs">%s</span></td></tr>'%1429 (key, i, desc))1430 1431 rows = list(reversed(rows))1432 rows = '\n'.join(rows)1433 body += """1434 <hr class="usercontrol">1435 <table width="100%%">1436 <tr><td width="1%%"></td><td width="20%%"><b>Revision</b></td> <td width="20%%"><b>Last Edited</b></td><td width="30%%"></td>1437 %s1438 </table>1439 """%rows1440 1380 1441 return """ 1442 <html> 1443 <head>%s</head> 1444 <body>%s</body> 1445 </html> 1446 """%(head, body) 1381 return template("notebook/worksheet_revision_list.html", data = data, 1382 worksheet = worksheet, 1383 worksheet_filename = worksheet.filename(), 1384 username = username, 1385 JSMATH = JSMATH, 1386 JSMATH_IMAGE_FONTS = JSMATH_IMAGE_FONTS, 1387 JEDITABLE_TINYMCE = JEDITABLE_TINYMCE, 1388 sage_jsmath_macros = sage_jsmath_macros) 1447 1389 1448 1390 1449 1391 def html_specific_revision(self, username, ws, rev): 1392 """ 1393 Returns the HTML for a revision of the worksheet. 1394 1395 INPUT: 1396 - ``username`` - a string 1397 - ``ws`` - an instance of Worksheet 1398 - ``rev`` - a string containing the key of the revision 1399 1400 OUTPUT: 1401 - a string containing the HTML 1402 """ 1450 1403 t = time.time() - float(rev[:-4]) 1451 when = worksheet.convert_seconds_to_meaningful_time_span(t) 1452 head, body = self.html_worksheet_page_template(ws, username, 1453 "Revision from %s ago <a href='revisions'>Revision List</a>"%when, select="revisions") 1404 time_ago = worksheet.convert_seconds_to_meaningful_time_span(t) 1454 1405 1455 1406 filename = ws.get_snapshot_text_filename(rev) 1456 1407 txt = bz2.decompress(open(filename).read()) 1457 1408 W = self.scratch_worksheet() 1458 1409 W.delete_cells_directory() 1459 1410 W.edit_save(txt) 1460 html = W.html_worksheet_body(do_print=True, publish=True)1411 body_worksheet_html = W.html_worksheet_body(do_print=True, publish=True) 1461 1412 1462 1413 data = ws.snapshot_data() # pairs ('how long ago', key) 1463 1414 prev_rev = None … … class Notebook(SageObject): 1470 1421 next_rev = data[i+1][1] 1471 1422 break 1472 1423 1473 if prev_rev: 1474 prev = '<a class="listcontrol" href="revisions?rev=%s">Older</a> '%prev_rev 1475 else: 1476 prev = 'Oldest' 1477 1478 if next_rev: 1479 next = '<a class="listcontrol" href="revisions?rev=%s">Newer</a> '%next_rev 1480 else: 1481 next = 'Newest' 1482 1483 actions = """ 1484 %s 1485 %s 1486 <a class="listcontrol" href="revisions?rev=%s&action=revert">Revert to this one</a> <span class="lastedit">(note that images are note recorded)</span> 1487 <a class="listcontrol" href="revisions?rev=%s&action=publish">Publish this one</a> 1488 """%(prev, next, rev, rev) 1489 1490 s = """ 1491 %s 1492 <hr class="usercontrol"> 1493 <table width="100%%"> 1494 %s 1495 <hr class="usercontrol"> 1496 %s 1497 </table> 1498 """%(actions, html, actions) 1499 body += s 1500 1501 return """ 1502 <html> 1503 <head>%s</head> 1504 <body>%s</body> 1505 </html> 1506 """%(head, body) 1507 1508 def html_worksheet_page_template(self, worksheet, username, title, select=None, backwards=False): 1509 head = self._html_head(worksheet_filename=worksheet.filename(), username=username) 1510 head += '<script type="text/javascript">worksheet_filename="%s"; worksheet_name="%s"; server_ping_while_alive(); </script>'%(worksheet.filename(), worksheet.name()) 1511 body = self._html_body(worksheet.filename(), top_only=True, username=username) 1512 body += self.html_worksheet_topbar(worksheet, select=select, username=username, backwards=backwards) 1513 body += '<hr class="usercontrol">' 1514 body += '<span class="sharebar">%s</span>'%title 1515 body += '<br>'*3 1516 return head, body 1424 return template("notebook/specific_revision.html", worksheet = ws, 1425 worksheet_filename = ws.filename(), 1426 username = username, rev = rev, 1427 prev_rev = prev_rev, next_rev = next_rev, 1428 time_ago = time_ago, 1429 body_worksheet_html = body_worksheet_html, 1430 JSMATH = JSMATH, 1431 JSMATH_IMAGE_FONTS = JSMATH_IMAGE_FONTS, 1432 JEDITABLE_TINYMCE = JEDITABLE_TINYMCE, 1433 sage_jsmath_macros = sage_jsmath_macros) 1517 1434 1518 1435 1519 1436 def html_share(self, worksheet, username): 1520 head, body = self.html_worksheet_page_template(worksheet, username, "Share this document", select="share") 1437 """ 1438 Returns the HTML for the share page of a worksheet. 1521 1439 1522 if not (self.user(username).is_admin() or username == worksheet.owner()): 1523 body += "Only the owner of a worksheet is allowed to share it." 1524 body += 'You can do whatever you want if you <a href="copy">make your own copy</a>.' 1525 else: 1526 body += 'This Sage Worksheet is currently shared with the people listed in the box below.<br>' 1527 body += 'You may add or remove collaborators (separate user names by commas).<br><br>' 1440 INPUT: 1441 - ``username`` - a string 1442 - ``worksheet`` - an instance of Worksheet 1528 1443 1529 collabs = ', '.join(worksheet.collaborators()) 1530 body += '<form width=70% method="post" action="invite_collab">\n' 1531 body += '<textarea name="collaborators" rows=5 cols=70 class="edit" id="collaborators">%s</textarea><br><br>'%collabs 1532 body += '<input type="submit" title="Give access to your worksheet to the above collaborators" value="Invite Collaborators">' 1533 body += '</form>' 1444 OUTPUT: 1445 - a string containing the HTML 1446 1447 EXAMPLES:: 1448 1449 sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir()) 1450 sage: W = nb.create_new_worksheet('Test', 'admin') 1451 sage: nb.html_share(W, 'admin') 1452 '\n<!D...span class="username">Sage Users:</span>\n<span class="users">\n \n</span>\n\n\n\n </body>\n</html>' 1453 """ 1454 U = self.users() 1455 other_users = [x for x, u in U.iteritems() if not u.is_guest() and not u.username() in [username, 'pub', '_sage_']] 1456 other_users.sort(lambda x,y: cmp(x.lower(), y.lower())) 1534 1457 1535 body += '<br>'*2 1536 body += '<hr class="usercontrol">' 1537 body += '<span class="username">Sage Users:</span>' 1538 U = self.users() 1539 K = [x for x, u in U.iteritems() if not u.is_guest() and not u.username() in [username, 'pub', '_sage_']] 1540 def mycmp(x,y): 1541 return cmp(x.lower(), y.lower()) 1542 K.sort(mycmp) 1543 body += '<span class="users">%s</span>'%(', '.join(K)) 1544 1545 1546 return """ 1547 <html> 1548 <head>%s</head> 1549 <body>%s</body> 1550 </html> 1551 """%(head, body) 1552 1458 return template("notebook/worksheet_share.html", worksheet = worksheet, 1459 worksheet_filename = worksheet.filename(), 1460 username = username, other_users = other_users, 1461 user_is_admin = self.user(username).is_admin(), 1462 JSMATH = JSMATH, 1463 JSMATH_IMAGE_FONTS = JSMATH_IMAGE_FONTS, 1464 JEDITABLE_TINYMCE = JEDITABLE_TINYMCE, 1465 sage_jsmath_macros = sage_jsmath_macros) 1553 1466 1554 1467 1555 1468 def html_download_or_delete_datafile(self, ws, username, filename): 1556 head, body = self.html_worksheet_page_template(ws, username, "Data file: %s"%filename) 1469 """ 1470 Returns the HTML for the download or delete datafile page. 1471 1472 INPUT: 1473 - ``username`` - a string 1474 - ``ws`` - an instance of Worksheet 1475 - ``filename`` - the name of the file 1476 1477 OUTPUT: 1478 - a string containing the HTML 1479 1480 EXAMPLES:: 1481 1482 sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir()) 1483 sage: W = nb.create_new_worksheet('Test', 'admin') 1484 sage: nb.html_download_or_delete_datafile(W, 'admin', 'bar') 1485 '\n<!D...ploaded to this worksheet.</p>\n\n<hr class="usercontrol" />\n\n\n\n\n </body>\n</html>' 1486 """ 1557 1487 path = "/home/%s/data/%s"%(ws.filename(), filename) 1558 body += 'You may download <a href="%s">%s</a>'%(path, filename)1559 1488 1560 X = self.get_worksheets_with_viewer(username) 1561 v = [x for x in X if x.is_active(username)] 1562 sort_worksheet_list(v, 'name', False) 1563 ws_form = ['<option selected>select worksheet</option>'] + \ 1564 ["""<option value='link_datafile("%s","%s")'>%s</option>"""%( 1565 x.filename(), filename, x.name()) for x in v] 1566 ws_form = '\n'.join(ws_form) 1567 ws_form = "<select onchange='go_option(this);' class='worksheet'>%s</select>"%ws_form 1568 body += ' or create a linked copy to the worksheet %s,'%ws_form 1569 body += ' or <a href="/home/%s/datafile?name=%s&action=delete">delete %s.</a>'%(ws.filename(),filename, filename) 1489 worksheets = self.get_worksheets_with_viewer(username) 1490 active_worksheets = [worksheet for worksheet in worksheets if worksheet.is_active(username)] 1491 sort_worksheet_list(active_worksheets, 'name', False) 1492 1493 ext = os.path.splitext(filename)[1].lower() 1494 file_is_image, file_is_text = False, False 1495 text_file_content = "" 1496 1497 if ext in ['.png', '.jpg', '.gif']: 1498 file_is_image = True 1499 if ext in ['.txt', '.tex', '.sage', '.spyx', '.py', '.f', '.f90', '.c']: 1500 file_is_text = True 1501 text_file_content = open('%s/%s'%(ws.data_directory(), filename)).read() 1570 1502 1571 body += "<br><br>Access %s in this worksheet by typing <tt>DATA+'%s'</tt>. Here DATA is a special variable that gives the exact path to all data files uploaded to this worksheet.<br><br>"%(filename, filename) 1572 1573 body += '<hr class="usercontrol">' 1574 ext = os.path.splitext(filename)[1].lower() 1575 if ext in ['.png', '.jpg', '.gif']: 1576 body += '<div align=center><img src="%s"></div>'%path 1577 elif ext in ['.txt', '.tex', '.sage', '.spyx', '.py', '.f', '.f90', '.c']: 1578 body += '<form method="post" action="savedatafile" enctype="multipart/form-data">' 1579 body += '<input type="submit" value="Save Changes" name="button_save"> <input type="submit" value="Cancel" name="button_cancel"><br>' 1580 body += '<textarea class="edit" name="textfield" rows=17 cols=70 id="textfield">%s</textarea>'%open('%s/%s'%(ws.data_directory(), filename)).read() 1581 body += '<input type="hidden" name="filename" value="%s" id="filename">'%filename 1582 body += '</form>' 1583 1584 return """ 1585 <html> 1586 <head>%s</head> 1587 <body>%s</body> 1588 </html> 1589 """%(head, body) 1503 return template("notebook/download_or_delete_datafile.html", 1504 worksheet = ws, 1505 worksheet_filename = ws.filename(), 1506 username = username, 1507 active_worksheets = active_worksheets, 1508 filename_ = filename, 1509 path = path, 1510 file_is_image = file_is_image, 1511 file_is_text = file_is_text, 1512 text_file_content = text_file_content, 1513 JSMATH = JSMATH, 1514 JSMATH_IMAGE_FONTS = JSMATH_IMAGE_FONTS, 1515 JEDITABLE_TINYMCE = JEDITABLE_TINYMCE, 1516 sage_jsmath_macros = sage_jsmath_macros) 1590 1517 1591 1518 1592 1519 … … class Notebook(SageObject): 1685 1612 ########################################################### 1686 1613 # HTML -- generate most html related to the whole notebook page 1687 1614 ########################################################### 1688 def html_slide_controls(self): 1689 return """ 1690 <div class="hidden" id="slide_controls"> 1691 <div class="slideshow_control"> 1692 <a class="slide_arrow" onClick="slide_next()">></a> 1693 <a class="slide_arrow" onClick="slide_last()">>></a> %s 1694 <a class="cell_mode" onClick="cell_mode()">Exit</a> 1695 </div> 1696 <div class="slideshow_progress" id="slideshow_progress" onClick="slide_next()"> 1697 <div class="slideshow_progress_bar" id="slideshow_progress_bar"> </div> 1698 <div class="slideshow_progress_text" id="slideshow_progress_text"> </div> 1699 </div> 1700 <div class="slideshow_control"> 1701 <a class="slide_arrow" onClick="slide_first()"><<</a> 1702 <a class="slide_arrow" onClick="slide_prev()"><</a> 1703 </div> 1704 </div> 1705 """%vbar 1615 def html_debug_window(self): 1616 """ 1617 Returns the HTML for the debug window 1706 1618 1707 def html_debug_window(self): 1708 return """ 1619 OUTPUT: 1620 - the HTML for the debug window 1621 1622 EXAMPLES:: 1623 1624 sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir()) 1625 sage: print(nb.html_debug_window()) 1709 1626 <div class='debug_window'> 1710 <div class='debug_output'><pre id='debug_output'></pre></div> 1711 <textarea rows=5 id='debug_input' class='debug_input' 1712 onKeyPress='return debug_keypress(event);' 1713 onFocus='debug_focus();' onBlur='debug_blur();'></textarea> 1714 </div>""" 1627 <div class='debug_output'><pre id='debug_output'></pre></div> 1628 <textarea rows=5 id='debug_input' class='debug_input' 1629 onKeyPress='return debug_keypress(event);' 1630 onFocus='debug_focus();' onBlur='debug_blur();'></textarea> 1631 </div> 1632 """ 1633 return template("notebook/debug_window.html") 1715 1634 1716 1635 1717 def _html_head(self, worksheet_filename, username):1718 if worksheet_filename is not None:1719 worksheet = self.get_worksheet_with_filename(worksheet_filename)1720 head = '\n<title>%s (Sage)</title>'%(worksheet.name())1721 else:1722 head = '\n<title>Sage Notebook | Welcome</title>'1723 1724 head += '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">'1725 # Load the Sage javascript libray.1726 head += '\n<script type="text/javascript" src="/javascript_local/jquery/jquery.js"></script>'1727 head += '\n<script type="text/javascript" src="/javascript/main.js"></script>\n'1728 head += '\n<link rel=stylesheet href="/css/main.css" type="text/css">\n'1729 1730 if JSMATH:1731 # turn off the ugly scary font warning.1732 head += '\n <STYLE> #jsMath_Warning {display: none} </STYLE>\n'1733 head += '<script type="text/javascript">jsMath = {Controls: {cookie: {scale: 115}}}</script>\n'1734 if not JSMATH_IMAGE_FONTS:1735 head +=' <script type="text/javascript" src="/javascript_local/jsmath/plugins/noImageFonts.js"></script>\n'1736 1737 # Move the jsMath button 20 pixels from the right edge1738 # (apparently in some browsers, it covers up the scroll1739 # bar)1740 head += """<script type="text/javascript">1741 jsMath.styles = {1742 '#jsMath_button': 'position:fixed; bottom:1px; right:20px; background-color:white; '1743 + 'border: solid 1px #959595; margin:0px; padding: 0px 3px 1px 3px; '1744 + 'z-index:102; color:black; text-decoration:none; font-size:x-small; '1745 + 'width:auto; cursor:hand;',1746 };1747 </script>1748 """1749 head += '<script type="text/javascript" src="/javascript_local/jsmath/jsMath.js"></script>\n'1750 head += r'''<script type="text/javascript">/*The extensions here do the following:1751 - verb implements the \verb command:1752 see http://www.math.union.edu/~dpvc/jsMath/authors/verb.html1753 - moreArrows implements \xrightarrow, among other things:1754 see http://www.math.union.edu/~dpvc/jsMath/authors//moreArrows.html1755 - AMSmath implements a number of AMS math commands:1756 see http://www.math.union.edu/~dpvc/jsMath/authors/AMSmath.html1757 */1758 jsMath.Extension.Require("verb");1759 jsMath.Extension.Require("moreArrows");1760 jsMath.Extension.Require("AMSmath");1761 jsMath.Extension.Require("AMSsymbols");1762 </script>'''1763 1764 # import latex macros1765 for m in sage_jsmath_macros:1766 head += '<script>' + m + '</script>\n'1767 1768 # Load the jquery and ui-jquery javascript library.1769 # This is used for interact functionality in the notebook, and will be used1770 # to enable drag and drop, image zoom, etc.1771 head += '''1772 <script type="text/javascript" src="/javascript_local/jqueryui/jquery.ui.all.min.js"></script>1773 <script type="text/javascript" src="/javascript_local/jquery/plugins/farbtastic/farbtastic.min.js"></script>1774 <script type="text/javascript" src="/javascript_local/jquery/plugins/dimensions/jquery.dimensions.min.js"></script>1775 <script type="text/javascript" src="/javascript_local/jquery/plugins/jquery.event.extendedclick.js"></script>1776 1777 <link rel="stylesheet" href="/javascript_local/jquery/plugins/farbtastic/farbtastic.css" type="text/css" />1778 <link rel="stylesheet" href="/javascript_local/jqueryui/themes/flora/flora.all.css">1779 '''1780 # TODO: get the lazy loading plugin1781 1782 # TODO: Load individual ui plugins, not the whole package:1783 # <script type="text/javascript" src="/javascript_local/jqueryui/ui.mouse.min.js"></script>1784 # <script type="text/javascript" src="/javascript_local/jqueryui/ui.slider.min.js"></script>1785 # <script type="text/javascript" src="/javascript_local/jqueryui/ui.draggable.min.js"></script>1786 # <script type="text/javascript" src="/javascript_local/jqueryui/ui.draggable.ext.min.js"></script>1787 # <script type="text/javascript" src="/javascript_local/jqueryui/ui.resizable.min.js"></script>1788 # <script type="text/javascript" src="/javascript_local/jqueryui/ui.dialog.min.js"></script>1789 1790 1791 # This was for syntax hilighting1792 # head +=' <script type="text/javascript" src="/javascript/highlight/prettify.js"></script>\n'1793 # head += '<link rel=stylesheet href="/css/highlight/prettify.css" type="text/css">\n'1794 1795 head +=' <script type="text/javascript" src="/javascript/sage3d.js"></script>\n'1796 1797 # Jmol -- embedded 3d graphics.1798 head +=' <script type="text/javascript" src="/java/jmol/appletweb/Jmol.js"></script>\n'1799 1800 head +=' <script>jmolInitialize("/java/jmol");jmolSetCallback("menuFile","/java/jmol/appletweb/SageMenu.mnu");</script>\n' # this must stay in the <head>1801 1802 # TinyMCE and jEditable -- in-place editing of text cells1803 if JEDITABLE_TINYMCE:1804 head += """<script type="text/javascript" src="/javascript_local/tiny_mce/tiny_mce.js"></script>1805 <script src="/javascript_local/jquery/plugins/jquery.jeditable.mini.js" type="text/javascript" charset="utf-8"></script>1806 <script type="text/javascript">1807 1808 function toggleEditor(id) {1809 if (!tinyMCE.get(id))1810 tinyMCE.execCommand('mceAddControl', false, id);1811 else1812 tinyMCE.execCommand('mceRemoveControl', false, id);1813 }1814 1815 $.fn.tinymce = function(options){1816 return this.each(function(){1817 tinyMCE.execCommand("mceAddControl", true, this.id);1818 });1819 }1820 1821 function initMCE(){1822 tinyMCE.init({mode : "none",1823 plugins: "table,searchreplace,safari,paste,autosave",1824 theme : "advanced",1825 theme_advanced_toolbar_location : "top",1826 theme_advanced_toolbar_align : "left",1827 theme_advanced_statusbar_location : "bottom",1828 theme_advanced_buttons1 : "\1829 formatselect,fontselect,fontsizeselect,bold,italic,underline,strikethrough,forecolor,backcolor,|,\1830 bullist,numlist,|,\1831 undo,redo,search,pastetext,pasteword",1832 theme_advanced_buttons2 : "\1833 justifyleft,justifycenter,justifyright,justifyfull,outdent,indent,|,\1834 charmap,|,\1835 table,tablecontrols,|,\1836 code,|,\1837 link,image,unlink",1838 theme_advanced_buttons3 : "",1839 theme_advanced_resizing : true,1840 setup : function(ed) {1841 ed.onKeyDown.add(function(ed, e) {1842 if(key_enter_shift(key_event(e))) {1843 $(ed.formElement).submit();1844 }1845 })}1846 });1847 };1848 1849 initMCE();1850 1851 1852 $.editable.addInputType('mce', {1853 element : function(settings, original) {1854 var textarea = $('<textarea id="'+$(original).attr("id")+'_mce"/>');1855 if (settings.rows) {1856 textarea.attr('rows', settings.rows);1857 } else {1858 textarea.height(settings.height);1859 }1860 if (settings.cols) {1861 textarea.attr('cols', settings.cols);1862 } else {1863 textarea.width(settings.width);1864 }1865 $(this).append(textarea);1866 return(textarea);1867 },1868 plugin : function(settings, original) {1869 tinyMCE.execCommand("mceAddControl", true, $(original).attr("id")+'_mce');1870 },1871 submit : function(settings, original) {1872 tinyMCE.triggerSave();1873 tinyMCE.execCommand("mceRemoveControl", true, $(original).attr("id")+'_mce');1874 },1875 reset : function(settings, original) {1876 tinyMCE.execCommand("mceRemoveControl", true, $(original).attr("id")+'_mce');1877 original.reset();1878 }1879 });1880 </script>1881 """1882 1883 return head1884 1885 def html_worksheet_topbar(self, worksheet, select=None, username='guest', backwards=False):1886 body = ''1887 body += """1888 <table width="100%%" id="topbar">1889 <tr>1890 <td align=left> %s </td> <td align=right> %s </td>1891 </tr>1892 <tr>1893 <td align=left> %s </td> <td align=right> %s </td>1894 </tr>1895 </table>1896 """%(worksheet.html_title(username), worksheet.html_save_discard_buttons(),1897 worksheet.html_menu(), worksheet.html_share_publish_buttons(select=select, backwards=backwards))1898 1899 body += self.html_slide_controls()1900 return body1901 1902 1903 def _html_body(self, worksheet_filename, show_debug=False, username='', top_only=False):1904 worksheet = self.get_worksheet_with_filename(worksheet_filename)1905 worksheet_html = worksheet.html()1906 1907 body = ''1908 1909 if worksheet.is_published() or self.user_is_guest(username):1910 original_worksheet = worksheet.worksheet_that_was_published()1911 if original_worksheet.user_is_collaborator(username) or original_worksheet.is_owner(username):1912 s = "Edit this."1913 url = 'edit_published_page'1914 elif self.user_is_guest(username):1915 s = 'Log in to edit a copy.'1916 url = '/'1917 else:1918 s = 'Edit a copy.'1919 url = 'edit_published_page'1920 r = worksheet.rating()1921 if r == -1:1922 rating = ''1923 else:1924 rating = '<a class="usercontrol" href="rating_info">This page is rated %.1f.</a>'%r1925 if not self.user_is_guest(username) \1926 and not worksheet.is_publisher(username):1927 if worksheet.is_rater(username):1928 action = "Rerate"1929 else:1930 action = "Rate"1931 rating += ' <span class="usercontrol">%s it: </span>'%action1932 rating += ' '.join(['<a class="usercontrol" onClick="rate_worksheet(%s)"> %s </a>'%(i,i) for1933 i in range(5)])1934 rating += ' <input name="rating_comment" id="rating_comment"></input>'1935 1936 download_name = os.path.split(worksheet.name())[-1]1937 edit_line = '<a class="usercontrol" href="%s">%s</a>'%(url, s) + \1938 ' <a class="usercontrol" href="download/%s.sws">Download.</a>'%download_name + \1939 ' <span class="ratingmsg">%s</span>'%rating1940 1941 body += edit_line1942 #This document was published using <a href="/">Sage</a>.'1943 body += '<span class="pubmsg">'1944 body += '<a href="/pub/">Other published documents...</a></span>'1945 body += '<hr class="usercontrol">'1946 body += '<h1 align=center>%s</h1>'%original_worksheet.name()1947 body += '<h2 align=center>%s</h2>'%worksheet.html_time_since_last_edited()1948 body += worksheet_html1949 body += '<hr class="usercontrol">'1950 body += ' '*101951 1952 1953 1954 else:1955 1956 entries = [("$('#topbar').toggle()", 'Toggle', 'Toggle the top bar'),1957 ('/', 'Home', 'Back to your personal worksheet list'),1958 ('/pub', 'Published', 'Browse the published worksheets'),1959 ('history_window()', 'Log', 'View a log of recent computations'),1960 ('/settings', 'Settings', 'Account Settings'),1961 ('bugreport()', 'Report a Problem', 'Report a problem or submit a bug to improve Sage'),1962 ('help()', 'Help', 'Documentation')]1963 1964 if not self.user_is_guest(username):1965 entries.append(('/logout', 'Sign out', 'Log out of the Sage notebook'))1966 1967 body += self.html_banner_and_control(username, entries)1968 if top_only:1969 return body1970 1971 if worksheet_filename:1972 body += self.html_worksheet_topbar(worksheet, select="use", username=username)1973 1974 if self.__show_debug or show_debug:1975 body += self.html_debug_window()1976 1977 1978 body += '<div class="worksheet" id="worksheet">%s</div>'%worksheet_html1979 1980 endpanespan = '</td></tr></table></span>\n'1981 1982 1983 if worksheet is None:1984 return body + endpanespan1985 1986 if worksheet.user_is_only_viewer(username):1987 body += '<script type="text/javascript">worksheet_locked=true;</script>'1988 else:1989 body += '<script type="text/javascript">worksheet_locked=false;</script>'1990 1991 if worksheet.computing():1992 # Set the update checking back in motion.1993 body += '<script type="text/javascript"> active_cell_list = %r; \n'%worksheet.queue_id_list()1994 body += 'for(var i = 0; i < active_cell_list.length; i++)'1995 body += ' cell_set_running(active_cell_list[i]); \n'1996 body += 'start_update_check();\n'1997 body +=' </script>\n'1998 1999 return body2000 2001 1636 def html_plain_text_window(self, worksheet, username): 2002 1637 """ 2003 Return a window that displays a plain text version of the1638 Returns a window that displays a plain text version of the 2004 1639 worksheet 2005 1640 2006 1641 INPUT: 1642 - ``worksheet`` - a worksheet 1643 - ``username`` - name of the user 1644 1645 OUTPUT: 1646 - a window that displays a plain text version of the 1647 worksheet 2007 1648 1649 EXAMPLES:: 2008 1650 2009 - ``worksheet`` - a worksheet 2010 2011 - ``username`` - name of the user 1651 sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir()) 1652 sage: W = nb.create_new_worksheet('Test', 'admin') 1653 sage: nb.html_plain_text_window(W, 'admin') 1654 '\n<!D...>\n\n<pre class="plaintext" id="cell_intext" name="textfield"></pre>\n\n\n </body>\n</html>' 2012 1655 """ 2013 head, body = self.html_worksheet_page_template(worksheet, username, 'View plain text', select="text") 2014 2015 t = worksheet.plain_text(prompts=True, banner=False) 2016 t = escape(t) 2017 body += """ 2018 <pre class="plaintext" id="cell_intext" name="textfield">%s 2019 </pre> 2020 """%t.strip() 1656 plain_text = worksheet.plain_text(prompts=True, banner=False) 1657 plain_text = escape(plain_text).strip() 2021 1658 2022 return """ 2023 <html> 2024 <head>%s</head> 2025 <body>%s</body> 2026 </html> 2027 """%(head, body) 2028 1659 return template("notebook/plain_text_window.html", worksheet = worksheet, 1660 worksheet_filename = worksheet.filename(), 1661 username = username, 1662 plain_text = plain_text, JSMATH = JSMATH, 1663 JSMATH_IMAGE_FONTS = JSMATH_IMAGE_FONTS, 1664 JEDITABLE_TINYMCE = JEDITABLE_TINYMCE, 1665 sage_jsmath_macros = sage_jsmath_macros) 1666 2029 1667 def html_edit_window(self, worksheet, username): 2030 1668 r""" 2031 1669 Return a window for editing ``worksheet``. 2032 1670 2033 1671 INPUT: 1672 - ``username`` - a string containing the username 1673 - ``worksheet`` - a Worksheet instance 1674 1675 OUTPUT: 1676 - html for a window for editing ``worksheet``. 1677 1678 EXAMPLES:: 2034 1679 2035 2036 - ``worksheet`` - a worksheet 1680 sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir()) 1681 sage: W = nb.create_new_worksheet('Test', 'admin') 1682 sage: nb.html_edit_window(W, 'admin') 1683 '\n<!D...Test\nsystem:sage\n\n{{{id=0|\n\n///\n}}}</textarea>\n</form>\n\n\n </body>\n</html>' 2037 1684 """ 2038 head, body = self.html_worksheet_page_template(worksheet, username, 'Edit plain text <input type="submit" value="Save Changes" name="button_save" id="button_save"> <input type="submit" value="Cancel" name="button_cancel">', select="edit") 2039 2040 2041 body += """<script type="text/javascript"> 2042 function save_worksheet() { 2043 } 2044 function save_worksheet_and_close() { 2045 } 2046 </script> 2047 """ 2048 t = worksheet.edit_text() 2049 t = escape(t) 2050 body = '<form method="post" action="save" enctype="multipart/form-data">' + body 2051 body += """ 2052 <textarea class="plaintextedit" id="cell_intext" name="textfield" rows="%s">%s</textarea> 2053 </form> 2054 """%(t.count("\n")+1,t) 1685 text = worksheet.edit_text() 1686 text = escape(text) 1687 n_lines = text.count("\n")+1 2055 1688 2056 return """ 2057 <html> 2058 <head>%s</head> 2059 <body>%s</body> 2060 </html> 2061 """%(head, body) 1689 return template("notebook/edit_window.html", worksheet = worksheet, 1690 worksheet_filename = worksheet.filename(), 1691 username = username, text = text, 1692 n_lines = n_lines, JSMATH = JSMATH, 1693 JSMATH_IMAGE_FONTS = JSMATH_IMAGE_FONTS, 1694 JEDITABLE_TINYMCE = JEDITABLE_TINYMCE, 1695 sage_jsmath_macros = sage_jsmath_macros) 2062 1696 2063 1697 def html_beforepublish_window(self, worksheet, username): 2064 1698 """ 2065 1699 Return the html code for a page dedicated to worksheet publishing 2066 1700 prior to the publication of the given worksheet. 2067 1701 2068 INPUT: worksheet - instance of Worksheet username - string 1702 INPUT: 1703 - ``worksheet`` - instance of Worksheet 1704 - ``username`` - string 1705 1706 EXAMPLES:: 1707 1708 sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir()) 1709 sage: W = nb.create_new_worksheet('Test', 'admin') 1710 sage: nb.html_beforepublish_window(W, 'admin') 1711 '\n<!D...publish when changes are made</form></span>\n<br /><br /><br />\n\n\n </body>\n</html>' 2069 1712 """ 2070 1713 msg = """You can publish your worksheet to the Internet, where anyone will be able to access and view it online. 2071 1714 Your worksheet will be assigned a unique address (URL) that you can send to your friends and colleagues.<br/><br/> … … function save_worksheet_and_close() { 2077 1720 <input type="checkbox" name="auto" style="margin-left:13px" /> Automatically re-publish when changes are made 2078 1721 </form> 2079 1722 """ 2080 head, body = self.html_worksheet_page_template(worksheet, username, msg, select="publish", backwards=True) 1723 return template("notebook/beforepublish_window.html", worksheet = worksheet, 1724 worksheet_filename = worksheet.filename(), 1725 username = username, JSMATH = JSMATH, 1726 JSMATH_IMAGE_FONTS = JSMATH_IMAGE_FONTS, 1727 JEDITABLE_TINYMCE = JEDITABLE_TINYMCE, 1728 sage_jsmath_macros = sage_jsmath_macros) 2081 1729 2082 return """ 2083 <html> 2084 <head>%s</head> 2085 <body>%s</body> 2086 </html> 2087 """%(head, body) 2088 2089 def html_afterpublish_window(self, worksheet, username, addr, dtime): 1730 def html_afterpublish_window(self, worksheet, username, url, dtime): 2090 1731 """ 2091 1732 Return the html code for a page dedicated to worksheet publishing 2092 1733 after the publication of the given worksheet. 2093 1734 2094 INPUT: worksheet - instance of Worksheet username - string addr - 2095 string dtime - instance of time.struct_time 1735 INPUT: 1736 - ``worksheet`` - instance of Worksheet 1737 - ``username`` - string 1738 - ``url`` - a string representing the url of the published worksheet 1739 - ``dtime`` - instance of time.struct_time representing the publishing time 2096 1740 """ 2097 1741 from time import strftime 2098 1742 time = strftime("%B %d, %Y %I:%M %p", dtime) 2099 msg = """Worksheet is publicly viewable at <a href="%s" style="color:#FFF" target="_blank">%s</a><br />2100 Published on %s<br/><br />2101 <input type="button" value="Re-publish worksheet" onClick="parent.location=\'?re'"><input type="button" value="Stop publishing" style="margin-left:5px" onClick="parent.location=\'?stop'"><br /><br />2102 <input type="checkbox" name="auto"%s onchange="parent.location=\'?auto'"/> Automatically re-publish when changes are made2103 """ % (addr, addr, time, ' checked="true" ' if worksheet.is_auto_publish() else '')2104 head, body = self.html_worksheet_page_template(worksheet, username, msg, select="publish", backwards=True)2105 1743 2106 return """ 2107 <html> 2108 <head>%s</head> 2109 <body>%s</body> 2110 </html> 2111 """%(head, body) 1744 return template("notebook/afterpublish_window.html", worksheet = worksheet, 1745 worksheet_filename = worksheet.filename(), 1746 username = username, url = url, 1747 time = time, JSMATH = JSMATH, 1748 JSMATH_IMAGE_FONTS = JSMATH_IMAGE_FONTS, 1749 JEDITABLE_TINYMCE = JEDITABLE_TINYMCE, 1750 sage_jsmath_macros = sage_jsmath_macros) 2112 1751 2113 1752 def html_upload_data_window(self, ws, username): 2114 head, body = self.html_worksheet_page_template(ws, username, "Upload or Create Data File") 1753 """ 1754 Returns the html for the "Upload Data" window 1755 1756 INPUT: 1757 - ``worksheet`` - instance of Worksheet 1758 - ``username`` - string 1759 1760 EXAMPLES:: 2115 1761 2116 body += """ 2117 <div class="upload_worksheet_menu" id="upload_worksheet_menu"> 2118 <h1><font size=+1>Upload or create data file attached to the worksheet '%s'</font></h1> 2119 <hr> 2120 <form method="POST" action="do_upload_data" 2121 name="upload" enctype="multipart/form-data"> 2122 <table><tr> 2123 <td> 2124 Browse your computer to select a file to upload:<br> 2125 <input class="upload_worksheet_menu" size="50" type="file" name="fileField" value="" id="upload_filename"></input><br><br> 2126 Or enter the url of a file on the web:<br> 2127 2128 <input class="upload_worksheet_menu" size="50" type="text" name="urlField" value="" id="upload_url"></input></br> 2129 <br><br> 2130 Or enter the name of a new file, which will be created:<br> 2131 <input class="upload_worksheet_menu" size="50" type="text" name="newField" value="" id="upload_filename"></input><br><br> 2132 2133 What do you want to call it? (if different than the original name)<br> 2134 <input class="upload_worksheet_menu" size="50" type="text" name="nameField" value="" id="upload_name"></input></br> 2135 </td> 2136 </tr> 2137 <tr> 2138 <td><br><input type="button" class="upload_worksheet_menu" value="Upload File" onClick="form.submit();"></td> 2139 </tr> 2140 </form><br> 2141 </div> 2142 </body> 2143 </html> 2144 """%(ws.name()) 2145 2146 return """ 2147 <html> 2148 <head>%s</head> 2149 <body>%s</body> 2150 </html> 2151 """%(head, body) 1762 sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir()) 1763 sage: W = nb.create_new_worksheet('Test', 'admin') 1764 sage: nb.html_upload_data_window(W, 'admin') 1765 '\n<!D...orksheet_menu" value="Upload File" onClick="form.submit()...r />\n</div>\n\n\n </body>\n</html>' 1766 """ 1767 return template("notebook/upload_data_window.html", worksheet = worksheet, 1768 worksheet_filename = ws.filename(), 1769 username = username, JSMATH = JSMATH, 1770 JSMATH_IMAGE_FONTS = JSMATH_IMAGE_FONTS, 1771 JEDITABLE_TINYMCE = JEDITABLE_TINYMCE, 1772 sage_jsmath_macros = sage_jsmath_macros) 1773 2152 1774 2153 1775 def html(self, worksheet_filename=None, username='guest', show_debug=False, admin=False): 1776 """ 1777 Returns the html for index page of a worksheet. 1778 1779 INPUT: 1780 - ``worksheet_filename`` - a string 1781 - ``username`` - a string 1782 - ``show_debug`` - a boolean 1783 - ``admin`` - a boolean 1784 1785 EXAMPLES:: 1786 1787 sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir()) 1788 sage: W = nb.create_new_worksheet('Test', 'admin') 1789 sage: nb.html(W.filename(), 'admin') 1790 '\n<!D...ipt type="text/javascript">worksheet_locked=false;</script>\n\n\n\n </body>\n</html>' 1791 """ 2154 1792 if worksheet_filename is None or worksheet_filename == '': 2155 1793 worksheet_filename = None 2156 1794 W = None … … function save_worksheet_and_close() { 2160 1798 except KeyError: 2161 1799 W = None 2162 1800 2163 head = self._html_head(worksheet_filename=worksheet_filename, username=username) 2164 body = self._html_body(worksheet_filename=worksheet_filename, username=username, show_debug=show_debug) 2165 2166 head += '<script type="text/javascript">user_name="%s"; </script>'%username 2167 2168 if worksheet_filename is not None: 2169 head += '<script type="text/javascript">worksheet_filename="%s"; worksheet_name="%s"; server_ping_while_alive(); </script>'%(worksheet_filename, W.name()) 2170 2171 # Uncomment this to force rename when the worksheet is opened (annoying!) 2172 #if W and W.name() == "Untitled": 2173 # head += '<script type="text/javascript">setTimeout("rename_worksheet()",1)</script>' 2174 2175 return """ 2176 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 2177 <html> 2178 <head>%s</head> 2179 <body class="worksheet-online" onLoad="initialize_the_notebook();">%s</body> 2180 </html> 2181 """%(head, body) 1801 template_page = "notebook/index.html" 1802 if W.docbrowser(): 1803 template_page = "notebook/doc_page.html" 1804 1805 return template(template_page, worksheet = W, 1806 worksheet_filename = W.filename(), 1807 worksheet_html = W.html(), 1808 notebook = self, username = username, 1809 show_debug = show_debug, 1810 JSMATH = JSMATH, 1811 JSMATH_IMAGE_FONTS = JSMATH_IMAGE_FONTS, 1812 JEDITABLE_TINYMCE = JEDITABLE_TINYMCE, 1813 sage_jsmath_macros = sage_jsmath_macros) 2182 1814 2183 1815 #################################################################### 2184 1816 # Configuration html. 2185 1817 # In each case the settings html is a form that when submitted 2186 1818 # pulls up another web page and sets the corresponding options. 2187 1819 #################################################################### 2188 def html_system_select_form_element(self, ws):2189 system = ws.system()2190 options = ''2191 i = SYSTEM_NAMES.index(system)2192 for j, S in enumerate(SYSTEMS):2193 if i == j:2194 selected = "selected"2195 else:2196 selected = ''2197 T = SYSTEM_NAMES[j]2198 options += '<option title="Evaluate all input cells using %s" %s value="%s">%s</option>\n'%(T, selected, T,S)2199 s = """<select onchange="go_system_select(this, %s);" class="worksheet">2200 %s2201 </select>"""%(i, options)2202 return s2203 2204 def html_pretty_print_check_form_element(self, ws):2205 pretty_print = ws.pretty_print()2206 if pretty_print:2207 check='checked="checked"'2208 else:2209 check=''2210 s = """<input type="checkbox" title="Enable/disable pretty_printing"2211 onchange="pretty_print_check(this.checked);"2212 class="worksheet" value="pretty_print" %s> Typeset"""%(check)2213 return s2214 1820 2215 1821 2216 1822 def html_worksheet_settings(self, ws, username): 2217 head, body = self.html_worksheet_page_template(ws, username, 'Worksheet Settings <button name="button_save">Save Settings</button> <input type="submit" value="Cancel" name="button_cancel"/>') 1823 """ 1824 Returns the html for the setings page of the worksheet. 1825 1826 INPUT: 1827 - ``ws`` - instance of Worksheet 1828 - ``username`` - string 2218 1829 2219 body = '<form width=70%% method="post" action="input_settings" enctype="multipart/form-data">' + body 2220 body += '</form>' 2221 2222 return """ 2223 <html> 2224 <head>%s</head> 2225 <body>%s</body> 2226 </html> 2227 """%(head, body) 1830 EXAMPLES:: 1831 1832 sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir()) 1833 sage: W = nb.create_new_worksheet('Test', 'admin') 1834 sage: nb.html_worksheet_settings(W, 'admin') 1835 '\n<!D...lue="Cancel" name="button_cancel"/></span>\n<br /><br /><br />\n\n</form>\n\n\n </body>\n</html>' 1836 """ 1837 return template("notebook/worksheet_settings.html", worksheet = ws, 1838 worksheet_filename = ws.filename(), 1839 username = username, JSMATH = JSMATH, 1840 JSMATH_IMAGE_FONTS = JSMATH_IMAGE_FONTS, 1841 JEDITABLE_TINYMCE = JEDITABLE_TINYMCE, 1842 sage_jsmath_macros = sage_jsmath_macros) 2228 1843 2229 1844 def html_settings(self): 2230 1845 s = """ … … function save_worksheet_and_close() { 2241 1856 return s 2242 1857 2243 1858 def html_doc(self, username): 2244 top = self._html_head(None, username) + self.html_topbar(username) 2245 body = """ 2246 <br> 2247 <div class="docidx"> 2248 <h1>Sage Documentation</h1> 2249 <br> 2250 <hr class="usercontrol"> 2251 <br><br> 2252 <font size=+2> 2253 <a href="/doc/live/">Live Documentation</a><br><br> 2254 <a href="/doc/static/">Static Documentation</a><br><br> 2255 <a href="/help/">Sage Notebook Howto</a><br><br> 2256 <br><br> 2257 <br> 2258 <hr class="usercontrol"> 2259 </font> 2260 </div> 2261 """ 2262 #(<a href="/doc/static/">static</a>) 1859 """ 1860 Returns the html for the documentation pages. 1861 1862 INPUT: 1863 - ``worksheet_filename`` - a string 1864 - ``username`` - a string 1865 - ``show_debug`` - a boolean 1866 - ``admin`` - a boolean 2263 1867 2264 s = """ 2265 <html> 2266 %s 2267 <body> 2268 %s 2269 </body> 2270 </html> 2271 """%(top, body) 1868 EXAMPLES:: 2272 1869 2273 return s 1870 sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir()) 1871 sage: W = nb.create_new_worksheet('Test', 'admin') 1872 sage: nb.html_doc('admin') 1873 '\n<!D...c Documentation</a><br /><br />\n <a href="/help/">Sage Notebook Howto... </body>\n</html>' 1874 """ 1875 return template("notebook/doc.html", username = username, 1876 JSMATH = JSMATH, 1877 JSMATH_IMAGE_FONTS = JSMATH_IMAGE_FONTS, 1878 JEDITABLE_TINYMCE = JEDITABLE_TINYMCE, 1879 sage_jsmath_macros = sage_jsmath_macros) 2274 1880 2275 1881 2276 1882 #################################################################### -
sage/server/notebook/templates/account_recovery.html
diff --git a/sage/server/notebook/templates/account_recovery.html b/sage/server/notebook/templates/account_recovery.html
a b 1 1 2 {% extends "base.html" %} 2 3 3 4 {% block title %}Account Recovery{% endblock %} -
sage/server/notebook/templates/account_settings.html
diff --git a/sage/server/notebook/templates/account_settings.html b/sage/server/notebook/templates/account_settings.html
a b 1 1 2 {% extends "base.html" %} 2 3 3 4 {% block title %}Account Settings{% endblock %} -
sage/server/notebook/templates/banner.html
diff --git a/sage/server/notebook/templates/banner.html b/sage/server/notebook/templates/banner.html
a b 1 1 2 <div class="banner"> 2 <table width="100% %">3 <table width="100%"> 3 4 <tr> 4 5 <td> 5 6 <a class="banner" href="http://www.sagemath.org"> 6 <img align="top" src="/images/sagelogo.png" alt="Sage"> Notebook</a>7 <img align="top" src="/images/sagelogo.png" alt="Sage"> Notebook</a> 7 8 </td> 8 9 <td> 9 10 <span class="ping" id="ping">Searching for Sage server...</span> -
sage/server/notebook/templates/base.html
diff --git a/sage/server/notebook/templates/base.html b/sage/server/notebook/templates/base.html
a b 1 1 2 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> 2 3 <html lang="en"> 3 <head> 4 <title>{% block title %}{% endblock %} | {{ sitename }}</title> 5 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 6 <link type="text/css" rel="stylesheet" href="/css/{% block css %}master{% endblock %}.css" media="screen" /> 7 {% block javascript %}{% endblock %} 8 </head> 9 <body{% block onload %}{% endblock %}> 10 {% block body %}{% endblock %} 11 </body> 12 </html> 4 <head> 5 <title>{% block title %}{% endblock %}</title> 6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 7 {% block pre_main_css %}{% endblock %} 8 <link type="text/css" rel="stylesheet" href="/css/{% block css %}master{% endblock %}.css" media="screen" /> 9 {% block more_css %}{% endblock %} 10 {% block javascript %}{% endblock %} 11 </head> 12 <body {% block body_attrs %}{% endblock %}> 13 {% block body %}{% endblock %} 14 </body> 15 </html> 16 No newline at end of file -
sage/server/notebook/templates/base_authenticated.html
diff --git a/sage/server/notebook/templates/base_authenticated.html b/sage/server/notebook/templates/base_authenticated.html
a b 1 1 2 {% extends "base.html" %} 2 3 3 4 {% block css %}main{% endblock %} -
new file sage/server/notebook/templates/command_history.html
diff --git a/sage/server/notebook/templates/command_history.html b/sage/server/notebook/templates/command_history.html new file mode 100644
- + 1 2 {# 3 INPUT: 4 - history_text - a string containing the history text of the notebook 5 #} 6 <html> 7 <head> 8 <title>Command History</title> 9 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 10 </head> 11 <body> 12 <pre>{{history_text}}</pre> 13 <a name="bottom"></a> 14 <script type="text/javascript"> window.location="#bottom"</script> 15 </body> 16 </html> 17 No newline at end of file -
sage/server/notebook/templates/error_message.html
diff --git a/sage/server/notebook/templates/error_message.html b/sage/server/notebook/templates/error_message.html
a b 1 1 2 {% extends "base.html" %} 2 3 3 4 {% block title %}Error{% endblock %} 4 5 5 {% block content%}6 {% block body %} 6 7 <br><a class="usercontrol" href="/">Home</a> 7 8 <hr class="usercontrol"> 8 9 <br/><br/> -
sage/server/notebook/templates/history.html
diff --git a/sage/server/notebook/templates/history.html b/sage/server/notebook/templates/history.html
a b 1 1 2 {% extends "base.html" %} 2 3 3 4 {% block title %}Sage: History for {{username}} {% endblock %} -
sage/server/notebook/templates/list_top.html
diff --git a/sage/server/notebook/templates/list_top.html b/sage/server/notebook/templates/list_top.html
a b 1 1 2 {% include 'top_bar.html' %} 2 3 3 4 -
sage/server/notebook/templates/login.html
diff --git a/sage/server/notebook/templates/login.html b/sage/server/notebook/templates/login.html
a b 1 1 2 {% extends "base.html" %} 2 3 3 4 {% block title %}Sign in{% endblock %} -
new file sage/server/notebook/templates/notebook/afterpublish_window.html
diff --git a/sage/server/notebook/templates/notebook/afterpublish_window.html b/sage/server/notebook/templates/notebook/afterpublish_window.html new file mode 100644
- + 1 2 {% extends "notebook/worksheet_page_template.html" %} 3 {# 4 INPUT: 5 - worksheet - an instance of Worksheet 6 - worksheet_filename - a string containing a worksheet's filename 7 - username - a string containing a username 8 - url - a string containing the url of the published page 9 - time - a string representing the time of publication 10 - JSMATH - a boolean stating whether to include jsMath 11 - JSMATH_IMAGE_FONTS - a boolean stating whether to include jsMath iamage fonts 12 - JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE 13 - sage_jsmath_macros - an array containing strings of Javascript of Sage macros for jsMath 14 #} 15 16 {% set checked = 'checked="true"' if worksheet.is_auto_publish() else '' %} 17 18 {% set title = 'Worksheet is publicly viewable at <a href="%s" style="color:#FFF" target="_blank">%s</a><br />Published on %s<br/><br /><input type="button" value="Re-publish worksheet" onClick="parent.location=\'?re\'"><input type="button" value="Stop publishing" style="margin-left:5px" onClick="parent.location=\'?stop\'"><br /><br /><input type="checkbox" name="auto" %s onchange="parent.location=\'?auto\'"/> Automatically re-publish when changes are made'|format(url, url, time, checked) %} 19 {% set select = "publish" %} 20 {% set backwards = true %} 21 No newline at end of file -
new file sage/server/notebook/templates/notebook/beforepublish_window.html
diff --git a/sage/server/notebook/templates/notebook/beforepublish_window.html b/sage/server/notebook/templates/notebook/beforepublish_window.html new file mode 100644
- + 1 2 {% extends "notebook/worksheet_page_template.html" %} 3 {# 4 INPUT: 5 - worksheet - an instance of Worksheet 6 - worksheet_filename - a string containing a worksheet's filename 7 - username - a string containing a username 8 - JSMATH - a boolean stating whether to include jsMath 9 - JSMATH_IMAGE_FONTS - a boolean stating whether to include jsMath iamage fonts 10 - JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE 11 - sage_jsmath_macros - an array containing strings of Javascript of Sage macros for jsMath 12 #} 13 14 {% set title = '<p>You can publish your worksheet to the Internet, where anyone will be able to access and view it online.</p><p>Your worksheet will be assigned a unique address (URL) that you can send to your friends and colleagues.</p><p>Do you want to publish this worksheet?</p><form method="get" action="."><input type="hidden" name="yes" value="" /><input type="submit" value="Yes" style="margin-left:10px" /><input type="button" value="No" style="margin-left:5px" onClick="parent.location=\'../\'"><br/><br/><input type="checkbox" name="auto" style="margin-left:13px" /> Automatically re-publish when changes are made</form>' %} 15 {% set select = "publish" %} 16 {% set backwards = true %} 17 No newline at end of file -
new file sage/server/notebook/templates/notebook/debug_window.html
diff --git a/sage/server/notebook/templates/notebook/debug_window.html b/sage/server/notebook/templates/notebook/debug_window.html new file mode 100644
- + 1 2 <div class='debug_window'> 3 <div class='debug_output'><pre id='debug_output'></pre></div> 4 <textarea rows=5 id='debug_input' class='debug_input' 5 onKeyPress='return debug_keypress(event);' 6 onFocus='debug_focus();' onBlur='debug_blur();'></textarea> 7 </div> 8 No newline at end of file -
new file sage/server/notebook/templates/notebook/doc.html
diff --git a/sage/server/notebook/templates/notebook/doc.html b/sage/server/notebook/templates/notebook/doc.html new file mode 100644
- + 1 {% extends "base.html" %} 2 {# 3 INPUT: 4 - worksheet - an instance of Worksheet 5 - worksheet_filename - a string containing a worksheet's filename 6 - username - a string containing a username 7 - JSMATH - a boolean stating whether to include jsMath 8 - JSMATH_IMAGE_FONTS - a boolean stating whether to include jsMath iamage fonts 9 - JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE 10 - sage_jsmath_macros - an array containing strings of Javascript of Sage macros for jsMath 11 #} 12 13 {% include "notebook/head.tmpl" %} 14 15 {% block title %} 16 {{ common_title(worksheet_filename, worksheet) }} 17 {% endblock %} 18 19 {% block css %}main{% endblock %} 20 21 {% block morecss %}<style type="text/css" rel="stylesheet" href="_static/default.css" media="screen" />{% endblock %} 22 23 {% block javascript %} 24 {{ common_javascript(worksheet, worksheet_filename, username, JSMATH, JSMATH_IMAGE_FONTS, JEDITABLE_TINYMCE, sage_jsmath_macros) }} 25 {% endblock %} 26 27 {% block body %} 28 <br /> 29 <div class="docidx"> 30 <h1>Sage Documentation</h1> 31 <br /> 32 <hr class="usercontrol" /> 33 <br /><br /> 34 <font size=+2> 35 <a href="/doc/live/">Live Documentation</a><br /><br /> 36 <a href="/doc/static/">Static Documentation</a><br /><br /> 37 <a href="/help/">Sage Notebook Howto</a><br /><br /> 38 <br /><br /> 39 <br /> 40 <hr class="usercontrol" /> 41 </font> 42 </div> 43 {% endblock %} 44 No newline at end of file -
new file sage/server/notebook/templates/notebook/doc_page.html
diff --git a/sage/server/notebook/templates/notebook/doc_page.html b/sage/server/notebook/templates/notebook/doc_page.html new file mode 100644
- + 1 {% extends "notebook/index.html" %} 2 3 {% block pre_main_css %} 4 <link type="text/css" rel="stylesheet" href="_static/default.css" media="screen" /> 5 {% endblock %} 6 No newline at end of file -
new file sage/server/notebook/templates/notebook/download_or_delete_datafile.html
diff --git a/sage/server/notebook/templates/notebook/download_or_delete_datafile.html b/sage/server/notebook/templates/notebook/download_or_delete_datafile.html new file mode 100644
- + 1 2 {% extends "notebook/worksheet_page_template.html" %} 3 {# 4 INPUT: 5 - worksheet - an instance of Worksheet 6 - worksheet_filename - a string containing a worksheet's filename 7 - username - a string containing a username 8 - active_worksheets - a list of the Worksheet instances that are active for username 9 - filename_ - the name of the file 10 - path - the path to the file 11 - file_is_image - a boolean stating whether the file is an image 12 - file_is_text - a boolean stating whether the file is a text file 13 - text_file_content - a string containing the content of a text file 14 - JSMATH - a boolean stating whether to include jsMath 15 - JSMATH_IMAGE_FONTS - a boolean stating whether to include jsMath iamage fonts 16 - JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE 17 - sage_jsmath_macros - an array containing strings of Javascript of Sage macros for jsMath 18 #} 19 {% set title = "Data file: %s"|format(filename_) %} 20 21 {% block body_addition %} 22 <p>You may download <a href="{{ path }}">{{ filename_ }}</a> or create a linked copy to the worksheet <select onchange="go_option(this);" class="worksheet"> 23 <option selected>select worksheet</option> 24 {% for worksheet in active_worksheets %} 25 <option value='link_datafile("{{ worksheet.filename() }}","{{ filename_ }}")'>{{ worksheet.name() }}</option> 26 {% endfor %} 27 </select> or <a href="/home/{{ worksheet.filename() }}/datafile?name={{ filename_ }}&action=delete">delete {{ filename_ }}.</a></p> 28 29 <p>Access {{ filename_ }} in this worksheet by typing <tt>DATA+'{{ filename_ }}'</tt>. Here DATA is a special variable that gives the exact path to all data files uploaded to this worksheet.</p> 30 31 <hr class="usercontrol" /> 32 33 {% if file_is_image %} 34 <div align=center><img src="{{ path }}"></div> 35 {% elif file_is_text %} 36 <form method="post" action="savedatafile" enctype="multipart/form-data"> 37 <input type="submit" value="Save Changes" name="button_save" /> <input type="submit" value="Cancel" name="button_cancel" style="display:block" /> 38 <textarea class="edit" name="textfield" rows=17 cols=70 id="textfield">{{ text_file_content }}</textarea> 39 <input type="hidden" name="filename" value="{{ filename_ }}" id="filename" /> 40 </form> 41 {% endif %} 42 {% endblock %} 43 44 45 46 -
new file sage/server/notebook/templates/notebook/edit_window.html
diff --git a/sage/server/notebook/templates/notebook/edit_window.html b/sage/server/notebook/templates/notebook/edit_window.html new file mode 100644
- + 1 {% extends "notebook/worksheet_page_template.html" %} 2 {# 3 INPUT: 4 - worksheet - an instance of Worksheet 5 - worksheet_filename - a string containing a worksheet's filename 6 - username - a string containing a username 7 - text - a string containing the text of the worksheet 8 - n_lines - number of lines of the text of the worksheet 9 - JSMATH - a boolean stating whether to include jsMath 10 - JSMATH_IMAGE_FONTS - a boolean stating whether to include jsMath iamage fonts 11 - JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE 12 - sage_jsmath_macros - an array containing strings of Javascript of Sage macros for jsMath 13 #} 14 15 {% set title = 'Edit plain text <input type="submit" value="Save Changes" name="button_save" id="button_save"> <input type="submit" value="Cancel" name="button_cancel">' %} 16 {% set select = "edit" %} 17 18 {% block before_sharebar %} 19 <form method="post" action="save" enctype="multipart/form-data"> 20 {% endblock %} 21 {% block body_addition %} 22 <script type="text/javascript"> 23 function save_worksheet() { 24 } 25 function save_worksheet_and_close() { 26 } 27 </script> 28 <textarea class="plaintextedit" id="cell_intext" name="textfield" rows="{{ n_lines }}">{{ text }}</textarea> 29 </form> 30 {% endblock %} -
new file sage/server/notebook/templates/notebook/guest_top_bar_and_worksheet.html
diff --git a/sage/server/notebook/templates/notebook/guest_top_bar_and_worksheet.html b/sage/server/notebook/templates/notebook/guest_top_bar_and_worksheet.html new file mode 100644
- + 1 2 {# 3 INPUT: 4 - original_worksheet - an instance of Worksheet 5 - worksheet - an instance of Worksheet 6 - notebook - an instance of Notebook which contains worksheet 7 - worksheet_html - a string containing the html for the worksheet 8 - username - a string containing a username 9 #} 10 {% if original_worksheet.is_collaborator(username) or original_worksheet.is_owner(username) %} 11 {% set edit_text = "Edit this." %} 12 {% set url = "edit_published_page" %} 13 {% elif notebook.user_is_guest(username) %} 14 {% set edit_text = "Log in to edit a copy." %} 15 {% set url = "/" %} 16 {% else %} 17 {% set edit_text = "Edit a copy." %} 18 {% set url = "edit_published_page" %} 19 {% endif %} 20 21 {% set download_name = os.path.split(worksheet.name())[-1] %} 22 23 <a class="usercontrol" href="{{ url }}">{{ edit_text }}</a> 24 <a class="usercontrol" href="download/{{ download_name }}.sws">Download.</a> 25 <span class="ratingmsg"> 26 {% if worksheet.rating() != -1 %} 27 <a class="usercontrol" href="rating_info"> 28 This page is rated {{ "%.1f"|format(worksheet.rating()) }}. 29 </a> 30 {% endif %} 31 {% if not notebook.user_is_guest(username) 32 and not worksheet.is_publisher(username) %} 33 34 <span class="usercontrol"> 35 {{ "Rerate" if worksheet.is_rater(username) else "Rate" }} it: 36 </span> 37 {% for i in range(5) %} 38 <a class="usercontrol" 39 onClick="rate_worksheet({{ i }})"> 40 {{ i }} 41 </a> 42 {% endfor %} 43 <input name="rating_comment" id="rating_comment"></input> 44 {% endif %} 45 </span> 46 <span class="pubmsg"> 47 <a href="/pub/">Other published documents...</a> 48 </span> 49 <hr class="usercontrol" /> 50 <h1 align="center">{{ original_worksheet.name() }}</h1> 51 <h2 align="center">{{ worksheet.html_time_since_last_edited() }}</h2> 52 {{ worksheet_html }} 53 <hr class="usercontrol" /> 54 {% for i in range(10) %} 55 56 {% endfor %} 57 -
new file sage/server/notebook/templates/notebook/head.tmpl
diff --git a/sage/server/notebook/templates/notebook/head.tmpl b/sage/server/notebook/templates/notebook/head.tmpl new file mode 100644
- + 1 2 {# 3 INPUT: 4 - worksheet - an instance of Worksheet 5 - worksheet_filename - a string containing a worksheet's filename 6 - username - a string containing a user's name 7 - JSMATH - a boolean stating whether to include jsMath 8 - JSMATH_IMAGE_FONTS - a boolean stating whether to include jsMath iamage fonts 9 - JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE 10 - sage_jsmath_macros - an array containing strings of Javascript of Sage macros for jsMath 11 #} 12 {% macro common_title(worksheet_filename, worksheet) %} 13 {% if worksheet_filename %} 14 {{ worksheet.name() }} (Sage) 15 {% else %} 16 Sage Notebook | Welcome 17 {% endif %} 18 {% endmacro %} 19 20 {% macro common_css %} 21 <link rel=stylesheet href="/css/main.css" type="text/css" /> 22 {% endmacro %} 23 24 {% macro common_javascript(worksheet, worksheet_filename, username, JSMATH, JSMATH_IMAGE_FONTS, JEDITABLE_TINYMCE, sage_jsmath_macros) %} 25 <!-- Load the Sage javascript library. --> 26 <script type="text/javascript" src="/javascript_local/jquery/jquery.js"></script> 27 <script type="text/javascript" src="/javascript/main.js"></script> 28 29 {% if JSMATH %} 30 <!-- Turn off font warning. --> 31 <style> 32 #jsMath_Warning {display: none} 33 </style> 34 <script type="text/javascript"> 35 jsMath = {Controls: {cookie: {scale: 115}}} 36 </script> 37 {% if not JSMATH_IMAGE_FONTS %} 38 <script type="text/javascript" src="/javascript_local/jsmath/plugins/noImageFonts.js"></script> 39 {% endif %} 40 <!-- Move the jsMath button 20 pixels from the right edge 41 (apparently in some browsers, it covers up the scroll 42 bar) --> 43 <script type="text/javascript"> 44 jsMath.styles = { 45 '#jsMath_button': 46 'position:fixed; bottom:1px; right:20px; background-color:white;' 47 + 'border: solid 1px #959595; margin:0px; padding: 0px 3px 1px 3px; ' 48 + 'z-index:102; color:black; text-decoration:none; font-size:x-small; ' 49 + 'width:auto; cursor:hand;', 50 }; 51 </script> 52 <script type="text/javascript" src="/javascript_local/jsmath/jsMath.js"></script> 53 <script type="text/javascript"> 54 /* The extensions here do the following: 55 - verb implements the \verb command: 56 see http://www.math.union.edu/~dpvc/jsMath/authors/verb.html 57 - moreArrows implements \xrightarrow, among other things: 58 see http://www.math.union.edu/~dpvc/jsMath/authors//moreArrows.html 59 - AMSmath implements a number of AMS math commands: 60 see http://www.math.union.edu/~dpvc/jsMath/authors/AMSmath.html 61 */ 62 jsMath.Extension.Require("verb"); 63 jsMath.Extension.Require("moreArrows"); 64 jsMath.Extension.Require("AMSmath"); 65 jsMath.Extension.Require("AMSsymbols"); 66 </script> 67 {% endif %} 68 <!-- Import LaTeX macros --> 69 {% for m in sage_jsmath_macros %} 70 <script> {{ m }} </script> 71 {% endfor %} 72 73 <!-- Load the jquery and ui-jquery javascript library. 74 This is used for interact functionality in the notebook, and will be used 75 to enable drag and drop, image zoom, etc. --> 76 <script type="text/javascript" src="/javascript_local/jqueryui/jquery.ui.all.min.js"></script> 77 <script type="text/javascript" src="/javascript_local/jquery/plugins/farbtastic/farbtastic.min.js"></script> 78 <script type="text/javascript" src="/javascript_local/jquery/plugins/dimensions/jquery.dimensions.min.js"></script> 79 <script type="text/javascript" src="/javascript_local/jquery/plugins/jquery.event.extendedclick.js"></script> 80 81 <link rel="stylesheet" href="/javascript_local/jquery/plugins/farbtastic/farbtastic.css" type="text/css" /> 82 <link rel="stylesheet" href="/javascript_local/jqueryui/themes/flora/flora.all.css" /> 83 84 <!-- TODO: get the lazy loading plugin --> 85 86 <!-- TODO: Load individual ui plugins, not the whole package: 87 <script type="text/javascript" src="/javascript_local/jqueryui/ui.mouse.min.js"></script> 88 <script type="text/javascript" src="/javascript_local/jqueryui/ui.slider.min.js"></script> 89 <script type="text/javascript" src="/javascript_local/jqueryui/ui.draggable.min.js"></script> 90 <script type="text/javascript" src="/javascript_local/jqueryui/ui.draggable.ext.min.js"></script> 91 <script type="text/javascript" src="/javascript_local/jqueryui/ui.resizable.min.js"></script> 92 <script type="text/javascript" src="/javascript_local/jqueryui/ui.dialog.min.js"></script> 93 --> 94 95 <!-- This was for syntax highlighting 96 <script type="text/javascript" src="/javascript/highlight/prettify.js"></script> 97 <link rel=stylesheet href="/css/highlight/prettify.css" type="text/css" /> 98 --> 99 100 <script type="text/javascript" src="/javascript/sage3d.js"></script 101 102 <!-- Jmol - embedded 3D graphics --> 103 <script type="text/javascript" src="/java/jmol/appletweb/Jmol.js"></script> 104 <script>jmolInitialize("/java/jmol");jmolSetCallback("menuFile","/java/jmol/appletweb/SageMenu.mnu");</script> <!-- This must stay in <head> --> 105 106 <!-- TinyMCE and jEditable - in-place editing of text cells --> 107 {% if JEDITABLE_TINYMCE %} 108 <script type="text/javascript" src="/javascript_local/tiny_mce/tiny_mce.js"></script> 109 <script src="/javascript_local/jquery/plugins/jquery.jeditable.mini.js" type="text/javascript" charset="utf-8"></script> 110 <script type="text/javascript"> 111 112 function toggleEditor(id) { 113 if (!tinyMCE.get(id)) 114 tinyMCE.execCommand('mceAddControl', false, id); 115 else 116 tinyMCE.execCommand('mceRemoveControl', false, id); 117 } 118 119 $.fn.tinymce = function(options){ 120 return this.each(function(){ 121 tinyMCE.execCommand("mceAddControl", true, this.id); 122 }); 123 } 124 125 function initMCE(){ 126 tinyMCE.init({mode : "none", 127 plugins: "table,searchreplace,safari,paste,autosave", 128 theme : "advanced", 129 theme_advanced_toolbar_location : "top", 130 theme_advanced_toolbar_align : "left", 131 theme_advanced_statusbar_location : "bottom", 132 theme_advanced_buttons1 : "\ 133 formatselect,fontselect,fontsizeselect,bold,italic,underline,strikethrough,forecolor,backcolor,|,\ 134 bullist,numlist,|,\ 135 undo,redo,search,pastetext,pasteword", 136 theme_advanced_buttons2 : "\ 137 justifyleft,justifycenter,justifyright,justifyfull,outdent,indent,|,\ 138 charmap,|,\ 139 table,tablecontrols,|,\ 140 code,|,\ 141 link,image,unlink", 142 theme_advanced_buttons3 : "", 143 theme_advanced_resizing : true, 144 setup : function(ed) { 145 ed.onKeyDown.add(function(ed, e) { 146 if(key_enter_shift(key_event(e))) { 147 $(ed.formElement).submit(); 148 } 149 })} 150 }); 151 }; 152 153 initMCE(); 154 155 156 $.editable.addInputType('mce', { 157 element : function(settings, original) { 158 var textarea = $('<textarea id="'+$(original).attr("id")+'_mce"/>'); 159 if (settings.rows) { 160 textarea.attr('rows', settings.rows); 161 } else { 162 textarea.height(settings.height); 163 } 164 if (settings.cols) { 165 textarea.attr('cols', settings.cols); 166 } else { 167 textarea.width(settings.width); 168 } 169 $(this).append(textarea); 170 return(textarea); 171 }, 172 plugin : function(settings, original) { 173 tinyMCE.execCommand("mceAddControl", true, $(original).attr("id")+'_mce'); 174 }, 175 submit : function(settings, original) { 176 tinyMCE.triggerSave(); 177 tinyMCE.execCommand("mceRemoveControl", true, $(original).attr("id")+'_mce'); 178 }, 179 reset : function(settings, original) { 180 tinyMCE.execCommand("mceRemoveControl", true, $(original).attr("id")+'_mce'); 181 original.reset(); 182 } 183 }); 184 </script> 185 {% endif %} 186 <script type="text/javascript">user_name= "{{ username }}";</script> 187 {% if worksheet_filename %} 188 <script type="text/javascript"> 189 worksheet_filename="{{ worksheet_filename }}"; 190 worksheet_name="{{ worksheet.name() }}"; 191 server_ping_while_alive(); 192 </script> 193 {% endif %} 194 <!-- Uncomment this to force rename when the worksheet is opened (annoying!) 195 if W and 196 W.name() == "Untitled": 197 <script type="text/javascript">setTimeout("rename_worksheet()",1)</script> --> 198 {% endmacro %} 199 No newline at end of file -
new file sage/server/notebook/templates/notebook/index.html
diff --git a/sage/server/notebook/templates/notebook/index.html b/sage/server/notebook/templates/notebook/index.html new file mode 100644
- + 1 {% extends "base.html" %} 2 {# 3 INPUT: 4 - worksheet - an instance of Worksheet 5 - worksheet_filename - a string containing a worksheet's filename 6 - worksheet_html - a string containing the html for the worksheet 7 - notebook - an instance of Notebook which contains worksheet 8 - username - a string containing a username 9 - show_debug - a boolean stating whether to show debug information 10 - JSMATH - a boolean stating whether to include jsMath 11 - JSMATH_IMAGE_FONTS - a boolean stating whether to include jsMath iamage fonts 12 - JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE 13 - sage_jsmath_macros - an array containing strings of Javascript of Sage macros for jsMath 14 #} 15 16 {% if not select %} 17 {% set select = none %} 18 {% endif %} 19 20 {% if not backwards %} 21 {% set backwards = false %} 22 {% endif %} 23 24 {% include "notebook/head.tmpl" %} 25 26 {% block title %} 27 {{ common_title(worksheet_filename, worksheet) }} 28 {% endblock %} 29 30 {% block css %}main{% endblock %} 31 32 {% block javascript %} 33 {{ common_javascript(worksheet, worksheet_filename, username, JSMATH, JSMATH_IMAGE_FONTS, JEDITABLE_TINYMCE, sage_jsmath_macros) }} 34 {% endblock %} 35 36 {% block body_attrs %} 37 class="worksheet-online" onLoad="initialize_the_notebook();" 38 {% endblock %} 39 40 {% block body %} 41 {% if worksheet.is_published() or notebook.user_is_guest(username) %} 42 {% set original_worksheet = worksheet.worksheet_that_was_published() %} 43 {% include "notebook/guest_top_bar_and_worksheet.html" %} 44 {% else %} 45 {% include "notebook/top_bar_and_worksheet.html" %} 46 {% endif %} 47 {% if not worksheet %} 48 </td></tr></table></span> 49 {% endif %} 50 {% if worksheet.user_is_only_viewer(username) %} 51 <script type="text/javascript">worksheet_locked=true;</script> 52 {% else %} 53 <script type="text/javascript">worksheet_locked=false;</script> 54 {% endif %} 55 {% if worksheet.computing() %} 56 <!-- Set the update checking back in motion. --> 57 <script type="text/javascript"> 58 active_cell_list = {{ worksheet.queue_id_list() }}; 59 for(var i = 0; i < active_cell_list.length; i++) { 60 cell_set_running(active_cell_list[i]); 61 } 62 start_update_check(); 63 </script> 64 {% endif %} 65 {% endblock %} -
new file sage/server/notebook/templates/notebook/plain_text_window.html
diff --git a/sage/server/notebook/templates/notebook/plain_text_window.html b/sage/server/notebook/templates/notebook/plain_text_window.html new file mode 100644
- + 1 2 {% extends "notebook/worksheet_page_template.html" %} 3 {# 4 INPUT: 5 - worksheet - an instance of Worksheet 6 - worksheet_filename - a string containing a worksheet's filename 7 - username - a string containing a username 8 - plain_text - a string containing the plain text version 9 - JSMATH - a boolean stating whether to include jsMath 10 - JSMATH_IMAGE_FONTS - a boolean stating whether to include jsMath iamage fonts 11 - JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE 12 - sage_jsmath_macros - an array containing strings of Javascript of Sage macros for jsMath 13 #} 14 15 {% set title = "View plain text" %} 16 {% set select = "text" %} 17 18 {% block body_addition %} 19 <pre class="plaintext" id="cell_intext" name="textfield">{{ plain_text }}</pre> 20 {% endblock %} -
new file sage/server/notebook/templates/notebook/plain_text_worksheet.html
diff --git a/sage/server/notebook/templates/notebook/plain_text_worksheet.html b/sage/server/notebook/templates/notebook/plain_text_worksheet.html new file mode 100644
- + 1 2 {# 3 INPUT: 4 - worksheet_name - a string containing a worksheet's name 5 - worksheet_plain_text - a string containing the plain text version of a worksheet 6 #} 7 <head> 8 <title>Sage Worksheet: {{ worksheet_name }}</title> 9 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 10 </head> 11 <body> 12 <h1><a href=".">Sage Worksheet: %s</a></h1> 13 <pre>{{ worksheet_plain_text }}</pre> 14 </body> 15 No newline at end of file -
new file sage/server/notebook/templates/notebook/slide_controls.html
diff --git a/sage/server/notebook/templates/notebook/slide_controls.html b/sage/server/notebook/templates/notebook/slide_controls.html new file mode 100644
- + 1 2 <div class="hidden" id="slide_controls"> 3 <div class="slideshow_control"> 4 <a class="slide_arrow" onClick="slide_next()">></a> 5 <a class="slide_arrow" onClick="slide_last()">>></a> <span class="vbar"></span> 6 <a class="cell_mode" onClick="cell_mode()">Exit</a> 7 </div> 8 <div class="slideshow_progress" id="slideshow_progress" onClick="slide_next()"> 9 <div class="slideshow_progress_bar" id="slideshow_progress_bar"> </div> 10 <div class="slideshow_progress_text" id="slideshow_progress_text"> </div> 11 </div> 12 <div class="slideshow_control"> 13 <a class="slide_arrow" onClick="slide_first()"><<</a> 14 <a class="slide_arrow" onClick="slide_prev()"><</a> 15 </div> 16 </div> 17 18 19 20 21 22 23 -
new file sage/server/notebook/templates/notebook/specific_revision.html
diff --git a/sage/server/notebook/templates/notebook/specific_revision.html b/sage/server/notebook/templates/notebook/specific_revision.html new file mode 100644
- + 1 2 {% extends "notebook/worksheet_page_template.html" %} 3 {# 4 INPUT: 5 - worksheet - an instance of Worksheet 6 - worksheet_filename - a string containing a worksheet's filename 7 - username - a string containing a username 8 - rev - this revision's key 9 - prev_rev - the previous revision's key 10 - next_rev - the next revision's key 11 - time_ago - a string containing the time since revision 12 - body_worksheet_html - the body html of the worksheet 13 - JSMATH - a boolean stating whether to include jsMath 14 - JSMATH_IMAGE_FONTS - a boolean stating whether to include jsMath iamage fonts 15 - JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE 16 - sage_jsmath_macros - an array containing strings of Javascript of Sage macros for jsMath 17 #} 18 19 {% set select = "revisions" %} 20 {% set title = "Revision from %s ago <a href='revisions'>Revision List</a>"|format(time_ago) %} 21 22 {% macro actions %} 23 {% if prev_rev %} 24 <a class="listcontrol" href="revisions?rev={{ prev_rev }}">Older</a> 25 {% else %} 26 Oldest 27 {% endif %} 28 29 {% if next_rev %} 30 <a class="listcontrol" href="revisions?rev={{ next_rev }}">Newer</a> 31 {% else %} 32 Newest 33 {% endif %} 34 35 <a class="listcontrol" href="revisions?rev={{ rev }}&action=revert">Revert to this one</a> <span class="lastedit">(note that images are not recorded)</span> 36 <a class="listcontrol" href="revisions?rev={{ rev }}&action=publish">Publish this one</a> 37 {% endmacro %} 38 39 {% block body_addition %} 40 {{ actions() }} 41 <hr class="usercontrol" /> 42 <table width="100%%"> 43 {{ body_worksheet_html }} 44 <hr class="usercontrol" /> 45 {{ actions() }} 46 {% endblock %} -
new file sage/server/notebook/templates/notebook/top_bar_and_worksheet.html
diff --git a/sage/server/notebook/templates/notebook/top_bar_and_worksheet.html b/sage/server/notebook/templates/notebook/top_bar_and_worksheet.html new file mode 100644
- + 1 2 {# 3 INPUT: 4 - username - a string containing a username 5 - worksheet_filename - a string containing a worksheet's filename 6 - worksheet_html - a string containing the html for a worksheet 7 - show_debug - a boolean stating whether to show debug information 8 #} 9 {% include "notebook/user_controls.tmpl" %} 10 {% include "notebook/worksheet_topbar.tmpl" %} 11 {% set entries = [("$('#topbar').toggle()", 'Toggle', 'Toggle the top bar'), 12 ('/', 'Home', 'Back to your personal worksheet list'), 13 ('/pub', 'Published', 'Browse the published worksheets'), 14 ('history_window()', 'Log', 'View a log of recent computations'), 15 ('/settings', 'Settings', 'Account Settings'), 16 ('bugreport()', 'Report a Problem', 'Report a problem or submit a bug to improve Sage'), 17 ('help()', 'Help', 'Documentation'), 18 ('/logout', 'Sign out', 'Log out of the Sage notebook')] %} 19 <table width="100%"> 20 <tr> 21 <td>{% include "banner.html" %}</td> 22 <td align="right">{{ user_controls(username, entries) }}</td> 23 </tr> 24 </table> 25 {% if worksheet_filename %} 26 {{ worksheet_topbar(worksheet, "use", username) }} 27 {% endif %} 28 {% if show_debug %} 29 {% include "notebook/debug_window.html" %} 30 {% endif %} 31 32 <div class="worksheet" id="worksheet"> 33 {{ worksheet_html }} 34 </div> -
new file sage/server/notebook/templates/notebook/upload_data_window.html
diff --git a/sage/server/notebook/templates/notebook/upload_data_window.html b/sage/server/notebook/templates/notebook/upload_data_window.html new file mode 100644
- + 1 2 {% extends "notebook/worksheet_page_template.html" %} 3 {# 4 INPUT: 5 - worksheet - an instance of Worksheet 6 - worksheet_filename - a string containing a worksheet's filename 7 - username - a string containing a username 8 - JSMATH - a boolean stating whether to include jsMath 9 - JSMATH_IMAGE_FONTS - a boolean stating whether to include jsMath iamage fonts 10 - JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE 11 - sage_jsmath_macros - an array containing strings of Javascript of Sage macros for jsMath 12 #} 13 14 {% set title = 'Upload or Create Data File' %} 15 16 {% block body_addition %} 17 <div class="upload_worksheet_menu" id="upload_worksheet_menu"> 18 <h1><font size=+1>Upload or create data file attached to the worksheet '%s'</font></h1> 19 <hr /> 20 <form method="POST" action="do_upload_data" 21 name="upload" enctype="multipart/form-data"> 22 <table> 23 <tr> 24 <td> 25 Browse your computer to select a file to upload:<br /> 26 <input class="upload_worksheet_menu" size="50" type="file" name="fileField" value="" id="upload_filename"></input><br /><br /> 27 Or enter the url of a file on the web:<br /> 28 29 <input class="upload_worksheet_menu" size="50" type="text" name="urlField" value="" id="upload_url"></input><br /> 30 <br /><br /> 31 Or enter the name of a new file, which will be created:<br /> 32 <input class="upload_worksheet_menu" size="50" type="text" name="newField" value="" id="upload_filename"></input><br /><br /> 33 34 What do you want to call it? (if different than the original name)<br /> 35 <input class="upload_worksheet_menu" size="50" type="text" name="nameField" value="" id="upload_name"></input><br /> 36 </td> 37 </tr> 38 <tr> 39 <td><br /><input type="button" class="upload_worksheet_menu" value="Upload File" onClick="form.submit();" /></td> 40 </tr> 41 </table> 42 </form> 43 <br /> 44 </div> 45 {% endblock %} 46 47 No newline at end of file -
new file sage/server/notebook/templates/notebook/user_controls.tmpl
diff --git a/sage/server/notebook/templates/notebook/user_controls.tmpl b/sage/server/notebook/templates/notebook/user_controls.tmpl new file mode 100644
- + 1 2 {% macro user_controls(user, entries) %} 3 <span class="username">{{ user }}</span> 4 {% for href, name, title in entries %} 5 {% if '(' in href %} 6 {% set action = 'onClick="' ~ href ~ '"' %} 7 {% else %} 8 {% set action = 'href="' ~ href ~ '"' %} 9 {% endif %} 10 <span class="vbar"></span> 11 <a title="{{ title }}" class="usercontrol" {{ action }}>{{ name }}</a> 12 {% endfor %} 13 {% endmacro %} -
new file sage/server/notebook/templates/notebook/worksheet.html
diff --git a/sage/server/notebook/templates/notebook/worksheet.html b/sage/server/notebook/templates/notebook/worksheet.html new file mode 100644
- + 1 2 {# 3 INPUT: 4 - worksheet_name - a string containing a worksheet's name 5 - worksheet_html - a string containing the html for a worksheet 6 - do_print - a boolean stating whether to render a print version of the 7 worksheet 8 #} 9 {% extends "base.html" %} 10 11 {% block title %}Sage Worksheet: {{ worksheet_name }}{% endblock %} 12 13 {% block css %}main{% endblock %} 14 15 {% block javascript %} 16 <script type="text/javascript" src="/javascript_local/jquery/jquery.js"></script> 17 <script type="text/javascript" src="/javascript/main.js"></script> 18 {% if do_print %} 19 <script type="text/javascript" src="/javascript_local/jsmath/jsMath.js"></script> 20 {% endif %} 21 {% endblock %} 22 23 {% block body_attrs %} 24 {% if not do_print %} 25 class="worksheet-online" onLoad="initialize_the_notebook();" 26 {% endif %} 27 {% endblock %} 28 29 {% block body %} 30 {% if do_print %} 31 <div class="worksheet_print_title"> {{ worksheet_name }}</div> 32 {% endif %} 33 {{ worksheet_html }} 34 {% if do_print %} 35 <script type="text/javascript">jsMath.Process();</script> 36 {% endif %} 37 {% endblock %} 38 No newline at end of file -
new file sage/server/notebook/templates/notebook/worksheet_page_template.html
diff --git a/sage/server/notebook/templates/notebook/worksheet_page_template.html b/sage/server/notebook/templates/notebook/worksheet_page_template.html new file mode 100644
- + 1 {% extends "base.html" %} 2 {# 3 INPUT: 4 - worksheet - an instance of Worksheet 5 - worksheet_filename - a string containing a worksheet's filename 6 - username - a string containing a username 7 - title - a string 8 - select - a string containing the control that is selected 9 - backwards - a boolean 10 - JSMATH - a boolean stating whether to include jsMath 11 - JSMATH_IMAGE_FONTS - a boolean stating whether to include jsMath iamage fonts 12 - JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE 13 - sage_jsmath_macros - an array containing strings of Javascript of Sage macros for jsMath 14 #} 15 16 {% if not select %} 17 {% set select = none %} 18 {% endif %} 19 20 {% if not backwards %} 21 {% set backwards = false %} 22 {% endif %} 23 24 {% include "notebook/head.tmpl" %} 25 {% include "notebook/worksheet_top.tmpl" %} 26 {% include "notebook/worksheet_topbar.tmpl" %} 27 28 {% block title %} 29 {{ common_title(worksheet_filename, worksheet) }} 30 {% endblock %} 31 32 {% block css %}main{% endblock %} 33 34 {% block javascript %} 35 {{ common_javascript(worksheet, worksheet_filename, username, JSMATH, JSMATH_IMAGE_FONTS, JEDITABLE_TINYMCE, sage_jsmath_macros) }} 36 {% endblock %} 37 38 {% block body %} 39 {{ worksheet_top(username) }} 40 {{ worksheet_topbar(worksheet, select, username, backwards) }} 41 <hr class="usercontrol" /> 42 {% block before_sharebar %}{% endblock %} 43 <span class="sharebar">{{ title }}</span> 44 <br /><br /><br /> 45 {% block body_addition %}{% endblock %} 46 {% endblock %} 47 No newline at end of file -
new file sage/server/notebook/templates/notebook/worksheet_revision_list.html
diff --git a/sage/server/notebook/templates/notebook/worksheet_revision_list.html b/sage/server/notebook/templates/notebook/worksheet_revision_list.html new file mode 100644
- + 1 2 {% extends "notebook/worksheet_page_template.html" %} 3 {# 4 INPUT: 5 - data - a list of pairs of the form ('how long ago', key) 6 - worksheet - an instance of Worksheet 7 - worksheet_filename - a string containing a worksheet's filename 8 - username - a string containing a username 9 - JSMATH - a boolean stating whether to include jsMath 10 - JSMATH_IMAGE_FONTS - a boolean stating whether to include jsMath iamage fonts 11 - JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE 12 - sage_jsmath_macros - an array containing strings of Javascript of Sage macros for jsMath 13 #} 14 15 16 {% set title = "Revision History" %} 17 {% set select = "revisions" %} 18 19 {% block body_addition %} 20 <hr class="usercontrol"> 21 <table width="100%%"> 22 <tr> 23 <td width="1%%"></td> 24 <td width="20%%"><b>Revision</b></td> 25 <td width="20%%"><b>Last Edited</b></td> 26 <td width="30%%"></td> 27 </tr> 28 {% for desc, key in data|reverse %} 29 <tr> 30 <td></td> 31 <td><a href="revisions?rev={{ key }}">Revision {{ loop.revindex0 }}</a></td> 32 <td><span class="revs">{{ desc }}</span></td> 33 </tr> 34 {% endfor %} 35 </table> 36 {% endblock %} 37 No newline at end of file -
new file sage/server/notebook/templates/notebook/worksheet_settings.html
diff --git a/sage/server/notebook/templates/notebook/worksheet_settings.html b/sage/server/notebook/templates/notebook/worksheet_settings.html new file mode 100644
- + 1 2 {% extends "notebook/worksheet_page_template.html" %} 3 {# 4 INPUT: 5 - worksheet - an instance of Worksheet 6 - worksheet_filename - a string containing a worksheet's filename 7 - username - a string containing a username 8 - JSMATH - a boolean stating whether to include jsMath 9 - JSMATH_IMAGE_FONTS - a boolean stating whether to include jsMath iamage fonts 10 - JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE 11 - sage_jsmath_macros - an array containing strings of Javascript of Sage macros for jsMath 12 #} 13 14 {% set title = 'Worksheet Settings <button name="button_save">Save Settings</button> <input type="submit" value="Cancel" name="button_cancel"/>' %} 15 16 {% block before_sharebar %} 17 <form width=70%% method="post" action="input_settings" enctype="multipart/form-data"> 18 {% endblock %} 19 {% block body_addition %} 20 </form> 21 {% endblock %} 22 23 24 -
new file sage/server/notebook/templates/notebook/worksheet_share.html
diff --git a/sage/server/notebook/templates/notebook/worksheet_share.html b/sage/server/notebook/templates/notebook/worksheet_share.html new file mode 100644
- + 1 2 {% extends "notebook/worksheet_page_template.html" %} 3 {# 4 INPUT: 5 - worksheet - an instance of Worksheet 6 - worksheet_filename - a string containing a worksheet's filename 7 - username - a string containing a username 8 - other_users - a list of strings containing other users names 9 - user_is_admin - a boolean stating whether the user is an admin 10 - JSMATH - a boolean stating whether to include jsMath 11 - JSMATH_IMAGE_FONTS - a boolean stating whether to include jsMath iamage fonts 12 - JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE 13 - sage_jsmath_macros - an array containing strings of Javascript of Sage macros for jsMath 14 #} 15 16 {% set title = "Share this document" %} 17 {% set select = "share" %} 18 19 {% block body_addition %} 20 {% if not (user_is_admin or username == worksheet.owner()) %} 21 Only the owner of a worksheet is allowed to share it. You can do whatever you want if you <a href="copy">make your own copy</a>. 22 {% else %} 23 <p>This Sage Worksheet is currently shared with the people listed in the box below.</p> 24 <p style="margin-bottom:1em">You may add or remove collaborators (separate user names by commas).</p> 25 26 <form width=70% method="post" action="invite_collab" style="margin-bottom:1em"> 27 <textarea name="collaborators" rows=5 cols=70 class="edit" id="collaborators" style="display:block; margin-bottom:1em;">{{ worksheet.collaborators()|join(', ') }}</textarea> 28 <input type="submit" title="Give access to your worksheet to the above collaborators" value="Invite Collaborators" /> 29 </form> 30 31 <hr class="usercontrol" /> 32 <span class="username">Sage Users:</span> 33 <span class="users"> 34 {{ other_users|join(', ') }} 35 </span> 36 {% endif %} 37 {% endblock %} -
new file sage/server/notebook/templates/notebook/worksheet_top.tmpl
diff --git a/sage/server/notebook/templates/notebook/worksheet_top.tmpl b/sage/server/notebook/templates/notebook/worksheet_top.tmpl new file mode 100644
- + 1 {# 2 INPUT: 3 - username - a string containing a username 4 #} 5 6 {% macro worksheet_top(username) %} 7 {% include "notebook/user_controls.tmpl" %} 8 {% include "notebook/worksheet_topbar.tmpl" %} 9 {% set entries = [("$('#topbar').toggle()", 'Toggle', 'Toggle the top bar'), 10 ('/', 'Home', 'Back to your personal worksheet list'), 11 ('/pub', 'Published', 'Browse the published worksheets'), 12 ('history_window()', 'Log', 'View a log of recent computations'), 13 ('/settings', 'Settings', 'Account Settings'), 14 ('bugreport()', 'Report a Problem', 'Report a problem or submit a bug to improve Sage'), 15 ('help()', 'Help', 'Documentation'), 16 ('/logout', 'Sign out', 'Log out of the Sage notebook')] %} 17 <table width="100%"> 18 <tr> 19 <td>{% include "banner.html" %}</td> 20 <td align="right">{{ user_controls(username, entries) }}</td> 21 </tr> 22 </table> 23 {% endmacro %} -
new file sage/server/notebook/templates/notebook/worksheet_topbar.tmpl
diff --git a/sage/server/notebook/templates/notebook/worksheet_topbar.tmpl b/sage/server/notebook/templates/notebook/worksheet_topbar.tmpl new file mode 100644
- + 1 2 {# 3 INPUT: 4 - worksheet - an instance of Worksheet 5 - select - a string containing the control that is selected 6 - username - a string containing a username 7 - backwards - a boolean 8 #} 9 {% macro worksheet_topbar(worksheet, select=None, username='guest', backwards=false) %} 10 <table width="100%%" id="topbar"> 11 <tr> 12 <td align="left"> {{ worksheet.html_title(username) }} </td> 13 <td align="right"> {{ worksheet.html_save_discard_buttons() }} </td> 14 </tr> 15 <tr> 16 <td align="left"> {{ worksheet.html_menu() }} </td> 17 <td align="right"> {{ worksheet.html_share_publish_buttons(select, backwards) }}</td> 18 </tr> 19 </table> 20 <div class="hidden" id="slide_controls"> 21 <div class="slideshow_control"> 22 <a class="slide_arrow" onClick="slide_next()">></a> 23 <a class="slide_arrow" onClick="slide_last()">>></a> <span class="vbar"></span> 24 <a class="cell_mode" onClick="cell_mode()">Exit</a> 25 </div> 26 <div class="slideshow_progress" id="slideshow_progress" onClick="slide_next()"> 27 <div class="slideshow_progress_bar" id="slideshow_progress_bar"> </div> 28 <div class="slideshow_progress_text" id="slideshow_progress_text"> </div> 29 </div> 30 <div class="slideshow_control"> 31 <a class="slide_arrow" onClick="slide_first()"><<</a> 32 <a class="slide_arrow" onClick="slide_prev()"><</a> 33 </div> 34 </div> 35 {% endmacro %} -
sage/server/notebook/templates/registration.html
diff --git a/sage/server/notebook/templates/registration.html b/sage/server/notebook/templates/registration.html
a b 1 1 2 {% extends "base.html" %} 2 3 3 4 {% block title %}Sign up{% endblock %} -
sage/server/notebook/templates/search.html
diff --git a/sage/server/notebook/templates/search.html b/sage/server/notebook/templates/search.html
a b 1 1 2 <span class="flush-right"> 2 3 <input id="search_worksheets" size=20 onkeypress="return search_worksheets_enter_pressed(event, '{{ typ }}');" value="{{ search }}"></input> 3 4 <button class="add_new_worksheet_menu" onClick="search_worksheets('{{ typ }}');">Search Worksheets</button> -
sage/server/notebook/templates/source_code.html
diff --git a/sage/server/notebook/templates/source_code.html b/sage/server/notebook/templates/source_code.html
a b 1 1 2 {% extends "base.html" %} 2 3 3 4 {% block title %}{{ src_filename }} - Source Code{% endblock %} -
sage/server/notebook/templates/template_error.html
diff --git a/sage/server/notebook/templates/template_error.html b/sage/server/notebook/templates/template_error.html
a b 1 1 2 {% extends "base.html" %} 2 3 3 4 {% block title %}Error{% endblock %} -
sage/server/notebook/templates/top_bar.html
diff --git a/sage/server/notebook/templates/top_bar.html b/sage/server/notebook/templates/top_bar.html
a b 1 1 2 <table width="100%%"> 2 3 <tr> 3 4 <td> -
sage/server/notebook/templates/upload.html
diff --git a/sage/server/notebook/templates/upload.html b/sage/server/notebook/templates/upload.html
a b 1 1 2 {% extends "base.html" %} 2 3 3 4 {% block title %}Upload File{% endblock %} -
sage/server/notebook/templates/user_management.html
diff --git a/sage/server/notebook/templates/user_management.html b/sage/server/notebook/templates/user_management.html
a b 1 1 2 {% extends "base.html" %} 2 3 3 4 {% block title %}User Management{% endblock %} -
new file sage/server/notebook/templates/worksheet/attached.html
diff --git a/sage/server/notebook/templates/worksheet/attached.html b/sage/server/notebook/templates/worksheet/attached.html new file mode 100644
- + 1 {# 2 INPUT: 3 - attached_files - dictionary of attached files 4 #} 5 {% for file, tm in attached_files %} 6 <div class="attached_filename" onClick="inspect_attached_file('{{ file }}')"> 7 {{ file }} 8 </div> 9 {% endfor %} 10 No newline at end of file -
new file sage/server/notebook/templates/worksheet/completions.html
diff --git a/sage/server/notebook/templates/worksheet/completions.html b/sage/server/notebook/templates/worksheet/completions.html new file mode 100644
- + 1 {# 2 INPUT: 3 - cell_id - id for the cell of the completions 4 - completions_enumerated - enumerated (enumerate()) 2D list of completions in 5 column-major order 6 #} 7 <ul class='completion_menu_one' 8 {% for col_i, column in completions_enumerated %} 9 <li class='completion_menu_one'> 10 <ul class='completion_menu_two'> 11 {% for row in column %} 12 <li id='completion{{ cell_id }}_{{ loop.index0 }}_{{ col_i }}' class='completion_menu_two'> 13 <a onClick='do_replacement({{ cell_id }}, "{{ row }}"); return false;' 14 onMouseOver='this.focus(); select_replacement({{ loop.index0 }},{{ col_i }});'>{{ row }}</a> 15 </li> 16 {% endfor %} 17 </ul> 18 </li> 19 {% endfor %} 20 </ul> -
new file sage/server/notebook/templates/worksheet/menu.html
diff --git a/sage/server/notebook/templates/worksheet/menu.html b/sage/server/notebook/templates/worksheet/menu.html new file mode 100644
- + 1 {# 2 INPUT 3 - name - string with worksheet name 4 - filename_ - string with worksheet filename 5 - data - list of data to put in the Data menu 6 - systems_enumerated - enumerated list of systems 7 - system_names - list of system names 8 - current_system_index - the currently selected system_index 9 - pretty_print - a boolean stating whether to typeset as default 10 - doc_worksheet - a boolean stating whether the worksheet is the doc worksheet 11 #} 12 <select class="worksheet" onchange="go_option(this);"> 13 <option title="Select a file related function" value="" selected>File...</option> 14 <option title="Load a new worksheet stored in a file" value="upload_worksheet_button();">Upload worksheet from a file</option> 15 <option title="Create a new worksheet" value="new_worksheet();">New worksheet</option> 16 <option title="Save this worksheet to an sws file" value="download_worksheet('{{ name }}');">Download to a file</option> 17 <option title="Print this worksheet" value="print_worksheet();">Print</option> 18 <option title="Rename this worksheet" value="rename_worksheet();">Rename worksheet</option> 19 <option title="Copy this worksheet" value="copy_worksheet();">Copy worksheet</option> 20 <option title="Move this worksheet to the trash" value="delete_worksheet('{{ filename_ }}');">Delete worksheet</option> 21 </select> 22 23 <select class="worksheet" onchange="go_option(this);" > 24 <option title="Select a worksheet function" value="" selected>Action...</option> 25 <option title="Interrupt currently running calculations, if possible" value="interrupt();">Interrupt</option> 26 <option title="Restart the worksheet process" value="restart_sage();">Restart worksheet</option> 27 <option title="Quit the worksheet process" value="save_worksheet_and_close();">Save and quit worksheet</option> 28 <option value="">---------------------------</option> 29 <option title="Evaluate all input cells in the worksheet" value="evaluate_all();">Evaluate All</option> 30 <option title="Hide all output" value="hide_all();">Hide All Output</option> 31 <option title="Show all output" value="show_all();">Show All Output</option> 32 <option title="Delete all output" value="delete_all_output();">Delete All Output</option> 33 <option value="">---------------------------</option> 34 <option title="Switch to single-cell mode" value="slide_mode();">One Cell Mode</option> 35 <option title="Switch to multi-cell mode" value="cell_mode();">Multi Cell Mode</option> 36 </select> 37 38 <select class="worksheet" onchange="handle_data_menu(this);" > 39 <option title="Select an attached file" value="" selected>Data...</option> 40 <option title="Upload or create a data file in a wide range of formats" value="__upload_data_file__">Upload or create file...</option> 41 <option value="">--------------------</option> 42 {% for name in data %} 43 <option value="datafile?name={{ option }}">{{ option }}</option> 44 {% endfor %} 45 </select> 46 47 {% if not doc_worksheet %} 48 <select onchange="go_system_select(this, {{ current_system_index }});" class="worksheet"> 49 {% for system_index, system_name in systems_enumerated %} 50 <option title="Evaluate all input cells using {{ system_names[system_index] }}" 51 {{ "selected" if current_system_index == system_index else "" }} value="{{ system_names[system_index] }}"> 52 {{ system_name }} 53 </option> 54 {% endfor %} 55 </select> 56 <input type="checkbox" title="Enable/disable pretty_printing" 57 onchange="pretty_print_check(this.checked);" 58 class="worksheet" value="pretty_print" {{ "checked" if pretty_print else "" }} /> Typeset 59 {% endif %} 60 No newline at end of file -
new file sage/server/notebook/templates/worksheet/published_worksheet.html
diff --git a/sage/server/notebook/templates/worksheet/published_worksheet.html b/sage/server/notebook/templates/worksheet/published_worksheet.html new file mode 100644
- + 1 {# 2 INPUT: 3 - cell_id_list - a list of cell id's 4 - cells_html - string of cells HTML 5 #} 6 {% set published = true %} 7 {% set do_print = true %} 8 9 {% include "worksheet/worksheet_body.html" %} 10 11 12 <script language=javascript>jsMath.ProcessBeforeShowing();</script> -
new file sage/server/notebook/templates/worksheet/save_discard_buttons.html
diff --git a/sage/server/notebook/templates/worksheet/save_discard_buttons.html b/sage/server/notebook/templates/worksheet/save_discard_buttons.html new file mode 100644
- + 1 {# 2 INPUT: 3 doc_worksheet - boolean stating whether this worksheet is the doc worksheet 4 #} 5 {% if not doc_worksheet %} 6 <button name="button_save" title="Save changes" onClick="save_worksheet();">Save</button><button title="Save changes and close window" onClick="save_worksheet_and_close();" name="button_save">Save & quit</button><button title="Discard changes to this worksheet" onClick="worksheet_discard();">Discard & quit</button> 7 {% endif %} -
new file sage/server/notebook/templates/worksheet/share_publish_buttons.html
diff --git a/sage/server/notebook/templates/worksheet/share_publish_buttons.html b/sage/server/notebook/templates/worksheet/share_publish_buttons.html new file mode 100644
- + 1 2 {# 3 INPUT: 4 - worksheet - Worksheet instance 5 - select - a boolean 6 - backwards - a boolean 7 #} 8 {% if not worksheet.is_doc_worksheet() %} 9 {% macro cls(x) %} 10 {{ "control-select" if x == select else "control" }} 11 {% endmacro %} 12 {% macro backwards_text %} 13 {{ "../" if backwards else "" }} 14 {% endmacro %} 15 <a title="Print this worksheet" class="usercontrol" onClick="print_worksheet()"><img border=0 src="/images/icon_print.gif" alt="Print">Print</a> 16 <a class="{{ cls('use') }}" title="Interactively use this worksheet" onClick="edit_worksheet();">Worksheet</a> 17 <a class="{{ cls('edit') }}" title="Edit text version of this worksheet" href="{{ backwards_text() }}edit">Edit</a> 18 <a class="{{ cls('text') }}" title="View plain text version of this worksheet" href="{{ backwards_text() }}text">Text</a> 19 <a class="{{ cls('undo') }}" title="View changes to this worksheet over time" href="{{ backwards_text() }}revisions">Undo</a> 20 <a class="{{ cls('share') }}" title="Let others edit this worksheet" href="{{ backwards_text() }}share">Share</a> 21 <a class="{{ cls('publish') }}" title="Make this worksheet publicly viewable" href="{{ backwards_text() }}publish">Publish</a> 22 {% endif %} -
new file sage/server/notebook/templates/worksheet/time_last_edited.html
diff --git a/sage/server/notebook/templates/worksheet/time_last_edited.html b/sage/server/notebook/templates/worksheet/time_last_edited.html new file mode 100644
- + 1 {# 2 INPUT: 3 - time - string of time of last edit 4 - last_editor - string of name of last editor 5 #} 6 <span class="lastedit">last edited on {{ time }} by {{ last_editor }}</span> 7 No newline at end of file -
new file sage/server/notebook/templates/worksheet/time_since_last_edited.html
diff --git a/sage/server/notebook/templates/worksheet/time_since_last_edited.html b/sage/server/notebook/templates/worksheet/time_since_last_edited.html new file mode 100644
- + 1 {# 2 INPUT: 3 - time - string of time since last edit 4 - last_editor - string of name of last editor 5 #} 6 <span class="lastedit">{{ time }} ago by {{ last_editor }}</span> -
new file sage/server/notebook/templates/worksheet/title.html
diff --git a/sage/server/notebook/templates/worksheet/title.html b/sage/server/notebook/templates/worksheet/title.html new file mode 100644
- + 1 {# 2 - worksheet - Worksheet instance 3 - name - escaped name of the worksheet 4 - username - string of username 5 - doc_worksheet - boolean stating whether the worksheet is the doc worksheet 6 - warn - boolean stating whether to warn that another user is viewing 7 the worksheet 8 #} 9 <div class="worksheet_title"> 10 <a id="worksheet_title" class="worksheet_title" onClick="rename_worksheet(); return false;" title="Click to rename this worksheet">{{ name }}</a> 11 <br> {{ worksheet.html_time_last_edited() }} 12 {% if warn and username != 'guest' and not doc_worksheet%} 13 <span class="pingdown">(Someone else is viewing this worksheet)</span> 14 {% endif %} 15 </div> 16 No newline at end of file -
new file sage/server/notebook/templates/worksheet/worksheet.html
diff --git a/sage/server/notebook/templates/worksheet/worksheet.html b/sage/server/notebook/templates/worksheet/worksheet.html new file mode 100644
- + 1 {# 2 INPUT: 3 - do_print - a boolean 4 - cell_id_list - a list of cell id's 5 - confirm_before_leave - a boolean stating whether to popup a js confirm 6 dialog before leaving 7 - cells_html - string of cells HTML 8 - published - a boolean stating whether the worksheet is published 9 #} 10 {% include "worksheet/worksheet_body.html" %} 11 12 {% if do_print %} 13 <script language="javascript">jsMath.ProcessBeforeShowing();</script> 14 {% else %} 15 <script type="text/javascript">cell_id_list={{ cell_id_list }};</script> 16 {% endif %} 17 18 {% if not do_print and confirm_before_leave %} 19 <script type="text/javascript"> 20 window.onbeforeunload = confirmBrowseAway; 21 function confirmBrowseAway() 22 { 23 return "Unsubmitted cells will be lost."; 24 } 25 </script> 26 {% endif %} 27 No newline at end of file -
new file sage/server/notebook/templates/worksheet/worksheet_body.html
diff --git a/sage/server/notebook/templates/worksheet/worksheet_body.html b/sage/server/notebook/templates/worksheet/worksheet_body.html new file mode 100644
- + 1 {# 2 INPUT: 3 - cells_html - string of cells HTML 4 - published - a boolean stating whether the worksheet is published 5 #} 6 7 <div class="cell_input_active" id="cell_resizer"></div> 8 {% if not published %} 9 <div class="worksheet_cell_list" id="worksheet_cell_list"> 10 {% endif %} 11 12 {{ cells_html }} 13 14 {% if not do_print and not published %} 15 </div> 16 <div class="insert_new_cell" id="insert_last_cell"></div> 17 <script type="text/javascript"> 18 $("#insert_last_cell").plainclick(function(e) {insert_new_cell_after(cell_id_list[cell_id_list.length-1]);}); 19 $("#insert_last_cell").shiftclick(function(e) {insert_new_text_cell_after(cell_id_list[cell_id_list.length-1]);}); 20 </script> 21 <div class="worksheet_bottom_padding"></div> 22 {% endif %} 23 -
sage/server/notebook/templates/worksheet_listing.html
diff --git a/sage/server/notebook/templates/worksheet_listing.html b/sage/server/notebook/templates/worksheet_listing.html
a b 1 1 2 {% extends "base.html" %} 2 3 3 4 {% if pub %} -
sage/server/notebook/templates/yes_no.html
diff --git a/sage/server/notebook/templates/yes_no.html b/sage/server/notebook/templates/yes_no.html
a b 1 1 2 {% extends "base.html" %} 2 3 3 4 {% block title %}Confirm{% endblock %} -
sage/server/notebook/twist.py
diff --git a/sage/server/notebook/twist.py b/sage/server/notebook/twist.py
a b class WorksheetFile(resource.Resource): 191 191 s = notebook.html(worksheet_filename = W.filename(), 192 192 username = self.username) 193 193 194 #Hack to add in the needed CSS to get it to display nicely195 css_tag = lambda path: r'<link rel=stylesheet href="%s" type="text/css">'%path196 main_css = css_tag('/css/main.css')197 s = s.replace(main_css,css_tag('_static/default.css')+"\n"+main_css )198 199 194 return HTMLResponse(stream=s) 200 195 201 196 def childFactory(self, request, name): … … class ListOfUsers(resource.Resource): 2199 2194 if user_type(self.username) != 'admin': 2200 2195 s = message('You must an admin to manage other users.') 2201 2196 else: 2202 s = template('user_management.html', {'users':notebook.valid_login_names()})2197 s = template('user_management.html', users = notebook.valid_login_names()) 2203 2198 return HTMLResponse(stream = s) 2204 2199 2205 2200 class InvalidPage(resource.Resource): -
sage/server/notebook/worksheet.py
diff --git a/sage/server/notebook/worksheet.py b/sage/server/notebook/worksheet.py
a b import sage.server.support as support 52 52 # Imports specifically relevant to the sage notebook 53 53 import worksheet_conf 54 54 from cell import Cell, TextCell 55 from template import template 55 56 56 57 # Set some constants that will be used for regular expressions below. 57 58 whitespace = re.compile('\s') # Match any whitespace character … … class Worksheet: 2211 2212 ########################################################## 2212 2213 def html(self, include_title=True, do_print=False, 2213 2214 confirm_before_leave=False, read_only=False): 2215 """ 2216 INPUT: 2217 - publish - a boolean stating whether the worksheet is published 2218 - do_print - a boolean 2219 2220 OUTPUT: 2221 - returns the html for the worksheet 2222 2223 EXAMPLES:: 2224 2225 sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir()) 2226 sage: W = nb.create_new_worksheet('Test', 'admin') 2227 sage: W.html() 2228 '\n\n\n<div class="cell_input_active" id="cell_resizer"></div>\n\n<div class="worksheet_cell_list" id...' 2229 """ 2230 ncols = self.notebook().conf()['word_wrap_cols'] 2231 cells_html = "" 2214 2232 if self.is_published(): 2215 2233 try: 2216 2234 return self.__html 2217 2235 except AttributeError: 2218 s = self.html_worksheet_body(do_print=True) 2219 s += self.javascript_for_jsmath_rendering() 2236 for cell in self.cell_list(): 2237 cells_html += cell.html(ncols, do_print=True) + '\n' 2238 s = template("worksheet/published_worksheet.html", ncols = ncols, 2239 cells_html = cells_html) 2220 2240 self.__html = s 2221 2241 return s 2222 2223 s = '' 2224 2225 s += self.html_worksheet_body(do_print=do_print) 2226 2227 if do_print: 2228 s += self.javascript_for_jsmath_rendering() 2229 else: 2230 s += self.javascript_for_being_active_worksheet() 2231 2232 if not do_print and confirm_before_leave: 2233 s += self.javascript_confirm_before_leave() 2234 2235 return s 2242 for cell in self.cell_list(): 2243 cells_html += cell.html(ncols, do_print=do_print) + '\n' 2244 2245 return template("worksheet/worksheet.html", published = self.is_published(), 2246 do_print = do_print, confirm_before_leave = confirm_before_leave, 2247 cells_html = cells_html, 2248 cell_id_list = self.compute_cell_id_list()) 2236 2249 2237 2250 def truncated_name(self, max=30): 2238 2251 name = self.name() … … class Worksheet: 2243 2256 def html_title(self, username='guest'): 2244 2257 import cgi 2245 2258 name = self.truncated_name() 2246 2247 2259 warn = self.warn_about_other_person_editing(username, WARN_THRESHOLD) 2248 2260 2249 s = '' 2250 s += '<div class="worksheet_title">' 2251 s += '<a id="worksheet_title" class="worksheet_title" onClick="rename_worksheet(); return false;" title="Click to rename this worksheet">%s</a>'%(cgi.escape(name)) 2252 s += '<br>' + self.html_time_last_edited() 2253 if warn and username != 'guest' and not self.is_doc_worksheet(): 2254 s += ' <span class="pingdown">(Someone else is viewing this worksheet)</span>' 2255 s += '</div>' 2256 2257 return s 2261 return template("worksheet/title.html", worksheet = self, 2262 name = cgi.escape(self.truncated_name()), 2263 warn = warn, doc_worksheet = self.is_doc_worksheet(), 2264 username = username) 2258 2265 2259 2266 def is_doc_worksheet(self): 2260 2267 try: … … class Worksheet: 2266 2273 self.__is_doc_worksheet = value 2267 2274 2268 2275 def html_save_discard_buttons(self): 2269 if self.is_doc_worksheet(): 2270 return '' 2271 return """ 2272 <button name="button_save" title="Save changes" onClick="save_worksheet();">Save</button><button title="Save changes and close window" onClick="save_worksheet_and_close();" name="button_save">Save & quit</button><button title="Discard changes to this worksheet" onClick="worksheet_discard();">Discard & quit</button> 2273 """ 2274 2276 r""" 2277 OUTPUT: 2278 - returns the html for the save, discard, etc. buttons 2279 2280 EXAMPLES:: 2281 2282 sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir()) 2283 sage: W = nb.create_new_worksheet('Test', 'admin') 2284 sage: W.html_save_discard_buttons() 2285 '\n\n<button name="button_save" title="Save changes" onClick="save_worksheet();">Save<...' 2286 """ 2287 return template("worksheet/save_discard_buttons.html", doc_worksheet = self.is_doc_worksheet()) 2288 2275 2289 def html_share_publish_buttons(self, select=None, backwards=False): 2276 if self.is_doc_worksheet(): 2277 return '' 2278 def cls(x): 2279 if x == select: 2280 return "control-select" 2281 else: 2282 return "control" 2283 backwards = '../' if backwards else '' 2284 return """ 2285 2286 <a title="Print this worksheet" class="usercontrol" onClick="print_worksheet()"><img border=0 src="/images/icon_print.gif" alt="Print">Print</a> 2287 <a class="%s" title="Interactively use this worksheet" onClick="edit_worksheet();">Worksheet</a> 2288 <a class="%s" title="Edit text version of this worksheet" href="%sedit">Edit</a> 2289 <a class="%s" title="View plain text version of this worksheet" href="%stext">Text</a> 2290 <a class="%s" href="%srevisions" title="View changes to this worksheet over time">Undo</a> 2291 <a class="%s" href="%sshare" title="Let others edit this worksheet">Share</a> 2292 <a class="%s" href="%spublish" title="Make this worksheet publicly viewable">Publish</a> 2293 """%(cls('use'),cls('edit'),backwards,cls('text'),backwards,cls('revisions'),backwards,cls('share'),backwards,cls('publish'),backwards) 2294 2295 def html_data_options_list(self): 2296 D = self.attached_data_files() 2297 D.sort() 2298 x = '\n'.join(['<option value="datafile?name=%s">%s</option>'%(nm,nm) for nm in D]) 2299 return x 2300 2301 def html_file_menu(self): 2302 ## <option title="Save this worksheet as an HTML web page" onClick="save_as('html');">Save as HTML (zipped) </option> 2303 ## <option title="Save this worksheet to LaTeX format" onClick="save_as('latex');">Save as LaTeX (zipped) </option> 2304 ## <option title="Save this worksheet as a PDF file" onClick="save_as('pdf');">Save as PDF</option> 2305 ## <option title="Save this worksheet as a text file" onClick="save_as('text');">Save as Text</option> 2306 2307 if self.is_doc_worksheet(): 2308 system_select = '' 2309 pretty_print_check = '' 2310 else: 2311 system_select = self.notebook().html_system_select_form_element(self) 2312 pretty_print_check = self.notebook().html_pretty_print_check_form_element(self) 2313 2314 data = self.html_data_options_list() 2315 2316 return """ 2317 <select class="worksheet" onchange="go_option(this);"> 2318 <option title="Select a file related function" value="" selected>File...</option> 2319 <option title="Load a new worksheet stored in a file" value="upload_worksheet_button();">Upload worksheet from a file</option> 2320 <option title="Create a new worksheet" value="new_worksheet();">New worksheet</option> 2321 <option title="Save this worksheet to an sws file" value="download_worksheet('%s');">Download to a file</option> 2322 <option title="Print this worksheet" value="print_worksheet();">Print</option> 2323 <option title="Rename this worksheet" value="rename_worksheet();">Rename worksheet</option> 2324 <option title="Copy this worksheet" value="copy_worksheet();">Copy worksheet</option> 2325 <option title="Move this worksheet to the trash" value="delete_worksheet('%s');">Delete worksheet</option> 2326 </select> 2327 2328 <select class="worksheet" onchange="go_option(this);" > 2329 <option title="Select a worksheet function" value="" selected>Action...</option> 2330 <option title="Interrupt currently running calculations, if possible" value="interrupt();">Interrupt</option> 2331 <option title="Restart the worksheet process" value="restart_sage();">Restart worksheet</option> 2332 <option title="Quit the worksheet process" value="save_worksheet_and_close();">Save and quit worksheet</option> 2333 <option value="">---------------------------</option> 2334 <option title="Evaluate all input cells in the worksheet" value="evaluate_all();">Evaluate All</option> 2335 <option title="Hide all output" value="hide_all();">Hide All Output</option> 2336 <option title="Show all output" value="show_all();">Show All Output</option> 2337 <option title="Delete all output" value="delete_all_output();">Delete All Output</option> 2338 <option value="">---------------------------</option> 2339 <option title="Switch to single-cell mode" value="slide_mode();">One Cell Mode</option> 2340 <option title="Switch to multi-cell mode" value="cell_mode();">Multi Cell Mode</option> 2341 </select> 2342 2343 <select class="worksheet" onchange="handle_data_menu(this);" > 2344 <option title="Select an attached file" value="" selected>Data...</option> 2345 <option title="Upload or create a data file in a wide range of formats" value="__upload_data_file__">Upload or create file...</option> 2346 <option value="">--------------------</option> 2347 %s 2348 </select> 2349 2350 %s 2351 %s 2352 """%(_notebook.clean_name(self.name()), self.filename(), 2353 data, system_select, pretty_print_check) 2290 r""" 2291 INPUT: 2292 - select - a boolean 2293 - backwards - a boolean 2294 2295 OUTPUT: 2296 - returns the html for the share, publish, etc. buttons 2297 2298 EXAMPLES:: 2299 2300 sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir()) 2301 sage: W = nb.create_new_worksheet('Test', 'admin') 2302 sage: W.html_share_publish_buttons() 2303 '\n\n\n\n\n<a title="Print this worksheet" class="usercontrol" onClick="print_worksheet()">...' 2304 """ 2305 return template("worksheet/share_publish_buttons.html", worksheet = self, select = select, backwards = backwards) 2306 2354 2307 # <option title="Browse the data directory" value="data/">Browse data directory...</option> 2355 2308 # <option title="Browse the directory of output from cells" value="cells/">Browse cell output directories...</option> 2356 2309 2357 2310 # <option title="Configure this worksheet" value="worksheet_settings();">Worksheet settings</option> 2358 2311 2359 2312 def html_menu(self): 2360 name = self.filename() 2361 2362 menu = ' '*3 + self.html_file_menu() 2363 2364 filename = os.path.split(self.filename())[-1] 2365 download_name = _notebook.clean_name(self.name()) 2366 2367 #menu += ' </span>' #why is this here? it isn't opened anywhere. 2368 2369 return menu 2313 """ 2314 OUTPUT: 2315 - returns the html for the menus of the worksheet 2316 2317 EXAMPLES:: 2318 2319 sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir()) 2320 sage: W = nb.create_new_worksheet('Test', 'admin') 2321 sage: W.html_menu() 2322 '\n <select class="worksheet" onchange="go_option(this);">\n ...' 2323 """ 2324 return template("worksheet/menu.html", name = _notebook.clean_name(self.name()), 2325 filename_ = self.filename(), data = self.attached_data_files().sort(), 2326 systems_enumerated = enumerate(self.notebook().systems()), 2327 system_names = self.notebook().system_names(), 2328 current_system_index = self.notebook().system_names().index(self.system()), 2329 pretty_print = self.pretty_print(), 2330 doc_worksheet = self.is_doc_worksheet()) 2370 2331 2371 2332 def html_worksheet_body(self, do_print, publish=False): 2372 n = len(self.cell_list()) 2333 """ 2334 INPUT: 2335 - publish - a boolean stating whether the worksheet is published 2336 - do_print - a boolean 2337 2338 OUTPUT: 2339 - returns the html for the File menu of the worksheet 2340 2341 EXAMPLES:: 2342 2343 sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir()) 2344 sage: W = nb.create_new_worksheet('Test', 'admin') 2345 sage: W.html_worksheet_body(false) 2346 '\n\n<div class="cell_input_active" id="cell_resizer"></div>\n\n<div class="worksheet_cell_list" id...' 2347 """ 2373 2348 published = self.is_published() or publish 2374 2375 s = '<div class="cell_input_active" id="cell_resizer"></div>' 2376 D = self.notebook().conf() 2377 ncols = D['word_wrap_cols'] 2378 if not published: 2379 s += '<div class="worksheet_cell_list" id="worksheet_cell_list">\n' 2380 2381 for i in range(n): 2382 cell = self.cell_list()[i] 2383 s += cell.html(ncols, do_print=do_print) + '\n' 2384 2385 if not do_print and not published: 2386 s += '\n</div>\n' 2387 s += """<div class="insert_new_cell" id="insert_last_cell"> 2388 </div> 2389 <script type="text/javascript"> 2390 $("#insert_last_cell").plainclick(function(e) {insert_new_cell_after(cell_id_list[cell_id_list.length-1]);}); 2391 $("#insert_last_cell").shiftclick(function(e) {insert_new_text_cell_after(cell_id_list[cell_id_list.length-1]);}); 2392 </script>""" 2393 s += '<div class="worksheet_bottom_padding"></div>\n' 2394 return s 2395 2396 def javascript_for_being_active_worksheet(self): 2397 s = '<script type="text/javascript">cell_id_list=%s;</script>'%self.compute_cell_id_list() 2398 #s += 'for(i=0;i<cell_id_list.length;i++) prettify_cell(cell_id_list[i]);</script>\n' 2399 return s 2400 2401 def javascript_for_jsmath_rendering(self): 2402 return '<script language=javascript>jsMath.ProcessBeforeShowing();</script>\n' 2403 2404 def javascript_confirm_before_leave(self): 2405 return """<script type="text/javascript"> 2406 window.onbeforeunload = confirmBrowseAway; 2407 function confirmBrowseAway() 2408 { 2409 return "Unsubmitted cells will be lost."; 2410 } 2411 </script> 2412 """ 2413 2349 ncols = self.notebook().conf()['word_wrap_cols'] 2350 cells_html = "" 2351 for cell in self.cell_list(): 2352 cells_html += cell.html(ncols, do_print=do_print) + '\n' 2353 2354 return template("worksheet/worksheet_body.html", 2355 cells_html = cells_html, 2356 published = published, 2357 do_print = do_print) 2414 2358 2415 2359 2416 2360 ########################################################## … … class Worksheet: 2470 2414 user = self.last_to_edit() 2471 2415 if user != username: 2472 2416 return True, user 2473 False2417 return False 2474 2418 2475 2419 def html_time_since_last_edited(self): 2476 2420 t = self.time_since_last_edited() 2477 2421 tm = convert_seconds_to_meaningful_time_span(t) 2478 who = ' by %s'%self.last_to_edit() 2479 return '<span class="lastedit">%s ago%s</span>'%(tm, who) 2422 return template("worksheet/time_since_last_edited.html", 2423 last_editor = self.last_to_edit(), 2424 time = tm) 2480 2425 2481 2426 def html_time_last_edited(self): 2482 tm = convert_time_to_string(self.last_edited()) 2483 who = self.last_to_edit() 2484 t = '<span class="lastedit">last edited on %s by %s</span>'%(tm, who) 2485 return t 2427 return template("worksheet/time_last_edited.html", 2428 time = convert_time_to_string(self.last_edited()), 2429 last_editor = self.last_to_edit()) 2486 2430 2487 2431 2488 2432 ########################################################## … … class Worksheet: 3840 3784 # List of attached files. 3841 3785 ########################################################## 3842 3786 def attached_html(self): 3843 s = '' 3844 div = '<div class="attached_filename" onClick="inspect_attached_file(\'%s\')">' 3845 A = self.attached_files() 3846 D = self.DIR() 3847 for F, tm in A.iteritems(): 3848 # uncomment this to remove some absolute path info... 3849 # if F[:len(D)] == D: F = F[len(D)+1:] 3850 s += div%F + '%s</div>'%F 3851 return s 3787 return template("worksheet/attached.html", 3788 attached_files = self.attached_files()) 3852 3789 3853 3790 ########################################################## 3854 3791 # Showing and hiding all cells … … def first_word(s): 4081 4018 4082 4019 4083 4020 def format_completions_as_html(cell_id, completions): 4021 """ 4022 INPUT: 4023 - cell_id - id for the cell of the completions 4024 - completions - list of completions in row-major order 4025 4026 OUTPUT: 4027 - html for the completions formatted in rows and columns 4028 """ 4084 4029 if len(completions) == 0: 4085 4030 return '' 4086 lists = [] 4087 4088 # compute the width of each column 4089 column_width = [] 4090 for i in range(len(completions[0])): 4091 column_width.append(max([len(x[i]) for x in completions if i < len(x)])) 4092 4093 for i in range(len(completions)): 4094 row = completions[i] 4095 for j in range(len(row)): 4096 if len(lists) <= j: 4097 lists.append([]) 4098 cell = """ 4099 <li id='completion%s_%s_%s' class='completion_menu_two'> 4100 <a onClick='do_replacement(%s, "%s"); return false;' 4101 onMouseOver='this.focus(); select_replacement(%s,%s);' 4102 >%s</a> 4103 </li>"""%(cell_id, i, j, cell_id, row[j], i,j, 4104 row[j]) 4105 #row[j] + ' '*(column_width[j]-len(row[j])) ) 4106 4107 lists[j].append(cell) 4108 4109 grid = "<ul class='completion_menu_one'>" 4110 for L in lists: 4111 s = "\n ".join(L) 4112 grid += "\n <li class='completion_menu_one'>\n <ul class='completion_menu_two'>\n%s\n </ul>\n </li>"%s 4113 4114 return grid + "\n</ul>" 4031 4032 return template("worksheet/completions.html", cell_id = cell_id, 4033 # Transpose and enumerate completions to column-major 4034 completions_enumerated = enumerate(map(list, zip(*completions)))) 4115 4035 4116 4036 4117 4037 def extract_name(text):