Ticket #6568: sage-trac-6568.1.patch

File sage-trac-6568.1.patch, 101.0 KB (added by timdumol, 12 years ago)

Migrated notebook.py from HTML to Jinja. Base: r12658 (Sage 4.4.1)

  • sage/server/notebook/notebook.py

    # HG changeset patch
    # User Tim Dumol <tim@timdumol.com>
    # Date 1248202265 -28800
    # Node ID 95f3679a5a9d3572700acc8e74421707433bec73
    # Parent  faa0164492450842fad46876f70659e312e3b902
    * 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
    
    diff -r faa016449245 -r 95f3679a5a9d sage/server/notebook/notebook.py
    a b  
    2424                                    tmp_dir, pad_zeros, cputime)
    2525from   sage.misc.package   import is_package_installed
    2626from   sage.version        import version
     27
    2728# Sage Notebook
    2829import css          # style
    2930import js           # javascript
     
    3334import server_conf  # server configuration
    3435import user_conf    # user configuration
    3536import user         # users
     37from template import template
    3638
    3739from cgi import escape
    3840
     
    908910            return MAX_HISTORY_LENGTH
    909911       
    910912    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
     913        return template("command_history.html", history_text = escape(self.history_text()))
    923914
    924915       
    925916    def history_with_start(self, start):
     
    11691160    # Importing and exporting worksheets to a plain text format
    11701161    ##########################################################
    11711162
    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
     1163    def plain_text_worksheet_html(self, filename, prompts=True):
     1164        """
     1165        Outputs html containing the plain text version of a worksheet
     1166
     1167        INPUT:
     1168        - ``filename`` - filename of a worksheet
     1169        - ``prompts``  - boolean
     1170
     1171        OUTPUT:
     1172        - A string containing the html for the plain text version
     1173        """
     1174        worksheet = self.get_worksheet_with_filename(filename)
     1175        text = worksheet.plain_text(prompts = prompts)
     1176        return template("plain_text_worksheet.html",
     1177                        worksheet_name = worksheet.name(),
     1178                        worksheet_plain_text = escape(worksheet.plain_text(prompts = prompts)))
    11851179
    11861180    ##########################################################
    11871181    # Directories for worksheets, etc.
     
    13101304        return s
    13111305
    13121306    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
     1307        worksheet = self.get_worksheet_with_filename(filename)
     1308        return template("worksheet.html", worksheet_name = worksheet.name(),
     1309                 worksheet_html = worksheet.html(include_title=False, do_print=do_print))
    13331310
    13341311   
    13351312
     
    13561333        return W
    13571334
    13581335    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 -- settings
    1370         #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 s
    1381 
    1382     def html_banner_and_control(self, user, entries):
    1383         return """
    1384         <table width="100%%"><tr><td>
    1385         %s
    1386         </td><td align=right>
    1387         %s
    1388         </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>'%user
    1397         for href, name, title in entries:
    1398             if '(' in href:
    1399                 action = 'onClick="%s"'%href
    1400             else:
    1401                 action = 'href="%s"'%href
    1402             x = '<a title="%s" class="usercontrol" %s>%s</a>\n'%(title, action, name)
    1403             s += vbar + x
    1404         return s
    1405 
    1406     def html_banner(self):
    1407         ver=version
    1408         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         """%ver
    1415         return s
    1416 
     1336        return template("top_bar.html", user = user, pub = pub,
     1337                        notebook = self)
     1338   
    14171339
    14181340    ##########################################################
    14191341    # Revision history for a worksheet
    14201342    ##########################################################
    14211343    def html_worksheet_revision_list(self, username, worksheet):
    1422         head, body = self.html_worksheet_page_template(worksheet, username, "Revision history", select="revisions")
     1344        """
     1345        Returns the HTML for the revision list of a worksheet.
     1346
     1347        INPUT:
     1348        - ``username`` - a string
     1349        - ``worksheet`` - an instance of Worksheet
     1350
     1351        OUTPUT:
     1352        - a string containing the HTML
     1353        """
    14231354        data = worksheet.snapshot_data()  # pairs ('how long ago', key)
    1424         rows = []
    1425         i = 0
    1426         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 %s
    1438 </table>
    1439 """%rows
    14401355
    1441         return """
    1442         <html>
    1443         <head>%s</head>
    1444         <body>%s</body>
    1445         </html>
    1446         """%(head, body)
     1356        return template("worksheet_revision_list.html", data = data,
     1357                        worksheet = worksheet,
     1358                        worksheet_filename = worksheet.filename(),
     1359                        username = username,
     1360                        JSMATH = JSMATH,
     1361                        JSMATH_IMAGE_FONTS = JSMATH_IMAGE_FONTS,
     1362                        JEDITABLE_TINYMCE = JEDITABLE_TINYMCE,
     1363                        sage_jsmath_macros = sage_jsmath_macros)
    14471364
    14481365
    14491366    def html_specific_revision(self, username, ws, rev):
     1367        """
     1368        Returns the HTML for a revision of the worksheet.
     1369
     1370        INPUT:
     1371        - ``username`` - a string
     1372        - ``ws`` - an instance of Worksheet
     1373        - ``rev`` - a string containing the key of the revision
     1374
     1375        OUTPUT:
     1376        - a string containing the HTML
     1377        """
    14501378        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&nbsp;&nbsp;&nbsp;&nbsp;<a href='revisions'>Revision List</a>"%when, select="revisions")
     1379        time_ago = worksheet.convert_seconds_to_meaningful_time_span(t)
    14541380       
    14551381        filename = ws.get_snapshot_text_filename(rev)
    14561382        txt = bz2.decompress(open(filename).read())
    14571383        W = self.scratch_worksheet()
    14581384        W.delete_cells_directory()
    14591385        W.edit_save(txt)
    1460         html = W.html_worksheet_body(do_print=True, publish=True)
     1386        body_worksheet_html = W.html_worksheet_body(do_print=True, publish=True)
    14611387
    14621388        data = ws.snapshot_data()  # pairs ('how long ago', key)
    14631389        prev_rev = None
     
    14701396                    next_rev = data[i+1][1]
    14711397                break
    14721398           
    1473         if prev_rev:
    1474             prev = '<a class="listcontrol" href="revisions?rev=%s">Older</a>&nbsp;&nbsp;'%prev_rev
    1475         else:
    1476             prev = 'Oldest'
    1477            
    1478         if next_rev:
    1479             next = '<a class="listcontrol" href="revisions?rev=%s">Newer</a>&nbsp;&nbsp;'%next_rev
    1480         else:
    1481             next = 'Newest'
     1399        return template("specific_revision.html", worksheet = ws,
     1400                        worksheet_filename = ws.filename(),
     1401                        username = username, rev = rev,
     1402                        prev_rev = prev_rev, next_rev = next_rev,
     1403                        time_ago = time_ago,
     1404                        body_worksheet_html = body_worksheet_html,
     1405                        JSMATH = JSMATH,
     1406                        JSMATH_IMAGE_FONTS = JSMATH_IMAGE_FONTS,
     1407                        JEDITABLE_TINYMCE = JEDITABLE_TINYMCE,
     1408                        sage_jsmath_macros = sage_jsmath_macros)
    14821409
    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>&nbsp;&nbsp;
    1487         <a class="listcontrol" href="revisions?rev=%s&action=publish">Publish this one</a>&nbsp;&nbsp;
    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 
     1410    # TODO: Make obsolete
    15081411    def html_worksheet_page_template(self, worksheet, username, title, select=None, backwards=False):
    15091412        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())
    15111413        body = self._html_body(worksheet.filename(), top_only=True, username=username)
    15121414        body += self.html_worksheet_topbar(worksheet, select=select, username=username, backwards=backwards)
    15131415        body += '<hr class="usercontrol">'
     
    15171419       
    15181420
    15191421    def html_share(self, worksheet, username):
     1422        """
     1423        Returns the HTML for the share page of a worksheet.
     1424
     1425        INPUT:
     1426        - ``username`` - a string
     1427        - ``worksheet`` - an instance of Worksheet
     1428
     1429        OUTPUT:
     1430        - a string containing the HTML
     1431        """
    15201432        head, body = self.html_worksheet_page_template(worksheet, username, "Share this document", select="share")
     1433        U = self.users()
     1434        other_users = [x for x, u in U.iteritems() if not u.is_guest() and not u.username() in [username, 'pub', '_sage_']]
     1435        other_users.sort(lambda x,y: cmp(x.lower(), y.lower()))
    15211436
    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>'
    1528 
    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>'
    1534 
    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 
     1437        return template("worksheet_share.html", worksheet = worksheet,
     1438                        worksheet_filename = worksheet.filename(),
     1439                        username = username, other_users = other_users,
     1440                        user_is_admin = self.user(username).is_admin(),
     1441                        JSMATH = JSMATH,
     1442                        JSMATH_IMAGE_FONTS = JSMATH_IMAGE_FONTS,
     1443                        JEDITABLE_TINYMCE = JEDITABLE_TINYMCE,
     1444                        sage_jsmath_macros = sage_jsmath_macros)
    15531445
    15541446
    15551447    def html_download_or_delete_datafile(self, ws, username, filename):
    1556         head, body = self.html_worksheet_page_template(ws, username, "Data file: %s"%filename)
     1448        """
     1449        Returns the HTML for the download or delete datafile page.
     1450
     1451        INPUT:
     1452        - ``username`` - a string
     1453        - ``ws`` - an instance of Worksheet
     1454        - ``filename`` - the name of the file
     1455
     1456        OUTPUT:
     1457        - a string containing the HTML
     1458        """
    15571459        path = "/home/%s/data/%s"%(ws.filename(), filename)
    1558         body += 'You may download <a href="%s">%s</a>'%(path, filename)
    15591460
    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)
    1570 
    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)
     1461        worksheets = self.get_worksheets_with_viewer(username)
     1462        active_worksheets = [x for x in X if x.is_active(username)]
     1463        sort_worksheet_list(active_worksheets, 'name', False)
    15721464       
    1573         body += '<hr class="usercontrol">'
    15741465        ext = os.path.splitext(filename)[1].lower()
    15751466        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>'
     1467            file_is_image = True
     1468        if ext in ['.txt', '.tex', '.sage', '.spyx', '.py', '.f', '.f90', '.c']:
     1469            file_is_text = True
     1470            text_file_content = open('%s/%s'%(ws.data_directory(), filename)).read()
    15831471
    1584         return """
    1585         <html>
    1586         <head>%s</head>
    1587         <body>%s</body>
    1588         </html>
    1589         """%(head, body)
     1472        return template("download_or_delete_datafile.html",
     1473                        worksheet = ws,
     1474                        worksheet_filename = ws.filename(),
     1475                        username = username,
     1476                        active_worksheets = active_worksheets,
     1477                        filename = filename,
     1478                        path = path,
     1479                        file_is_image = file_is_image,
     1480                        file_is_text = file_is_text,
     1481                        text_file_content = text_file_content,
     1482                        JSMATH = JSMATH,
     1483                        JSMATH_IMAGE_FONTS = JSMATH_IMAGE_FONTS,
     1484                        JEDITABLE_TINYMCE = JEDITABLE_TINYMCE,
     1485                        sage_jsmath_macros = sage_jsmath_macros)
    15901486
    15911487
    15921488
     
    16861582    # HTML -- generate most html related to the whole notebook page
    16871583    ###########################################################
    16881584    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()">&gt;</a>
    1693               <a class="slide_arrow" onClick="slide_last()">&gt;&gt;</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">&nbsp;</div>
    1698               <div class="slideshow_progress_text" id="slideshow_progress_text">&nbsp;</div>
    1699             </div>
    1700             <div class="slideshow_control">
    1701               <a class="slide_arrow" onClick="slide_first()">&lt;&lt;</a>
    1702               <a class="slide_arrow" onClick="slide_prev()">&lt;</a>
    1703             </div>
    1704           </div>
    1705           """%vbar
     1585        return template("slide_controls.html")
    17061586
    17071587    def html_debug_window(self):
    1708         return """
    1709         <div class='debug_window'>
     1588        """
     1589Returns the HTML for the debug window 
     1590DEPRECATED
     1591
     1592OUTPUT:
     1593- the HTML for the debug window
     1594   
     1595EXAMPLES::
     1596    sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
     1597    sage: print(nb.html_debug_window())
     1598    <div class='debug_window'>
    17101599        <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>"""
     1600        <textarea rows=5 id='debug_input' class='debug_input'
     1601                  onKeyPress='return debug_keypress(event);'
     1602                  onFocus='debug_focus();' onBlur='debug_blur();'></textarea>
     1603    </div>
     1604        """
     1605        return template("debug_window.html")
    17151606
    17161607   
    17171608    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 edge
    1738             # (apparently in some browsers, it covers up the scroll
    1739             # 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.html
    1753       - moreArrows implements \xrightarrow, among other things:
    1754         see http://www.math.union.edu/~dpvc/jsMath/authors//moreArrows.html
    1755       - AMSmath implements a number of AMS math commands:
    1756         see http://www.math.union.edu/~dpvc/jsMath/authors/AMSmath.html
    1757     */
    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 macros
    1765         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 used
    1770         # 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 plugin
    1781 
    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 hilighting 
    1792 #        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 cells
    1803         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         else
    1812                 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 head
     1609        worksheet = self.get_worksheet_with_filename(worksheet_filename)
     1610        return template("head.html", worksheet = worksheet,
     1611                        worksheet_filename = worksheet_filename,
     1612                        username = username, JSMATH = JSMATH,
     1613                        JSMATH_IMAGE_FONTS = JSMATH_IMAGE_FONTS,
     1614                        JEDITABLE_TINYMCE = JEDITABLE_TINYMCE,
     1615                        sage_jsmath_macros = sage_jsmath_macros)
    18841616
    18851617    def html_worksheet_topbar(self, worksheet, select=None, username='guest', backwards=False):
     1618        """
     1619Returns the HTML for the topbar of a worksheet
     1620
     1621DEPRECATED
     1622
     1623INPUT:
     1624-   worksheet - a Worksheet instance
     1625-   select    - a string
     1626-   username  - a string of a username
     1627-   backwards - a boolean
     1628
     1629OUTPUT:
     1630-   html - the HTML for the topbar of a worksheet
     1631        """
    18861632        body = ''
    18871633        body += """
    18881634<table width="100%%" id="topbar">
     
    19041650        worksheet = self.get_worksheet_with_filename(worksheet_filename)
    19051651        worksheet_html = worksheet.html()
    19061652
    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>'%r
    1925             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 += '&nbsp;&nbsp; <span class="usercontrol">%s it: </span>'%action
    1932                 rating += '  '.join(['<a class="usercontrol" onClick="rate_worksheet(%s)">&nbsp;%s&nbsp;</a>'%(i,i) for
    1933                                    i in range(5)])
    1934                 rating += '&nbsp;&nbsp; <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>'%rating
    1940 
    1941             body += edit_line
    1942             #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_html
    1949             body += '<hr class="usercontrol">'
    1950             body += '&nbsp;'*10
    1951            
    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 body
    1970            
    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_html
    1979 
    1980         endpanespan = '</td></tr></table></span>\n'
    1981 
    1982        
    1983         if worksheet is None:
    1984              return body + endpanespan
    1985 
    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 body
     1653        return template("worksheet_body.html", username = username,
     1654                            worksheet = worksheet, top_only = top_only,
     1655                            worksheet_filename = worksheet_filename,
     1656                            worksheet_html = worksheet_html,
     1657                            notebook = self, show_debug = self.__show_debug or show_debug)
    20001658
    20011659    def html_plain_text_window(self, worksheet, username):
    20021660        """
     
    20101668       
    20111669        -  ``username`` - name of the user
    20121670        """
    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()
     1671        plain_text = worksheet.plain_text(prompts=True, banner=False)
     1672        plain_text = escape(plain_text).strip()
    20211673         
    2022         return """
    2023         <html>
    2024         <head>%s</head>
    2025         <body>%s</body>
    2026         </html>
    2027         """%(head, body)
    2028 
     1674        return template("plain_text_window.html", worksheet = worksheet,
     1675                        worksheet_filename = worksheet.filename(),
     1676                        username = username,
     1677                        plain_text = plain_text, JSMATH = JSMATH,
     1678                        JSMATH_IMAGE_FONTS = JSMATH_IMAGE_FONTS,
     1679                        JEDITABLE_TINYMCE = JEDITABLE_TINYMCE,
     1680                        sage_jsmath_macros = sage_jsmath_macros)
     1681                       
    20291682    def html_edit_window(self, worksheet, username):
    20301683        r"""
    20311684        Return a window for editing ``worksheet``.
    20321685       
    20331686        INPUT:
    2034        
    2035        
    2036         -  ``worksheet`` - a worksheet
     1687        - ``username`` - a string containing the username
     1688        - ``worksheet`` - a Worksheet instance
    20371689        """
    2038         head, body = self.html_worksheet_page_template(worksheet, username, 'Edit plain text &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<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)
     1690        text = worksheet.edit_text()
     1691        text = escape(text)
     1692        n_lines = text.count("\n")+1
    20551693         
    2056         return """
    2057         <html>
    2058         <head>%s</head>
    2059         <body>%s</body>
    2060         </html>
    2061         """%(head, body)
     1694        return template("edit_window.html", worksheet = worksheet,
     1695                        worksheet_filename = worksheet.filename(),
     1696                        username = username, text = text,
     1697                        n_lines = n_lines, JSMATH = JSMATH,
     1698                        JSMATH_IMAGE_FONTS = JSMATH_IMAGE_FONTS,
     1699                        JEDITABLE_TINYMCE = JEDITABLE_TINYMCE,
     1700                        sage_jsmath_macros = sage_jsmath_macros)
    20621701   
    20631702    def html_beforepublish_window(self, worksheet, username):
    20641703        """
    20651704        Return the html code for a page dedicated to worksheet publishing
    20661705        prior to the publication of the given worksheet.
    20671706       
    2068         INPUT: worksheet - instance of Worksheet username - string
     1707        INPUT:
     1708        - ``worksheet`` - instance of Worksheet
     1709        - ``username`` - string
    20691710        """
    20701711        msg = """You can publish your worksheet to the Internet, where anyone will be able to access and view it online.
    20711712        Your worksheet will be assigned a unique address (URL) that you can send to your friends and colleagues.<br/><br/>
     
    20791720        """
    20801721        head, body = self.html_worksheet_page_template(worksheet, username, msg, select="publish", backwards=True)
    20811722       
    2082         return """
    2083         <html>
    2084         <head>%s</head>
    2085         <body>%s</body>
    2086         </html>
    2087         """%(head, body)
     1723        return template("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)
    20881729       
    2089     def html_afterpublish_window(self, worksheet, username, addr, dtime):
     1730    def html_afterpublish_window(self, worksheet, username, url, dtime):
    20901731        """
    20911732        Return the html code for a page dedicated to worksheet publishing
    20921733        after the publication of the given worksheet.
    20931734       
    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
    20961740        """
    20971741        from time import strftime
    20981742        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 made
    2103         """ % (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)
    21051743       
    2106         return """
    2107         <html>
    2108         <head>%s</head>
    2109         <body>%s</body>
    2110         </html>
    2111         """%(head, body)
     1744        return template("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)
    21121751
    21131752    def html_upload_data_window(self, ws, username):
    2114         head, body = self.html_worksheet_page_template(ws, username, "Upload or Create Data File")
    2115        
    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())
     1753        """
     1754        Returns the html for the "Upload Data" window
    21451755
    2146         return """
    2147         <html>
    2148         <head>%s</head>
    2149         <body>%s</body>
    2150         </html>
    2151         """%(head, body)
     1756        INPUT:
     1757        - ``worksheet`` - instance of Worksheet
     1758        - ``username`` - string
     1759        """
     1760        return template("upload_data_window.html", worksheet = worksheet,
     1761                        worksheet_filename = worksheet.filename(),
     1762                        username = username, JSMATH = JSMATH,
     1763                        JSMATH_IMAGE_FONTS = JSMATH_IMAGE_FONTS,
     1764                        JEDITABLE_TINYMCE = JEDITABLE_TINYMCE,
     1765                        sage_jsmath_macros = sage_jsmath_macros)
     1766   
    21521767
    21531768    def html(self, worksheet_filename=None, username='guest', show_debug=False, admin=False):
     1769        """
     1770        Returns the html for index page of a worksheet.
     1771
     1772        INPUT:
     1773        - ``worksheet_filename`` - a string
     1774        - ``username`` - a string
     1775        - ``show_debug`` - a boolean
     1776        - ``admin`` - a boolean
     1777        """
    21541778        if worksheet_filename is None or worksheet_filename == '':
    21551779            worksheet_filename = None
    21561780            W = None
     
    21601784            except KeyError:
    21611785                W = None
    21621786
    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)
     1787        return template("index.html", worksheet = W,
     1788                        worksheet_filename = W.filename(),
     1789                        worksheet_html = W.html(),
     1790                        notebook = self, username = username,
     1791                        show_debug = show_debug,
     1792                        JSMATH = JSMATH,
     1793                        JSMATH_IMAGE_FONTS = JSMATH_IMAGE_FONTS,
     1794                        JEDITABLE_TINYMCE = JEDITABLE_TINYMCE,
     1795                        sage_jsmath_macros = sage_jsmath_macros)
    21821796
    21831797    ####################################################################
    21841798    # Configuration html.
     
    22191833        body = '<form width=70%% method="post" action="input_settings"  enctype="multipart/form-data">' + body
    22201834        body += '</form>'
    22211835           
    2222         return """
    2223         <html>
    2224         <head>%s</head>
    2225         <body>%s</body>
    2226         </html>
    2227         """%(head, body)
     1836        return template("worksheet_settings.html", worksheet = ws,
     1837                        worksheet_filename = ws.filename(),
     1838                        username = username, JSMATH = JSMATH,
     1839                        JSMATH_IMAGE_FONTS = JSMATH_IMAGE_FONTS,
     1840                        JEDITABLE_TINYMCE = JEDITABLE_TINYMCE,
     1841                        sage_jsmath_macros = sage_jsmath_macros)
    22281842
    22291843    def html_settings(self):
    22301844        s = """
     
    22421856
    22431857    def html_doc(self, username):
    22441858        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>)
    2263 
    2264         s = """
    2265         <html>
    2266         %s
    2267         <body>
    2268         %s
    2269         </body>
    2270         </html>
    2271         """%(top, body)
    22721859       
    2273         return s
     1860        return template("doc.html", username = username,
     1861                        JSMATH = JSMATH,
     1862                        JSMATH_IMAGE_FONTS = JSMATH_IMAGE_FONTS,
     1863                        JEDITABLE_TINYMCE = JEDITABLE_TINYMCE,
     1864                        sage_jsmath_macros = sage_jsmath_macros)
    22741865       
    22751866
    22761867####################################################################
  • new file sage/server/notebook/templates/afterpublish_window.html

    diff -r faa016449245 -r 95f3679a5a9d sage/server/notebook/templates/afterpublish_window.html
    - +  
     1{% extends "worksheet_page_template.html" %}
     2<!--
     3INPUT:
     4- worksheet - an instance of Worksheet
     5- worksheet_filename - a string containing a worksheet's filename
     6- username - a string containing a username
     7- url - a string containing the url of the published page
     8- time - a string representing the time of publication
     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 checked = 'checked="true"' if worksheet.is_auto_publis() else '' %}
     16
     17{% 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) %}
     18{% set select = "publish" %}
     19{% set backwards = true %}
     20 No newline at end of file
  • sage/server/notebook/templates/banner.html

    diff -r faa016449245 -r 95f3679a5a9d sage/server/notebook/templates/banner.html
    a b  
    11<div class="banner">
    2   <table width="100%%">
     2  <table width="100%">
    33    <tr>
    44      <td>
    55        <a class="banner" href="http://www.sagemath.org">
    6         <img align="top" src="/images/sagelogo.png" alt="Sage">Notebook</a>
     6        <img align="top" src="/images/sagelogo.png" alt="Sage">&nbsp;Notebook</a>
    77      </td>
    88      <td>
    99        <span class="ping" id="ping">Searching for Sage server...</span>
  • sage/server/notebook/templates/base.html

    diff -r faa016449245 -r 95f3679a5a9d sage/server/notebook/templates/base.html
    a b  
    11<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
    22<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>
     3    <head>
     4        <title>{% block title %}{% endblock %}</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 more_css %}{% endblock %}
     8        {% block javascript %}{% endblock %}
     9    </head>
     10    <body {% block body_attrs %}{% endblock %}>
     11        {% block body %}{% endblock %}
     12    </body>
    1213</html>
  • new file sage/server/notebook/templates/beforepublish_window.html

    diff -r faa016449245 -r 95f3679a5a9d sage/server/notebook/templates/beforepublish_window.html
    - +  
     1{% extends "worksheet_page_template.html" %}
     2<!--
     3INPUT:
     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{% 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>' %}
     14{% set select = "publish" %}
     15{% set backwards = true %}
     16 No newline at end of file
  • new file sage/server/notebook/templates/command_history.html

    diff -r faa016449245 -r 95f3679a5a9d sage/server/notebook/templates/command_history.html
    - +  
     1<!--
     2    INPUT:
     3    - history_text - a string containing the history text of the notebook
     4-->
     5<html>
     6    <head>
     7        <title>Command History</title>
     8        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     9    </head>
     10    <body>
     11        <pre>{{history_text}}</pre>
     12        <a name="bottom"></a>
     13        <script type="text/javascript"> window.location="#bottom"</script>
     14    </body>
     15</html>
     16 No newline at end of file
  • new file sage/server/notebook/templates/debug_window.html

    diff -r faa016449245 -r 95f3679a5a9d sage/server/notebook/templates/debug_window.html
    - +  
     1<div class='debug_window'>
     2    <div class='debug_output'><pre id='debug_output'></pre></div>
     3    <textarea rows=5 id='debug_input' class='debug_input'
     4              onKeyPress='return debug_keypress(event);'
     5              onFocus='debug_focus();' onBlur='debug_blur();'></textarea>
     6</div>
     7 No newline at end of file
  • new file sage/server/notebook/templates/doc.html

    diff -r faa016449245 -r 95f3679a5a9d sage/server/notebook/templates/doc.html
    - +  
     1{% extends "base.html" %}
     2<!--
     3INPUT:
     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 "head.tmpl" %}
     14
     15{% block title %}
     16{{ common_title(worksheet_filename, worksheet) }}
     17{% endblock %}
     18   
     19{% block css %}
     20main
     21{% 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/download_or_delete_datafile.html

    diff -r faa016449245 -r 95f3679a5a9d sage/server/notebook/templates/download_or_delete_datafile.html
    - +  
     1{% extends "worksheet_page_template.html" %}
     2<!--
     3INPUT:
     4- worksheet - an instance of Worksheet
     5- worksheet_filename - a string containing a worksheet's filename
     6- username - a string containing a username
     7- active_worksheets - a list of the Worksheet instances that are active for username
     8- filename - the name of the file
     9- path - the path to the file
     10- file_is_image - a boolean stating whether the file is an image
     11- file_is_text - a boolean stating whether the file is a text file
     12- text_file_content - a string containing the content of a text file
     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{% set title = "Data file: %s"|format(filename) %}
     19
     20{% block body_addition %}
     21<p>You may download <a href="{{ path }}">{{ filename }}</a> or create a linked copy to the worksheet <select onchange="go_option(this);" class="worksheet">
     22<option selected>select worksheet</option>
     23{% for worksheet in active_worksheets %}
     24    <option value='link_datafile("{{ worksheet.filename() }}","{{ filename }}")'>{{ worksheet.name() }}</option>
     25{% endfor %}
     26</select> or <a href="/home/{{ worksheet.filename() }}/datafile?name={{ filename }}&action=delete">delete {{ filename }}.</a></p>
     27
     28<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>
     29
     30<hr class="usercontrol" />
     31
     32{% if file_is_image %}
     33<div align=center><img src="{{ path }}"></div>
     34{% elif file_is_text %}
     35<form method="post" action="savedatafile" enctype="multipart/form-data">
     36    <input type="submit" value="Save Changes" name="button_save" /> <input type="submit" value="Cancel" name="button_cancel" style="display:block" />
     37    <textarea class="edit" name="textfield" rows=17 cols=70 id="textfield">{{ text_file_content }}</textarea>
     38    <input type="hidden" name="filename" value="{{ filename }}" id="filename" />
     39</form>
     40{% endif %}
     41{% endblock %}
     42
     43
     44
     45
  • new file sage/server/notebook/templates/edit_window.html

    diff -r faa016449245 -r 95f3679a5a9d sage/server/notebook/templates/edit_window.html
    - +  
     1{% extends "worksheet_page_template.html" %}
     2<!--
     3INPUT:
     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 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<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/guest_top_bar_and_worksheet.html

    diff -r faa016449245 -r 95f3679a5a9d sage/server/notebook/templates/guest_top_bar_and_worksheet.html
    - +  
     1<!--
     2INPUT:
     3- original_worksheet - an instance of Worksheet
     4- worksheet - an instance of Worksheet
     5- notebook - an instance of Notebook which contains worksheet
     6- worksheet_html - a string containing the html for the worksheet
     7- username - a string containing a username
     8{% if original_worksheet.is_collaborator(username) or original_worksheet.is_owner(username) %}
     9    {% set edit_text = "Edit this." %}
     10    {% set url       = "edit_published_page" %}
     11{% elif notebook.user_is_guest(username) %}
     12    {% set edit_text = "Log in to edit a copy." %}
     13    {% set url       = "/" %}
     14{% else %}
     15    {% set edit_text = "Edit a copy." %}
     16    {% set url       = "edit_published_page" %}
     17{% endif %}
     18
     19{% set download_name = os.path.split(worksheet.name())[-1] %}
     20
     21<a class="usercontrol" href="{{ url }}">{{ edit_text }}</a>
     22&nbsp;&nbsp;<a class="usercontrol" href="download/{{ download_name }}.sws">Download.</a>
     23&nbsp;&nbsp;<span class="ratingmsg">
     24    {% if worksheet.rating() != -1 %}
     25        <a class="usercontrol" href="rating_info">
     26            This page is rated {{ "%.1f"|format("worksheet.rating()") }}.
     27        </a>
     28    {% endif %}
     29    {% if not notebook.user_is_guest(username)
     30        and not worksheet.is_publisher(username) %}
     31        &nbsp;&nbsp;
     32        <span class="usercontrol">
     33            {{ "Rerate" if worksheet.is_rater(username) else "Rate" }}
     34        </span>
     35        {% for i in range(5) %}
     36            <a class="usercontrol"
     37               onClick="rate_worksheet({{ i }})">
     38                &nbsp;{{ i }}&nbsp;
     39            </a>
     40        {% endfor %}
     41            &nbsp;&nbsp; <input name="rating_comment" id="rating_comment"></input>
     42    {% endif %}
     43</span>
     44<span class="pubmsg">
     45    <a href="/pub/">Other published documents...</a>
     46</span>
     47<hr class="usercontrol" />
     48<h1 align="center">{{ original_worksheet.name() }}</h1>
     49<h2 align="center">{{ worksheet.html_time_since_last_edited() }}</h2>
     50{{ worksheet_html }}
     51<hr class="usercontrol" />
     52{% for i in range(10) %}
     53&nbsp;
     54{% endfor %}
     55
  • new file sage/server/notebook/templates/head.html

    diff -r faa016449245 -r 95f3679a5a9d sage/server/notebook/templates/head.html
    - +  
     1<!--
     2INPUT:
     3- worksheet - an instance of Worksheet
     4- worksheet_filename - a string containing a worksheet's filename
     5- username - a string containing a user's name
     6- JSMATH - a boolean stating whether to include jsMath
     7- JSMATH_IMAGE_FONTS - a boolean stating whether to include jsMath iamage fonts
     8- JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE
     9- sage_jsmath_macros - an array containing strings of Javascript of Sage macros for jsMath
     10  -->
     11<title>
     12    {% if worksheet_filename %}
     13        {{ worksheet.name() }} (Sage)
     14    {% else %}
     15        Sage Notebook | Welcome
     16    {% endif %}
     17</title>
     18
     19<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     20<!-- Load the Sage javascript library. -->
     21<script type="text/javascript" src="/javascript_local/jquery/jquery.js"></script>
     22<script type="text/javascript" src="/javascript/main.js"></script>
     23<link rel=stylesheet href="/css/main.css" type="text/css" />
     24 
     25{% if JSMATH %}
     26    <!-- Turn off font warning. -->
     27    <style>
     28        #jsMath_Warning {display: none}
     29    </style>
     30    <script type="text/javascript">
     31        jsMath = {Controls: {cookie: {scale: 115}}}
     32    </script>
     33    {% if not JSMATH_IMAGE_FONTS %}
     34        <script type="text/javascript" src="/javascript_local/jsmath/plugins/noImageFonts.js"></script>
     35    {% endif %}
     36    <!-- Move the jsMath button 20 pixels from the right edge
     37         (apparently in some browsers, it covers up the scroll
     38         bar) -->
     39    <script type="text/javascript">
     40        jsMath.styles = {
     41            '#jsMath_button':
     42                'position:fixed; bottom:1px; right:20px; background-color:white;'
     43                    + 'border: solid 1px #959595; margin:0px; padding: 0px 3px 1px 3px; '
     44                    + 'z-index:102; color:black; text-decoration:none; font-size:x-small; '
     45                    + 'width:auto; cursor:hand;',
     46        };
     47    </script>
     48    <script type="text/javascript" src="/javascript_local/jsmath/jsMath.js"></script>
     49    <script type="text/javascript">
     50        /* The extensions here do the following:
     51            - verb implements the \verb command:
     52              see http://www.math.union.edu/~dpvc/jsMath/authors/verb.html
     53            - moreArrows implements \xrightarrow, among other things:
     54              see http://www.math.union.edu/~dpvc/jsMath/authors//moreArrows.html
     55            - AMSmath implements a number of AMS math commands:
     56              see http://www.math.union.edu/~dpvc/jsMath/authors/AMSmath.html
     57        */
     58        jsMath.Extension.Require("verb");
     59        jsMath.Extension.Require("moreArrows");
     60        jsMath.Extension.Require("AMSmath");
     61        jsMath.Extension.Require("AMSsymbols");
     62    </script>
     63{% endif %}
     64<!-- Import LaTeX macros -->
     65{% for m in sage_jsmath_macros %}
     66<script> {{ m }} </script>
     67{% endfor %}
     68
     69<!-- Load the jquery and ui-jquery javascript library.
     70     This is used for interact functionality in the notebook, and will be used
     71     to enable drag and drop, image zoom, etc. -->
     72<script type="text/javascript" src="/javascript_local/jqueryui/jquery.ui.all.min.js"></script>
     73<script type="text/javascript" src="/javascript_local/jquery/plugins/farbtastic/farbtastic.min.js"></script>
     74<script type="text/javascript" src="/javascript_local/jquery/plugins/dimensions/jquery.dimensions.min.js"></script>
     75<script type="text/javascript" src="/javascript_local/jquery/plugins/jquery.event.extendedclick.js"></script>
     76
     77<link rel="stylesheet" href="/javascript_local/jquery/plugins/farbtastic/farbtastic.css" type="text/css" /> 
     78<link rel="stylesheet" href="/javascript_local/jqueryui/themes/flora/flora.all.css" />
     79
     80<!-- TODO: get the lazy loading plugin -->
     81
     82<!-- TODO: Load individual ui plugins, not the whole package:
     83     <script type="text/javascript" src="/javascript_local/jqueryui/ui.mouse.min.js"></script>
     84     <script type="text/javascript" src="/javascript_local/jqueryui/ui.slider.min.js"></script>
     85     <script type="text/javascript" src="/javascript_local/jqueryui/ui.draggable.min.js"></script>
     86     <script type="text/javascript" src="/javascript_local/jqueryui/ui.draggable.ext.min.js"></script>
     87     <script type="text/javascript" src="/javascript_local/jqueryui/ui.resizable.min.js"></script>
     88     <script type="text/javascript" src="/javascript_local/jqueryui/ui.dialog.min.js"></script>
     89-->
     90
     91<!-- This was for syntax highlighting
     92     <script type="text/javascript" src="/javascript/highlight/prettify.js"></script>
     93     <link rel=stylesheet href="/css/highlight/prettify.css" type="text/css" />
     94-->
     95
     96<script type="text/javascript" src="/javascript/sage3d.js"></script
     97
     98<!-- Jmol - embedded 3D graphics -->
     99<script type="text/javascript" src="/java/jmol/appletweb/Jmol.js"></script>
     100<script>jmolInitialize("/java/jmol");jmolSetCallback("menuFile","/java/jmol/appletweb/SageMenu.mnu");</script> <!-- This must stay in <head> -->
     101
     102<!-- TinyMCE and jEditable - in-place editing of text cells -->
     103{% if JEDITABLE_TINYMCE %}
     104    <script type="text/javascript" src="/javascript_local/tiny_mce/tiny_mce.js"></script>
     105    <script src="/javascript_local/jquery/plugins/jquery.jeditable.mini.js" type="text/javascript" charset="utf-8"></script>
     106    <script type="text/javascript">
     107   
     108    function toggleEditor(id) {
     109            if (!tinyMCE.get(id))
     110                    tinyMCE.execCommand('mceAddControl', false, id);
     111            else
     112                    tinyMCE.execCommand('mceRemoveControl', false, id);
     113    }
     114   
     115    $.fn.tinymce = function(options){
     116       return this.each(function(){
     117          tinyMCE.execCommand("mceAddControl", true, this.id);
     118       });
     119    }
     120   
     121    function initMCE(){
     122       tinyMCE.init({mode : "none",
     123          plugins: "table,searchreplace,safari,paste,autosave",
     124          theme : "advanced",
     125          theme_advanced_toolbar_location : "top",
     126          theme_advanced_toolbar_align : "left",
     127          theme_advanced_statusbar_location : "bottom",
     128          theme_advanced_buttons1 : "\
     129    formatselect,fontselect,fontsizeselect,bold,italic,underline,strikethrough,forecolor,backcolor,|,\
     130    bullist,numlist,|,\
     131    undo,redo,search,pastetext,pasteword",
     132          theme_advanced_buttons2 : "\
     133    justifyleft,justifycenter,justifyright,justifyfull,outdent,indent,|,\
     134    charmap,|,\
     135    table,tablecontrols,|,\
     136    code,|,\
     137    link,image,unlink",
     138          theme_advanced_buttons3 : "",
     139          theme_advanced_resizing : true,
     140          setup : function(ed) {
     141          ed.onKeyDown.add(function(ed, e) {
     142              if(key_enter_shift(key_event(e))) {
     143                $(ed.formElement).submit();
     144              }
     145          })}
     146       });
     147    };
     148   
     149    initMCE();
     150   
     151   
     152    $.editable.addInputType('mce', {
     153       element : function(settings, original) {
     154          var textarea = $('<textarea id="'+$(original).attr("id")+'_mce"/>');
     155          if (settings.rows) {
     156             textarea.attr('rows', settings.rows);
     157          } else {
     158             textarea.height(settings.height);
     159          }
     160          if (settings.cols) {
     161             textarea.attr('cols', settings.cols);
     162          } else {
     163             textarea.width(settings.width);
     164          }
     165          $(this).append(textarea);
     166             return(textarea);
     167          },
     168       plugin : function(settings, original) {
     169          tinyMCE.execCommand("mceAddControl", true, $(original).attr("id")+'_mce');
     170          },
     171       submit : function(settings, original) {
     172          tinyMCE.triggerSave();
     173          tinyMCE.execCommand("mceRemoveControl", true, $(original).attr("id")+'_mce');
     174          },
     175       reset : function(settings, original) {
     176          tinyMCE.execCommand("mceRemoveControl", true, $(original).attr("id")+'_mce');
     177          original.reset();
     178       }
     179    });
     180    </script>
     181{% endif %}
     182<script type="text/javascript">user_name= "{{ username }}";</script>
     183{% if worksheet_filename %}
     184<script  type="text/javascript">
     185    worksheet_filename="{{ worksheet_filename }}";
     186    worksheet_name="{{ worksheet.name() }}";
     187    server_ping_while_alive();
     188</script>
     189{% endif %}
     190<!-- Uncomment this to force rename when the worksheet is opened (annoying!)
     191     if W and
     192        W.name() == "Untitled":
     193        <script  type="text/javascript">setTimeout("rename_worksheet()",1)</script> -->
     194
     195
     196
     197
     198
  • new file sage/server/notebook/templates/head.tmpl

    diff -r faa016449245 -r 95f3679a5a9d sage/server/notebook/templates/head.tmpl
    - +  
     1<!--
     2INPUT:
     3- worksheet - an instance of Worksheet
     4- worksheet_filename - a string containing a worksheet's filename
     5- username - a string containing a user's name
     6- JSMATH - a boolean stating whether to include jsMath
     7- JSMATH_IMAGE_FONTS - a boolean stating whether to include jsMath iamage fonts
     8- JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE
     9- sage_jsmath_macros - an array containing strings of Javascript of Sage macros for jsMath
     10  -->
     11{% macro common_title(worksheet_filename, worksheet) %}
     12    {% if worksheet_filename %}
     13        {{ worksheet.name() }} (Sage)
     14    {% else %}
     15        Sage Notebook | Welcome
     16    {% endif %}
     17{% endmacro %}
     18
     19{% macro common_css %}
     20<link rel=stylesheet href="/css/main.css" type="text/css" />
     21{% endmacro %}
     22
     23{% macro common_javascript(worksheet, worksheet_filename, username, JSMATH, JSMATH_IMAGE_FONTS, JEDITABLE_TINYMCE, sage_jsmath_macros) %}
     24<!-- Load the Sage javascript library. -->
     25<script type="text/javascript" src="/javascript_local/jquery/jquery.js"></script>
     26<script type="text/javascript" src="/javascript/main.js"></script>
     27 
     28{% if JSMATH %}
     29    <!-- Turn off font warning. -->
     30    <style>
     31        #jsMath_Warning {display: none}
     32    </style>
     33    <script type="text/javascript">
     34        jsMath = {Controls: {cookie: {scale: 115}}}
     35    </script>
     36    {% if not JSMATH_IMAGE_FONTS %}
     37        <script type="text/javascript" src="/javascript_local/jsmath/plugins/noImageFonts.js"></script>
     38    {% endif %}
     39    <!-- Move the jsMath button 20 pixels from the right edge
     40         (apparently in some browsers, it covers up the scroll
     41         bar) -->
     42    <script type="text/javascript">
     43        jsMath.styles = {
     44            '#jsMath_button':
     45                'position:fixed; bottom:1px; right:20px; background-color:white;'
     46                    + 'border: solid 1px #959595; margin:0px; padding: 0px 3px 1px 3px; '
     47                    + 'z-index:102; color:black; text-decoration:none; font-size:x-small; '
     48                    + 'width:auto; cursor:hand;',
     49        };
     50    </script>
     51    <script type="text/javascript" src="/javascript_local/jsmath/jsMath.js"></script>
     52    <script type="text/javascript">
     53        /* The extensions here do the following:
     54            - verb implements the \verb command:
     55              see http://www.math.union.edu/~dpvc/jsMath/authors/verb.html
     56            - moreArrows implements \xrightarrow, among other things:
     57              see http://www.math.union.edu/~dpvc/jsMath/authors//moreArrows.html
     58            - AMSmath implements a number of AMS math commands:
     59              see http://www.math.union.edu/~dpvc/jsMath/authors/AMSmath.html
     60        */
     61        jsMath.Extension.Require("verb");
     62        jsMath.Extension.Require("moreArrows");
     63        jsMath.Extension.Require("AMSmath");
     64        jsMath.Extension.Require("AMSsymbols");
     65    </script>
     66{% endif %}
     67<!-- Import LaTeX macros -->
     68{% for m in sage_jsmath_macros %}
     69<script> {{ m }} </script>
     70{% endfor %}
     71
     72<!-- Load the jquery and ui-jquery javascript library.
     73     This is used for interact functionality in the notebook, and will be used
     74     to enable drag and drop, image zoom, etc. -->
     75<script type="text/javascript" src="/javascript_local/jqueryui/jquery.ui.all.min.js"></script>
     76<script type="text/javascript" src="/javascript_local/jquery/plugins/farbtastic/farbtastic.min.js"></script>
     77<script type="text/javascript" src="/javascript_local/jquery/plugins/dimensions/jquery.dimensions.min.js"></script>
     78<script type="text/javascript" src="/javascript_local/jquery/plugins/jquery.event.extendedclick.js"></script>
     79
     80<link rel="stylesheet" href="/javascript_local/jquery/plugins/farbtastic/farbtastic.css" type="text/css" /> 
     81<link rel="stylesheet" href="/javascript_local/jqueryui/themes/flora/flora.all.css" />
     82
     83<!-- TODO: get the lazy loading plugin -->
     84
     85<!-- TODO: Load individual ui plugins, not the whole package:
     86     <script type="text/javascript" src="/javascript_local/jqueryui/ui.mouse.min.js"></script>
     87     <script type="text/javascript" src="/javascript_local/jqueryui/ui.slider.min.js"></script>
     88     <script type="text/javascript" src="/javascript_local/jqueryui/ui.draggable.min.js"></script>
     89     <script type="text/javascript" src="/javascript_local/jqueryui/ui.draggable.ext.min.js"></script>
     90     <script type="text/javascript" src="/javascript_local/jqueryui/ui.resizable.min.js"></script>
     91     <script type="text/javascript" src="/javascript_local/jqueryui/ui.dialog.min.js"></script>
     92-->
     93
     94<!-- This was for syntax highlighting
     95     <script type="text/javascript" src="/javascript/highlight/prettify.js"></script>
     96     <link rel=stylesheet href="/css/highlight/prettify.css" type="text/css" />
     97-->
     98
     99<script type="text/javascript" src="/javascript/sage3d.js"></script
     100
     101<!-- Jmol - embedded 3D graphics -->
     102<script type="text/javascript" src="/java/jmol/appletweb/Jmol.js"></script>
     103<script>jmolInitialize("/java/jmol");jmolSetCallback("menuFile","/java/jmol/appletweb/SageMenu.mnu");</script> <!-- This must stay in <head> -->
     104
     105<!-- TinyMCE and jEditable - in-place editing of text cells -->
     106{% if JEDITABLE_TINYMCE %}
     107    <script type="text/javascript" src="/javascript_local/tiny_mce/tiny_mce.js"></script>
     108    <script src="/javascript_local/jquery/plugins/jquery.jeditable.mini.js" type="text/javascript" charset="utf-8"></script>
     109    <script type="text/javascript">
     110   
     111    function toggleEditor(id) {
     112            if (!tinyMCE.get(id))
     113                    tinyMCE.execCommand('mceAddControl', false, id);
     114            else
     115                    tinyMCE.execCommand('mceRemoveControl', false, id);
     116    }
     117   
     118    $.fn.tinymce = function(options){
     119       return this.each(function(){
     120          tinyMCE.execCommand("mceAddControl", true, this.id);
     121       });
     122    }
     123   
     124    function initMCE(){
     125       tinyMCE.init({mode : "none",
     126          plugins: "table,searchreplace,safari,paste,autosave",
     127          theme : "advanced",
     128          theme_advanced_toolbar_location : "top",
     129          theme_advanced_toolbar_align : "left",
     130          theme_advanced_statusbar_location : "bottom",
     131          theme_advanced_buttons1 : "\
     132    formatselect,fontselect,fontsizeselect,bold,italic,underline,strikethrough,forecolor,backcolor,|,\
     133    bullist,numlist,|,\
     134    undo,redo,search,pastetext,pasteword",
     135          theme_advanced_buttons2 : "\
     136    justifyleft,justifycenter,justifyright,justifyfull,outdent,indent,|,\
     137    charmap,|,\
     138    table,tablecontrols,|,\
     139    code,|,\
     140    link,image,unlink",
     141          theme_advanced_buttons3 : "",
     142          theme_advanced_resizing : true,
     143          setup : function(ed) {
     144          ed.onKeyDown.add(function(ed, e) {
     145              if(key_enter_shift(key_event(e))) {
     146                $(ed.formElement).submit();
     147              }
     148          })}
     149       });
     150    };
     151   
     152    initMCE();
     153   
     154   
     155    $.editable.addInputType('mce', {
     156       element : function(settings, original) {
     157          var textarea = $('<textarea id="'+$(original).attr("id")+'_mce"/>');
     158          if (settings.rows) {
     159             textarea.attr('rows', settings.rows);
     160          } else {
     161             textarea.height(settings.height);
     162          }
     163          if (settings.cols) {
     164             textarea.attr('cols', settings.cols);
     165          } else {
     166             textarea.width(settings.width);
     167          }
     168          $(this).append(textarea);
     169             return(textarea);
     170          },
     171       plugin : function(settings, original) {
     172          tinyMCE.execCommand("mceAddControl", true, $(original).attr("id")+'_mce');
     173          },
     174       submit : function(settings, original) {
     175          tinyMCE.triggerSave();
     176          tinyMCE.execCommand("mceRemoveControl", true, $(original).attr("id")+'_mce');
     177          },
     178       reset : function(settings, original) {
     179          tinyMCE.execCommand("mceRemoveControl", true, $(original).attr("id")+'_mce');
     180          original.reset();
     181       }
     182    });
     183    </script>
     184{% endif %}
     185<script type="text/javascript">user_name= "{{ username }}";</script>
     186{% if worksheet_filename %}
     187<script  type="text/javascript">
     188    worksheet_filename="{{ worksheet_filename }}";
     189    worksheet_name="{{ worksheet.name() }}";
     190    server_ping_while_alive();
     191</script>
     192{% endif %}
     193<!-- Uncomment this to force rename when the worksheet is opened (annoying!)
     194     if W and
     195        W.name() == "Untitled":
     196        <script  type="text/javascript">setTimeout("rename_worksheet()",1)</script> -->
     197{% endmacro %}
     198 No newline at end of file
  • new file sage/server/notebook/templates/index.html

    diff -r faa016449245 -r 95f3679a5a9d sage/server/notebook/templates/index.html
    - +  
     1{% extends "base.html" %}
     2<!--
     3INPUT:
     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 "head.tmpl" %}
     25
     26{% block title %}
     27{{ common_title(worksheet_filename, worksheet) }}
     28{% endblock %}
     29   
     30{% block css %}
     31main
     32{% 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_attrs %}
     39class="worksheet-online" onLoad="initialize_the_notebook();"
     40{% endblock %}
     41
     42{% block body %}
     43{% if worksheet.is_published() or notebook.user_is_guest(username) %}
     44    {% set original_worksheet = worksheet.worksheet_that_was_published() %}
     45    {% include "guest_top_bar_and_worksheet.html" %}
     46{% else %}
     47    {% include "top_bar_and_worksheet.html" %}
     48{% endif %}
     49{% if not worksheet %}
     50    </td></tr></table></span>
     51{% endif %}
     52{% if worksheet.user_is_only_viewer(username) %}
     53    <script type="text/javascript">worksheet_locked=true;</script>
     54{% else %}
     55    <script type="text/javascript">worksheet_locked=false;</script>
     56{% endif %}
     57   
     58{% if worksheet.computing() %}
     59    <!-- Set the update checking back in motion. -->
     60    <script type="text/javascript">
     61        active_cell_list = {{ worksheet.queue_id_list() }};
     62        for(var i = 0; i < active_cell_list.length; i++) {
     63            cell_set_running(active_cell_list[i]);
     64        }
     65        start_update_check();
     66    </script>
     67{% endif %}
     68{% endblock %}
     69 No newline at end of file
  • new file sage/server/notebook/templates/plain_text_window.html

    diff -r faa016449245 -r 95f3679a5a9d sage/server/notebook/templates/plain_text_window.html
    - +  
     1{% extends "worksheet_page_template.html" %}
     2<!--
     3INPUT:
     4- worksheet - an instance of Worksheet
     5- worksheet_filename - a string containing a worksheet's filename
     6- username - a string containing a username
     7- plain_text - a string containing the plain text version
     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 = "View plain text" %}
     15{% set select = "text" %}
     16
     17{% block body_addition %}
     18<pre class="plaintext" id="cell_intext" name="textfield">plain_text</pre>
     19{% endblock %}
  • new file sage/server/notebook/templates/plain_text_worksheet.html

    diff -r faa016449245 -r 95f3679a5a9d sage/server/notebook/templates/plain_text_worksheet.html
    - +  
     1<!-- INPUT:
     2     - worksheet_name - a string containing a worksheet's name
     3     - worksheet_plain_text - a string containing the plain text version of a worksheet
     4-->
     5<head>
     6    <title>Sage Worksheet: {{ worksheet_name }}</title>
     7    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     8</head>
     9<body>
     10    <h1><a href=".">Sage Worksheet: %s</a></h1>
     11    <pre>{{ worksheet_plain_text }}</pre>
     12</body>
     13 No newline at end of file
  • new file sage/server/notebook/templates/slide_controls.html

    diff -r faa016449245 -r 95f3679a5a9d sage/server/notebook/templates/slide_controls.html
    - +  
     1<div class="hidden" id="slide_controls">
     2    <div class="slideshow_control">
     3        <a class="slide_arrow" onClick="slide_next()">&gt;</a>
     4        <a class="slide_arrow" onClick="slide_last()">&gt;&gt;</a> <span class="vbar"></span>
     5        <a class="cell_mode" onClick="cell_mode()">Exit</a>
     6    </div>
     7    <div class="slideshow_progress" id="slideshow_progress" onClick="slide_next()">
     8        <div class="slideshow_progress_bar" id="slideshow_progress_bar">&nbsp;</div>
     9        <div class="slideshow_progress_text" id="slideshow_progress_text">&nbsp;</div>
     10    </div>
     11    <div class="slideshow_control">
     12        <a class="slide_arrow" onClick="slide_first()">&lt;&lt;</a>
     13        <a class="slide_arrow" onClick="slide_prev()">&lt;</a>
     14    </div>
     15</div>
     16
     17
     18
     19
     20
     21
     22
  • new file sage/server/notebook/templates/specific_revision.html

    diff -r faa016449245 -r 95f3679a5a9d sage/server/notebook/templates/specific_revision.html
    - +  
     1{% extends "worksheet_page_template.html" %}
     2<!--
     3INPUT:
     4- worksheet - an instance of Worksheet
     5- worksheet_filename - a string containing a worksheet's filename
     6- username - a string containing a username
     7- rev - this revision's key
     8- prev_rev - the previous revision's key
     9- next_rev - the next revision's key
     10- time_ago - a string containing the time since revision
     11- body_worksheet_html - the body html of the worksheet
     12- JSMATH - a boolean stating whether to include jsMath
     13- JSMATH_IMAGE_FONTS - a boolean stating whether to include jsMath iamage fonts
     14- JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE
     15- sage_jsmath_macros - an array containing strings of Javascript of Sage macros for jsMath
     16-->
     17
     18{% set select = "revisions" %}
     19{% set title = "Revision from %s ago&nbsp;&nbsp;&nbsp;&nbsp;<a href='revisions'>Revision List</a>"|format(time_ago) %}
     20   
     21{% macro actions %}
     22{% if prev_rev %}
     23    <a class="listcontrol" href="revisions?rev={{ prev_rev }}">Older</a>&nbsp;&nbsp;
     24{% else %}
     25    Oldest
     26{% endif %}
     27
     28{% if next_rev %}
     29    <a class="listcontrol" href="revisions?rev={{ next_rev }}">Newer</a>&nbsp;&nbsp;
     30{% else %}
     31    Newest
     32{% endif %}
     33
     34<a class="listcontrol" href="revisions?rev={{ rev }}&action=revert">Revert to this one</a> <span class="lastedit">(note that images are not recorded)</span>&nbsp;&nbsp;
     35<a class="listcontrol" href="revisions?rev={{ rev }}&action=publish">Publish this one</a>&nbsp;&nbsp;
     36{% endmacro %}
     37
     38{% block body_addition %}
     39{{ actions() }}
     40<hr class="usercontrol" />       
     41<table width="100%%">
     42{{ body_worksheet_html }}
     43<hr class="usercontrol" />
     44{{ actions() }}
     45{% endblock %}
  • new file sage/server/notebook/templates/top_bar_and_worksheet.html

    diff -r faa016449245 -r 95f3679a5a9d sage/server/notebook/templates/top_bar_and_worksheet.html
    - +  
     1<!--
     2INPUT:
     3- username - a string containing a username
     4- worksheet_filename - a string containing a worksheet's filename
     5- worksheet_html - a string containing the html for a worksheet
     6- show_debug - a boolean stating whether to show debug information
     7  -->
     8{% include "user_controls.tmpl" %}
     9{% include "worksheet_topbar.tmpl" %}
     10{% set entries = [("$('#topbar').toggle()", 'Toggle', 'Toggle the top bar'),
     11                       ('/', 'Home', 'Back to your personal worksheet list'),
     12                       ('/pub', 'Published', 'Browse the published worksheets'),
     13                       ('history_window()', 'Log', 'View a log of recent computations'),
     14                       ('/settings', 'Settings', 'Account Settings'),
     15                       ('bugreport()', 'Report a Problem', 'Report a problem or submit a bug to improve Sage'),
     16                       ('help()', 'Help', 'Documentation'),
     17                       ('/logout', 'Sign out', 'Log out of the Sage notebook')] %}
     18<table width="100%">
     19    <tr>
     20        <td>{% include "banner.html" %}</td>
     21        <td align="right">{{ user_controls(username, entries) }}</td>
     22    </tr>
     23</table>
     24{% if worksheet_filename %}
     25{{ worksheet_topbar(worksheet, "use", username) }}
     26{% endif %}
     27{% if show_debug %}
     28{% include "debug_window.html" %}
     29{% endif %}
     30
     31<div class="worksheet" id="worksheet">
     32    {{ worksheet_html }}
     33</div>
     34 No newline at end of file
  • new file sage/server/notebook/templates/upload_data_window.html

    diff -r faa016449245 -r 95f3679a5a9d sage/server/notebook/templates/upload_data_window.html
    - +  
     1{% extends "worksheet_page_template.html" %}
     2<!--
     3INPUT:
     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{% set title = 'Upload or Create Data File' %}
     14
     15{% block body_addition %}
     16<div class="upload_worksheet_menu" id="upload_worksheet_menu">
     17    <h1><font size=+1>Upload or create data file attached to the worksheet '%s'</font></h1>
     18    <hr />
     19    <form method="POST" action="do_upload_data"
     20          name="upload" enctype="multipart/form-data">
     21        <table>
     22            <tr>
     23                <td>
     24                    Browse your computer to select a file to upload:<br />
     25                    <input class="upload_worksheet_menu" size="50" type="file" name="fileField" value="" id="upload_filename"></input><br /><br />
     26                    Or enter the url of a file on the web:<br />
     27                   
     28                    <input class="upload_worksheet_menu" size="50" type="text" name="urlField" value="" id="upload_url"></input><br />
     29                    <br /><br />
     30                    Or enter the name of a new file, which will be created:<br />
     31                    <input class="upload_worksheet_menu" size="50" type="text" name="newField" value="" id="upload_filename"></input><br /><br />
     32                   
     33                    What do you want to call it? (if different than the original name)<br />
     34                    <input class="upload_worksheet_menu" size="50" type="text" name="nameField" value="" id="upload_name"></input><br />
     35                </td>
     36            </tr>
     37            <tr>
     38                <td><br /><input type="button" class="upload_worksheet_menu" value="Upload File" onClick="form.submit();" /></td>
     39            </tr>
     40        </table>
     41    </form>
     42    <br />
     43</div>
     44{% endblock %}
     45       
     46 No newline at end of file
  • new file sage/server/notebook/templates/user_controls.tmpl

    diff -r faa016449245 -r 95f3679a5a9d sage/server/notebook/templates/user_controls.tmpl
    - +  
     1{% macro user_controls(user, entries) %}
     2    <span class="username">{{ user }}</span>
     3    {% for href, name, title in entries %}
     4        {% if '(' in href %}
     5            {% set action = 'onClick="' ~ href ~ '"' %}
     6        {% else %}
     7            {% set action = 'href="' ~ href ~ '"' %}
     8        {% endif %}
     9        <span class="vbar"></span>
     10        <a title="{{ title }}" class="usercontrol" {{ action }}>{{ name }}</a>
     11    {% endfor %}
     12{% endmacro %}
  • new file sage/server/notebook/templates/worksheet.html

    diff -r faa016449245 -r 95f3679a5a9d sage/server/notebook/templates/worksheet.html
    - +  
     1<!-- INPUT:
     2     - worksheet_name - a string containing a worksheet's name
     3     - worksheet_html - a string containing the html for a worksheet
     4  -->
     5{% extends "base.html" %}
     6
     7{% block title %}Sage Worksheet: {{ worksheet_name }}{% endblock %}
     8
     9{% block javascript %}
     10<script type="text/javascript" src="/javascript_local/jquery/jquery.js"></script>
     11<script type="text/javascript" src="/javascript/main.js"></script>
     12{% if do_print %}
     13    <script type="text/javascript" src="/javascript_local/jsmath/jsMath.js"></script>
     14{% endif %}   
     15{% endblock %}
     16
     17{% block body_attrs %}
     18{% if not do_print %}
     19    class="worksheet-online" onLoad="initialize_the_notebook();"
     20{% endif %}
     21{% endblock %}
     22
     23{% block body %}
     24{% if do_print %}
     25    <div class="worksheet_print_title"> {{ worksheet_name }}</div>
     26{% endif %}
     27{{ worksheet_html }}
     28{% if do_print %}
     29    <script type="text/javascript">jsMath.Process();</script>
     30{% endif %}
     31{% endblock %}
     32 No newline at end of file
  • new file sage/server/notebook/templates/worksheet_body.html

    diff -r faa016449245 -r 95f3679a5a9d sage/server/notebook/templates/worksheet_body.html
    - +  
     1<!--
     2INPUT:
     3- worksheet - an instance of Worksheet
     4- notebook - an instance of Notebook which contains worksheet
     5- worksheet_filename - a string containing a worksheet's filename
     6- worksheet_html - a string containing the html for the worksheet
     7- username - a string containing a username
     8- show_debug - a boolean stating whether to show debug information
     9- top_only - a boolean stating whether to output the top bar only
     10  -->
     11{% if worksheet.is_published() or notebook.user_is_guest(username) %}
     12    {% set original_worksheet = worksheet.worksheet_that_was_published() %}
     13    {% include "guest_top_bar_and_worksheet.html" %}
     14{% else %}
     15    {% include "top_bar_and_worksheet.html" %}
     16{% endif %}
     17{% if not top_only %} 
     18{% if not worksheet %}
     19    </td></tr></table></span>
     20{% endif %}
     21{% if worksheet.user_is_only_viewer(username) %}
     22    <script type="text/javascript">worksheet_locked=true;</script>
     23{% else %}
     24    <script type="text/javascript">worksheet_locked=false;</script>
     25{% endif %}
     26   
     27{% if worksheet.computing() %}
     28    <!-- Set the update checking back in motion. -->
     29    <script type="text/javascript">
     30        active_cell_list = {{ worksheet.queue_id_list() }};
     31        for(var i = 0; i < active_cell_list.length; i++) {
     32            cell_set_running(active_cell_list[i]);
     33        }
     34        start_update_check();
     35    </script>
     36{% endif %}
     37{% endif %}
     38 No newline at end of file
  • new file sage/server/notebook/templates/worksheet_page_template.html

    diff -r faa016449245 -r 95f3679a5a9d sage/server/notebook/templates/worksheet_page_template.html
    - +  
     1{% extends "base.html" %}
     2<!--
     3INPUT:
     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 "head.tmpl" %}
     25{% include "worksheet_top.tmpl" %}
     26{% include "worksheet_topbar.tmpl" %}
     27
     28{% block title %}
     29{{ common_title(worksheet_filename, worksheet) }}
     30{% endblock %}
     31   
     32{% block css %}
     33main
     34{% endblock %}
     35
     36{% block javascript %}
     37{{ common_javascript(worksheet, worksheet_filename, username, JSMATH, JSMATH_IMAGE_FONTS, JEDITABLE_TINYMCE, sage_jsmath_macros) }}
     38{% endblock %}
     39
     40{% block body %}
     41{{ worksheet_top(username) }}
     42{{ worksheet_topbar(worksheet, select, username, backwards) }}
     43<hr class="usercontrol" />
     44{% block before_sharebar %}{% endblock %}
     45<span class="sharebar">{{ title }}</span>
     46<br /><br /><br />
     47{% block body_addition %}{% endblock %}
     48{% endblock %}
     49
  • new file sage/server/notebook/templates/worksheet_revision_list.html

    diff -r faa016449245 -r 95f3679a5a9d sage/server/notebook/templates/worksheet_revision_list.html
    - +  
     1{% extends "worksheet_page_template.html" %}
     2<!--
     3INPUT:
     4- data - a list of pairs of the form ('how long ago', key)
     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
     15{% set title  = "Revision History" %}
     16{% set select = "revisions" %}
     17
     18{% block body_addition %}
     19<hr class="usercontrol">
     20<table width="100%%">
     21    <tr>
     22        <td width="1%%"></td>
     23        <td width="20%%"><b>Revision</b></td>
     24        <td width="20%%"><b>Last Edited</b></td>
     25        <td width="30%%"></td>
     26    </tr>
     27{% for desc, key in data|reverse %}
     28    <tr>
     29        <td></td>
     30        <td><a href="revisions?rev={{ key }}">Revision {{ loop.revindex0 }}</a></td>
     31        <td><span class="revs">{{ desc }}</span></td>
     32    </tr>
     33{% endfor %}
     34</table>
     35{% endblock %}
     36 No newline at end of file
  • new file sage/server/notebook/templates/worksheet_settings.html

    diff -r faa016449245 -r 95f3679a5a9d sage/server/notebook/templates/worksheet_settings.html
    - +  
     1{% extends "worksheet_page_template.html" %}
     2<!--
     3INPUT:
     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{% set title = 'Worksheet Settings &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button name="button_save">Save Settings</button>  <input type="submit" value="Cancel" name="button_cancel"/>' %}
     14
     15{% block before_sharebar %}
     16<form width=70%% method="post" action="input_settings"  enctype="multipart/form-data">
     17{% endblock %}
     18{% block body_addition %}
     19</form>
     20{% endblock %}
     21
     22
     23
  • new file sage/server/notebook/templates/worksheet_share.html

    diff -r faa016449245 -r 95f3679a5a9d sage/server/notebook/templates/worksheet_share.html
    - +  
     1{% extends "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    - other_users - a list of strings containing other users names
     8    - user_is_admin - a boolean stating whether the user is an admin
     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 = "Share this document" %}
     16{% set select = "share" %}
     17
     18{% block body_addition %}
     19{% if not (user_is_admin or username == worksheet.owner()) %}
     20    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>.
     21{% else %}
     22<p>This Sage Worksheet is currently shared with the people listed in the box below.</p>
     23<p style="margin-bottom:1em">You may add or remove collaborators (separate user names by commas).</p>
     24
     25<form width=70% method="post" action="invite_collab" style="margin-bottom:1em">
     26    <textarea name="collaborators" rows=5 cols=70 class="edit" id="collaborators" style="display:block; margin-bottom:1em;">{{ worksheet.collaborators()|join(', ') }}</textarea>
     27    <input type="submit" title="Give access to your worksheet to the above collaborators" value="Invite Collaborators" />
     28</form>
     29
     30<hr class="usercontrol" />
     31<span class="username">Sage Users:</span>
     32<span class="users">
     33    {{ other_users|join(', ') }}
     34</span>
     35{% endif %}
     36{% endblock %}
  • new file sage/server/notebook/templates/worksheet_top.tmpl

    diff -r faa016449245 -r 95f3679a5a9d sage/server/notebook/templates/worksheet_top.tmpl
    - +  
     1<!--
     2INPUT:
     3- username - a string containing a username
     4-->
     5
     6{% macro worksheet_top(username) %}
     7{% include "user_controls.tmpl" %}
     8{% include "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/worksheet_topbar.tmpl

    diff -r faa016449245 -r 95f3679a5a9d sage/server/notebook/templates/worksheet_topbar.tmpl
    - +  
     1<!--
     2INPUT:
     3- worksheet - an instance of Worksheet
     4- select    - a string containing the control that is selected
     5- username  - a string containing a username
     6- backwards - a boolean
     7  -->
     8{% macro worksheet_topbar(worksheet, select=None, username='guest', backwards=false) %}
     9    <table width="100%%" id="topbar">
     10        <tr>
     11            <td align="left"> {{ worksheet.html_title(username) }} </td>
     12            <td align="right"> {{ worksheet.html_save_discard_buttons() }} </td>
     13        </tr>
     14        <tr>
     15            <td align="left"> {{ worksheet.html_menu() }} </td>
     16            <td align="right"> {{ worksheet.html_share_publish_buttons(select, backwards) }}</td>
     17        </tr>
     18    </table>
     19{% endmacro %}