Ticket #7786: trac_7786-template-jinja-idiomatic.2,patch

File trac_7786-template-jinja-idiomatic.2,patch, 211.6 KB (added by timdumol, 11 years ago)

Rebased on #7650 and its dependencies. Apply this patch alone to sagenb repo.

Line 
1diff -r 8afee2ec056a sagenb/data/sage/css/account_settings.css
2--- a/sagenb/data/sage/css/account_settings.css Sat Oct 24 18:17:19 2009 +0800
3+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
4@@ -1,39 +0,0 @@
5-html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td { margin: 0; padding: 0; border: 0; outline: 0; font-weight: inherit; font-style: inherit; font-size: 100%; font-family: inherit; vertical-align: baseline; }
6-
7-*:focus { outline: 0; }
8-
9-body { line-height: 1em; color: black; background: #fff; }
10-
11-ol, ul { list-style: none; }
12-
13-/* tables still need 'cellspacing="0"' in the markup */
14-table { border-collapse: separate; border-spacing: 0; vertical-align: middle; }
15-
16-caption, th, td { text-align: left; font-weight: normal; vertical-align: middle; }
17-
18-q, blockquote { quotes: "" ""; }
19-q:before, q:after, blockquote:before, blockquote:after { content: ""; }
20-
21-img a { border: none; }
22-
23-html { font-size: 100.1%; }
24-
25-body { font: 100%/1.4 Arial, Helvetica, sans-serif; }
26-
27-h1 { background: #DCDCDC; border-bottom: 1px solid #CCC; font-size: 2em; padding: 0 5px; }
28-
29-label { display: block; }
30-
31-#buttons { background: #DCDCDC; padding: 5px; }
32-#buttons button { margin-right: 1em; }
33-
34-h2 { font-size: 1.5em; }
35-
36-.section { border-bottom: 1px solid #CCC; padding: 5px; }
37-.section div { margin-bottom: 0.5em; }
38-
39-.error { color: red; }
40-
41-.updated { color: green; }
42-
43-input.c1 { width: 200px; }
44diff -r 8afee2ec056a sagenb/data/sage/css/main.css
45--- a/sagenb/data/sage/css/main.css     Sat Oct 24 18:17:19 2009 +0800
46+++ b/sagenb/data/sage/css/main.css     Sun Jan 03 03:07:50 2010 +0800
47@@ -1,6 +1,6 @@
48 thead { font-weight: bold; }
49 
50-body { background-color: white; }
51+body { background-color: white; font-family: "Gill Sans", "Gill Sans MT", "Myriad Pro", Myriad, "Liberation Sans", "Nimbus Sans L", Tahoma, Geneva, "Helvetica Neue", Helvetica, Arial, sans-serif; }
52 body.worksheet-online { margin-bottom: 80%; }
53 
54 .hidden { display: none; }
55@@ -16,13 +16,13 @@
56 body div#banner #ping { float: left; }
57 body div#banner div.version { float: left; clear: left; font-size: xx-small; text-indent: 13px; color: black; }
58 
59-#controls { float: right; width: 65%; }
60-#controls ul { list-style: none; margin: 0; padding: 0; text-align: right; }
61-#controls ul li { border-right: 1px solid #000; color: #112abb; display: inline; font-size: 14px; margin: 0; padding: 0 0.5em; }
62-#controls ul li:last-child { border-right: 0; }
63-#controls ul li.username { border: 0; color: #000; font-family: sans-serif; font-weight: bold; padding: 0; }
64-#controls ul a { text-decoration: underline; white-space: nowrap; }
65-#controls ul a:hover { cursor: pointer; }
66+#main-controls { float: right; width: 65%; }
67+#main-controls ul { list-style: none; margin: 0; padding: 0; text-align: right; }
68+#main-controls ul li { border-right: 1px solid #000; color: #112abb; display: inline; font-size: 14px; margin: 0; padding: 0 0.5em; }
69+#main-controls ul li:last-child { border-right: 0; }
70+#main-controls ul li.username { border: 0; color: #000; font-family: sans-serif; font-weight: bold; padding: 0; }
71+#main-controls ul a { text-decoration: underline; white-space: nowrap; }
72+#main-controls ul a:hover { cursor: pointer; }
73 
74 #top-bar { position: relative; padding: 10px 5px; border-bottom: 1px solid #c9d7f1; min-height: 40px; margin-bottom: 0.5em; overflow: hidden; display: inline-block; }
75 #top-bar { display: block; }
76@@ -31,8 +31,8 @@
77 
78 hr.usercontrol { clear: both; float: left; }
79 
80-div#usercontrols { overflow: hidden; display: inline-block; clear: both; border-bottom: 1px solid #c9d7f1; padding: 10px; }
81-div#usercontrols { display: block; }
82+div#user-controls { overflow: hidden; display: inline-block; clear: both; border-bottom: 1px solid #c9d7f1; padding: 10px; }
83+div#user-controls { display: block; }
84 div#worksheet-list-controls { padding: 10px; clear: both; overflow: hidden; display: inline-block; }
85 div#worksheet-list-controls { display: block; }
86 div#worksheet-list-controls div.action-buttons { float: left; }
87@@ -172,8 +172,6 @@
88 a.new_worksheet { font-family: arial, monospace; font-size: 12pt; text-align: right; color: #0000aa; }
89 a.new_worksheet:hover { cursor: pointer; }
90 
91-div.worksheet_bottom_padding { height: 50%; }
92-div.worksheet_top_padding { height: 5%; }
93 div.worksheet_menu { top: 50px; }
94 
95 a.worksheet_title { text-decoration: none; font-size: 20px; font-family: arial; font-weight: bold; color: #000000; }
96@@ -212,7 +210,7 @@
97 span.control:hover a.cs, span.control a:hover.cs { color: black; border: 1px solid #333333; }
98 
99 /* *********** WORKSHEET ************************* */
100-div.worksheet { background-color: white; border: 1px solid #aaa; }
101+div.worksheet { background-color: white; border: 1px solid #aaa; padding: .75em 0.2em; }
102 div.banner { background-color: white; font-family: sans-serif; font-size: 18px; text-decoration: none; color: #1950c8; }
103 div.banner a.banner { text-decoration: none; border: none; margin-top: 2px; }
104 
105@@ -248,7 +246,7 @@
106 textarea.cell_input_active { background-color: white; border: 2px solid  #8888fe; font-family: monospace; font-size: 12pt; overflow: hidden; padding-bottom: 0px; padding-left: 5px; padding-right: 0px; padding-top: 3px; margin-top: 0px; margin-bottom: 0px; line-height: 1.2em; width: 97%; }
107 
108 div.cell_input_active { background-color: white; border: 2px solid  #8888fe; font-family: monospace; font-size: 12pt; padding-bottom: 0px; padding-left: 5px; padding-right: 0px; padding-top: 3px; margin-top: 0px; margin-bottom: 0px; line-height: 1.2em; width: 97%; z-index: -100; visibility: hidden; position: absolute; }
109-div.cell_input_print { background-color: white; border: 1px solid  #a8a8a8; font-family: monospace; font-size: 12pt; padding-bottom: 1px; padding-left: 6px; padding-right: 1px; padding-top: 4px; margin-top: 0px; margin-bottom: 0px; line-height: 1.2em; width: 97%; }
110+div.cell_input_print { background-color: white; border: 1px solid  #a8a8a8; font-family: monospace; font-size: 12pt; padding-bottom: 1px; padding-left: 6px; padding-right: 1px; padding-top: 4px; margin-top: 0px; margin-bottom: 0px; line-height: 1.2em; width: 97%; whitespace: pre-wrap; }
111 
112 textarea.cell_input:hover { cursor: text; }
113 
114@@ -304,25 +302,29 @@
115 .thin-right { position: absolute; top: auto; right: 0; width: 70%; }
116 
117 /* *********** User Home (Worksheet listing) ************************* */
118-span.ratingmsg { color: #112abb; padding: 0.3em; font-size: 14px; }
119-span.pubmsg { font-family: sans-serif; color: #112abb; padding: 0.3em; font-size: 12px; }
120+.ratingmsg { color: #112abb; padding: 0.3em; font-size: 14px; }
121+
122+.pubmsg { font-family: sans-serif; color: #112abb; padding: 0.3em; font-size: 12px; }
123 
124 #worksheet-list { clear: both; width: 100%; }
125 #worksheet-list thead { background-color: #e8eef7; }
126 #worksheet-list td.checkbox { padding: 4px; }
127 
128-a.usercontrol { color: #112abb; padding: 0.3em; font-size: 14px; text-decoration: underline; }
129-a.usercontrol:hover { cursor: pointer; }
130+.controls a, .usercontrol { color: #112abb; font-size: 14px; text-decoration: underline; }
131+.controls a:hover, .usercontrol:hover { cursor: pointer; }
132 
133-span.usercontrol { color: #112abb; padding: 0.3em; font-size: 14px; }
134+.controls span { color: #112abb; padding: 0.3em; font-size: 14px; }
135 
136-a.boldusercontrol { color: #112abb; padding: 0.5em; font-weight: bold; font-size: 14px; }
137+.user-controls a, .boldusercontrol { color: #112abb; font-weight: bold; font-size: 14px; }
138+
139+.user-controls a, .controls a, .controls span { padding: 0.3em; }
140+
141 a.control, a.control-select { background-color: #7799bb; font-family: sans-serif; color: #ffffff; padding-top: 0.25em; padding-bottom: 0.25em; padding-left: 0.5em; padding-right: 0.5em; font-size: 15px; font-weight: bold; text-decoration: none; }
142 a.control:hover { cursor: pointer; }
143 a.control-select { background-color: #4477aa; }
144 a.control-select:hover { cursor: pointer; }
145 
146-span.sharebar { background-color: #4477aa; font-family: sans-serif; color: #ffffff; position: absolute; left: 0.5em; right: 0ex; padding-top: 0.5em; padding-bottom: 0.5em; padding-left: 2em; font-size: 18px; font-weight: bold; }
147+.sharebar { background-color: #4477aa; font-family: sans-serif; color: #ffffff; padding-top: 0.5em; padding-bottom: 0.5em; padding-left: 2em; font-size: 1.25em; font-weight: bold; }
148 
149 textarea.edit { font-family: courier, monospace; font-size: 10pt; border: 1px solid #8cacbb; color: black; background-color: white; padding: 3px; overflow: auto; margin-top: 0.5em; }
150 
151@@ -347,9 +349,11 @@
152 
153 div.ultrathinspace { border: 0; height: 0px; }
154 
155-span.lastedit { font-family: sans-serif; font-size: 10px; color: #717171; }
156-span.revs { font-family: sans-serif; font-size: 12px; font-weight: bold; color: #333333; }
157-span.users { font-family: sans-serif; font-size: 13px; color: #222222; }
158+.lastedit { font-family: sans-serif; font-size: 10px; color: #717171; }
159+
160+.revs { font-family: sans-serif; font-size: 12px; font-weight: bold; color: #333333; }
161+
162+.users { font-family: sans-serif; font-size: 13px; color: #222222; }
163 
164 a.share { font-family: sans-serif; font-size: 10px; color: #7777cc; }
165 
166@@ -368,9 +372,76 @@
167 div.docidx { text-align: center; font-family: sans-serif; font-size: 16px; color: #222; font-weight: bold; }
168 
169 span.ping { display: none; }
170-span.pingdown { font-family: sans-serif; font-size: 15px; font-weight: bold; color: white; background-color: #990000; }
171+span.pingdown { font-family: sans-serif; font-size: 15px; font-weight: bold; color: white; background-color: #990000; margin-left: 1em; }
172 
173-/* These have been scraped directly from pygment. */
174+#print-page h1 { text-align: center; }
175+
176+#guest-worksheet-page h1, #guest-worksheet-page h2 { text-align: center; }
177+#guest-worksheet-page ul.controls { margin: 0; padding: 0; border: 0; outline: 0; overflow: hidden; display: inline-block; }
178+#guest-worksheet-page ul.controls { display: block; }
179+#guest-worksheet-page ul.controls li { list-style-type: none; margin-left: 0px; white-space: nowrap; display: inline; float: left; padding-left: 0.5em; padding-right: 0.5em; }
180+#guest-worksheet-page ul.controls li.first { padding-left: 0px; }
181+#guest-worksheet-page ul.controls li.last { padding-right: 0px; }
182+
183+#before-publish-page form a { text-decoration: none; }
184+#before-publish-page form button { margin-left: 1em; margin-bottom: 0.5em; }
185+#before-publish-page form input { margin-left: 1em; }
186+
187+#after-publish-page input { margin-top: 1em; }
188+
189+#edit-page .sharebar span { margin-right: 2em; }
190+
191+.settings-page { line-height: 1.4; }
192+.settings-page h1 { font-size: 2em; padding: 0 5px; }
193+.settings-page label { display: block; }
194+.settings-page #buttons { padding: 5px; }
195+.settings-page #buttons button { margin-right: 1em; }
196+.settings-page #buttons a { text-decoration: none; }
197+.settings-page h2 { font-size: 1.5em; margin: 0 0 0.75em; }
198+.settings-page .section { border-bottom: 1px solid #CCC; padding: 5px; margin: 0.5em 0; }
199+.settings-page .section div { margin-bottom: 0.5em; }
200+.settings-page .error, .settings-page .error_found { color: red; }
201+.settings-page .error_found { font-size: 1.2em; }
202+.settings-page .updated { color: green; }
203+.settings-page input.c1 { width: 200px; }
204+
205+#settings-nav { margin: 0; padding: 0; border: 0; outline: 0; overflow: hidden; display: inline-block; }
206+#settings-nav { display: block; }
207+#settings-nav li { list-style-type: none; margin-left: 0px; white-space: nowrap; display: inline; float: left; padding-left: 0.5em; padding-right: 0.5em; }
208+#settings-nav li.first { padding-left: 0px; }
209+#settings-nav li.last { padding-right: 0px; }
210+#settings-nav li { border-right: 1px solid #ccc; }
211+#settings-nav li:last-child, #settings-nav li.last { border-right: none; }
212+
213+#user-management-page table { border-collapse: collapse; }
214+#user-management-page th, #user-management-page td { border: 1px solid #696969; padding: 0.25em; }
215+#user-management-page th { background: #CCC; }
216+#user-management-page a:link, #user-management-page a:visited { color: #112abb; }
217+
218+.accounts-page #wrapper { margin: 0 auto; max-width: 600px; }
219+.accounts-page h1, .accounts-page h2, .accounts-page h3, .accounts-page h4, .accounts-page h5 { font-weight: normal; }
220+.accounts-page h1 { border-bottom: 1px solid #696969; font-size: 2em; padding: 10px 0; }
221+.accounts-page h2 { font-weight: bold; }
222+.accounts-page h1, .accounts-page h2, .accounts-page p, .accounts-page li { margin-bottom: 10px; }
223+.accounts-page .entry { margin-bottom: 10px; border: 1px solid #999; padding: 3px; width: 200; }
224+.accounts-page li { border-bottom: 1px solid #CCC; }
225+.accounts-page .error { color: red; }
226+.accounts-page .error_found { color: red; font-size: 1.5em; }
227+.accounts-page button { margin-right: 1em; }
228+.accounts-page form label { display: block; }
229+.accounts-page form div { margin-bottom: 1em; }
230+.accounts-page form a { text-decoration: none; }
231+
232+#login-page h2 { font-size: 1.5em; margin-bottom: 0.375em; }
233+#login-page h1, #login-page h2, #login-page h3, #login-page h4, #login-page h5, #login-page h6 { line-height: 1em; }
234+#login-page p { margin-bottom: 1em; }
235+#login-page strong { font-weight: bold; }
236+#login-page #desc { float: left; margin-right: 400px; }
237+#login-page div { padding: 0.5em 1em; }
238+#login-page #sign-in-box { background-color: #efefff; float: left; margin-left: -400px; width: 350px; }
239+#login-page #sign-in-box form label { display: block; }
240+#login-page #sign-in-box a { font-size: 0.875em; }
241+
242 .hll { background-color: #ffffcc; }
243 
244 .c { color: #408090; font-style: italic; }
245@@ -474,5 +545,3 @@
246 .vc, .vg, .vi { color: #bb60d5; }
247 
248 .il { color: #208050; }
249-
250-/* end stuff scraped from pygment */
251diff -r 8afee2ec056a sagenb/data/sage/css/master.css
252--- a/sagenb/data/sage/css/master.css   Sat Oct 24 18:17:19 2009 +0800
253+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
254@@ -1,47 +0,0 @@
255-html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td { margin: 0; padding: 0; border: 0; outline: 0; font-weight: inherit; font-style: inherit; font-size: 100%; font-family: inherit; vertical-align: baseline; }
256-
257-*:focus { outline: 0; }
258-
259-body { line-height: 1em; color: black; background: #fff; }
260-
261-ol, ul { list-style: none; }
262-
263-/* tables still need 'cellspacing="0"' in the markup */
264-table { border-collapse: separate; border-spacing: 0; vertical-align: middle; }
265-
266-caption, th, td { text-align: left; font-weight: normal; vertical-align: middle; }
267-
268-q, blockquote { quotes: "" ""; }
269-q:before, q:after, blockquote:before, blockquote:after { content: ""; }
270-
271-img a { border: none; }
272-
273-html { font-size: 100.1%; }
274-
275-body { font: .9em/1.2em Arial, Helvetica, sans-serif; }
276-
277-div { padding: 0.5em 1em; }
278-
279-#desc { float: left; margin-right: 400px; }
280-
281-#sign-in-box { float: left; margin-left: -400px; width: 350px; background-color: #efefff; }
282-#sign-in-box form label { display: block; }
283-
284-p { margin-bottom: 1em; }
285-
286-h1, h2, h3, h4, h5, h6 { line-height: 1em; }
287-
288-h2 { font-size: 1.5em; margin-bottom: 0.375em; }
289-
290-#banner { font-size: 1.2em; float: left; clear: both; margin-bottom: 0.25em; }
291-#banner a.banner { text-decoration: none; border: none; margin-top: 2px; float: left; }
292-#banner a.banner:visited { color: #1950c8; }
293-#banner #ping { display: none; }
294-#banner div.version { float: left; clear: left; font-size: xx-small; text-indent: 13px; color: black; }
295-
296-.section { border-bottom: 1px solid #CCC; padding: 5px; }
297-.section > div { max-width: 350px; text-align: right; }
298-
299-input.c1 { width: 200px; }
300-
301-strong { font-weight: bold; }
302diff -r 8afee2ec056a sagenb/data/sage/css/registration.css
303--- a/sagenb/data/sage/css/registration.css     Sat Oct 24 18:17:19 2009 +0800
304+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
305@@ -1,28 +0,0 @@
306-html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, dl, dt, dd, ol, ul, li, table, caption, tbody, tfoot, thead, tr, th, td { border: 0; font-family: inherit; font-size: 100%; font-style: inherit; font-weight: inherit; margin: 0; outline: 0; padding: 0; text-decoration: none; vertical-align: baseline; }
307-
308-html { font-size: 100.1%; }
309-
310-body { font: 0.88em/1.4 Arial, Helvetica, sans-serif; }
311-
312-#wrapper { margin: 0 auto; max-width: 600px; }
313-
314-h1, h2, h3, h4, h5 { font-wieght: normal; }
315-
316-h1 { border-bottom: 1px solid #696969; font-size: 2em; padding: 10px 0; }
317-
318-h2 { font-weight: bold; }
319-
320-h1, h2, p, li { margin-bottom: 10px; }
321-
322-.entry { margin-bottom: 10px; border: 1px solid #999; padding: 3px; width: 200; }
323-
324-li { border-bottom: 1px solid #CCC; }
325-
326-.error { color: red; }
327-
328-.error_found { color: red; font-size: 1.5em; }
329-
330-button { margin-right: 1em; }
331-
332-form label { display: block; }
333-form div { margin-bottom: 1em; }
334diff -r 8afee2ec056a sagenb/data/sage/css/user_management.css
335--- a/sagenb/data/sage/css/user_management.css  Sat Oct 24 18:17:19 2009 +0800
336+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
337@@ -1,49 +0,0 @@
338-html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td { margin: 0; padding: 0; border: 0; outline: 0; font-weight: inherit; font-style: inherit; font-size: 100%; font-family: inherit; vertical-align: baseline; }
339-
340-*:focus { outline: 0; }
341-
342-body { line-height: 1em; color: black; background: #fff; }
343-
344-ol, ul { list-style: none; }
345-
346-/* tables still need 'cellspacing="0"' in the markup */
347-table { border-collapse: separate; border-spacing: 0; vertical-align: middle; }
348-
349-caption, th, td { text-align: left; font-weight: normal; vertical-align: middle; }
350-
351-q, blockquote { quotes: "" ""; }
352-q:before, q:after, blockquote:before, blockquote:after { content: ""; }
353-
354-img a { border: none; }
355-
356-html { font-size: 100.1%; }
357-
358-body { font: .9em/1.2em Arial, Helvetica, sans-serif; }
359-
360-div { padding: 0.5em 1em; }
361-
362-#desc { float: left; margin-right: 400px; }
363-
364-#sign-in-box { float: left; margin-left: -400px; width: 350px; background-color: #efefff; }
365-#sign-in-box form label { display: block; }
366-
367-p { margin-bottom: 1em; }
368-
369-h1, h2, h3, h4, h5, h6 { line-height: 1em; }
370-
371-h2 { font-size: 1.5em; margin-bottom: 0.375em; }
372-
373-#banner { font-size: 1.2em; float: left; clear: both; margin-bottom: 0.25em; }
374-#banner a.banner { text-decoration: none; border: none; margin-top: 2px; float: left; }
375-#banner a.banner:visited { color: #1950c8; }
376-#banner #ping { display: none; }
377-#banner div.version { float: left; clear: left; font-size: xx-small; text-indent: 13px; color: black; }
378-
379-.section { border-bottom: 1px solid #CCC; padding: 5px; }
380-.section > div { max-width: 350px; text-align: right; }
381-
382-input.c1 { width: 200px; }
383-
384-strong { font-weight: bold; }
385-
386-body { margin: 10px; }
387diff -r 8afee2ec056a sagenb/data/sage/html/account_recovery.html
388--- a/sagenb/data/sage/html/account_recovery.html       Sat Oct 24 18:17:19 2009 +0800
389+++ b/sagenb/data/sage/html/account_recovery.html       Sun Jan 03 03:07:50 2010 +0800
390@@ -1,7 +1,7 @@
391 {% extends "html/base.html" %}
392 
393 {% block title %}Account Recovery{% endblock %}
394-{% block css %}registration{% endblock %}
395+{% block page_id %}account-recovery-page{% endblock %}
396 
397 {% block body %}
398 <div id="wrapper">
399@@ -18,6 +18,4 @@
400         </div>
401 </form>
402 </div>
403-
404-
405 {% endblock %}
406diff -r 8afee2ec056a sagenb/data/sage/html/account_settings.html
407--- a/sagenb/data/sage/html/account_settings.html       Sat Oct 24 18:17:19 2009 +0800
408+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
409@@ -1,62 +0,0 @@
410-{% extends "html/base.html" %}
411-
412-{% block title %}Account Settings{% endblock %}
413-{% block css %}account_settings{% endblock %}
414-{% block page_id %}account-settings-page{% endblock %}
415-{% block body %}
416-<h1>Account Settings</h1>
417-<div class="section">{% if admin %}<a href="/users">Manage Users</a> | <a href="/notebooksettings">Notebook Settings</a> | {% endif %}<a href="/">My Worksheets</a> | <a href="/logout">Sign Out</a></div>
418-
419-  <form method="post" action="/settings">
420-   
421-    <div class="section">
422-      <h2>Change Auto-Save Interval</h2>
423-      <div>
424-       Minutes:
425-       <select name="autosave">
426-        {% for i, selected in autosave_intervals %}
427-         <option{{ selected }}>{{ i }}</option>
428-       {% endfor %}
429-       </select>
430-      </div>
431-    </div>
432-    <div class="section">
433-      <h2>Change Password</h2>
434-      <div id="passwd">
435-          <div>
436-              <label for="old-pass">Old password</label>
437-              <input type="password" name="old-pass" />
438-          </div>
439-          <div>
440-              <label for="new-pass">New password</label>
441-              <input type="password" name="new-pass" />
442-          </div>
443-          <div>
444-              <label for="retype-pass">Retype new password</label>
445-              <input type="password" name="retype-pass" />
446-          </div>
447-      </div>
448-    </div>
449-
450-    {% if true %}
451-       <div class="section">
452-          <h2>Change E-mail Address</h2>
453-   
454-          <div>
455-              <div>
456-                  <label>Current e-mail</label>
457-                  {{ email_address }} {{ email_confirmed }}
458-              </div>
459-              <div>
460-                  <label for="new-email">New e-mail</label>
461-                  <input type="text" name="new-email" class="c1" />
462-              </div>
463-          </div>
464-        </div>
465-       {% endif %}
466-    <div id="buttons">
467-    <button type="submit">Save</button>
468-    <a href="/"><button>Cancel</button></a>
469-    </div>
470-  </form>
471-{% endblock %}
472diff -r 8afee2ec056a sagenb/data/sage/html/accounts/account_recovery.html
473--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
474+++ b/sagenb/data/sage/html/accounts/account_recovery.html      Sun Jan 03 03:07:50 2010 +0800
475@@ -0,0 +1,21 @@
476+{% extends "html/accounts/base.html" %}
477+
478+{% block title %}Account Recovery{% endblock %}
479+{% block page_id %}account-recovery-page{% endblock %}
480+
481+{% block body %}
482+<div id="wrapper">
483+    <h1>Account Recovery</h1>
484+    <p>A new password will be emailed to the email address connected to your account. However if you didn't confirm your email address you will be unable to recover your account.</p> 
485+
486+    <form method="GET" action="/forgotpass">
487+        <div>
488+            <label for="username">Username</label>
489+            <input type="text" name="username" size="15" />
490+        </div>
491+        <div>
492+            <button type="submit">Submit</button> <a href="/"><button >Cancel</button></a>
493+        </div>
494+</form>
495+</div>
496+{% endblock %}
497diff -r 8afee2ec056a sagenb/data/sage/html/accounts/base.html
498--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
499+++ b/sagenb/data/sage/html/accounts/base.html  Sun Jan 03 03:07:50 2010 +0800
500@@ -0,0 +1,2 @@
501+{% extends "html/base.html" %}
502+{% block body_classes %}accounts-page{% endblock %}
503diff -r 8afee2ec056a sagenb/data/sage/html/accounts/registration.html
504--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
505+++ b/sagenb/data/sage/html/accounts/registration.html  Sun Jan 03 03:07:50 2010 +0800
506@@ -0,0 +1,85 @@
507+{% extends "html/accounts/base.html" %}
508+
509+{% block title %}Sign up{% endblock %}
510+
511+{% block page_id %}registration-page{% endblock %}
512+
513+{% block body %}
514+<div id="wrapper">
515+    <h1>Sign up for a Sage Notebook account</h1>
516+    {% if error %}
517+    <h2 class="error_found">Error{{ error[1:] }}found</h2>
518+    {% endif %}
519+    <form method="POST" action="/register">
520+        <ol>
521+            <li>
522+                <h2>Create a username</h2>
523+                <p>Your username must start with a letter and be between 3 and 64
524+                characters long. You may only use letters, numbers, underscores, @,
525+                and dots.</p>
526+                <input type="text" name="username" value="{{ username }}" class="entry" tabindex="1" />
527+                {% if username_missing %}
528+                <p><span class="error">Error:</span> No username given</p>
529+                {% endif %}
530+                {% if username_taken %}
531+                <p><span class="error">Error:</span> Username already in use</p>
532+                {% endif %}
533+                {% if username_invalid %}
534+                <p><span class="error">Error:</span> Bad username</p>
535+                {% endif %}
536+            </li>
537+            <li>
538+                <h2>Create a good password</h2>
539+                <p>
540+                    Your password must be between 4 and 32 characters
541+                    long. Your password can not contain your username nor spaces.
542+                </p>
543+                <input type="password" name="password" class="entry" tabindex="2" />
544+                {% if password_missing %}
545+                <p><span class="error">Error:</span> No password given</p>
546+                {% endif %}
547+                {% if password_invalid %}
548+                <p><span class="error">Error:</span> Bad password</p>
549+                {% endif %}
550+            </li>
551+            <li><h2>Re-type your password</h2>
552+            <input type="password" name="retype_password" class="entry" tabindex="3" />
553+            {% if passwords_dont_match or retype_password_missing %}
554+            <p><span class="error">Error:</span> Passwords didn't match</p>
555+            {% endif %}
556+            </li>
557+            {% if email or email_missing or email_invaild %}
558+            <li>
559+                <h2>Enter your email address</h2>
560+                <p>
561+                    Your email address is required for account
562+                    confirmation and recovery. You will be emailed a confirmation link
563+                    right after you successfully sign up.
564+                </p>
565+                <input type="text" name="email" value="{{ email_address }}" class="entry" tabindex="4" />
566+                {% if email_missing %}
567+                <p><span class="error">Error:</span> No email address given</p>
568+                {% endif %}
569+                {% if email_invalid %}
570+                <p><span class="error">Error:</span> Invalid email address</p>
571+                {% endif %}
572+            </li>
573+            {% endif %}
574+            {% if challenge %}
575+            <li>
576+                <h2>Answer a challenge</h2>
577+                {{ challenge_html }}
578+                {% if challenge_missing %}
579+                <p><span class="error">Error:</span> No challenge response given</p>
580+                {% endif %}
581+                {% if challenge_invalid %}
582+                <p><span class="error">Error:</span> Invalid challenge response</p>
583+                {% endif %}
584+            </li>
585+            {% endif %}
586+        </ol>
587+        <button type="submit" tabindex="100" id="create-account-button">Create account</button>
588+        <a href="/"><button tabindex="101">Cancel</button></a>
589+    </form>
590+</div>
591+{% endblock %}
592\ No newline at end of file
593diff -r 8afee2ec056a sagenb/data/sage/html/admin_add_user.html
594--- a/sagenb/data/sage/html/admin_add_user.html Sat Oct 24 18:17:19 2009 +0800
595+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
596@@ -1,101 +0,0 @@
597-<html>
598-<head>
599-<title>Add New User | {{ sitename }}</title>
600-<style>
601-/***** Global Settings *****/
602-
603-html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,dl,dt,dd,ol,ul,li,table,caption,tbody,tfoot,thead,tr,th,td {
604-border:0;
605-font-family:inherit;
606-font-size:100%;
607-font-style:inherit;
608-font-weight:inherit;
609-margin:0;
610-outline:0;
611-padding:0;
612-text-decoration:none;
613-vertical-align:baseline
614-}
615-
616-html {
617-font-size:100.1%
618-}
619-
620-body {
621-font:0.88em/1.4 Arial, Helvetica, sans-serif;
622-}
623-
624-#wrapper {
625-margin:0 auto;
626-max-width:600px
627-}
628-
629-/***** Headings *****/
630-
631-h1,h2,h3,h4,h5 {
632-font-wieght:normal
633-}
634-
635-h1 {
636-border-bottom:1px solid #696969;
637-font-size:2em;
638-padding:10px 0
639-}
640-
641-h2 {
642-font-weight:bold
643-}
644-
645-h1, h2, p, li, .entry {
646-margin-bottom:10px
647-}
648-
649-.entry {
650-border:1px solid #999;
651-padding:3px;
652-width:200
653-}
654-
655-li {
656-border-bottom:1px solid #CCC
657-}
658-
659-.error, .error_found {
660-color:red
661-}
662-
663-.error_found {
664-font-size:1.5em
665-}
666-
667-.button {
668-font-size:1.2em
669-}
670-</style>
671-</head>
672-<body>
673-<div id="wrapper">
674-<h1>Add New User</h1>
675-{% if error %}
676-<h2 class="error_found">Username Error</h2>
677-{% endif %}
678-<form method="POST" action="/adduser">
679-<ol>
680-<li><h2>Pick a username</h2>
681-<p>The username must start with a letter and be between 4 and 32 characters long. It can only consist of letters, numbers, underscores, and one dot (.).</p>
682-<input type="text" name="username" value="{{ username }}" class="entry" />
683-{% if username_error %}
684-{% if username_error == 'invalid' %}
685-<p><span class="error">Error:</span> Invalid username</p>
686-{% else %}
687-<p><span class="error">Error:</span> Username taken</p>
688-{% endif %}
689-{% endif %}
690-</li>
691-</ol>
692-<input type="submit" value="Create account" class="button" />
693-<input type="button" value="Cancel" style="margin-left:10px" onClick="parent.location='/users'" class="button" />
694-</form>
695-</div>
696-</body>
697-</html>
698\ No newline at end of file
699diff -r 8afee2ec056a sagenb/data/sage/html/banner.html
700--- a/sagenb/data/sage/html/banner.html Sat Oct 24 18:17:19 2009 +0800
701+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
702@@ -1,9 +0,0 @@
703-<div id="banner">
704-    <a class="banner" href="http://nb.sagemath.org/">
705-        <img align="top" src="/images/sagenb.png" alt="Sage" /><span>The Sage Notebook</span>
706-    </a>
707-       <span class="ping" id="ping">Searching for Sage server...</span>
708-    <div class="version">
709-        Version {{ sage_version }}
710-    </div>
711-</div>
712diff -r 8afee2ec056a sagenb/data/sage/html/base.html
713--- a/sagenb/data/sage/html/base.html   Sat Oct 24 18:17:19 2009 +0800
714+++ b/sagenb/data/sage/html/base.html   Sun Jan 03 03:07:50 2010 +0800
715@@ -1,19 +1,46 @@
716+{%- macro render_title -%}{% block title %}{% endblock %}{%- endmacro -%}
717 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
718 <html lang="en">
719     <head>
720-        <title>{% block title %}{% endblock %}</title>
721+        <title>{{ render_title() }} -- Sage</title>
722         <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
723         {% block pre_main_css %}{% endblock %}
724-        <link type="text/css" rel="stylesheet" href="/css/{% block css %}master{% endblock %}.css" media="screen" />
725+        <link type="text/css" rel="stylesheet" href="/css/{% block css %}main{% endblock %}.css" />
726         {% block more_css %}{% endblock %}
727-       <!-- jQuery - general-purpose functions -->
728+        {# jQuery and other universally used libraries #}
729         <script type="text/javascript" src="/javascript/jquery/jquery-1.3.2.min.js"></script>
730         {% block javascript %}
731-       <!-- Worksheet list functions -->
732+        {# Page-specific libraries #}
733         <script type="text/javascript" src="/javascript/sage/ws_list.js"></script>
734         {% endblock %}
735+        {# Behavior #}
736+        <script type="text/javascript" src="/javascript/sage/master.js"></script>
737     </head>
738-    <body {% block body_attrs %}{% endblock %} id="{% block page_id %}{% endblock %}">
739-        {% block body %}{% endblock %}
740+    <body id="{% block page_id %}{% endblock %}"
741+          class="{% block body_classes %}{% endblock %}">
742+        {% block body %}
743+        <div id="header">
744+            {% block header %}
745+            <div id="top-bar">
746+                <div id="banner">
747+                    <a class="banner" href="http://nb.sagemath.org/">
748+                        <img align="top" src="/images/sagenb.png" alt="Sage" /><span>The Sage Notebook</span>
749+                    </a>
750+                    <span class="ping" id="ping">Searching for Sage server...</span>
751+                    <div class="version">
752+                        Version {{ sage_version }}
753+                    </div>
754+                </div>
755+                {% block controls %}
756+                {% endblock %}
757+            </div>
758+            {% endblock %}
759+        </div>
760+        <div id="main">
761+            {% block main %}
762+
763+            {% endblock %}
764+        </div>
765+        {% endblock %}
766     </body>
767-</html>
768+</html>
769\ No newline at end of file
770diff -r 8afee2ec056a sagenb/data/sage/html/base_authenticated.html
771--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
772+++ b/sagenb/data/sage/html/base_authenticated.html     Sun Jan 03 03:07:50 2010 +0800
773@@ -0,0 +1,24 @@
774+{% extends "html/base.html" %}
775+{% block controls %}
776+<div id="main-controls" class="controls">
777+    <ul>
778+        <li class="username">{{ username }}</li>
779+        {% if username == 'guest' %}
780+        <li><a title="Please log in to the Sage notebook" href="/">Log in</a></li>
781+        {% else %}
782+        <li><a id="toggle-link" title="Toggle the top bar" onClick="$('#worksheet-bar').toggle()">Toggle</a></li>
783+        <li><a title="Back to your personal worksheet list" href="/home/{{ username }}">Home</a></li>
784+        {% if pub %}
785+        <li><span>Published</span></li>
786+        {% else %}
787+        <li><a title="Browse the published worksheets" href="/pub">Published</a></li>
788+        <li><a title="View a log of recent computations" href="#" onClick="history_window()">Log</a></li>
789+        {% endif %}
790+        <li><a title="Change account settings including password" href="/settings">Settings</a></li>
791+        <li><a title="Documentation" href="#" onClick="help()">Help</a></li>
792+        <li><a title="Report a problem or submit a bug to improve Sage" href="#" onClick="bugreport()">Report a Problem</a></li>
793+        <li><a title="Log out of the Sage notebook" href="/logout">Sign out</a></li>
794+        {% endif %}
795+    </ul>
796+</div>
797+{% endblock %}
798diff -r 8afee2ec056a sagenb/data/sage/html/base_popup.html
799--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
800+++ b/sagenb/data/sage/html/base_popup.html     Sun Jan 03 03:07:50 2010 +0800
801@@ -0,0 +1,4 @@
802+{% extends "html/base.html" %}
803+
804+{% block body %}
805+{% endblock %}
806diff -r 8afee2ec056a sagenb/data/sage/html/command_history.html
807--- a/sagenb/data/sage/html/command_history.html        Sat Oct 24 18:17:19 2009 +0800
808+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
809@@ -1,16 +0,0 @@
810-
811-{#
812-INPUT:
813-    - history_text - a string containing the history text of the notebook
814-#}
815-<html>
816-    <head>
817-        <title>Command History</title>
818-        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
819-    </head>
820-    <body>
821-        <pre>{{history_text}}</pre>
822-        <a name="bottom"></a>
823-        <script type="text/javascript"> window.location="#bottom"</script>
824-    </body>
825-</html>
826\ No newline at end of file
827diff -r 8afee2ec056a sagenb/data/sage/html/docs.html
828--- a/sagenb/data/sage/html/docs.html   Sat Oct 24 18:17:19 2009 +0800
829+++ b/sagenb/data/sage/html/docs.html   Sun Jan 03 03:07:50 2010 +0800
830@@ -1,18 +1,14 @@
831-{% extends "html/base.html" %}
832+{% extends "html/base_authenticated.html" %}
833 
834 {% block title %}Sage Documentation{% endblock %}
835 
836-{% block css %}main{% endblock %}
837-
838 {% block javascript %}
839 <script type="text/javascript" src="/javascript/sage/ws_list.js"></script>
840 {% endblock%}
841 
842 {% block page_id %}docs-main-page{% endblock %}
843 
844-{% block body %}
845-
846-{% include "html/top_bar.html" %}
847+{% block main %}
848 
849 <div class="control-bar">
850     <ul class="controls">
851diff -r 8afee2ec056a sagenb/data/sage/html/error_message.html
852--- a/sagenb/data/sage/html/error_message.html  Sat Oct 24 18:17:19 2009 +0800
853+++ b/sagenb/data/sage/html/error_message.html  Sun Jan 03 03:07:50 2010 +0800
854@@ -1,14 +1,14 @@
855-{% extends "html/base.html" %}
856+{% extends "html/base_authenticated.html" %}
857 
858 {% block title %}Error{% endblock %}
859 
860-{% block body %}
861-<br><a class="usercontrol" href="/">Home</a>
862-<hr class="usercontrol">
863-<br/><br/>
864-{{ msg }}
865-<br/><br/>
866+{% block main %}
867+<div>
868+    {{ msg }}
869+</div>
870 {% if cont %}
871-<center><a class="boldusercontrol" href="{{ cont }}"><font size=+1>Continue</font></a></center>
872+<div>
873+    <a class="boldusercontrol" href="{{ cont }}">Continue</a>
874+</div>
875 {% endif %}
876 {% endblock %}
877diff -r 8afee2ec056a sagenb/data/sage/html/history.html
878--- a/sagenb/data/sage/html/history.html        Sat Oct 24 18:17:19 2009 +0800
879+++ b/sagenb/data/sage/html/history.html        Sun Jan 03 03:07:50 2010 +0800
880@@ -2,8 +2,6 @@
881 
882 {% block title %}Sage: History for {{username}} {% endblock %}
883 
884-{% block css %}main{% endblock %}
885-
886 {% block javascript %}
887 <script type="text/javascript" src="/javascript/sage/ws_list.js"></script>
888 {% endblock %}
889@@ -12,8 +10,6 @@
890 
891 {% block body %}
892 
893-{% include "html/top_bar.html" %}
894-
895     <pre>{{ text | escape }}</pre>
896     <a title="Click here to turn the above into a Sage worksheet" href="/live_history">Create a new Sage worksheet version of the last 100 commands in the above log.</a>
897     <a name="bottom"></a>
898diff -r 8afee2ec056a sagenb/data/sage/html/list_top.html
899--- a/sagenb/data/sage/html/list_top.html       Sat Oct 24 18:17:19 2009 +0800
900+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
901@@ -1,19 +0,0 @@
902-{% include "html/top_bar.html" %}
903-
904-<div id="usercontrols">
905-    {% if pub is not defined or not pub %}
906-    <a class="boldusercontrol" href="/new_worksheet" target="_blank">New Worksheet</a>
907-    <a class="boldusercontrol" href="/upload">Upload</a>
908-    {% if not accounts %}
909-    <a class="boldusercontrol" href="/download_worksheets.zip">Download All Active</a>
910-    {% endif %}
911-    {% endif %}
912-
913-    <div id='search-area'>
914-      <form action="." method="GET">
915-        <input type="hidden" value="{{ typ if not pub else 'pub' }}" name="typ" />
916-        <input id="search-worksheets" size="20" value="{{ search if search else "" }}" name="search" />
917-        <button class="add_new_worksheet_menu" id="search-worksheets-button" type="submit">Search Worksheets</button>
918-      </form>
919-    </div>
920-</div>
921diff -r 8afee2ec056a sagenb/data/sage/html/login.html
922--- a/sagenb/data/sage/html/login.html  Sat Oct 24 18:17:19 2009 +0800
923+++ b/sagenb/data/sage/html/login.html  Sun Jan 03 03:07:50 2010 +0800
924@@ -2,9 +2,9 @@
925 
926 {% block title %}Sign in{% endblock %}
927 
928-{% block body %}
929-{% include "html/banner.html" %}       
930+{% block page_id %}login-page{% endblock %}
931 
932+{% block main %}
933 {% if welcome %}
934 <h2>Congratulations {{ welcome }}! You can now sign into the Sage Notebook.</h2>
935 {% endif %}
936@@ -69,25 +69,25 @@
937             {% endif %}
938         </div>
939         <div>
940-            <input type="checkbox" name="remember" />Remember me
941+            <input type="checkbox" name="remember" /> Remember me
942         </div>
943         <div>
944             <button type="submit">Sign in</button>
945         </div>
946     </form>
947+    {% if accounts %}
948     <div>
949-        {% if accounts %}
950         <a href="/register" id="register-link"><strong>Sign up for a new Sage Notebook account</strong></a>
951-        {% endif %}
952     </div>
953+    {% endif %}
954     <div>
955         <a href="/pub"><strong>Browse published Sage worksheets<br>(no login required)</strong></a>
956     </div>
957+    {% if recovery %}
958     <div>
959-        {% if recovery %}
960         <a href="/forgotpass"><strong>Forgot password</strong></a>
961-        {% endif %}
962     </div>
963+    {% endif %}
964 </div>
965 {% endblock %}
966 
967diff -r 8afee2ec056a sagenb/data/sage/html/notebook/afterpublish_window.html
968--- a/sagenb/data/sage/html/notebook/afterpublish_window.html   Sat Oct 24 18:17:19 2009 +0800
969+++ b/sagenb/data/sage/html/notebook/afterpublish_window.html   Sun Jan 03 03:07:50 2010 +0800
970@@ -1,26 +1,16 @@
971-{% extends "html/notebook/worksheet_page_template.html" %}
972-{#
973-INPUT:
974-- worksheet - an instance of Worksheet
975-- worksheet_filename - a string containing a worksheet's filename
976-- username - a string containing a username
977-- url - a string containing the url of the published page
978-- time - a string representing the time of publication
979-- JSMATH - a boolean stating whether to include jsMath
980-- JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE
981-#}
982+{% extends "html/notebook/base_aux.html" %}
983+
984+{% block page_id %}after-publish-page{% endblock %}
985 
986 {% set checked = 'checked="true"' if worksheet.is_auto_publish() else '' %}
987 
988 {% block sharebar_title %}
989-Worksheet is publicly viewable at <a href="{{ url }}" style="color:#FFF" target="_blank">{{ url }}</a>
990-<br />
991-Published on {{ time }}
992-<br />
993-<br />
994-<input type="button" value="Re-publish worksheet" onClick="parent.location='?re'" />
995-<input type="button" value="Stop publishing" style="margin-left:5px" onClick="parent.location='?stop'" />
996-<br /><br />
997+<p>Worksheet is publicly viewable at <a href="{{ url }}" style="color:#FFF" target="_blank">{{ url }}</a></p>
998+<p>Published on {{ time }}</p>
999+<div>
1000+    <a href=".?re"><button>Re-publish worksheet</button></a>
1001+    <a onClick="parent.location+='?stop'"><button>Stop publishing</button></p></a>
1002+</div>
1003 <input type="checkbox" name="auto" {{ checked }} onchange="parent.location='?auto'"/> <label for="auto">Automatically re-publish when changes are made</label>
1004 {% endblock %}
1005 {% set select = "publish" %}
1006diff -r 8afee2ec056a sagenb/data/sage/html/notebook/base.html
1007--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
1008+++ b/sagenb/data/sage/html/notebook/base.html  Sun Jan 03 03:07:50 2010 +0800
1009@@ -0,0 +1,168 @@
1010+{% extends "html/base_authenticated.html" %}
1011+{#
1012+INPUT:
1013+- notebook - an instance of Notebook
1014+- worksheet - an instance of Worksheet
1015+- username  - a string containing a username
1016+- title - a string
1017+- select    - a string containing the control that is selected
1018+- backwards - a boolean
1019+#}
1020+
1021+{% set system_names = worksheet.notebook().system_names() %}
1022+{% block title %}{{ worksheet.name() }}{% endblock %}
1023+
1024+
1025+{% block javascript %}
1026+<!-- jQuery UI - interacts, widgets, drag-drop, etc. -->
1027+<link rel="stylesheet" href="/javascript/jqueryui/css/sage/jquery-ui-1.7.2.custom.css" />
1028+<script type="text/javascript" src="/javascript/jqueryui/js/jquery-ui-1.7.2.custom.min.js"></script>
1029+
1030+<!-- jQuery plugins - color pickers, shift-click, AJAX forms, IE fixes -->
1031+<link rel="stylesheet" href="/javascript/jquery/plugins/farbtastic/farbtastic.css" type="text/css" />
1032+<script type="text/javascript" src="/javascript/jquery/plugins/farbtastic/farbtastic.min.js"></script>
1033+<script type="text/javascript" src="/javascript/jquery/plugins/extendedclick/jquery.event.extendedclick.min.js"></script>
1034+<script type="text/javascript" src="/javascript/jquery/plugins/form/jquery.form.min.js"></script>
1035+<script type="text/javascript" src="/javascript/jquery/plugins/jquery.bgiframe.min.js"></script>
1036+<link rel="stylesheet" href="/javascript/jquery/plugins/jpicker/css/jPicker-1.0.11.css" type="text/css" />
1037+<script type="text/javascript" src="/javascript/jquery/plugins/jpicker/jpicker-1.0.11.min.js"></script>
1038+<link rel="stylesheet" media="screen" type="text/css" href="/javascript/jquery/plugins/colorpicker/css/colorpicker.css" />
1039+<script type="text/javascript" src="/javascript/jquery/plugins/colorpicker/js/colorpicker.min.js"></script>
1040+
1041+<script type="text/javascript" src="/javascript/sage/main.js"></script>
1042+
1043+{% if JSMATH %}
1044+<!-- jsMath - typeset mathematics -->
1045+<script type="text/javascript" src="/javascript/sage/jsmath.js"></script>
1046+{% endif %}
1047+
1048+<!-- Sage3d - accelerated 3D graphics -->
1049+<script type="text/javascript" src="/javascript/sage3d/sage3d.js"></script>
1050+
1051+<!-- Jmol - embedded 3D graphics -->
1052+<script type="text/javascript" src="/java/jmol/appletweb/Jmol.js"></script>
1053+<!-- This must stay in head -->
1054+<script>jmolInitialize("/java/jmol");jmolSetCallback("menuFile","/java/jmol/appletweb/SageMenu.mnu");</script>
1055+
1056+{% if JEDITABLE_TINYMCE and not worksheet.docbrowser() and not worksheet.is_published() %}
1057+<!-- TinyMCE and jEditable - in-place editing of text cells -->
1058+<script type="text/javascript" src="/javascript/tiny_mce/tiny_mce.js"></script>
1059+<script type="text/javascript" src="/javascript/jquery/plugins/jeditable/jquery.jeditable.mini.js" charset="utf-8"></script>
1060+<script type="text/javascript" src="/javascript/sage/tinymce.js"></script>
1061+{% endif %}
1062+
1063+<script type="text/javascript">user_name= "{{ username }}";</script>
1064+{% if worksheet.filename() %}
1065+<script  type="text/javascript">
1066+    $(document).ready(function() {
1067+    worksheet_filename="{{ worksheet.filename() }}";
1068+    worksheet_name="{{ worksheet.name() }}";
1069+    server_ping_while_alive();
1070+    });
1071+</script>
1072+{% endif %}
1073+
1074+{% endblock %}
1075+
1076+{% block main %}
1077+<div id="worksheet-bar">
1078+    <div class="worksheet_title">
1079+        <a id="worksheet_title" class="worksheet_title"
1080+           onClick="rename_worksheet(); return false;"
1081+           title="Click to rename this worksheet">
1082+            {{ worksheet.name() }}
1083+        </a>
1084+        <div><span class="lastedit">{{ worksheet.html_time_last_edited() }}</span></div>
1085+        {% if worksheet.warn_about_other_person_editing(username) and username != 'guest' and not worksheet.is_doc_worksheet() %}
1086+        <span class="pingdown">(Someone else is viewing this worksheet)</span>
1087+        {% endif %}
1088+    </div>
1089+    <div id="save-discard-buttons">
1090+        {% if not worksheet.is_doc_worksheet() %}
1091+        <button name="button_save" title="Save changes" onClick="save_worksheet();">Save</button><button title="Save changes and close window" onClick="save_worksheet_and_close();" name="button_save">Save & quit</button><button title="Discard changes to this worksheet" onClick="worksheet_discard();">Discard & quit</button>
1092+        {% endif %}
1093+    </div>
1094+   
1095+    <div id="worksheet-menu">
1096+        <select class="worksheet"  onchange="go_option(this);" id="file-menu">
1097+            <option title="Select a file related function" value=""  selected>File...</option>
1098+            <option title="Load a new worksheet stored in a file" value="upload_worksheet_button();">Load worksheet from a file...</option>
1099+            <option title="Create a new worksheet" value="new_worksheet();">New worksheet</option>
1100+            <option title="Save this worksheet to an sws file" value="download_worksheet();">Save worksheet to a file...</option>
1101+            <option title="Print this worksheet" value="print_worksheet();">Print</option>
1102+            <option title="Rename this worksheet" value="rename_worksheet();">Rename worksheet</option>
1103+            <option title="Copy this worksheet" value="copy_worksheet();">Copy worksheet</option>
1104+            <option title="Move this worksheet to the trash" value="delete_worksheet('{{ worksheet.filename() }}');">Delete worksheet</option>
1105+        </select>
1106+
1107+        <select class="worksheet"  onchange="go_option(this);"  id="action-menu">
1108+            <option title="Select a worksheet function" value="" selected>Action...</option>
1109+            <option title="Interrupt currently running calculations, if possible" value="interrupt();">Interrupt</option>
1110+            <option title="Restart the worksheet process" value="restart_sage();">Restart worksheet</option>
1111+            <option title="Quit the worksheet process" value="save_worksheet_and_close();">Save and quit worksheet</option>
1112+            <option value="">---------------------------</option>
1113+            <option title="Evaluate all input cells in the worksheet" value="evaluate_all();">Evaluate All</option>
1114+            <option title="Hide all output" value="hide_all();">Hide All Output</option>
1115+            <option title="Show all output" value="show_all();">Show All Output</option>
1116+            <option title="Delete all output" value="delete_all_output();">Delete All Output</option>
1117+            <option value="">---------------------------</option>
1118+            <option title="Switch to single-cell mode" value="slide_mode();">One Cell Mode</option>
1119+            <option title="Switch to multi-cell mode" value="cell_mode();">Multi Cell Mode</option>
1120+        </select>
1121+        <select class="worksheet" onchange="handle_data_menu(this);" id="data-menu">
1122+            <option title="Select an attached file" value="" selected>Data...</option>
1123+            <option title="Upload or create a data file in a wide range of formats" value="__upload_data_file__">Upload or create file...</option>
1124+            <option value="">--------------------</option>
1125+            {% for name in worksheet.attached_data_files()|sort %}
1126+            <option value="datafile?name={{ name }}">{{ name }}</option>
1127+            {% endfor %}
1128+        </select>
1129+
1130+        {% if not worksheet.is_doc_worksheet() %}
1131+        <select onchange="go_system_select(this, {{ worksheet.system_index() }});" class="worksheet" id="systems-menu">
1132+            {% for system_name in worksheet.notebook().systems() %}
1133+            <option title="Evaluate all input cells using {{ system_names[loop.index0] }}"
1134+                    {{ "selected" if worksheet.system_index() == loop.index0 else "" }} value="{{ system_names[loop.index0] }}">
1135+                {{ system_name }}
1136+            </option>
1137+            {% endfor %}
1138+        </select>   
1139+        <input type="checkbox" title="Enable/disable pretty_printing"
1140+               onchange="pretty_print_check(this.checked);"
1141+               class="worksheet" value="pretty_print" {{ "checked" if worksheet.pretty_print() else "" }} />&nbsp;Typeset
1142+        {% endif %}
1143+    </div>
1144+    <div id="share-publish-buttons">
1145+        {% if not worksheet.is_doc_worksheet() %}
1146+        {% macro cls(x) %}
1147+        {{ "control-select" if x == select else "control" }}
1148+        {% endmacro %}
1149+        {% macro backwards_text() %}{{ "../" if backwards else "" }}{% endmacro %}
1150+        <a title="Print this worksheet" class="print-link" onClick="print_worksheet()"><img border=0 src="/images/icon_print.gif" alt="Print">Print</a>
1151+        <a class="{{ cls('use') }}" title="Interactively use this worksheet" onClick="edit_worksheet();">Worksheet</a>       
1152+        <a class="{{ cls('edit') }}" title="Edit text version of this worksheet" href="{{ backwards_text() }}edit">Edit</a>
1153+        <a class="{{ cls('text') }}" title="View plain text version of this worksheet" href="{{ backwards_text() }}text">Text</a>
1154+        <a class="{{ cls('undo') }}" title="View changes to this worksheet over time" href="{{ backwards_text() }}revisions">Undo</a>
1155+        <a class="{{ cls('share') }}" title="Let others edit this worksheet" href="{{ backwards_text() }}share">Share</a>
1156+        <a class="{{ cls('publish') }}" title="Make this worksheet publicly viewable" href="{{ backwards_text() }}publish">Publish</a>
1157+        {% endif %}
1158+    </div>
1159+</div>
1160+<div class="hidden" id="slide_controls">
1161+    <div class="slideshow_control">
1162+        <a class="slide_arrow" onClick="slide_next()">&gt;</a>
1163+        <a class="slide_arrow" onClick="slide_last()">&gt;&gt;</a> <span class="vbar"></span>
1164+        <a class="cell_mode" onClick="cell_mode()">Exit</a>
1165+    </div>
1166+    <div class="slideshow_progress" id="slideshow_progress" onClick="slide_next()">
1167+        <div class="slideshow_progress_bar" id="slideshow_progress_bar">&nbsp;</div>
1168+        <div class="slideshow_progress_text" id="slideshow_progress_text">&nbsp;</div>
1169+    </div>
1170+    <div class="slideshow_control">
1171+        <a class="slide_arrow" onClick="slide_first()">&lt;&lt;</a>
1172+        <a class="slide_arrow" onClick="slide_prev()">&lt;</a>
1173+    </div>
1174+</div>
1175+{% block worksheet_main %}{% endblock %}
1176+{% endblock %}
1177+
1178diff -r 8afee2ec056a sagenb/data/sage/html/notebook/base_aux.html
1179--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
1180+++ b/sagenb/data/sage/html/notebook/base_aux.html      Sun Jan 03 03:07:50 2010 +0800
1181@@ -0,0 +1,8 @@
1182+{% extends "html/notebook/base.html" %}
1183+{# Base template for auxilliary pages (Edit, Text, etc.) #}
1184+
1185+{% block worksheet_main %}
1186+{% block before_sharebar %}{% endblock %}
1187+<div class="sharebar">{% block sharebar_title %}{% endblock %}</div>
1188+{% block after_sharebar %}{% endblock %}
1189+{% endblock %}
1190diff -r 8afee2ec056a sagenb/data/sage/html/notebook/beforepublish_window.html
1191--- a/sagenb/data/sage/html/notebook/beforepublish_window.html  Sat Oct 24 18:17:19 2009 +0800
1192+++ b/sagenb/data/sage/html/notebook/beforepublish_window.html  Sun Jan 03 03:07:50 2010 +0800
1193@@ -1,13 +1,6 @@
1194-{% extends "html/notebook/worksheet_page_template.html" %}
1195-{#
1196-INPUT:
1197-- worksheet - an instance of Worksheet
1198-- worksheet_filename - a string containing a worksheet's filename
1199-- username - a string containing a username
1200-- JSMATH - a boolean stating whether to include jsMath
1201-- JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE
1202-#}
1203+{% extends "html/notebook/base_aux.html" %}
1204 
1205+{% block page_id %}before-publish-page{% endblock %}
1206 {% block sharebar_title %}
1207 <p>You can publish your worksheet to the Internet, where anyone will be able to access and view it online.</p>
1208 
1209@@ -17,11 +10,13 @@
1210 
1211 <form method="get" action=".">
1212     <input type="hidden" name="yes" value="" />
1213-    <input type="submit" value="Yes" style="margin-left:10px" />
1214-    <input type="button" value="No" style="margin-left:5px" onClick="parent.location='../'" />
1215-    <br/>
1216-    <br/>
1217-    <input type="checkbox" name="auto" style="margin-left:13px" /> Automatically re-publish when changes are made
1218+    <div>
1219+        <button type="submit">Yes</button>
1220+        <a href="../"><button>No</button></a>
1221+    </div>
1222+    <div>
1223+        <input type="checkbox" name="auto" /> <label for="auto"> Automatically re-publish when changes are made</label>
1224+    </div>
1225 </form>
1226 {% endblock %}
1227 {% set select = "publish" %}
1228diff -r 8afee2ec056a sagenb/data/sage/html/notebook/cell.html
1229--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
1230+++ b/sagenb/data/sage/html/notebook/cell.html  Sun Jan 03 03:07:50 2010 +0800
1231@@ -0,0 +1,105 @@
1232+{#
1233+INPUT:
1234+
1235+        - ``cell`` -- Cell instance
1236+
1237+        - ``wrap`` - an integer stating column position to wrap lines. Defaults to
1238+          configuration if not given.
1239+
1240+        - ``div_wrap`` - a boolean stating whether to wrap ``div``.
1241+
1242+        - ``do_print`` - a boolean stating whether the HTML is for
1243+        print or not.
1244+#}
1245+{% if do_print %}
1246+    {% set wrap = 68 %}
1247+    {% set div_wrap = 68 %}
1248+{% endif %}
1249+{% set cell_cls = "cell_evaluated" if cell.evaluated() or do_print else "cell_not_evaluated" %}
1250+
1251+{% if div_wrap %}
1252+<div id="cell_outer_{{ cell.id() }}" class="cell_visible">
1253+    <div id="cell_{{ cell.id() }}" class="{{ cell_cls }}">
1254+{% endif %}
1255+        {% if 'hideall' not in cell.percent_directives() %}
1256+            {# input #}
1257+            <div class="insert_new_cell" id="insert_new_cell_before{{ cell.id() }}">
1258+            </div>
1259+            <script type="text/javascript">
1260+                $("#insert_new_cell_before{{ cell.id() }}").plainclick(function(e) {insert_new_cell_before({{ cell.id() }});});
1261+                $("#insert_new_cell_before{{ cell.id() }}").shiftclick(function(e) {insert_new_text_cell_before({{ cell.id() }});});
1262+            </script>
1263+            {% if 'hide' in cell.percent_directives() %}
1264+                {% set input_cls = 'cell_input_hide' %}
1265+            {% else %}
1266+                {% set input_cls = 'cell_input' %}
1267+            {% endif %}
1268+            {% if do_print %}
1269+                <div class="cell_input_print">
1270+                     {{ cell.input_text().rstrip()|escape + '&nbsp;' }}
1271+                </div>
1272+            {% else %}
1273+                <textarea class="cell_input" rows="{{ max(1, number_of_rows(t.strip(), 80)) }}"
1274+                          cols="80"
1275+                          id="cell_input_{{ cell.id() }}"
1276+                          {# TODO: Migrate these 'on' handlers to a .js file #}
1277+                          onKeyPress="return input_keypress({{ cell.id() }}, event);"
1278+                          onKeyDown="return input_keydown({{ cell.id() }},event);"
1279+                          onKeyUp="return input_keyup({{ cell.id() }}, event);"
1280+                          onBlur="cell_blur({{ cell.id() }}); return true;"
1281+                          onFocus="cell_focused(this, {{ cell.id() }}); return true;">{{ cell.input_text().rstrip() }}</textarea>
1282+                <a href="javascript:evaluate_cell({{ cell.id() }},0)"
1283+                   class="eval_button"
1284+                   id="eval_button{{ cell.id() }}"
1285+                   alt="Click here or press shift-return to evaluate">
1286+                    evaluate
1287+                </a>
1288+            {% endif %}
1289+            {# end input #}
1290+
1291+            <div id='introspect_div_{{ cell.id() }}' class='introspection'></div>
1292+        {% endif %}
1293+
1294+        {% if do_print and self.cell_output_type() == 'hidden' %}
1295+        <pre>
1296+        </pre>
1297+        {% else %}
1298+        {% set output_cls = 'cell_div_output_running' if cell.computing() else 'cell_div_output_' + cell.cell_output_type() %}
1299+        <div class="cell_output_div">
1300+            <table class="cell_output_box">
1301+                <tr>
1302+                    <td class="cell_number" id="cell_number_{{ cell.id() }}"
1303+                        {{ '' if do_print else 'onClick="cycle_cell_output_type(%s);"'|format(cell.id()) }} >
1304+                        {% for i in range(7) %}&nbsp;{% endfor %}
1305+                    </td>
1306+                    <td class="output_cell">
1307+                        <div class="{{ output_cls }}" id="cell_div_output_{{ cell.id() }}">
1308+                            <div class="cell_output_{{ "print_" if do_print else '' }}{{ cell.cell_output_type() }}"
1309+                                id="cell_output_{{ cell.id() }}">
1310+                                {% if cell.introspect() %}
1311+                                    {{ cell.output_text(0, html=true) }}
1312+                                {% else %}
1313+                                    {{ cell.output_text(wrap, html=true) }}
1314+                                {% endif %}
1315+                            </div>
1316+                            {% if not do_print %}
1317+                                <div class="cell_output_{{ 'print_' if do_print else '' }}nowrap_{{ cell.cell_output_type() }}"
1318+                                     id="cell_output_nowrap_{{ cell.id() }}">
1319+                                    {{ cell.output_text(0, html=true) }}
1320+                                </div>
1321+                            {% endif %}
1322+                                <div class="cell_output_html_{{ cell.cell_output_type() }}"
1323+                                     id="cell_output_html_{{ cell.id() }}">
1324+                                    {{ cell.output_html() }}
1325+                                </div>
1326+                        </div>
1327+                    </td>
1328+                </tr>
1329+            </table>
1330+        </div>
1331+        {% endif %}
1332+       
1333+{% if div_wrap %}
1334+    </div>
1335+</div>
1336+{% endif %}
1337diff -r 8afee2ec056a sagenb/data/sage/html/notebook/debug_window.html
1338--- a/sagenb/data/sage/html/notebook/debug_window.html  Sat Oct 24 18:17:19 2009 +0800
1339+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
1340@@ -1,7 +0,0 @@
1341-
1342-<div class='debug_window'>
1343-    <div class='debug_output'><pre id='debug_output'></pre></div>
1344-    <textarea rows=5 id='debug_input' class='debug_input'
1345-              onKeyPress='return debug_keypress(event);'
1346-              onFocus='debug_focus();' onBlur='debug_blur();'></textarea>
1347-</div>
1348\ No newline at end of file
1349diff -r 8afee2ec056a sagenb/data/sage/html/notebook/doc_page.html
1350--- a/sagenb/data/sage/html/notebook/doc_page.html      Sat Oct 24 18:17:19 2009 +0800
1351+++ b/sagenb/data/sage/html/notebook/doc_page.html      Sun Jan 03 03:07:50 2010 +0800
1352@@ -1,4 +1,4 @@
1353-{% extends "html/notebook/index.html" %}
1354+{% extends "html/notebook/worksheet_page.html" %}
1355 
1356 {% block pre_main_css %}
1357 <link type="text/css" rel="stylesheet" href="_static/default.css" media="screen" />
1358diff -r 8afee2ec056a sagenb/data/sage/html/notebook/download_or_delete_datafile.html
1359--- a/sagenb/data/sage/html/notebook/download_or_delete_datafile.html   Sat Oct 24 18:17:19 2009 +0800
1360+++ b/sagenb/data/sage/html/notebook/download_or_delete_datafile.html   Sun Jan 03 03:07:50 2010 +0800
1361@@ -1,19 +1,16 @@
1362-{% extends "html/notebook/worksheet_page_template.html" %}
1363+{% extends "html/notebook/base_aux.html" %}
1364 {#
1365 INPUT:
1366 - worksheet - an instance of Worksheet
1367-- worksheet_filename - a string containing a worksheet's filename
1368 - username - a string containing a username
1369-- active_worksheets - a list of the Worksheet instances that are active for username
1370 - filename_ - the name of the file
1371-- path - the path to the file
1372 - file_is_image - a boolean stating whether the file is an image
1373 - file_is_text - a boolean stating whether the file is a text file
1374 - text_file_content - a string containing the content of a text file
1375-- JSMATH - a boolean stating whether to include jsMath
1376-- JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE
1377 #}
1378 
1379+{% set path = "/home/%s/data/%s"|format(worksheet.filename(), filename_) %}
1380+
1381 {% block sharebar_title %}
1382 Data file: {{ filename_ }}
1383 {% endblock %}
1384@@ -21,7 +18,7 @@
1385 {% block after_sharebar %}
1386 <p>You may download <a href="{{ path }}">{{ filename_ }}</a> or create a linked copy to the worksheet <select onchange="go_option(this);" class="worksheet">
1387 <option selected>select worksheet</option>
1388-{% for worksheet in active_worksheets %}
1389+{% for worksheet in notebook.active_worksheets_for(username) %}
1390     <option value='link_datafile("{{ worksheet.filename() }}","{{ filename_ }}")'>{{ worksheet.name() }}</option>
1391 {% endfor %}
1392 </select> or <a href="/home/{{ worksheet.filename() }}/datafile?name={{ filename_ }}&action=delete">delete {{ filename_ }}.</a></p>
1393diff -r 8afee2ec056a sagenb/data/sage/html/notebook/edit_window.html
1394--- a/sagenb/data/sage/html/notebook/edit_window.html   Sat Oct 24 18:17:19 2009 +0800
1395+++ b/sagenb/data/sage/html/notebook/edit_window.html   Sun Jan 03 03:07:50 2010 +0800
1396@@ -1,23 +1,18 @@
1397-{% extends "html/notebook/worksheet_page_template.html" %}
1398-{#
1399-INPUT:
1400-- worksheet - an instance of Worksheet
1401-- worksheet_filename - a string containing a worksheet's filename
1402-- username - a string containing a username
1403-- text - a string containing the text of the worksheet
1404-- n_lines - number of lines of the text of the worksheet
1405-- JSMATH - a boolean stating whether to include jsMath
1406-- JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE
1407-#}
1408+{% extends "html/notebook/base_aux.html" %}
1409 
1410-{% block sharebar_title %}
1411-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">
1412-{% endblock %}
1413-{% set select = "edit" %}
1414+{% block page_id %}edit-page{% endblock %}
1415 
1416 {% block before_sharebar %}
1417 <form method="post" action="save" enctype="multipart/form-data">
1418 {% endblock %}
1419+   
1420+{% block sharebar_title %}
1421+    <span>Edit plain text</span>
1422+    <button type="submit" name="button_save" id="button_save">Save Changes</button>
1423+    <button type="submit" name="button_cancel">Cancel</button>
1424+{% endblock %}
1425+{% set select = "edit" %}
1426+
1427 {% block after_sharebar %}
1428 <script type="text/javascript">
1429     function save_worksheet() {
1430@@ -25,6 +20,6 @@
1431     function save_worksheet_and_close() {
1432     }
1433 </script>
1434-    <textarea class="plaintextedit" id="cell_intext" name="textfield" rows="{{ n_lines }}">{{ text }}</textarea>
1435+    <textarea class="plaintextedit" id="cell_intext" name="textfield" rows="{{ worksheet.edit_text().count("\n")+1 }}">{{ worksheet.edit_text()|escape }}</textarea>
1436 </form>
1437 {% endblock %}
1438diff -r 8afee2ec056a sagenb/data/sage/html/notebook/guest_top_bar_and_worksheet.html
1439--- a/sagenb/data/sage/html/notebook/guest_top_bar_and_worksheet.html   Sat Oct 24 18:17:19 2009 +0800
1440+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
1441@@ -1,59 +0,0 @@
1442-
1443-{#
1444-INPUT:
1445-- original_worksheet - an instance of Worksheet
1446-- worksheet - an instance of Worksheet
1447-- notebook - an instance of Notebook which contains worksheet
1448-- worksheet_html - a string containing the html for the worksheet
1449-- username - a string containing a username
1450-#}
1451-{% if original_worksheet.is_collaborator(username) or original_worksheet.is_owner(username) %}
1452-    {% set edit_text = "Edit this." %}
1453-    {% set url       = "edit_published_page" %}
1454-{% elif notebook.user_is_guest(username) %}
1455-    {% set edit_text = "Log in to edit a copy." %}
1456-    {% set url       = "/" %}
1457-{% else %}
1458-    {% set edit_text = "Edit a copy." %}
1459-    {% set url       = "edit_published_page" %}
1460-{% endif %}
1461-
1462-{% set download_name = worksheet.download_name() %}
1463-
1464-<a class="usercontrol" href="{{ url }}">{{ edit_text }}</a>
1465-&nbsp;&nbsp;<a class="usercontrol" href="download/{{ download_name }}.sws">Download.</a>
1466-&nbsp;&nbsp;<span class="ratingmsg">
1467-    {% if worksheet.rating() != -1 %}
1468-        <a class="usercontrol" href="rating_info">
1469-            This page is rated {{ "%.1f"|format(worksheet.rating()) }}.
1470-        </a>
1471-    {% endif %}
1472-    {% if not notebook.user_is_guest(username)
1473-        and not worksheet.is_publisher(username) %}
1474-        &nbsp;&nbsp;
1475-        <span class="usercontrol">
1476-            {{ "Rerate" if worksheet.is_rater(username) else "Rate" }} it:
1477-        </span>
1478-        {% for i in range(5) %}
1479-            <a class="usercontrol"
1480-               onClick="rate_worksheet({{ i }})">
1481-                &nbsp;{{ i }}&nbsp;
1482-            </a>
1483-        {% endfor %}
1484-            &nbsp;&nbsp; <input name="rating_comment" id="rating_comment"></input>
1485-    {% endif %}
1486-</span>
1487-<span class="pubmsg">
1488-    <a href="/pub/">Other published documents...</a>
1489-</span>
1490-<hr class="usercontrol" />
1491-<h1 align="center" class="title">{{ worksheet.name() }}</h1>
1492-<h2 align="center">{{ worksheet.html_time_since_last_edited() }}</h2>
1493-{{ worksheet_html }}
1494-<hr class="usercontrol" />
1495-{% for i in range(10) %}
1496-&nbsp;
1497-{% endfor %}
1498-
1499-
1500-
1501diff -r 8afee2ec056a sagenb/data/sage/html/notebook/guest_worksheet_page.html
1502--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
1503+++ b/sagenb/data/sage/html/notebook/guest_worksheet_page.html  Sun Jan 03 03:07:50 2010 +0800
1504@@ -0,0 +1,62 @@
1505+{% extends "html/notebook/base.html" %}
1506+{#
1507+INPUT:
1508+- worksheet - an instance of Worksheet
1509+- notebook - an instance of Notebook which contains worksheet
1510+- username - a string containing a username
1511+#}
1512+
1513+{% block page_id %}guest-worksheet-page{% endblock %}
1514+
1515+{% set original_worksheet = worksheet.worksheet_that_was_published() %}
1516+{% if original_worksheet.is_collaborator(username) or original_worksheet.is_owner(username) %}
1517+    {% set edit_text = "Edit this." %}
1518+    {% set url       = "edit_published_page" %}
1519+{% elif notebook.user_is_guest(username) %}
1520+    {% set edit_text = "Log in to edit a copy." %}
1521+    {% set url       = "/" %}
1522+{% else %}
1523+    {% set edit_text = "Edit a copy." %}
1524+    {% set url       = "edit_published_page" %}
1525+{% endif %}
1526+
1527+{% set download_name = worksheet.download_name() %}
1528+
1529+{% block body %}
1530+<ul class="controls">
1531+    <li><a href="{{ url }}">{{ edit_text }}</a></li>
1532+    <li><a href="download/{{ download_name }}.sws">Download.</a></li>
1533+    {% if true or worksheet.rating() != -1 or
1534+       not (notebook.user_is_guest(username) or worksheet.is_publisher(username)) %}
1535+    <li>
1536+        {% if true or worksheet.rating() != -1 %}
1537+            <a class="usercontrol" href="rating_info">
1538+                This page is rated {{ "%.1f"|format(worksheet.rating()) }}.
1539+            </a>
1540+        {% endif %}
1541+        {% if true or not (notebook.user_is_guest(username) or worksheet.is_publisher(username)) %}
1542+            <span>
1543+                {{ "Rerate" if worksheet.is_rater(username) else "Rate" }} it:
1544+            </span>
1545+            {% for i in range(5) %}
1546+                <a class="usercontrol"
1547+                   onClick="rate_worksheet({{ i }})">{{ i }}</a>
1548+            {% endfor %}
1549+                &nbsp;&nbsp; <input name="rating_comment" id="rating_comment"></input>
1550+        {% endif %}
1551+    </li>
1552+    {% endif %}
1553+    <li><a href="/pub/">Other published documents...</a></li>
1554+</ul>
1555+<hr class="usercontrol" />
1556+<h1 class="title">{{ worksheet.name() }}</h1>
1557+<h2 class="lastedit">{{ worksheet.html_time_since_last_edited() }}</h2>
1558+{{ worksheet.html(do_print=false, publish=true) }}
1559+<hr class="usercontrol" />
1560+{% for i in range(10) %}
1561+&nbsp;
1562+{% endfor %}
1563+{% endblock %}
1564+
1565+
1566+
1567diff -r 8afee2ec056a sagenb/data/sage/html/notebook/head.tmpl
1568--- a/sagenb/data/sage/html/notebook/head.tmpl  Sat Oct 24 18:17:19 2009 +0800
1569+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
1570@@ -1,64 +0,0 @@
1571-{#
1572-INPUT:
1573-- worksheet - an instance of Worksheet
1574-- worksheet_filename - a string containing a worksheet's filename
1575-- username - a string containing a user's name
1576-- JSMATH - a boolean stating whether to include jsMath
1577-- JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE
1578-  #}
1579-{% macro common_title(worksheet_filename, worksheet) %}
1580-    {% if worksheet_filename %}
1581-        {{ worksheet.name() }} (Sage)
1582-    {% else %}
1583-        Sage Notebook | Welcome
1584-    {% endif %}
1585-{% endmacro %}
1586-
1587-{% macro common_javascript(worksheet, worksheet_filename, username, JSMATH, JEDITABLE_TINYMCE) %}
1588-<!-- jQuery UI - interacts, widgets, drag-drop, etc. -->
1589-<link rel="stylesheet" href="/javascript/jqueryui/css/sage/jquery-ui-1.7.2.custom.css" />
1590-<script type="text/javascript" src="/javascript/jqueryui/js/jquery-ui-1.7.2.custom.min.js"></script>
1591-
1592-<!-- jQuery plugins - color pickers, shift-click, AJAX forms, IE fixes -->
1593-<link rel="stylesheet" href="/javascript/jquery/plugins/farbtastic/farbtastic.css" type="text/css" />
1594-<script type="text/javascript" src="/javascript/jquery/plugins/farbtastic/farbtastic.min.js"></script>
1595-<script type="text/javascript" src="/javascript/jquery/plugins/extendedclick/jquery.event.extendedclick.min.js"></script>
1596-<script type="text/javascript" src="/javascript/jquery/plugins/form/jquery.form.min.js"></script>
1597-<script type="text/javascript" src="/javascript/jquery/plugins/jquery.bgiframe.min.js"></script>
1598-<link rel="stylesheet" href="/javascript/jquery/plugins/jpicker/css/jPicker-1.0.11.css" type="text/css" />
1599-<script type="text/javascript" src="/javascript/jquery/plugins/jpicker/jpicker-1.0.11.min.js"></script>
1600-<link rel="stylesheet" media="screen" type="text/css" href="/javascript/jquery/plugins/colorpicker/css/colorpicker.css" />
1601-<script type="text/javascript" src="/javascript/jquery/plugins/colorpicker/js/colorpicker.min.js"></script>
1602-
1603-<script type="text/javascript" src="/javascript/sage/main.js"></script>
1604
1605-{% if JSMATH %}
1606-<!-- jsMath - typeset mathematics -->
1607-<script type="text/javascript" src="/javascript/sage/jsmath.js"></script>
1608-{% endif %}
1609-
1610-<!-- Sage3d - accelerated 3D graphics -->
1611-<script type="text/javascript" src="/javascript/sage3d/sage3d.js"></script>
1612-
1613-<!-- Jmol - embedded 3D graphics -->
1614-<script type="text/javascript" src="/java/jmol/appletweb/Jmol.js"></script>
1615-<!-- This must stay in head -->
1616-<script>jmolInitialize("/java/jmol");jmolSetCallback("menuFile","/java/jmol/appletweb/SageMenu.mnu");</script>
1617-
1618-{% if JEDITABLE_TINYMCE and not worksheet.docbrowser() and not worksheet.is_published() %}
1619-<!-- TinyMCE and jEditable - in-place editing of text cells -->
1620-<script type="text/javascript" src="/javascript/tiny_mce/tiny_mce.js"></script>
1621-<script type="text/javascript" src="/javascript/jquery/plugins/jeditable/jquery.jeditable.mini.js" charset="utf-8"></script>
1622-<script type="text/javascript" src="/javascript/sage/tinymce.js"></script>
1623-{% endif %}
1624-
1625-<script type="text/javascript">user_name= "{{ username }}";</script>
1626-{% if worksheet_filename %}
1627-<script  type="text/javascript">
1628-  worksheet_filename="{{ worksheet_filename }}";
1629-  worksheet_name="{{ worksheet.name() }}";
1630-  server_ping_while_alive();
1631-</script>
1632-{% endif %}
1633-
1634-{% endmacro %}
1635diff -r 8afee2ec056a sagenb/data/sage/html/notebook/index.html
1636--- a/sagenb/data/sage/html/notebook/index.html Sat Oct 24 18:17:19 2009 +0800
1637+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
1638@@ -1,76 +0,0 @@
1639-{% extends "html/base.html" %}
1640- {#
1641- INPUT:
1642- - worksheet - an instance of Worksheet
1643- - worksheet_filename - a string containing a worksheet's filename
1644- - notebook - an instance of Notebook which contains worksheet
1645- - username  - a string containing a username
1646- - show_debug - a boolean stating whether to show debug information
1647- - JSMATH - a boolean stating whether to include jsMath
1648- - JSMATH_IMAGE_FONTS - a boolean stating whether to include jsMath iamage fonts
1649- - JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE
1650- - sage_jsmath_macros - an array containing strings of Javascript of Sage macros for jsMath
1651- - do_print - a boolean stating whether the file is for print mode
1652- - worksheet_html - a string containing the html for a worksheet
1653- - select    - a string containing the control that is selected
1654- - backwards - a boolean
1655- - warn - boolean stating whether to warn that another user is viewing
1656-          the worksheet
1657-#}
1658-
1659-{% if not select %}
1660-    {% set select = none %}
1661-{% endif %}
1662-
1663-{% if not backwards %}
1664-    {% set backwards = false %}
1665-{% endif %}
1666-   
1667-{% include "html/notebook/head.tmpl"%}
1668-
1669-{% block title %}
1670-{{ common_title(worksheet_filename, worksheet) }}
1671-{% endblock %}
1672-   
1673-{% block css %}main{% endblock %}
1674-
1675-{% block javascript %}
1676-{{ common_javascript(worksheet, worksheet_filename, username, JSMATH, JEDITABLE_TINYMCE) }}
1677-{% endblock %}
1678-
1679-{# TODO: Hack until the template restructuring #}
1680-{% block body_attrs %}
1681-{% if worksheet.is_published() or notebook.user_is_guest(username) %}
1682-        class="worksheet-online" onLoad="initialize_the_notebook();"
1683-    {% else %}
1684-        class="worksheet-online" onLoad="initialize_the_notebook();" id="user-worksheet-index"
1685-{% endif %}
1686-{% endblock %}
1687-
1688-
1689-{% block body %}
1690-{% if worksheet.is_published() or notebook.user_is_guest(username) %}
1691-    {% set original_worksheet = worksheet.worksheet_that_was_published() %}
1692-    {% include "html/notebook/guest_top_bar_and_worksheet.html" %}
1693-{% else %}
1694-    {% include "html/notebook/top_bar_and_worksheet.html" %}
1695-{% endif %}
1696-{% if not worksheet %}
1697-    </td></tr></table></span>
1698-{% endif %}
1699-{% if worksheet.is_only_viewer(username) %}
1700-    <script type="text/javascript">worksheet_locked=true;</script>
1701-{% else %}
1702-    <script type="text/javascript">worksheet_locked=false;</script>
1703-{% endif %}
1704-{% if worksheet.computing() %}
1705-    <!-- Set the update checking back in motion. -->
1706-    <script type="text/javascript">
1707-        active_cell_list = {{ worksheet.queue_id_list() }};
1708-        for(var i = 0; i < active_cell_list.length; i++) {
1709-            cell_set_running(active_cell_list[i]);
1710-        }
1711-        start_update_check();
1712-    </script>
1713-{% endif %}
1714-{% endblock %}
1715diff -r 8afee2ec056a sagenb/data/sage/html/notebook/plain_text_window.html
1716--- a/sagenb/data/sage/html/notebook/plain_text_window.html     Sat Oct 24 18:17:19 2009 +0800
1717+++ b/sagenb/data/sage/html/notebook/plain_text_window.html     Sun Jan 03 03:07:50 2010 +0800
1718@@ -1,13 +1,4 @@
1719-{% extends "html/notebook/worksheet_page_template.html" %}
1720-{#
1721-INPUT:
1722-- worksheet - an instance of Worksheet
1723-- worksheet_filename - a string containing a worksheet's filename
1724-- username - a string containing a username
1725-- plain_text - a string containing the plain text version
1726-- JSMATH - a boolean stating whether to include jsMath
1727-- JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE
1728-#}
1729+{% extends "html/notebook/base_aux.html" %}
1730 
1731 {% block sharebar_title %}
1732 View plain text
1733@@ -16,5 +7,5 @@
1734 {% set select = "text" %}
1735 
1736 {% block after_sharebar %}
1737-<pre class="plaintext" id="cell_intext" name="textfield">{{ plain_text }}</pre>
1738+<pre class="plaintext" id="cell_intext" name="textfield">{{ worksheet.plain_text(prompts=true, banner=false)|escape|trim }}</pre>
1739 {% endblock %}
1740diff -r 8afee2ec056a sagenb/data/sage/html/notebook/plain_text_worksheet.html
1741--- a/sagenb/data/sage/html/notebook/plain_text_worksheet.html  Sat Oct 24 18:17:19 2009 +0800
1742+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
1743@@ -1,14 +0,0 @@
1744-
1745-{#
1746-INPUT:
1747-     - worksheet_name - a string containing a worksheet's name
1748-     - worksheet_plain_text - a string containing the plain text version of a worksheet
1749-#}
1750-<head>
1751-    <title>Sage Worksheet: {{ worksheet_name }}</title>
1752-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
1753-</head>
1754-<body>
1755-    <h1><a href=".">Sage Worksheet: %s</a></h1>
1756-    <pre>{{ worksheet_plain_text }}</pre>
1757-</body>
1758\ No newline at end of file
1759diff -r 8afee2ec056a sagenb/data/sage/html/notebook/print_worksheet.html
1760--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
1761+++ b/sagenb/data/sage/html/notebook/print_worksheet.html       Sun Jan 03 03:07:50 2010 +0800
1762@@ -0,0 +1,10 @@
1763+{% extends "html/notebook/base.html" %}
1764+
1765+{% block page_id %}print-page{% endblock %}
1766+
1767+{% block body %}
1768+<h1>{{ worksheet.name() }}</h1>
1769+{{ worksheet.html(do_print=true) }}
1770+{% endblock %}
1771+
1772+
1773\ No newline at end of file
1774diff -r 8afee2ec056a sagenb/data/sage/html/notebook/render_cell.tmpl
1775--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
1776+++ b/sagenb/data/sage/html/notebook/render_cell.tmpl   Sun Jan 03 03:07:50 2010 +0800
1777@@ -0,0 +1,99 @@
1778+{% macro render_cell(cell, wrap, div_wrap, do_print) %}
1779+{#
1780+INPUT:
1781+        - ``wrap`` - an integer stating column position to wrap lines. Defaults to
1782+          configuration if not given.
1783+
1784+        - ``div_wrap`` - a boolean stating whether to wrap ``div``.
1785+
1786+        - ``do_print`` - a boolean stating whether the HTML is for
1787+        print or not.
1788+#}
1789+{% if do_print %}
1790+    {% set wrap = 68 %}
1791+    {% set div_wrap = 68 %}
1792+{% endif %}
1793+{% set cell_cls = "cell_evaluated" if cell.evaluated() or do_print else "cell_not_evaluated" %}
1794+
1795+{% if div_wrap %}
1796+<div id="cell_outer_{{ cell.id() }}" class="cell_visible">
1797+    <div id="cell_{{ cell.id() }}" class="{{ cell_cls }}">
1798+{% endif %}
1799+        {% if 'hideall' not in cell.percent_directives() %}
1800+            {# input #}
1801+            {% if 'hide' in cell.percent_directives() %}
1802+                {% set input_cls = 'cell_input_hide' %}
1803+            {% else %}
1804+                {% set input_cls = 'cell_input' %}
1805+            {% endif %}
1806+            {% if do_print %}
1807+                <div class="cell_input_print">
1808+                     {{ cell.input_text().rstrip()|escape + '&nbsp;' }}
1809+                </div>
1810+            {% else %}
1811+                <textarea class="cell_input" rows="{{ max(1, number_of_rows(t.strip(), 80)) }}"
1812+                          cols="80"
1813+                          id="cell_input_{{ cell.id() }}"
1814+                          {# TODO: Migrate these 'on' handlers to a .js file #}
1815+                          onKeyPress="return input_keypress({{ cell.id() }}, event);"
1816+                          onKeyDown="return input_keydown({{ cell.id() }},event);"
1817+                          onKeyUp="return input_keyup({{ cell.id() }}, event);"
1818+                          onBlur="cell_blur({{ cell.id() }}); return true;"
1819+                          onFocus="cell_focused(this, {{ cell.id() }}); return true;">{{ cell.input_text().rstrip() }}</textarea>
1820+                <a href="javascript:evaluate_cell({{ cell.id() }},0)"
1821+                   class="eval_button"
1822+                   id="eval_button{{ cell.id() }}"
1823+                   alt="Click here or press shift-return to evaluate">
1824+                    evaluate
1825+                </a>
1826+            {% endif %}
1827+            {# end input #}
1828+
1829+            <div id='introspect_div_{{ cell.id() }}' class='introspection'></div>
1830+        {% endif %}
1831+
1832+        {% if do_print and self.cell_output_type() == 'hidden' %}
1833+        <pre>
1834+        </pre>
1835+        {% else %}
1836+        {% set output_cls = 'cell_div_output_running' if cell.computing() else 'cell_div_output_' + cell.cell_output_type() %}
1837+        <div class="cell_output_div">
1838+            <table class="cell_output_box">
1839+                <tr>
1840+                    <td class="cell_number" id="cell_number_{{ cell.id() }}"
1841+                        {{ '' if do_print else 'onClick="cycle_cell_output_type(%s);"'|format(cell.id()) }} >
1842+                        {% for i in range(7) %}&nbsp;{% endfor %}
1843+                    </td>
1844+                    <td class="output_cell">
1845+                        <div class="{{ output_cls }}" id="cell_div_output_{{ cell.id() }}">
1846+                            <div class="cell_output_{{ "print_" if do_print else '' }}{{ cell.cell_output_type() }}"
1847+                                id="cell_output_{{ cell.id() }}">
1848+                                {% if cell.introspect() %}
1849+                                    {{ cell.output_text(0, html=true) }}
1850+                                {% else %}
1851+                                    {{ cell.output_text(wrap, html=true) }}
1852+                                {% endif %}
1853+                            </div>
1854+                            {% if not do_print %}
1855+                                <div class="cell_output_{{ 'print_' if do_print else '' }}nowrap_{{ cell.cell_output_type() }}"
1856+                                     id="cell_output_nowrap_{{ cell.id() }}">
1857+                                    {{ cell.output_text(0, html=true) }}
1858+                                </div>
1859+                            {% endif %}
1860+                                <div class="cell_output_html_{{ cell.cell_output_type() }}"
1861+                                     id="cell_output_html_{{ cell.id() }}">
1862+                                    {{ cell.output_html() }}
1863+                                </div>
1864+                        </div>
1865+                    </td>
1866+                </tr>
1867+            </table>
1868+        </div>
1869+        {% endif %}
1870+       
1871+{% if div_wrap %}
1872+    </div>
1873+</div>
1874+{% endif %}
1875+
1876+{% endmacro %}
1877diff -r 8afee2ec056a sagenb/data/sage/html/notebook/render_worksheet.tmpl
1878--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
1879+++ b/sagenb/data/sage/html/notebook/render_worksheet.tmpl      Sun Jan 03 03:07:50 2010 +0800
1880@@ -0,0 +1,28 @@
1881+{% include "html/notebook/render_cell.tmpl" %}
1882+{% macro render_worksheet(worksheet, do_print, publish) %}
1883+
1884+{% set wrap = conf['word_wrap_cols'] %}
1885+{% if not publish %}
1886+    {% set publish = worksheet.is_published() %}
1887+{% endif %}
1888+
1889+<div class="cell_input_active" id="cell_resizer"></div>
1890+{% if not publish %}
1891+<div class="worksheet_cell_list" id="worksheet_cell_list">
1892+{% endif %}
1893+
1894+{% for cell in worksheet.cell_list() %}
1895+{{ render_cell(cell, wrap, true, do_print or publish) }}
1896+{% endfor %}
1897+
1898+{% if not do_print and not publish %}
1899+</div>
1900+<div class="insert_new_cell" id="insert_last_cell"></div>
1901+<script type="text/javascript">
1902+$(document).ready(function() {                                 
1903+    $("#insert_last_cell").plainclick(function(e) {insert_new_cell_after(cell_id_list[cell_id_list.length-1]);});
1904+    $("#insert_last_cell").shiftclick(function(e) {insert_new_text_cell_after(cell_id_list[cell_id_list.length-1]);});
1905+});
1906+</script>
1907+{% endif %}
1908+{% endmacro %}
1909diff -r 8afee2ec056a sagenb/data/sage/html/notebook/slide_controls.html
1910--- a/sagenb/data/sage/html/notebook/slide_controls.html        Sat Oct 24 18:17:19 2009 +0800
1911+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
1912@@ -1,23 +0,0 @@
1913-
1914-<div class="hidden" id="slide_controls">
1915-    <div class="slideshow_control">
1916-        <a class="slide_arrow" onClick="slide_next()">&gt;</a>
1917-        <a class="slide_arrow" onClick="slide_last()">&gt;&gt;</a> <span class="vbar"></span>
1918-        <a class="cell_mode" onClick="cell_mode()">Exit</a>
1919-    </div>
1920-    <div class="slideshow_progress" id="slideshow_progress" onClick="slide_next()">
1921-        <div class="slideshow_progress_bar" id="slideshow_progress_bar">&nbsp;</div>
1922-        <div class="slideshow_progress_text" id="slideshow_progress_text">&nbsp;</div>
1923-    </div>
1924-    <div class="slideshow_control">
1925-        <a class="slide_arrow" onClick="slide_first()">&lt;&lt;</a>
1926-        <a class="slide_arrow" onClick="slide_prev()">&lt;</a>
1927-    </div>
1928-</div>
1929-
1930-
1931-
1932-
1933-
1934-
1935-
1936diff -r 8afee2ec056a sagenb/data/sage/html/notebook/specific_revision.html
1937--- a/sagenb/data/sage/html/notebook/specific_revision.html     Sat Oct 24 18:17:19 2009 +0800
1938+++ b/sagenb/data/sage/html/notebook/specific_revision.html     Sun Jan 03 03:07:50 2010 +0800
1939@@ -1,17 +1,4 @@
1940-{% extends "html/notebook/worksheet_page_template.html" %}
1941-{#
1942-INPUT:
1943-- worksheet - an instance of Worksheet
1944-- worksheet_filename - a string containing a worksheet's filename
1945-- username - a string containing a username
1946-- rev - this revision's key
1947-- prev_rev - the previous revision's key
1948-- next_rev - the next revision's key
1949-- time_ago - a string containing the time since revision
1950-- body_worksheet_html - the body html of the worksheet
1951-- JSMATH - a boolean stating whether to include jsMath
1952-- JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE
1953-#}
1954+{% extends "html/notebook/base_aux.html" %}
1955 
1956 {% set select = "revisions" %}
1957 {% block sharebar_title %}
1958@@ -40,7 +27,7 @@
1959 {% block after_sharebar %}
1960 {{ actions() }}
1961 <div id="revision-data">
1962-    {{ body_worksheet_html }}
1963+    {{ worksheet.html(do_print=true, publish=true) }}
1964 </div>
1965 {{ actions() }}
1966 <script type="text/javascript">
1967diff -r 8afee2ec056a sagenb/data/sage/html/notebook/text_cell.html
1968--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
1969+++ b/sagenb/data/sage/html/notebook/text_cell.html     Sun Jan 03 03:07:50 2010 +0800
1970@@ -0,0 +1,56 @@
1971+{#
1972+INPUT:
1973+
1974+- cell -- Cell instance
1975+
1976+- wrap -- number of columns to wrap
1977+
1978+- do_print -- whether to display for printing
1979+
1980+- do_math_parse -- whether to parse jsMath
1981+
1982+- editing -- whether user is editing the cell
1983+#}
1984+<span id="cell_outer_{{ cell.id() }}">
1985+
1986+
1987+    {% if not do_print %}
1988+    <div class="insert_new_cell" id="insert_new_cell_before{{ cell.id() }}">
1989+    </div>
1990+    <script type="text/javascript">
1991+        $("#insert_new_cell_before{{ cell.id() }}").plainclick(function(e) {insert_new_cell_before({{ cell.id() }});});
1992+        $("#insert_new_cell_before{{ cell.id() }}").shiftclick(function(e) {insert_new_text_cell_before({{ cell.id() }});});
1993+    </script>
1994+    {% endif %}
1995+    <div class="text_cell" id="cell_text_{{ cell.id() }}">
1996+        {% if do_math_parse %}
1997+            {{ cell.plain_text()|math_parse }}
1998+        {% else %}
1999+            {{ cell.plain_text() }}
2000+    {% endif %}
2001+    </div>
2002+{% if JEDITABLE_TINYMCE and not cell.worksheet().is_published() and not cell.worksheet().docbrowser() and not do_print %}
2003+    <script type="text/javascript">
2004+        $("#cell_text_{{ cell.id() }}").unbind('dblclick').editable(function(value,settings) {
2005+            evaluate_text_cell_input({{ cell.id() }},value,settings);
2006+            return(value);
2007+            },
2008+            {
2009+                tooltip   : "",
2010+                placeholder : "",
2011+        //      type   : 'textarea',
2012+                type   : 'mce',
2013+                onblur : 'ignore',
2014+                select : false,
2015+                submit : 'Save changes',
2016+                cancel : 'Cancel changes',
2017+                event  : "dblclick",
2018+                style  : "inherit",
2019+        });
2020+    </script>
2021+{% endif %}
2022+
2023+{% if editing and not do_print %}
2024+<script>$("#cell_text_{{ cell.id() }}").trigger('dblclick');</script>
2025+{% endif %}
2026+</span>
2027\ No newline at end of file
2028diff -r 8afee2ec056a sagenb/data/sage/html/notebook/top_bar_and_worksheet.html
2029--- a/sagenb/data/sage/html/notebook/top_bar_and_worksheet.html Sat Oct 24 18:17:19 2009 +0800
2030+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
2031@@ -1,21 +0,0 @@
2032-{#
2033-INPUT:
2034-- username - a string containing a username
2035-- worksheet_filename - a string containing a worksheet's filename
2036-- worksheet_html - a string containing the html for a worksheet
2037-- show_debug - a boolean stating whether to show debug information
2038-  #}
2039-{% include "html/notebook/worksheet_topbar.tmpl" %}
2040-{% set toggle=true %}
2041-{% include "html/top_bar.html" %}
2042-{% if worksheet.filename() %}
2043-    {{ worksheet_topbar(worksheet, "use", username) }}
2044-{% endif %}
2045-{% if show_debug %}
2046-    {% include "html/notebook/debug_window.html" %}
2047-{% endif %}
2048-
2049-<div class="worksheet" id="worksheet">
2050-    {{ worksheet_html }}
2051-</div>
2052-
2053diff -r 8afee2ec056a sagenb/data/sage/html/notebook/upload_data_window.html
2054--- a/sagenb/data/sage/html/notebook/upload_data_window.html    Sat Oct 24 18:17:19 2009 +0800
2055+++ b/sagenb/data/sage/html/notebook/upload_data_window.html    Sun Jan 03 03:07:50 2010 +0800
2056@@ -1,12 +1,5 @@
2057-{% extends "html/notebook/worksheet_page_template.html" %}
2058-{#
2059-INPUT:
2060-- worksheet - an instance of Worksheet
2061-- worksheet_filename - a string containing a worksheet's filename
2062-- username - a string containing a username
2063-- JSMATH - a boolean stating whether to include jsMath
2064-- JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE
2065-#}
2066+{% extends "html/notebook/base_aux.html" %}
2067+
2068 
2069 {% block page_id %}upload-data-page{% endblock %}
2070 
2071diff -r 8afee2ec056a sagenb/data/sage/html/notebook/worksheet.html
2072--- a/sagenb/data/sage/html/notebook/worksheet.html     Sat Oct 24 18:17:19 2009 +0800
2073+++ b/sagenb/data/sage/html/notebook/worksheet.html     Sun Jan 03 03:07:50 2010 +0800
2074@@ -1,35 +1,36 @@
2075 {#
2076 INPUT:
2077-     - worksheet_name - a string containing a worksheet's name
2078-     - worksheet_html - a string containing the html for a worksheet
2079-     - do_print - a boolean stating whether to render a print version of the
2080-                  worksheet
2081-  #}
2082-{% extends "html/base.html" %}
2083 
2084-{% block title %}Sage Worksheet: {{ worksheet_name }}{% endblock %}
2085+- worksheet -- Worksheet object
2086 
2087-{% block css %}main{% endblock %}
2088+- publish -- boolean whether this is for the published version
2089 
2090-{% block javascript %}
2091-<script type="text/javascript" src="/javascript/sage/main.js"></script>
2092-{% if do_print %}
2093-<script type="text/javascript" src="/javascript/sage/jsmath.js"></script>
2094-{% endif %}   
2095-{% endblock %}
2096+- do_print -- boolean whether this is for a print version
2097 
2098-{% block body_attrs %}
2099-{% if not do_print %}
2100-    class="worksheet-online" onLoad="initialize_the_notebook();"
2101+#}
2102+
2103+{% set wrap = conf['word_wrap_cols'] %}
2104+{% if not publish %}
2105+    {% set publish = worksheet.is_published() %}
2106 {% endif %}
2107-{% endblock %}
2108 
2109-{% block body %}
2110-{% if do_print %}
2111-    <div class="worksheet_print_title"> {{ worksheet_name }}</div>
2112+<div class="cell_input_active" id="cell_resizer"></div>
2113+{% if not publish %}
2114+<div class="worksheet_cell_list" id="worksheet_cell_list">
2115 {% endif %}
2116-{{ worksheet_html }}
2117-{% if do_print %}
2118-    <script type="text/javascript">jsMath.Process();</script>
2119+
2120+{% for cell in worksheet.cell_list() %}
2121+    {{ cell.html(wrap = wrap, div_wrap = true, do_print = do_print or publish) }}
2122+{% endfor %}
2123+
2124+{% if not do_print and not publish %}
2125+</div>
2126+<div class="insert_new_cell" id="insert_last_cell"></div>
2127+<script type="text/javascript">
2128+$(document).ready(function() {                                 
2129+    $("#insert_last_cell").plainclick(function(e) {insert_new_cell_after(cell_id_list[cell_id_list.length-1]);});
2130+    $("#insert_last_cell").shiftclick(function(e) {insert_new_text_cell_after(cell_id_list[cell_id_list.length-1]);});
2131+});
2132+</script>
2133 {% endif %}
2134-{% endblock %}
2135+
2136diff -r 8afee2ec056a sagenb/data/sage/html/notebook/worksheet_page.html
2137--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
2138+++ b/sagenb/data/sage/html/notebook/worksheet_page.html        Sun Jan 03 03:07:50 2010 +0800
2139@@ -0,0 +1,58 @@
2140+{% extends "html/notebook/base.html" %}
2141+{#
2142+INPUT:
2143+- worksheet - an instance of Worksheet
2144+- notebook - an instance of Notebook which contains worksheet
2145+- show_debug - a boolean stating whether to show debug information
2146+- do_print - a boolean stating whether the file is for print mode
2147+#}
2148+
2149+{% block body_classes %}worksheet-online{% if not (worksheet.is_published() or notebook.user_is_guest(username) or worksheet.is_doc_worksheet()) %} active-worksheet-page{% endif %}{% endblock %}
2150+{% block page_id %}user-worksheet-index{% endblock %}
2151+
2152+{% block worksheet_main %}
2153+{% set toggle=true %}
2154+<div class="worksheet" id="worksheet">
2155+    {{ worksheet.html() }}
2156+    {% if do_print %}
2157+    <script language="javascript">$(document).ready(function(){jsMath.ProcessBeforeShowing();});</script>
2158+    {% else %}
2159+    <script type="text/javascript">
2160+        $(document).ready(function() {                             
2161+        cell_id_list={{ worksheet.cell_id_list() }};
2162+        state_number={{ worksheet.state_number() }};
2163+        {% if not published %}if(worksheet_name == "Untitled") rename_worksheet();{% endif %}
2164+        });                     
2165+    </script>
2166+    {% endif %}
2167+
2168+</div>
2169+
2170+{% if show_debug %}
2171+<div class='debug_window'>
2172+    <div class='debug_output'><pre id='debug_output'></pre></div>
2173+    <textarea rows=5 id='debug_input' class='debug_input'
2174+              onKeyPress='return debug_keypress(event);'
2175+              onFocus='debug_focus();' onBlur='debug_blur();'>
2176+    </textarea>
2177+</div>
2178+{% endif %}
2179+
2180+{% if worksheet.is_only_viewer(username) %}
2181+<script type="text/javascript">worksheet_locked=true;</script>
2182+{% else %}
2183+<script type="text/javascript">worksheet_locked=false;</script>
2184+{% endif %}
2185+{% if worksheet.computing() %}
2186+<!-- Set the update checking back in motion. -->
2187+<script type="text/javascript">
2188+$(document).ready( function() {                         
2189+    active_cell_list = {{ worksheet.queue_id_list() }};
2190+    for (var i = 0; i < active_cell_list.length; i++) {
2191+        cell_set_running(active_cell_list[i]);
2192+    }
2193+    start_update_check();
2194+}                                                   
2195+</script>
2196+{% endif %}
2197+{% endblock %}
2198diff -r 8afee2ec056a sagenb/data/sage/html/notebook/worksheet_page_template.html
2199--- a/sagenb/data/sage/html/notebook/worksheet_page_template.html       Sat Oct 24 18:17:19 2009 +0800
2200+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
2201@@ -1,45 +0,0 @@
2202-{% extends "html/base.html" %}
2203-{#
2204-INPUT:
2205-- worksheet - an instance of Worksheet
2206-- worksheet_filename - a string containing a worksheet's filename
2207-- username  - a string containing a username
2208-- title - a string
2209-- select    - a string containing the control that is selected
2210-- backwards - a boolean
2211-- JSMATH - a boolean stating whether to include jsMath
2212-- JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE
2213-#}
2214-
2215-{% if not select %}
2216-    {% set select = none %}
2217-{% endif %}
2218-
2219-{% if not backwards %}
2220-    {% set backwards = false %}
2221-{% endif %}
2222-   
2223-{% include "html/notebook/head.tmpl" %}
2224-{% include "html/notebook/worksheet_topbar.tmpl" %}
2225-
2226-{% block title %}
2227-{{ common_title(worksheet_filename, worksheet) }}
2228-{% endblock %}
2229-   
2230-{% block css %}main{% endblock %}
2231-
2232-{% block javascript %}
2233-{{ common_javascript(worksheet, worksheet_filename, username, JSMATH, JEDITABLE_TINYMCE) }}
2234-{% endblock %}
2235-
2236-{% block body %}
2237-{% set toggle=true %}
2238-{% include "html/top_bar.html" %}
2239-{{ worksheet_topbar(worksheet, select, username, backwards) }}
2240-<hr class="usercontrol" />
2241-{% block before_sharebar %}{% endblock %}
2242-<span class="sharebar">{% block sharebar_title %}{% endblock %}</span>
2243-<br /><br /><br />
2244-{% block after_sharebar %}{% endblock %}
2245-{% endblock %}
2246-
2247diff -r 8afee2ec056a sagenb/data/sage/html/notebook/worksheet_revision_list.html
2248--- a/sagenb/data/sage/html/notebook/worksheet_revision_list.html       Sat Oct 24 18:17:19 2009 +0800
2249+++ b/sagenb/data/sage/html/notebook/worksheet_revision_list.html       Sun Jan 03 03:07:50 2010 +0800
2250@@ -1,13 +1,4 @@
2251-{% extends "html/notebook/worksheet_page_template.html" %}
2252-{#
2253-INPUT:
2254-- data - a list of pairs of the form ('how long ago', key)
2255-- worksheet - an instance of Worksheet
2256-- worksheet_filename - a string containing a worksheet's filename
2257-- username - a string containing a username
2258-- JSMATH - a boolean stating whether to include jsMath
2259-- JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE
2260-#}
2261+{% extends "html/notebook/base_aux.html" %}
2262 
2263 {% block page_id %}revision-list-page{% endblock %}
2264 
2265@@ -26,7 +17,7 @@
2266         </tr>
2267     </thead>
2268     <tbody>
2269-        {% for desc, key in data|reverse %}
2270+        {% for desc, key in worksheet.snapshot_data()|reverse %}
2271         <tr>
2272             <td><a href="revisions?rev={{ key }}">Revision {{ loop.revindex0 }}</a></td>
2273             <td><span class="revs">{{ desc }}</span></td>
2274diff -r 8afee2ec056a sagenb/data/sage/html/notebook/worksheet_settings.html
2275--- a/sagenb/data/sage/html/notebook/worksheet_settings.html    Sat Oct 24 18:17:19 2009 +0800
2276+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
2277@@ -1,23 +0,0 @@
2278-{% extends "html/notebook/worksheet_page_template.html" %}
2279-{#
2280-INPUT:
2281-- worksheet - an instance of Worksheet
2282-- worksheet_filename - a string containing a worksheet's filename
2283-- username - a string containing a username
2284-- JSMATH - a boolean stating whether to include jsMath
2285-- JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE
2286-#}
2287-
2288-{% block sharebar_title %}
2289-Worksheet Settings &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button name="button_save">Save Settings</button>  <input type="submit" value="Cancel" name="button_cancel"/>
2290-{% endblock %}
2291-
2292-{% block before_sharebar %}
2293-<form width=70% method="post" action="input_settings"  enctype="multipart/form-data">
2294-{% endblock %}
2295-{% block after_sharebar %}
2296-</form>
2297-{% endblock %}
2298-
2299-
2300-
2301diff -r 8afee2ec056a sagenb/data/sage/html/notebook/worksheet_share.html
2302--- a/sagenb/data/sage/html/notebook/worksheet_share.html       Sat Oct 24 18:17:19 2009 +0800
2303+++ b/sagenb/data/sage/html/notebook/worksheet_share.html       Sun Jan 03 03:07:50 2010 +0800
2304@@ -1,13 +1,9 @@
2305-{% extends "html/notebook/worksheet_page_template.html" %}
2306+{% extends "html/notebook/base_aux.html" %}
2307 {#
2308 INPUT:
2309     - worksheet - an instance of Worksheet
2310-    - worksheet_filename - a string containing a worksheet's filename
2311     - username - a string containing a username
2312     - other_users - a list of strings containing other users names
2313-    - user_is_admin - a boolean stating whether the user is an admin
2314-    - JSMATH - a boolean stating whether to include jsMath
2315-    - JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE
2316 #}
2317 
2318 {% block sharebar_title %}
2319@@ -17,7 +13,7 @@
2320 {% set select = "share" %}
2321 
2322 {% block after_sharebar %}
2323-{% if not (user_is_admin or username == worksheet.owner()) %}
2324+{% if not (notebook.user_is_admin(username) or username == worksheet.owner()) %}
2325     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>.
2326 {% else %}
2327 <p>This Sage Worksheet is currently shared with the people listed in the box below.</p>
2328diff -r 8afee2ec056a sagenb/data/sage/html/notebook/worksheet_topbar.tmpl
2329--- a/sagenb/data/sage/html/notebook/worksheet_topbar.tmpl      Sat Oct 24 18:17:19 2009 +0800
2330+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
2331@@ -1,48 +0,0 @@
2332-{#
2333-INPUT:
2334-- worksheet - an instance of Worksheet
2335-- select    - a string containing the control that is selected
2336-- username  - a string containing a username
2337-- backwards - a boolean
2338-#}
2339-{% macro worksheet_topbar(worksheet, select=None, username='guest',
2340-backwards=false, warn=false) %}
2341-<div id="worksheet-bar">
2342-    <div class="worksheet_title">
2343-        <a id="worksheet_title" class="worksheet_title"
2344-           onClick="rename_worksheet(); return false;"
2345-           title="Click to rename this worksheet">
2346-            {{ worksheet.name() }}
2347-        </a>
2348-        <br> {{ worksheet.html_time_last_edited() }}
2349-        {% if worksheet.warn_about_other_person_editing(username) and username != 'guest' and not worksheet.is_doc_worksheet() %}
2350-        &nbsp;&nbsp;<span class="pingdown">(Someone else is viewing this worksheet)</span>
2351-        {% endif %}
2352-    </div>
2353-    <div id="save-discard-buttons">
2354-        {{ worksheet.html_save_discard_buttons() }}
2355-    </div>
2356-   
2357-    <div id="worksheet-menu">
2358-        {{ worksheet.html_menu() }}
2359-    </div>
2360-    <div id="share-publish-buttons">
2361-        {{ worksheet.html_share_publish_buttons(select, backwards) }}
2362-    </div>
2363-</div>
2364-<div class="hidden" id="slide_controls">
2365-    <div class="slideshow_control">
2366-        <a class="slide_arrow" onClick="slide_next()">&gt;</a>
2367-        <a class="slide_arrow" onClick="slide_last()">&gt;&gt;</a> <span class="vbar"></span>
2368-        <a class="cell_mode" onClick="cell_mode()">Exit</a>
2369-    </div>
2370-    <div class="slideshow_progress" id="slideshow_progress" onClick="slide_next()">
2371-        <div class="slideshow_progress_bar" id="slideshow_progress_bar">&nbsp;</div>
2372-        <div class="slideshow_progress_text" id="slideshow_progress_text">&nbsp;</div>
2373-    </div>
2374-    <div class="slideshow_control">
2375-        <a class="slide_arrow" onClick="slide_first()">&lt;&lt;</a>
2376-        <a class="slide_arrow" onClick="slide_prev()">&lt;</a>
2377-    </div>
2378-</div>
2379-{% endmacro %}
2380diff -r 8afee2ec056a sagenb/data/sage/html/notebook_settings.html
2381--- a/sagenb/data/sage/html/notebook_settings.html      Sat Oct 24 18:17:19 2009 +0800
2382+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
2383@@ -1,27 +0,0 @@
2384-{% extends "html/base.html" %}
2385-
2386-{% block title %}Notebook Settings{% endblock %}
2387-{% block css %}account_settings{% endblock %}
2388-{% block more_css %}
2389-<link rel="stylesheet" href="/javascript/jquery/plugins/farbtastic/farbtastic.css" type="text/css" /> 
2390-{% endblock %}
2391-
2392-{% block javascript %}
2393-<script type="text/javascript" src="/javascript/jquery/plugins/farbtastic/farbtastic.min.js"></script>
2394-{% endblock %}
2395-
2396-{% block body %}
2397-<h1>Notebook Settings</h1>
2398-<div class="section"><a href="/users">Manage Users</a> | <a href="/settings">My Settings</a> | <a href="/">My Worksheets</a> | <a href="/logout">Sign Out</a></div>
2399-
2400-<form method="get" action="/notebooksettings">
2401-  <input type="hidden" name="form" value="on" />
2402-  {%- if auto_table %}
2403-  {{ auto_table }}
2404-  {%- endif %}
2405-  <div id="buttons">
2406-    <input type="submit" value="Save">
2407-    <input type="button" value="Cancel" style="margin-left:5px" onClick="parent.location='/'">
2408-  </div>
2409-</form>
2410-{% endblock %}
2411diff -r 8afee2ec056a sagenb/data/sage/html/registration.html
2412--- a/sagenb/data/sage/html/registration.html   Sat Oct 24 18:17:19 2009 +0800
2413+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
2414@@ -1,74 +0,0 @@
2415-{% extends "html/base.html" %}
2416-
2417-{% block title %}Sign up{% endblock %}
2418-
2419-{% block css %}registration{% endblock %}
2420-
2421-{% block body %}
2422-<div id="wrapper">
2423-  <h1>Sign up for a Sage Notebook account</h1>
2424-  {% if error %}
2425-  <h2 class="error_found">Error{{ error[1:] }}found</h2>
2426-  {% endif %}
2427-  <form method="POST" action="/register">
2428-    <ol>
2429-      <li><h2>Create a username</h2>
2430-       <p>Your username must start with a letter and be between 3 and 64
2431-          characters long. You may only use letters, numbers, underscores, @,
2432-          and dots.</p>
2433-       <input type="text" name="username" value="{{ username }}" class="entry" tabindex="1" />
2434-       {% if username_missing %}
2435-       <p><span class="error">Error:</span> No username given</p>
2436-       {% endif %}
2437-       {% if username_taken %}
2438-       <p><span class="error">Error:</span> Username already in use</p>
2439-       {% endif %}
2440-       {% if username_invalid %}
2441-       <p><span class="error">Error:</span> Bad username</p>
2442-       {% endif %}
2443-      </li>
2444-      <li><h2>Create a good password</h2>
2445-       <p>Your password must be between 4 and 32 characters long. Your password can not contain your username nor spaces.</p>
2446-       <input type="password" name="password" class="entry" tabindex="2" />
2447-       {% if password_missing %}
2448-       <p><span class="error">Error:</span> No password given</p>
2449-       {% endif %}
2450-       {% if password_invalid %}
2451-       <p><span class="error">Error:</span> Bad password</p>
2452-       {% endif %}
2453-      </li>
2454-      <li><h2>Re-type your password</h2>
2455-       <input type="password" name="retype_password" class="entry" tabindex="3" />
2456-       {% if passwords_dont_match or retype_password_missing %}
2457-       <p><span class="error">Error:</span> Passwords didn't match</p>
2458-       {% endif %}
2459-      </li>
2460-      {% if email or email_missing or email_invaild %}
2461-      <li><h2>Enter your email address</h2>
2462-       <p>Your email address is required for account confirmation and recovery. You will be emailed a confirmation link right after you successfully sign up.</p>
2463-       <input type="text" name="email" value="{{ email_address }}" class="entry" tabindex="4" />
2464-       {% if email_missing %}
2465-       <p><span class="error">Error:</span> No email address given</p>
2466-       {% endif %}
2467-       {% if email_invalid %}
2468-       <p><span class="error">Error:</span> Invalid email address</p>
2469-       {% endif %}
2470-      </li>
2471-      {% endif %}
2472-      {% if challenge %}
2473-      <li><h2>Answer a challenge</h2>
2474-       {{ challenge_html }}
2475-       {% if challenge_missing %}
2476-       <p><span class="error">Error:</span> No challenge response given</p>
2477-       {% endif %}
2478-       {% if challenge_invalid %}
2479-       <p><span class="error">Error:</span> Invalid challenge response</p>
2480-       {% endif %}
2481-      </li>
2482-      {% endif %}
2483-    </ol>
2484-    <button type="submit" tabindex="100" id="create-account-button">Create account</button>
2485-    <a href="/"><button tabindex="101">Cancel</button></a>
2486-  </form>
2487-</div>
2488-{% endblock %}
2489diff -r 8afee2ec056a sagenb/data/sage/html/settings/account_settings.html
2490--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
2491+++ b/sagenb/data/sage/html/settings/account_settings.html      Sun Jan 03 03:07:50 2010 +0800
2492@@ -0,0 +1,59 @@
2493+{% extends "html/settings/base.html" %}
2494+
2495+{% block title %}Account Settings{% endblock %}
2496+{% block page_id %}account-settings-page{% endblock %}
2497+
2498+{% block settings_main %}
2499+<form method="post" action="/settings">
2500+   
2501+    <div class="section">
2502+        <h2>Change Auto-Save Interval</h2>
2503+        <div>
2504+            Minutes:
2505+            <select name="autosave">
2506+                {% for i, selected in autosave_intervals %}
2507+                <option{{ selected }}>{{ i }}</option>
2508+                {% endfor %}
2509+            </select>
2510+        </div>
2511+    </div>
2512+    <div class="section">
2513+        <h2>Change Password</h2>
2514+        <div id="passwd">
2515+            <div>
2516+                <label for="old-pass">Old password</label>
2517+                <input type="password" name="old-pass" />
2518+            </div>
2519+            <div>
2520+                <label for="new-pass">New password</label>
2521+                <input type="password" name="new-pass" />
2522+            </div>
2523+            <div>
2524+                <label for="retype-pass">Retype new password</label>
2525+                <input type="password" name="retype-pass" />
2526+            </div>
2527+        </div>
2528+    </div>
2529+
2530+    {% if true %}
2531+    <div class="section">
2532+        <h2>Change E-mail Address</h2>
2533+       
2534+        <div>
2535+            <div>
2536+                <label>Current e-mail</label>
2537+                {{ email_address }} {{ email_confirmed }}
2538+            </div>
2539+            <div>
2540+                <label for="new-email">New e-mail</label>
2541+                <input type="text" name="new-email" class="c1" />
2542+            </div>
2543+        </div>
2544+    </div>
2545+    {% endif %}
2546+    <div id="buttons">
2547+        <button type="submit">Save</button>
2548+        <a href="/"><button>Cancel</button></a>
2549+    </div>
2550+</form>
2551+{% endblock %}
2552diff -r 8afee2ec056a sagenb/data/sage/html/settings/admin_add_user.html
2553--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
2554+++ b/sagenb/data/sage/html/settings/admin_add_user.html        Sun Jan 03 03:07:50 2010 +0800
2555@@ -0,0 +1,30 @@
2556+{% extends "html/settings/base.html" %}
2557+{% block title %}Add New User{% endblock %}
2558+{% block page_id %}add-user-page{% endblock %}
2559+
2560+{% block main %}
2561+<h1>Add New User</h1>
2562+{% if error %}
2563+<h2 class="error_found">Username Error</h2>
2564+{% endif %}
2565+<form method="POST" action="/adduser">
2566+<ol>
2567+<li><h2>Pick a username</h2>
2568+<p>The username must start with a letter and be between 4 and 32 characters long. It can only consist of letters, numbers, underscores, and one dot (.).</p>
2569+<input type="text" name="username" value="{{ username_input if username_input else '' }}" />
2570+{% if username_error %}
2571+{% if username_error == 'invalid' %}
2572+<p><span class="error">Error:</span> Invalid username</p>
2573+{% else %}
2574+<p><span class="error">Error:</span> Username taken</p>
2575+{% endif %}
2576+{% endif %}
2577+</li>
2578+</ol>
2579+<div id="buttons">
2580+    <button type="submit">Create Account</buttoN>
2581+    <a href="/users"><button>Cancel</button></a>
2582+</div>
2583+</form>
2584+</div>
2585+{% endblock %}
2586\ No newline at end of file
2587diff -r 8afee2ec056a sagenb/data/sage/html/settings/base.html
2588--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
2589+++ b/sagenb/data/sage/html/settings/base.html  Sun Jan 03 03:07:50 2010 +0800
2590@@ -0,0 +1,70 @@
2591+{% extends "html/base_authenticated.html" %}
2592+
2593+{% block body_classes %}settings-page{% endblock %}
2594+
2595+{% block main %}
2596+<h1>{{ render_title() }}</h1>
2597+{% block settings_nav %}
2598+<ul id="settings-nav" class="user-controls">
2599+    {% if admin %}
2600+    <li><a href="/users">Manage Users</a></li>
2601+    <li><a href="/notebooksettings">Notebook Settings</a></li>
2602+    {% endif %}
2603+    <li><a href="/settings">Account Settings</a></li>
2604+</ul>
2605+{% endblock %}
2606+{% block settings_main %}
2607+<form method="post" action="/settings">
2608+   
2609+    <div class="section">
2610+        <h2>Change Auto-Save Interval</h2>
2611+        <div>
2612+            Minutes:
2613+            <select name="autosave">
2614+                {% for i, selected in autosave_intervals %}
2615+                <option{{ selected }}>{{ i }}</option>
2616+                {% endfor %}
2617+            </select>
2618+        </div>
2619+    </div>
2620+    <div class="section">
2621+        <h2>Change Password</h2>
2622+        <div id="passwd">
2623+            <div>
2624+                <label for="old-pass">Old password</label>
2625+                <input type="password" name="old-pass" />
2626+            </div>
2627+            <div>
2628+                <label for="new-pass">New password</label>
2629+                <input type="password" name="new-pass" />
2630+            </div>
2631+            <div>
2632+                <label for="retype-pass">Retype new password</label>
2633+                <input type="password" name="retype-pass" />
2634+            </div>
2635+        </div>
2636+    </div>
2637+
2638+    {% if true %}
2639+    <div class="section">
2640+        <h2>Change E-mail Address</h2>
2641+       
2642+        <div>
2643+            <div>
2644+                <label>Current e-mail</label>
2645+                {{ email_address }} {{ email_confirmed }}
2646+            </div>
2647+            <div>
2648+                <label for="new-email">New e-mail</label>
2649+                <input type="text" name="new-email" class="c1" />
2650+            </div>
2651+        </div>
2652+    </div>
2653+    {% endif %}
2654+    <div id="buttons">
2655+        <button type="submit">Save</button>
2656+        <a href="/"><button>Cancel</button></a>
2657+    </div>
2658+</form>
2659+{% endblock %}
2660+{% endblock %}
2661diff -r 8afee2ec056a sagenb/data/sage/html/settings/notebook_settings.html
2662--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
2663+++ b/sagenb/data/sage/html/settings/notebook_settings.html     Sun Jan 03 03:07:50 2010 +0800
2664@@ -0,0 +1,25 @@
2665+{% extends "html/settings/base.html" %}
2666+{% block title %}Notebook Settings{% endblock %}
2667+
2668+{% block more_css %}
2669+<link rel="stylesheet" href="/javascript/jquery/plugins/farbtastic/farbtastic.css" type="text/css" /> 
2670+{% endblock %}
2671+
2672+{% block javascript %}
2673+<script type="text/javascript" src="/javascript/jquery/plugins/farbtastic/farbtastic.min.js"></script>
2674+{% endblock %}
2675+
2676+{% block page_id %}notebook-settings-page{% endblock %}
2677+
2678+{% block settings_main %}
2679+<form method="get" action="/notebooksettings">
2680+  <input type="hidden" name="form" value="on" />
2681+  {%- if auto_table %}
2682+  {{ auto_table }}
2683+  {%- endif %}
2684+  <div id="buttons">
2685+    <input type="submit" value="Save">
2686+    <input type="button" value="Cancel" style="margin-left:5px" onClick="parent.location='/'">
2687+  </div>
2688+</form>
2689+{% endblock %}
2690\ No newline at end of file
2691diff -r 8afee2ec056a sagenb/data/sage/html/settings/user_management.html
2692--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
2693+++ b/sagenb/data/sage/html/settings/user_management.html       Sun Jan 03 03:07:50 2010 +0800
2694@@ -0,0 +1,20 @@
2695+{% extends "html/settings/base.html" %}
2696+
2697+{% block title %}Users{% endblock %}
2698+{% block page_id %}user-management-page{% endblock %}
2699+
2700+{% block settings_main %}
2701+    <h1>User Management</h1>
2702+    <a href="/adduser" class="boldusercontrol">Add User</a>
2703+    {% if reset %}
2704+    <p>The password for the user {{ reset[0] }} has been reset to <strong>{{ reset[1] }}</strong></p>
2705+    {% endif %}
2706+    <table>
2707+      <tr><th>Users</th><th>Password</th><th>Suspension</th></tr>
2708+      {% for user in users %}
2709+      {% if user != 'admin' %}
2710+      <tr><td><a href="/home/{{ user }}/">{{ user }}</a></td><td><a href="/users/?reset={{ user }}">Reset</a></td><td><a href="/users/?suspension={{ user }}">{% if user.is_suspended() %}Unsuspend{% else %}Suspend{% endif %}</td></tr>
2711+      {% endif %}
2712+      {% endfor %}
2713+    </table>
2714+{% endblock %}
2715diff -r 8afee2ec056a sagenb/data/sage/html/template_error.html
2716--- a/sagenb/data/sage/html/template_error.html Sat Oct 24 18:17:19 2009 +0800
2717+++ b/sagenb/data/sage/html/template_error.html Sun Jan 03 03:07:50 2010 +0800
2718@@ -1,4 +1,4 @@
2719-{% extends "html/base.html" %}
2720+{% extends "html/base_authenticated.html" %}
2721 
2722 {% block title %}Error{% endblock %}
2723 
2724diff -r 8afee2ec056a sagenb/data/sage/html/top_bar.html
2725--- a/sagenb/data/sage/html/top_bar.html        Sat Oct 24 18:17:19 2009 +0800
2726+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
2727@@ -1,27 +0,0 @@
2728-<div id="top-bar">
2729-  {% include "html/banner.html" %}
2730-  <div id="controls">
2731-    <ul>
2732-      <li class="username">{{ username }}</li>
2733-      {% if username == 'guest' %}
2734-      <li><a title="Please log in to the Sage notebook" class="usercontrol" href="/">Log in</a></li>
2735-      {% else %}
2736-      {# TODO: Hack-ish. Remove on template cleanup. #}
2737-      {% if toggle %}
2738-      <li><a title="Toggle the top bar" class="usercontrol" onClick="$('#worksheet-bar').toggle()">Toggle</a></li>
2739-      {% endif %}
2740-      <li><a title="Back to your personal worksheet list" class="usercontrol" href="/home/{{ username }}">Home</a></li>
2741-      {% if pub %}
2742-      <li><span class="usercontrol">Published</span></li>
2743-      {% else %}
2744-      <li><a title="Browse the published worksheets" class="usercontrol" href="/pub">Published</a></li>
2745-      <li><a title="View a log of recent computations" class="usercontrol" href="#" onClick="history_window()">Log</a></li>
2746-      {% endif %}
2747-      <li><a title="Change account settings including password" class="usercontrol" href="/settings">Settings</a></li>
2748-      <li><a title="Documentation" class="usercontrol" href="#" onClick="help()">Help</a></li>
2749-      <li><a title="Report a problem or submit a bug to improve Sage" class="usercontrol" href="#" onClick="bugreport()">Report a Problem</a></li>
2750-      <li><a title="Log out of the Sage notebook" class="usercontrol" href="/logout">Sign out</a></li>
2751-      {% endif %}
2752-    </ul>
2753-  </div>
2754-</div>
2755diff -r 8afee2ec056a sagenb/data/sage/html/upload.html
2756--- a/sagenb/data/sage/html/upload.html Sat Oct 24 18:17:19 2009 +0800
2757+++ b/sagenb/data/sage/html/upload.html Sun Jan 03 03:07:50 2010 +0800
2758@@ -1,14 +1,11 @@
2759-{% extends "html/base.html" %}
2760+{% extends "html/base_authenticated.html" %}
2761 
2762 {% block title %}Upload File{% endblock %}
2763 
2764-{% block css %}main{% endblock %}
2765-
2766 {% block page_id %}upload-worksheet-page{% endblock %}
2767 
2768-{% block body %}
2769+{% block main %}
2770 
2771-{% include "html/top_bar.html" %}
2772 <div>
2773     <h2>Upload worksheet (an sws or txt file) to the Sage Notebook</h2>
2774     <form method="POST" action="upload_worksheet"
2775diff -r 8afee2ec056a sagenb/data/sage/html/user_management.html
2776--- a/sagenb/data/sage/html/user_management.html        Sat Oct 24 18:17:19 2009 +0800
2777+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
2778@@ -1,42 +0,0 @@
2779-<html>
2780-  <head>
2781-    <title>Users | {{ sitename }}</title>
2782-    <style>
2783-      body {
2784-      font:1em Arial, Sans-serif;
2785-      }
2786-
2787-      table {
2788-      border-collapse:collapse
2789-      }
2790-
2791-      th, td {
2792-      border:1px solid #696969;
2793-      padding:5px
2794-      }
2795-
2796-      th {
2797-      background:#CCC
2798-      }
2799-
2800-      a:link, a:visited {
2801-      color:blue
2802-      }
2803-    </style>
2804-  </head>
2805-  <body>
2806-    <h1>User Management</h1>
2807-    <a href="/adduser">Add User</a> | <a href="/notebooksettings">Notebook Settings</a> | <a href="/settings">My Settings</a> | <a href="/">My Worksheets</a> | <a href="/logout">Sign Out</a> {% if number_of_users %} <br/><br/>{{ number_of_users }} users {% endif %}<br/><br/>
2808-    {% if reset %}
2809-    <p>The password for the user {{ reset[0] }} has been reset to <strong>{{ reset[1] }}</strong></p>
2810-    {% endif %}
2811-    <table>
2812-      <tr><th>Users</th><th>Password</th><th>Suspension</th></tr>
2813-      {% for user in users %}
2814-      {% if user != 'admin' %}
2815-      <tr><td><a href="/home/{{ user }}/">{{ user }}</a></td><td><a href="/users/?reset={{ user }}">Reset</a></td><td><a href="/users/?suspension={{ user }}">{% if user.is_suspended() %}Unsuspend{% else %}Suspend{% endif %}</td></tr>
2816-      {% endif %}
2817-      {% endfor %}
2818-    </table>
2819-  </body>
2820-</html>
2821diff -r 8afee2ec056a sagenb/data/sage/html/worksheet/menu.html
2822--- a/sagenb/data/sage/html/worksheet/menu.html Sat Oct 24 18:17:19 2009 +0800
2823+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
2824@@ -1,58 +0,0 @@
2825-{#
2826-INPUT
2827-- name - string with worksheet name
2828-- filename_ - string with worksheet filename
2829-- data - list of data to put in the Data menu
2830-- systems_enumerated - enumerated list of systems
2831-- system_names - list of system names
2832-- current_system_index - the currently selected system_index
2833-- pretty_print - a boolean stating whether to typeset as default
2834-- doc_worksheet - a boolean stating whether the worksheet is the doc worksheet
2835-#}
2836-<select class="worksheet"  onchange="go_option(this);" id="file-menu">
2837-    <option title="Select a file related function" value=""  selected>File...</option>
2838-    <option title="Load a new worksheet stored in a file" value="upload_worksheet_button();">Load worksheet from a file...</option>
2839-    <option title="Create a new worksheet" value="new_worksheet();">New worksheet</option>
2840-    <option title="Save this worksheet to an sws file" value="download_worksheet();">Save worksheet to a file...</option>
2841-    <option title="Print this worksheet" value="print_worksheet();">Print</option>
2842-    <option title="Rename this worksheet" value="rename_worksheet();">Rename worksheet</option>
2843-    <option title="Copy this worksheet" value="copy_worksheet();">Copy worksheet</option>
2844-    <option title="Move this worksheet to the trash" value="delete_worksheet('{{ filename_ }}');">Delete worksheet</option>
2845-</select>
2846-
2847-<select class="worksheet"  onchange="go_option(this);"  id="action-menu">
2848-    <option title="Select a worksheet function" value="" selected>Action...</option>
2849-    <option title="Interrupt currently running calculations, if possible" value="interrupt();">Interrupt</option>
2850-    <option title="Restart the worksheet process" value="restart_sage();">Restart worksheet</option>
2851-    <option title="Quit the worksheet process" value="save_worksheet_and_close();">Save and quit worksheet</option>
2852-    <option value="">---------------------------</option>
2853-    <option title="Evaluate all input cells in the worksheet" value="evaluate_all();">Evaluate All</option>
2854-    <option title="Hide all output" value="hide_all();">Hide All Output</option>
2855-    <option title="Show all output" value="show_all();">Show All Output</option>
2856-    <option title="Delete all output" value="delete_all_output();">Delete All Output</option>
2857-    <option value="">---------------------------</option>
2858-    <option title="Switch to single-cell mode" value="slide_mode();">One Cell Mode</option>
2859-    <option title="Switch to multi-cell mode" value="cell_mode();">Multi Cell Mode</option>
2860-</select>
2861-<select class="worksheet" onchange="handle_data_menu(this);" id="data-menu">
2862-    <option title="Select an attached file" value="" selected>Data...</option>
2863-    <option title="Upload or create a data file in a wide range of formats" value="__upload_data_file__">Upload or create file...</option>
2864-    <option value="">--------------------</option>
2865-    {% for name in data %}
2866-    <option value="datafile?name={{ name }}">{{ name }}</option>
2867-    {% endfor %}
2868-</select>
2869-
2870-{% if not doc_worksheet %}
2871-<select onchange="go_system_select(this, {{ current_system_index }});" class="worksheet" id="systems-menu">
2872-    {% for system_index, system_name in systems_enumerated %}
2873-        <option title="Evaluate all input cells using {{ system_names[system_index] }}"
2874-            {{ "selected" if current_system_index == system_index else "" }} value="{{ system_names[system_index] }}">
2875-            {{ system_name }}
2876-        </option>
2877-    {% endfor %}
2878-</select>   
2879-<input type="checkbox" title="Enable/disable pretty_printing"
2880-       onchange="pretty_print_check(this.checked);"
2881-       class="worksheet" value="pretty_print" {{ "checked" if pretty_print else "" }} />&nbsp;Typeset
2882-{% endif %}
2883diff -r 8afee2ec056a sagenb/data/sage/html/worksheet/published_worksheet.html
2884--- a/sagenb/data/sage/html/worksheet/published_worksheet.html  Sat Oct 24 18:17:19 2009 +0800
2885+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
2886@@ -1,12 +0,0 @@
2887-{#
2888-INPUT:
2889-- cell_id_list - a list of cell id's
2890-- cells_html - string of cells HTML
2891-#}
2892-{% set published = true %}
2893-{% set do_print = true %}
2894-
2895-{% include "html/worksheet/worksheet_body.html" %}
2896-
2897-
2898-<script language=javascript>jsMath.ProcessBeforeShowing();</script>
2899diff -r 8afee2ec056a sagenb/data/sage/html/worksheet/ratings_info.html
2900--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
2901+++ b/sagenb/data/sage/html/worksheet/ratings_info.html Sun Jan 03 03:07:50 2010 +0800
2902@@ -0,0 +1,18 @@
2903+{% extends "html/base.html" %}
2904+
2905+{% block title %}Ratings for {{ worksheet.name() }}{% endblock %}
2906+
2907+{% block body %}
2908+<h2 align=center>Ratings for {{ worksheet.name() }}</h2>
2909+<h3 align=center><a href='/home/{{ worksheet.filename() }}'>Go to the worksheet.</a>
2910+<table width=70%%align=center border=1 cellpadding=10 cellspacing=0>
2911+    <tr bgcolor="#7799bb"><td width=30em>User</td><td width=10em align=center>Rating</td><td width=10em align=center width=60em>Comment</td></tr>
2912+    {% for rating in worksheet.ratings()|sort %}
2913+    <tr>
2914+        <td>rating[0]{# Person #}</td>
2915+        <td>rating[1]{# Rating #}</td>
2916+        <td>{{'' if rating|length < 3 else rating[2]}}{# Comment #}</td>
2917+    </tr>
2918+    {% endfor %}
2919+</table>
2920+{% endblock %}
2921diff -r 8afee2ec056a sagenb/data/sage/html/worksheet/save_discard_buttons.html
2922--- a/sagenb/data/sage/html/worksheet/save_discard_buttons.html Sat Oct 24 18:17:19 2009 +0800
2923+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
2924@@ -1,7 +0,0 @@
2925-{#
2926-INPUT:
2927-doc_worksheet - boolean stating whether this worksheet is the doc worksheet
2928-#}
2929-{% if not doc_worksheet %}
2930-<button name="button_save" title="Save changes" onClick="save_worksheet();">Save</button><button title="Save changes and close window" onClick="save_worksheet_and_close();" name="button_save">Save & quit</button><button title="Discard changes to this worksheet" onClick="worksheet_discard();">Discard & quit</button>
2931-{% endif %}
2932diff -r 8afee2ec056a sagenb/data/sage/html/worksheet/share_publish_buttons.html
2933--- a/sagenb/data/sage/html/worksheet/share_publish_buttons.html        Sat Oct 24 18:17:19 2009 +0800
2934+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
2935@@ -1,22 +0,0 @@
2936-
2937-{#
2938-INPUT:
2939-- worksheet - Worksheet instance
2940-- select - a boolean
2941-- backwards - a boolean
2942-#}
2943-{% if not worksheet.is_doc_worksheet() %}
2944-{% macro cls(x) %}
2945-{{ "control-select" if x == select else "control" }}
2946-{% endmacro %}
2947-{% macro backwards_text() %}
2948-{{ "../" if backwards else "" }}
2949-{% endmacro %}
2950-<a title="Print this worksheet" class="print-link" onClick="print_worksheet()"><img border=0 src="/images/icon_print.gif" alt="Print">Print</a>
2951-<a class="{{ cls('use') }}" title="Interactively use this worksheet" onClick="edit_worksheet();">Worksheet</a>       
2952-<a class="{{ cls('edit') }}" title="Edit text version of this worksheet" href="{{ backwards_text() }}edit">Edit</a>
2953-<a class="{{ cls('text') }}" title="View plain text version of this worksheet" href="{{ backwards_text() }}text">Text</a>
2954-<a class="{{ cls('undo') }}" title="View changes to this worksheet over time" href="{{ backwards_text() }}revisions">Undo</a>
2955-<a class="{{ cls('share') }}" title="Let others edit this worksheet" href="{{ backwards_text() }}share">Share</a>
2956-<a class="{{ cls('publish') }}" title="Make this worksheet publicly viewable" href="{{ backwards_text() }}publish">Publish</a>
2957-{% endif %}
2958diff -r 8afee2ec056a sagenb/data/sage/html/worksheet/title.html
2959--- a/sagenb/data/sage/html/worksheet/title.html        Sat Oct 24 18:17:19 2009 +0800
2960+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
2961@@ -1,13 +0,0 @@
2962-{#
2963-MARKED FOR DELETION.
2964-- worksheet - Worksheet instance
2965-- name - escaped name of the worksheet
2966-- username - string of username
2967-#}
2968-<div class="worksheet_title">
2969-     <a id="worksheet_title" class="worksheet_title" onClick="rename_worksheet(); return false;" title="Click to rename this worksheet">{{ name }}</a>
2970-     <br> {{ worksheet.html_time_last_edited() }}
2971-     {% if warn and username != 'guest' and not doc_worksheet%}
2972-     &nbsp;&nbsp;<span class="pingdown">(Someone else is viewing this worksheet)</span>
2973-     {% endif %}
2974- </div>
2975\ No newline at end of file
2976diff -r 8afee2ec056a sagenb/data/sage/html/worksheet/worksheet.html
2977--- a/sagenb/data/sage/html/worksheet/worksheet.html    Sat Oct 24 18:17:19 2009 +0800
2978+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
2979@@ -1,36 +0,0 @@
2980-{#
2981-INPUT:
2982-- do_print - a boolean
2983-- cell_id_list - a list of cell id's
2984-- confirm_before_leave - a boolean stating whether to popup a js confirm
2985-  dialog before leaving
2986-- cells_html - string of cells HTML
2987-- published - a boolean stating whether the worksheet is published
2988-- state_number - worksheet.state_number()
2989-#}
2990-{% include "html/worksheet/worksheet_body.html" %}
2991-
2992-{% if do_print %}
2993-<script language="javascript">jsMath.ProcessBeforeShowing();</script>
2994-{% else %}
2995-<script type="text/javascript">
2996-$(document).ready(function() {                             
2997-   cell_id_list={{ cell_id_list }};
2998-   state_number={{ state_number }};
2999-   {% if not published %}if(worksheet_name == "Untitled") rename_worksheet();{% endif %}
3000-});                     
3001-</script>
3002-{% endif %}
3003-
3004-{% if not do_print and confirm_before_leave %}
3005-<script type="text/javascript">
3006-$(document).ready(function() {                                 
3007-            window.onbeforeunload = confirmBrowseAway;
3008-            function confirmBrowseAway()
3009-            {
3010-            return "Unsubmitted cells will be lost.";
3011-            }
3012-});                             
3013-</script>
3014-{% endif %}
3015-
3016diff -r 8afee2ec056a sagenb/data/sage/html/worksheet/worksheet_body.html
3017--- a/sagenb/data/sage/html/worksheet/worksheet_body.html       Sat Oct 24 18:17:19 2009 +0800
3018+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
3019@@ -1,24 +0,0 @@
3020-{#
3021-INPUT:
3022-- cells_html - string of cells HTML
3023-- published - a boolean stating whether the worksheet is published
3024-#}
3025-
3026-<div class="cell_input_active" id="cell_resizer"></div>
3027-{% if not published %}
3028-<div class="worksheet_cell_list" id="worksheet_cell_list">
3029-{% endif %}
3030-
3031-{{ cells_html }}
3032-
3033-{% if not do_print and not published %}
3034-</div>
3035-<div class="insert_new_cell" id="insert_last_cell"></div>
3036-<script type="text/javascript">
3037-        $("#insert_last_cell").plainclick(function(e) {insert_new_cell_after(cell_id_list[cell_id_list.length-1]);});
3038-        $("#insert_last_cell").shiftclick(function(e) {insert_new_text_cell_after(cell_id_list[cell_id_list.length-1]);});
3039-</script>
3040-<div class="worksheet_bottom_padding"></div>
3041-{% endif %}
3042-
3043-
3044diff -r 8afee2ec056a sagenb/data/sage/html/worksheet_listing.html
3045--- a/sagenb/data/sage/html/worksheet_listing.html      Sat Oct 24 18:17:19 2009 +0800
3046+++ b/sagenb/data/sage/html/worksheet_listing.html      Sun Jan 03 03:07:50 2010 +0800
3047@@ -1,8 +1,9 @@
3048-{% extends "html/base.html" %}
3049+{% extends "html/base_authenticated.html" %}
3050 {#
3051 INPUT:
3052-- pub - a boolean stating whether to show in public mode.
3053-- typ - a string stating what kind of worksheets this listing shows
3054+- pub -- a boolean stating whether to show in public mode.
3055+- typ -- a string stating what kind of worksheets this listing shows
3056+- worksheets -- list of Worksheet objects
3057 #}
3058 {% if pub %}
3059 {% set worksheet_heading='Published Worksheets' %}
3060@@ -14,12 +15,11 @@
3061 {% set worksheet_heading='Archived Worksheets' %}
3062 {% endif %} 
3063 
3064-
3065 {% block title %}
3066 {{ worksheet_heading }}
3067 {% endblock %}
3068 
3069-{% block css %}main{% endblock %}
3070+{% block page_id %}worksheet-listing-page{% endblock %}
3071 
3072 {% block javascript %}
3073 {% if not pub %}
3074@@ -27,10 +27,8 @@
3075 <script type="text/javascript" src="/javascript/jqueryui/js/jquery-ui-1.7.2.custom.min.js"></script>
3076 <script type="text/javascript" src="/javascript/jquery/plugins/form/jquery.form.min.js"></script>
3077 <script type="text/javascript" src="/javascript/jquery/plugins/jquery.bgiframe.min.js"></script>
3078-{% endif %}
3079-{% if not pub %}
3080 <script type="text/javascript">
3081-                    var worksheet_filenames = {{ worksheet_filenames }};
3082+                            var worksheet_filenames = {{ worksheet_filenames }};
3083 </script>
3084 <script type="text/javascript" src="/javascript/sage/main.js"></script>
3085 <script type="text/javascript" src="/javascript/gears/gears_init.js"></script>
3086@@ -40,13 +38,26 @@
3087 {% endif %}
3088 {% endblock %}
3089 
3090-{% block onload %} onLoad="checkForGearsInstalled();"{% endblock %}
3091 
3092-{% block body %}
3093+{% block main %}
3094+<div id="user-main-controls" class="user-controls">
3095+    {% if pub is not defined or not pub %}
3096+    <a href="/new_worksheet" target="_blank">New Worksheet</a>
3097+    <a href="/upload">Upload</a>
3098+    {% if not accounts %}
3099+    <a href="/download_worksheets.zip">Download All Active</a>
3100+    {% endif %}
3101+    {% endif %}
3102 
3103-{% include "html/list_top.html" %}
3104-
3105-<div id="worksheet-list-controls">
3106+    <div id="search-area">
3107+        <form action="." method="GET">
3108+            <input type="hidden" value="{{ typ if not pub else 'pub' }}" name="typ" />
3109+            <input id="search-worksheets" size="20" value="{{ search if search else "" }}" name="search" />
3110+            <button class="add_new_worksheet_menu" id="search-worksheets-button" type="submit">Search Worksheets</button>
3111+        </form>
3112+    </div>
3113+</div>       
3114+<div id="worksheet-list-controls" class="controls">
3115     {% if not pub %}
3116     <div class="action-buttons">
3117         {% if typ == 'archive' %}
3118@@ -81,45 +92,45 @@
3119 
3120 <table cellspacing="0" cellpadding="0" id="worksheet-list">
3121     <thead>
3122-      <tr>
3123-        {% if not pub %}
3124-        <td class="checkbox">
3125-            <input id="controlbox" onClick="set_worksheet_list_checks();" class="entry" type="checkbox" />
3126-        </td>
3127-        {% else %}
3128-        <td><a class="listcontrol" href=".?sort=rating">Rating</a></td>
3129-        {% endif %}
3130+        <tr>
3131+            {% if not pub %}
3132+            <td class="checkbox">
3133+                <input id="controlbox" onClick="set_worksheet_list_checks();" class="entry" type="checkbox" />
3134+            </td>
3135+            {% else %}
3136+            <td><a class="listcontrol" href=".?sort=rating">Rating</a></td>
3137+            {% endif %}
3138 
3139-        <td>
3140-            <a class="listcontrol" href=".?typ={{ typ }}&sort=name{{ '' if sort != 'name' or reverse else '&reverse=True' }}">
3141-                {{ worksheet_heading }}
3142-            </a>
3143-        </td>
3144-       
3145-        <td>
3146-            <a class="listcontrol" href=".?typ={{ typ }}&sort=owner{{ '' if sort != 'owner' or reverse else '&reverse=True' }}">
3147-                Owner {{ '' if pub else ' / Collaborators' }}
3148-            </a>
3149-        </td>
3150+            <td>
3151+                <a class="listcontrol" href=".?typ={{ typ }}&sort=name{{ '' if sort != 'name' or reverse else '&reverse=True' }}">
3152+                    {{ worksheet_heading }}
3153+                </a>
3154+            </td>
3155+           
3156+            <td>
3157+                <a class="listcontrol" href=".?typ={{ typ }}&sort=owner{{ '' if sort != 'owner' or reverse else '&reverse=True' }}">
3158+                    Owner {{ '' if pub else ' / Collaborators' }}
3159+                </a>
3160+            </td>
3161 
3162-        <td>
3163-            <a class="listcontrol" href=".?typ={{ typ }}&{{ '' if sort != 'last_edited' or reverse else 'reverse=True' }}">
3164-                Last Edited
3165-            </a>
3166-        </td>
3167-      </tr>
3168+            <td>
3169+                <a class="listcontrol" href=".?typ={{ typ }}{{ '' if sort != 'last_edited' or reverse else 'reverse&=True' }}">
3170+                    Last Edited
3171+                </a>
3172+            </td>
3173+        </tr>
3174     </thead>
3175     <tbody>
3176         {% if not worksheets %}
3177         {% if pub %}
3178         <tr>
3179-            <td colspan="5" style="padding:20px;text-align:center">
3180+            <td colspan="5">
3181                 There are no published worksheets.
3182             </td>
3183         </tr>
3184         {% elif typ == 'active' %}
3185         <tr>
3186-            <td colspan="5" style="padding:20px;text-align:center">
3187+            <td colspan="5">
3188                 Welcome to Sage! You can <a href="/new_worksheet">create a new worksheet</a>,
3189                 view <a href="/pub/">published worksheets</a>, or read the
3190                 <a href="/help" target="_new">documentation</a>.
3191@@ -145,77 +156,77 @@
3192                 {% else %}
3193                 
3194                 <input type="checkbox" unchecked id="{{ name|css_escape }}" />
3195-                    {# I'm removing this select since it is a massive performance killer and these
3196-                    serve no real purpose at all.  Plus google docs got rid of the analogous menu.
3197-                    <select onchange="go_option(this);" class="worksheet_edit">
3198-                        <option value="" title="File options" selected>File</option>
3199-                        <option value="list_rename_worksheet('{{ name }}','{{ worksheet.name() }}');" title="Change the name of this worksheet.">
3200-                            Rename...
3201-                        </option>           
3202-                        <option value="list_edit_worksheet('{{ name }}');" title="Open this worksheet and edit it">Edit</option>
3203-                        <option value="list_copy_worksheet('{{ name }}');" title="Copy this worksheet">Copy Worksheet</option>
3204-                        <option value="list_share_worksheet('{{ name }}');" title="Share this worksheet with others">Collaborate</option>
3205-                        <option value="list_publish_worksheet('{{ name }}');" title="Publish this worksheet on the internet">Publish</option>
3206-                        <option value="list_revisions_of_worksheet('{{ name }}');" title="See all revisions of this worksheet">Revisions</option>
3207-                    </select>
3208-                    #}     
3209-                    {% endif %}
3210-                </td>
3211+                {# I'm removing this select since it is a massive performance killer and these
3212+                serve no real purpose at all.  Plus google docs got rid of the analogous menu.
3213+                <select onchange="go_option(this);" class="worksheet_edit">
3214+                    <option value="" title="File options" selected>File</option>
3215+                    <option value="list_rename_worksheet('{{ name }}','{{ worksheet.name() }}');" title="Change the name of this worksheet.">
3216+                        Rename...
3217+                    </option>           
3218+                    <option value="list_edit_worksheet('{{ name }}');" title="Open this worksheet and edit it">Edit</option>
3219+                    <option value="list_copy_worksheet('{{ name }}');" title="Copy this worksheet">Copy Worksheet</option>
3220+                    <option value="list_share_worksheet('{{ name }}');" title="Share this worksheet with others">Collaborate</option>
3221+                    <option value="list_publish_worksheet('{{ name }}');" title="Publish this worksheet on the internet">Publish</option>
3222+                    <option value="list_revisions_of_worksheet('{{ name }}');" title="See all revisions of this worksheet">Revisions</option>
3223+                </select>
3224+                #}     
3225+                {% endif %}
3226+            </td>
3227 
3228-                <td class="worksheet_link">
3229-                    <a title="{{ worksheet.name() | escape }}" id="name-{{ name|css_escape }}" class="worksheetname" href="/home/{{ name }}">
3230-                        {% if worksheet.compute_process_has_been_started() %}(running) {% endif %}
3231-                        {{ worksheet.truncated_name(50) | escape}}
3232-                    </a>
3233-                   
3234-                    {% if not pub and worksheet.is_published() %}(Published){% endif %}
3235-                </td>
3236-                <td class="owner_collab">
3237+            <td class="worksheet_link">
3238+                <a title="{{ worksheet.name() | escape }}" id="name-{{ name|css_escape }}" class="worksheetname" href="/home/{{ name }}">
3239+                    {% if worksheet.compute_process_has_been_started() %}(running) {% endif %}
3240+                    {{ worksheet.truncated_name(50) | escape}}
3241+                </a>
3242+               
3243+                {% if not pub and worksheet.is_published() %}(Published){% endif %}
3244+            </td>
3245+            <td class="owner_collab">
3246 
3247-                    {% if not pub %}
3248-                    {{ worksheet.owner() }}
3249-                    {% else %}
3250-                    {{worksheet.worksheet_that_was_published().owner()}}
3251-                    {% endif %}
3252-                   
3253-                    {% if not pub and typ != 'trash' %}
3254+                {% if not pub %}
3255+                {{ worksheet.owner() }}
3256+                {% else %}
3257+                {{worksheet.worksheet_that_was_published().owner()}}
3258+                {% endif %}
3259+               
3260+                {% if not pub and typ != 'trash' %}
3261 
3262-                    {% set shared = False %}
3263+                {% set shared = False %}
3264 
3265-                    {% if worksheet.collaborator_names() %}
3266-                    / {{ worksheet.collaborator_names(5) }}
3267-                    {% set shared = True %}
3268-                    {% endif %}
3269+                {% if worksheet.collaborator_names() %}
3270+                / {{ worksheet.collaborator_names(5) }}
3271+                {% set shared = True %}
3272+                {% endif %}
3273 
3274-                    {% if worksheet.viewer_names() %}
3275-                    / {{ worksheet.viewer_names(5) }}
3276-                    {% set shared = True %}
3277-                    {% endif %}
3278+                {% if worksheet.viewer_names() %}
3279+                / {{ worksheet.viewer_names(5) }}
3280+                {% set shared = True %}
3281+                {% endif %}
3282 
3283-                    {% if (worksheet.owner() != username) or username == 'admin' %}
3284-                    {% set shared = False %}
3285-                    {% endif %}
3286-                   
3287-                    {% if shared %}
3288-                    <a class="share" href="/home/{{ worksheet.filename() }}/share">Add or Delete</a>
3289-                    {% else %}
3290-                    <a class="share" href="/home/{{ worksheet.filename() }}/share">Share now</a>
3291-                    {% endif %}
3292+                {% if (worksheet.owner() != username) or username == 'admin' %}
3293+                {% set shared = False %}
3294+                {% endif %}
3295+               
3296+                {% if shared %}
3297+                <a class="share" href="/home/{{ worksheet.filename() }}/share">Add or Delete</a>
3298+                {% else %}
3299+                <a class="share" href="/home/{{ worksheet.filename() }}/share">Share now</a>
3300+                {% endif %}
3301 
3302-                    {% if worksheet.has_published_version() %}
3303-                    <a href="/home/{{ worksheet.published_version().filename() }}">
3304-                        (published)
3305-                    </a>
3306-                    {% endif %}
3307-                   
3308-                    {% endif %}
3309-                </td>
3310-                <td>
3311-                    {{ worksheet.html_time_since_last_edited() }}
3312-                </td>
3313-            </tr>
3314-            {% endfor %}
3315-            {% endif %}
3316-        </tbody>
3317-    </table>
3318-    {% endblock %}
3319+                {% if worksheet.has_published_version() %}
3320+                <a href="/home/{{ worksheet.published_version().filename() }}">
3321+                    (published)
3322+                </a>
3323+                {% endif %}
3324+               
3325+                {% endif %}
3326+            </td>
3327+            <td>
3328+                {{ worksheet.html_time_since_last_edited() }}
3329+            </td>
3330+        </tr>
3331+        {% endfor %}
3332+        {% endif %}
3333+    </tbody>
3334+</table>
3335+{% endblock %}
3336diff -r 8afee2ec056a sagenb/data/sage/js/master.js
3337--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
3338+++ b/sagenb/data/sage/js/master.js     Sun Jan 03 03:07:50 2010 +0800
3339@@ -0,0 +1,11 @@
3340+$(document).ready(function() {
3341+    body = $('body')
3342+    body_id = body.attr('id')
3343+    if (body_id == 'worksheet-listing-page') {
3344+        checkForGearsInstalled();
3345+    }
3346+
3347+    if (body.hasClass('worksheet-online')) {
3348+        initialize_the_notebook();
3349+    }
3350+});
3351\ No newline at end of file
3352diff -r 8afee2ec056a sagenb/notebook/cell.py
3353--- a/sagenb/notebook/cell.py   Sat Oct 24 18:17:19 2009 +0800
3354+++ b/sagenb/notebook/cell.py   Sun Jan 03 03:07:50 2010 +0800
3355@@ -39,6 +39,8 @@
3356 # we don't get several of these combined in one.
3357 re_cell = re.compile('"cell://.*?"')
3358 re_cell_2 = re.compile("'cell://.*?'")   # same, but with single quotes
3359+# Matches script blocks
3360+re_script = re.compile(r'<script[^>]*?>.*?</script>', re.DOTALL | re.I)
3361 
3362 JEDITABLE_TINYMCE = True
3363 
3364@@ -48,6 +50,7 @@
3365 from sphinx.application import Sphinx
3366 _SAGE_INTROSPECT = None
3367 
3368+
3369 class Cell_generic:
3370     def is_interactive_cell(self):
3371         """
3372@@ -79,41 +82,6 @@
3373         """
3374         raise NotImplementedError
3375 
3376-    def html_new_cell_before(self):
3377-        """
3378-        Returns the HTML code for inserting a new cell before self.
3379-
3380-        EXAMPLES::
3381-
3382-            sage: C = sagenb.notebook.cell.Cell(0, '2+3', '5', None)
3383-            sage: print C.html_new_cell_before()
3384-            <div class="insert_new_cell" id="insert_new_cell_before0">...
3385-        """
3386-        return """<div class="insert_new_cell" id="insert_new_cell_before%(id)s">
3387-                 </div>
3388-<script type="text/javascript">
3389-$("#insert_new_cell_before%(id)s").plainclick(function(e) {insert_new_cell_before(%(id)s);});
3390-$("#insert_new_cell_before%(id)s").shiftclick(function(e) {insert_new_text_cell_before(%(id)s);});
3391-</script>"""%{'id': self.id()}
3392-
3393-    def html_new_cell_after(self):
3394-        """
3395-        Returns the HTML code for inserting a new cell after self.
3396-
3397-        EXAMPLES::
3398-
3399-            sage: C = sagenb.notebook.cell.Cell(0, '2+3', '5', None)
3400-            sage: print C.html_new_cell_after()
3401-            <div class="insert_new_cell" id="insert_new_cell_after0">...
3402-        """
3403-        return """<div class="insert_new_cell" id="insert_new_cell_after%(id)s">
3404-                 </div>
3405-<script type="text/javascript">
3406-$("#insert_new_cell_after%(id)s").plainclick(function(e) {insert_new_cell_after(%(id)s);});
3407-$("#insert_new_cell_after%(id)s").shiftclick(function(e) {insert_new_text_cell_after(%(id)s);});
3408-</script>"""%{'id': self.id()}
3409-
3410-
3411 class TextCell(Cell_generic):
3412     def __init__(self, id, text, worksheet):
3413         """
3414@@ -202,16 +170,26 @@
3415         """
3416         return self.__worksheet
3417 
3418-    def html(self, ncols=0, do_print=False, do_math_parse=True, editing=False):
3419+    def html(self, wrap=None, div_wrap=True, do_print=False, do_math_parse=True, editing=False):
3420         """
3421         Returns an HTML version of self as a string.
3422 
3423         INPUT:
3424 
3425+        - ``wrap`` -- number of columns to wrap at (not used)
3426+
3427+        - ``div_wrap`` -- whether to wrap in a div (not used)
3428+       
3429         - ``do_math_parse`` - bool (default: True)
3430           If True, call math_parse (defined in cell.py)
3431           on the html.
3432 
3433+        - ``do_print`` - bool (default: False)
3434+          If True, display for printing
3435+
3436+        - ``editing`` - bool (default: False)
3437+          If True, # TODO: figure out what this does
3438+
3439         EXAMPLES::
3440 
3441             sage: C = sagenb.notebook.cell.TextCell(0, '2+3', None)
3442@@ -221,80 +199,10 @@
3443             sage: C.html(do_math_parse=True)
3444             '...<div class="text_cell" id="cell_text_0"><span class="math">2+3</span>...'
3445         """
3446-        s = '<span id="cell_outer_%s">'%self.__id
3447-
3448-        if not do_print:
3449-            s += self.html_new_cell_before()
3450-
3451-        s += """<div class="text_cell" id="cell_text_%s">%s</div>"""%(
3452-            self.__id,
3453-            self.html_inner(ncols=ncols, do_print=do_print, do_math_parse=do_math_parse, editing=editing))
3454-
3455-        if JEDITABLE_TINYMCE and hasattr(self.worksheet(),'is_published') and not self.worksheet().is_published() and not self.worksheet().docbrowser() and not do_print:
3456-
3457-            try:
3458-                z = ((self.__text).decode('utf-8')).encode('ascii', 'xmlcharrefreplace')
3459-            except Exception, msg:
3460-                print msg
3461-                # better to get the worksheet at all than to get a blank screen and nothing.
3462-                z = self.__text
3463-
3464-            s += """<script>$("#cell_text_%s").unbind('dblclick').editable(function(value,settings) {
3465-evaluate_text_cell_input(%s,value,settings);
3466-return(value);
3467-}, {
3468-      tooltip   : "",
3469-      placeholder : "",
3470-//      type   : 'textarea',
3471-      type   : 'mce',
3472-      onblur : 'ignore',
3473-      select : false,
3474-      submit : 'Save changes',
3475-      cancel : 'Cancel changes',
3476-      event  : "dblclick",
3477-      style  : "inherit",
3478-      data   : %r
3479-  });
3480-</script>"""%(self.__id,self.__id, z)
3481-
3482-
3483-        if editing and not do_print:
3484-            s += """<script>$("#cell_text_%s").trigger('dblclick');</script>"""%self.__id
3485-
3486-        s += '</span>'
3487-        return s
3488-
3489-    def html_inner(self,ncols=0, do_print=False, do_math_parse=True, editing=False):
3490-        """
3491-        Returns an HTML version of the content of self as a string.
3492-
3493-        INPUT:
3494-
3495-        - ``do_math_parse`` - bool (default: True)
3496-          If True, call math_parse (defined in cell.py)
3497-          on the html.
3498-
3499-        EXAMPLES::
3500-
3501-            sage: C = sagenb.notebook.cell.TextCell(0, '2+3', None)
3502-            sage: C.html_inner()
3503-            '2+3...'
3504-            sage: C.set_input_text("$2+3$")
3505-            sage: C.html_inner(do_math_parse=True)
3506-            '<span class="math">2+3</span>...'
3507-        """
3508-        t = self.__text
3509-        if do_math_parse:
3510-            # Do dollar sign math parsing
3511-            try:
3512-                t = math_parse(t)
3513-            except Exception, msg:
3514-                # Since there is no guarantee the user's input/output
3515-                # is in any way valid, and we don't want to stop the
3516-                # server process (which is doing this work).
3517-                pass
3518-        s = """%s"""%t
3519-        return s
3520+        from .template import template
3521+        return template(os.path.join('html', 'notebook', 'text_cell.html'),
3522+                        cell = self, wrap = wrap, do_print = do_print,
3523+                        do_math_parse = do_math_parse, editing = editing)
3524 
3525 
3526     def plain_text(self, prompts=False):
3527@@ -1510,13 +1418,7 @@
3528         # be evaluated twice.  They are only evaluated in the wrapped
3529         # version of the output.
3530         if ncols == 0:
3531-            while True:
3532-                i = t.lower().find('<script>')
3533-                if i == -1: break
3534-                j = t[i:].lower().find('</script>')
3535-                if j == -1: break
3536-                t = t[:i] + t[i+j+len('</script>'):]
3537-
3538+            t = re_script.sub('', t)
3539         return t
3540 
3541 
3542@@ -1802,22 +1704,7 @@
3543         TODO: Remove this hack (:meth:`doc_html`)
3544         """
3545         self.evaluate()
3546-        if wrap is None:
3547-            wrap = self.notebook().conf()['word_wrap_cols']
3548-        evaluated = self.evaluated()
3549-        if evaluated:
3550-            cls = 'cell_evaluated'
3551-        else:
3552-            cls = 'cell_not_evaluated'
3553-
3554-        html_in  = self.html_in(do_print=do_print)
3555-        introspect = "<div id='introspect_div_%s' class='introspection'></div>"%self.id()
3556-        #html_out = self.html_out(wrap, do_print=do_print)
3557-        html_out = self.html()
3558-        s = html_out
3559-        if div_wrap:
3560-            s = '\n\n<div id="cell_outer_%s" class="cell_visible"><div id="cell_%s" class="%s">'%(self.id(), self.id(), cls) + s + '</div></div>'
3561-        return s
3562+        return self.html(wrap, div_wrap, do_print)
3563 
3564     def html(self, wrap=None, div_wrap=True, do_print=False):
3565         r"""
3566@@ -1842,80 +1729,10 @@
3567             sage: C.html()
3568             '\n\n<div id="cell_outer_0" cl...</div>'
3569         """
3570-        if do_print:
3571-            wrap = 68
3572-            div_wrap = 68
3573-        key = (wrap,div_wrap,do_print)
3574-
3575-        if wrap is None:
3576-            wrap = self.notebook().conf()['word_wrap_cols']
3577-        evaluated = self.evaluated()
3578-        if evaluated or do_print:
3579-            cls = 'cell_evaluated'
3580-        else:
3581-            cls = 'cell_not_evaluated'
3582-
3583-        html_in  = self.html_in(do_print=do_print)
3584-        introspect = "<div id='introspect_div_%s' class='introspection'></div>"%self.id()
3585-        html_out = self.html_out(wrap, do_print=do_print)
3586-
3587-        if 'hideall' in self.percent_directives():
3588-            s = html_out
3589-        else:
3590-            s = html_in + introspect + html_out
3591-
3592-        if div_wrap:
3593-            s = '\n\n<div id="cell_outer_%s" class="cell_visible"><div id="cell_%s" class="%s">'%(self.id(), self.id(), cls) + s + '</div></div>'
3594-
3595-        #self._html_cache[key] = s
3596-        return s
3597-
3598-    def html_in(self, do_print=False, ncols=80):
3599-        """
3600-        Returns the HTML code for the input of this cell.
3601-
3602-        EXAMPLES::
3603-
3604-            sage: C = sagenb.notebook.cell.Cell(0, '2+3', '5', None)
3605-            sage: print C.html_in()
3606-            <div class="insert_new_cell" id="insert_new_cell_before0"...</a>
3607-        """
3608-        s = ''
3609-        id = self.__id
3610-        t = self.__in.rstrip()
3611-
3612-        cls = "cell_input_hide" if 'hide' in self.percent_directives() else "cell_input"
3613-
3614-        if not do_print:
3615-            s += self.html_new_cell_before()
3616-
3617-        r = max(1, number_of_rows(t.strip(), ncols))
3618-
3619-        if do_print:
3620-            if 'hide' in self.percent_directives():
3621-                return ''
3622-
3623-            tt = escape(t).replace('\n','<br>').replace('  ',' &nbsp;') + '&nbsp;'
3624-            s += '<div class="cell_input_print">%s</div>'%tt
3625-        else:
3626-            s += """
3627-               <textarea class="%s" rows=%s cols=%s
3628-                  id         = 'cell_input_%s'
3629-                  onKeyPress = 'return input_keypress(%s,event);'
3630-                  onKeyDown  = 'return input_keydown(%s,event);'
3631-                  onKeyUp    = 'return input_keyup(%s, event);'
3632-                  onBlur     = 'cell_blur(%s); return true;'
3633-                  onFocus    = 'cell_focused(this,%s); return true;'
3634-               >%s</textarea>
3635-            """%(cls, r, ncols, id, id, id, id, id, id, t)
3636-
3637-        if not do_print:
3638-           s+= '<a href="javascript:evaluate_cell(%s,0)" class="eval_button" id="eval_button%s" alt="Click here or press shift-return to evaluate">evaluate</a>'%(id,id)
3639-
3640-        t = escape(t)+" "
3641-
3642-        return s
3643-
3644+        from .template import template
3645+        return template(os.path.join('html', 'notebook', 'cell.html'),
3646+                        cell=self, wrap=wrap,
3647+                        div_wrap=div_wrap, do_print=do_print)
3648 
3649     def url_to_self(self):
3650         """
3651@@ -2087,84 +1904,6 @@
3652             files  = ('&nbsp'*3).join(files)
3653         return images + files
3654 
3655-    def html_out(self, ncols=0, do_print=False):
3656-        r"""
3657-        Returns the HTML for self's output.
3658-
3659-        INPUT:
3660-
3661-        - ``do_print`` -- a boolean stating whether to output HTML
3662-          for print
3663-
3664-        - ``ncols`` -- the number of columns
3665-
3666-        EXAMPLES::
3667-
3668-            sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb')
3669-            sage: nb.add_user('sage','sage','sage@sagemath.org',force=True)
3670-            sage: W = nb.create_new_worksheet('Test', 'sage')
3671-            sage: C = sagenb.notebook.cell.Cell(0, '2+3', '5', W)
3672-            sage: C.html_out()
3673-            '\n...<div class="cell_output_div">\n...</div>'
3674-        """
3675-        if do_print and self.cell_output_type() == 'hidden':
3676-            return '<pre>\n</pre>'
3677-
3678-        out_nowrap = self.output_text(0, html=True)
3679-
3680-        out_html = self.output_html()
3681-        if self.introspect():
3682-            out_wrap = out_nowrap
3683-        else:
3684-            out_wrap = self.output_text(ncols, html=True)
3685-
3686-        typ = self.cell_output_type()
3687-
3688-        if self.computing():
3689-            cls = "cell_div_output_running"
3690-        else:
3691-            cls = 'cell_div_output_' + typ
3692-
3693-        top = '<div class="%s" id="cell_div_output_%s">'%(
3694-                         cls, self.__id)
3695-
3696-        if do_print:
3697-            prnt = "print_"
3698-        else:
3699-            prnt = ""
3700-
3701-        out_wrap   = '<div class="cell_output_%s%s" id="cell_output_%s">%s</div>'%(
3702-            prnt, typ, self.__id, out_wrap)
3703-        if not do_print:
3704-            out_nowrap = '<div class="cell_output_%snowrap_%s" id="cell_output_nowrap_%s">%s</div>'%(
3705-                prnt, typ, self.__id, out_nowrap)
3706-        out_html   = '<div class="cell_output_html_%s" id="cell_output_html_%s">%s </div>'%(
3707-            typ, self.__id, out_html)
3708-
3709-        if do_print:
3710-            out = out_wrap + out_html
3711-        else:
3712-            out = out_wrap + out_nowrap + out_html
3713-
3714-        s = top + out + '</div>'
3715-
3716-        r = ''
3717-        r += '&nbsp;'*(7-len(r))
3718-        tbl = """
3719-               <div class="cell_output_div">
3720-               <table class="cell_output_box"><tr>
3721-               <td class="cell_number" id="cell_number_%s" %s>
3722-                 %s
3723-               </td>
3724-               <td class="output_cell">%s</td></tr></table></div>"""%(
3725-                   self.__id,
3726-                   '' if do_print else 'onClick="cycle_cell_output_type(%s);"'%self.__id,
3727-                   r, s)
3728-
3729-        return tbl
3730-
3731-
3732-
3733 ########
3734 
3735 def format_exception(s0, ncols):
3736diff -r 8afee2ec056a sagenb/notebook/js.py
3737--- a/sagenb/notebook/js.py     Sat Oct 24 18:17:19 2009 +0800
3738+++ b/sagenb/notebook/js.py     Sun Jan 03 03:07:50 2010 +0800
3739@@ -57,10 +57,11 @@
3740 
3741     """
3742     global _cache_javascript
3743-    if _cache_javascript is not None:
3744-        return _cache_javascript
3745+    #if _cache_javascript is not None:
3746+    #    return _cache_javascript
3747 
3748     from template import template
3749+
3750     s = template(os.path.join('js', 'notebook_lib.js'),
3751                  SAGE_URL=SAGE_URL,
3752                  KEY_CODES=keyhandler.all_tests())
3753@@ -71,7 +72,7 @@
3754     # Evil" clause in the license.  Does that prevent us from
3755     # distributing it (i.e., it adds an extra condition to the
3756     # software)?  See http://www.crockford.com/javascript/jsmin.py.txt
3757-    s = JavaScriptCompressor().getPacked(s)
3758+#    s = JavaScriptCompressor().getPacked(s.encode('utf-8'))
3759     _cache_javascript = s
3760     return s
3761 
3762diff -r 8afee2ec056a sagenb/notebook/notebook.py
3763--- a/sagenb/notebook/notebook.py       Sat Oct 24 18:17:19 2009 +0800
3764+++ b/sagenb/notebook/notebook.py       Sun Jan 03 03:07:50 2010 +0800
3765@@ -42,7 +42,7 @@
3766 import server_conf  # server configuration
3767 import user_conf    # user configuration
3768 import user         # users
3769-from   template import template
3770+from   template import template, prettify_time_ago
3771 
3772 
3773 try:
3774@@ -1177,31 +1177,6 @@
3775 
3776 
3777     ##########################################################
3778-    # Importing and exporting worksheets to a plain text format
3779-    ##########################################################
3780-
3781-    def plain_text_worksheet_html(self, filename, prompts=True):
3782-        """
3783-        Return HTML containing the plain text version of a worksheet.
3784-
3785-        INPUT:
3786-
3787-        - ``filename`` - a string; filename of a worksheet
3788-
3789-        - ``prompts`` - a bool (default: True); whether to format the
3790-          text for inclusion in docstrings
3791-
3792-        OUTPUT:
3793-
3794-        - a string - the worksheet's HTML representation
3795-        """
3796-        worksheet = self.get_worksheet_with_filename(filename)
3797-        text = escape(worksheet.plain_text(prompts = prompts))
3798-        return template(os.path.join("html", "notebook", "plain_text_worksheet.html"),
3799-                        worksheet_name = worksheet.name(),
3800-                        worksheet_plain_text = text)
3801-
3802-    ##########################################################
3803     # Server configuration
3804     ##########################################################
3805     def conf(self):
3806@@ -1246,36 +1221,6 @@
3807     ##########################################################
3808     # Worksheet HTML generation
3809     ##########################################################
3810-    def worksheet_html(self, filename, do_print=False):
3811-        r"""
3812-        Return the HTML for a given worksheet.
3813-
3814-        INPUT:
3815-
3816-        - ``filename`` - a string; the worksheet's filename
3817-
3818-        - ``do_print`` - a bool (default: False); whether this is a
3819-          printed worksheet
3820-
3821-        OUTPUT:
3822-
3823-        - a string - the worksheet rendered as HTML
3824-
3825-        EXAMPLES::
3826-
3827-            sage: nb = sagenb.notebook.notebook.load_notebook(tmp_dir()+'.sagenb')
3828-            sage: W = nb.create_new_worksheet('Test', 'admin')
3829-            sage: nb.worksheet_html(W.filename())
3830-            '...<!D...Test...cell_id_list=[1]...</body>...</html>'
3831-        """
3832-        worksheet = self.get_worksheet_with_filename(filename)
3833-        return template(os.path.join("html", "notebook", "worksheet.html"),
3834-                        worksheet_name = worksheet.name(),
3835-                 worksheet_html = worksheet.html(include_title=False, do_print=do_print),
3836-                        do_print = do_print)
3837-
3838-
3839-
3840     def worksheet_list_for_public(self, username, sort='last_edited', reverse=False, search=None):
3841         W = [x for x in self.__worksheets.itervalues() if x.is_published() and not x.is_trashed(user)]
3842 
3843@@ -1323,15 +1268,14 @@
3844             '\n\n{{{id=1|\n\n///\n}}}'
3845             sage: W.save_snapshot('admin')
3846             sage: nb.html_worksheet_revision_list('admin', W)
3847-            '...Revision...Last Edited...seconds...ago...'
3848+            u'...Revision...Last Edited...seconds...ago...'
3849         """
3850         data = worksheet.snapshot_data()  # pairs ('how long ago', key)
3851 
3852         return template(os.path.join("html", "notebook", "worksheet_revision_list.html"),
3853                         data = data, worksheet = worksheet,
3854                         worksheet_filename = worksheet.filename(),
3855-                        username = username, JSMATH = JSMATH,
3856-                        JEDITABLE_TINYMCE = JEDITABLE_TINYMCE)
3857+                        username = username)
3858 
3859 
3860     def html_specific_revision(self, username, ws, rev):
3861@@ -1351,14 +1295,13 @@
3862         - a string - the revision rendered as HTML
3863         """
3864         t = time.time() - float(rev[:-4])
3865-        time_ago = worksheet.convert_seconds_to_meaningful_time_span(t)
3866+        time_ago = prettify_time_ago(t)
3867 
3868         filename = ws.get_snapshot_text_filename(rev)
3869         txt = bz2.decompress(open(filename).read())
3870         W = self.scratch_worksheet()
3871         W.delete_cells_directory()
3872         W.edit_save(txt)
3873-        body_worksheet_html = W.html_worksheet_body(do_print=True, publish=True)
3874 
3875         data = ws.snapshot_data()  # pairs ('how long ago', key)
3876         prev_rev = None
3877@@ -1372,11 +1315,9 @@
3878                 break
3879 
3880         return template(os.path.join("html", "notebook", "specific_revision.html"),
3881-                        worksheet = ws, worksheet_filename = ws.filename(),
3882+                        worksheet = ws,
3883                         username = username, rev = rev, prev_rev = prev_rev,
3884-                        next_rev = next_rev, time_ago = time_ago,
3885-                        body_worksheet_html = body_worksheet_html,
3886-                        JSMATH = JSMATH, JEDITABLE_TINYMCE = JEDITABLE_TINYMCE)
3887+                        next_rev = next_rev, time_ago = time_ago)
3888 
3889     def html_share(self, worksheet, username):
3890         r"""
3891@@ -1397,7 +1338,7 @@
3892             sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb')
3893             sage: W = nb.create_new_worksheet('Test', 'admin')
3894             sage: nb.html_share(W, 'admin')
3895-            '...currently shared...add or remove collaborators...'
3896+            u'...currently shared...add or remove collaborators...'
3897         """
3898         U = self.users()
3899         other_users = [x for x, u in U.iteritems() if not u.is_guest() and not u.username() in [username, 'pub', '_sage_']]
3900@@ -1406,10 +1347,8 @@
3901         return template(os.path.join("html", "notebook", "worksheet_share.html"),
3902                         worksheet = worksheet,
3903                         worksheet_filename = worksheet.filename(),
3904-                        username = username, other_users = other_users,
3905-                        user_is_admin = self.user(username).is_admin(),
3906-                        JSMATH = JSMATH, JEDITABLE_TINYMCE = JEDITABLE_TINYMCE)
3907-
3908+                        username = username, other_users = other_users)
3909+   
3910     def html_download_or_delete_datafile(self, ws, username, filename):
3911         r"""
3912         Return the HTML for the download or delete datafile page.
3913@@ -1431,14 +1370,8 @@
3914             sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb')
3915             sage: W = nb.create_new_worksheet('Test', 'admin')
3916             sage: nb.html_download_or_delete_datafile(W, 'admin', 'bar')
3917-            '...Data file: bar...DATA is a special variable...uploaded...'
3918+            u'...Data file: bar...DATA is a special variable...uploaded...'
3919         """
3920-        path = "/home/%s/data/%s"%(ws.filename(), filename)
3921-
3922-        worksheets = self.get_worksheets_with_viewer(username)
3923-        active_worksheets = [worksheet for worksheet in worksheets if worksheet.is_active(username)]
3924-        sort_worksheet_list(active_worksheets, 'name', False)
3925-
3926         ext = os.path.splitext(filename)[1].lower()
3927         file_is_image, file_is_text = False, False
3928         text_file_content = ""
3929@@ -1452,17 +1385,18 @@
3930         return template(os.path.join("html", "notebook", "download_or_delete_datafile.html"),
3931                         worksheet = ws, worksheet_filename = ws.filename(),
3932                         username = username,
3933-                        active_worksheets = active_worksheets,
3934-                        filename_ = filename, path = path,
3935+                        filename_ = filename,
3936                         file_is_image = file_is_image,
3937                         file_is_text = file_is_text,
3938-                        text_file_content = text_file_content,
3939-                        JSMATH = JSMATH, JEDITABLE_TINYMCE = JEDITABLE_TINYMCE)
3940+                        text_file_content = text_file_content)
3941 
3942 
3943     ##########################################################
3944     # Accessing all worksheets with certain properties.
3945     ##########################################################
3946+    def active_worksheets_for(self, username):
3947+        return [ws for ws in self.get_worksheets_with_viewer(username) if ws.is_active(username)]
3948+   
3949     def get_all_worksheets(self):
3950         return [x for x in self.__worksheets.itervalues() if not x.owner() in ['_sage_', 'pub']]
3951 
3952@@ -1542,23 +1476,6 @@
3953     ###########################################################
3954     # HTML -- generate most html related to the whole notebook page
3955     ###########################################################
3956-    def html_debug_window(self):
3957-        r"""
3958-        Return the HTML for the debug window.
3959-
3960-        OUTPUT:
3961-
3962-        - a string - the debug window rendered as HTML
3963-
3964-        EXAMPLES::
3965-
3966-            sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb')
3967-            sage: nb.html_debug_window()
3968-            "\n<div class='debug_window'>...</div>"
3969-        """
3970-        return template(os.path.join("html", "notebook", "debug_window.html"))
3971-
3972-
3973     def html_plain_text_window(self, worksheet, username):
3974         r"""
3975         Return HTML for the window that displays a plain text version
3976@@ -1579,7 +1496,7 @@
3977             sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb')
3978             sage: W = nb.create_new_worksheet('Test', 'admin')
3979             sage: nb.html_plain_text_window(W, 'admin')
3980-            '...pre class="plaintext"...cell_intext...textfield...'
3981+            u'...pre class="plaintext"...cell_intext...textfield...'
3982         """
3983         plain_text = worksheet.plain_text(prompts=True, banner=False)
3984         plain_text = escape(plain_text).strip()
3985@@ -1609,17 +1526,13 @@
3986             sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb')
3987             sage: W = nb.create_new_worksheet('Test', 'admin')
3988             sage: nb.html_edit_window(W, 'admin')
3989-            '...textarea class="plaintextedit"...{{{id=1|...//...}}}...'
3990+            u'...textarea class="plaintextedit"...{{{id=1|...//...}}}...'
3991         """
3992-        text = worksheet.edit_text()
3993-        text = escape(text)
3994-        n_lines = text.count("\n")+1
3995 
3996         return template(os.path.join("html", "notebook", "edit_window.html"),
3997                         worksheet = worksheet,
3998                         worksheet_filename = worksheet.filename(),
3999-                        username = username, text = text, n_lines = n_lines,
4000-                        JSMATH = JSMATH, JEDITABLE_TINYMCE = JEDITABLE_TINYMCE)
4001+                        username = username)
4002 
4003     def html_beforepublish_window(self, worksheet, username):
4004         r"""
4005@@ -1641,7 +1554,7 @@
4006             sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb')
4007             sage: W = nb.create_new_worksheet('Test', 'admin')
4008             sage: nb.html_beforepublish_window(W, 'admin')
4009-            '...want to publish this worksheet?...re-publish when changes...'
4010+            u'...want to publish this worksheet?...re-publish when changes...'
4011         """
4012         msg = """You can publish your worksheet to the Internet, where anyone will be able to access and view it online.
4013         Your worksheet will be assigned a unique address (URL) that you can send to your friends and colleagues.<br/><br/>
4014@@ -1707,14 +1620,13 @@
4015             sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb')
4016             sage: W = nb.create_new_worksheet('Test', 'admin')
4017             sage: nb.html_upload_data_window(W, 'admin')
4018-            '...Upload or Create Data File...Browse...url...name of a new...'
4019+            u'...Upload or Create Data File...Browse...url...name of a new...'
4020         """
4021         return template(os.path.join("html", "notebook", "upload_data_window.html"),
4022-                        worksheet = ws, worksheet_filename = ws.filename(),
4023-                        username = username,
4024-                        JSMATH = JSMATH, JEDITABLE_TINYMCE = JEDITABLE_TINYMCE)
4025+                        worksheet = ws, username = username)
4026 
4027-    def html(self, worksheet_filename=None, username='guest', show_debug=False, admin=False):
4028+    def html(self, worksheet_filename=None, username='guest', show_debug=False,
4029+             admin=False, do_print=False):
4030         r"""
4031         Return the HTML for a worksheet's index page.
4032 
4033@@ -1737,7 +1649,7 @@
4034             sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb')
4035             sage: W = nb.create_new_worksheet('Test', 'admin')
4036             sage: nb.html(W.filename(), 'admin')
4037-            '...Test...cell_input...plainclick...state_number...worksheet_locked=false...'
4038+            u'...Test...cell_input...plainclick...state_number...worksheet_locked=false...'
4039         """
4040         if worksheet_filename is None or worksheet_filename == '':
4041             worksheet_filename = None
4042@@ -1748,15 +1660,17 @@
4043             except KeyError:
4044                 W = None
4045 
4046-        template_page = os.path.join("html", "notebook", "index.html")
4047+        template_page = os.path.join("html", "notebook", "worksheet_page.html")
4048         if W.docbrowser():
4049             template_page = os.path.join("html", "notebook", "doc_page.html")
4050+        elif do_print:
4051+            template_page = os.path.join('html', 'notebook', 'print_worksheet.html')
4052+        elif W.is_published() or self.user_is_guest(username):
4053+            template_page = os.path.join('html', 'notebook', 'guest_worksheet_page.html')
4054 
4055         return template(template_page, worksheet = W,
4056-                        worksheet_filename = W.filename(),
4057-                        worksheet_html = W.html(), notebook = self,
4058-                        username = username, show_debug = show_debug,
4059-                        JSMATH = JSMATH, JEDITABLE_TINYMCE = JEDITABLE_TINYMCE)
4060+                        notebook = self, do_print=do_print,
4061+                        username = username, show_debug = show_debug)
4062 
4063 ####################################################################
4064 
4065@@ -1993,8 +1907,6 @@
4066 # Misc
4067 ##########################################################
4068 
4069-def clean_name(name):
4070-    return ''.join([x if (x.isalnum() or x == '_') else '_' for x in name])
4071 
4072 def sort_worksheet_list(v, sort, reverse):
4073     """
4074diff -r 8afee2ec056a sagenb/notebook/template.py
4075--- a/sagenb/notebook/template.py       Sat Oct 24 18:17:19 2009 +0800
4076+++ b/sagenb/notebook/template.py       Sun Jan 03 03:07:50 2010 +0800
4077@@ -17,11 +17,13 @@
4078 
4079 import jinja
4080 
4081-from jinja.filters import stringfilter
4082+from jinja.filters import stringfilter, simplefilter
4083 
4084 import os, re, sys
4085 
4086 from sagenb.misc.misc import SAGE_VERSION, DATA
4087+from sagenb.notebook.cell import number_of_rows
4088+from sagenb.notebook.jsmath import math_parse
4089 
4090 
4091 TEMPLATE_PATH = os.path.join(DATA, 'sage')
4092@@ -71,39 +73,56 @@
4093     """
4094     return css_illegal_re.sub('-', string)
4095 
4096-def contained_in(container):
4097+def prettify_time_ago(t):
4098     """
4099-    Given a container, returns a function which takes an environment,
4100-    context, and value and returns True if that value is in the
4101-    container and False otherwise.  This is registered and used as a
4102-    test in the templates.
4103+    Converts seconds to a meaningful string.
4104+
4105+    INPUT
4106+
4107+    - t -- time in seconds
4108+
4109+    """
4110+    if t < 60:
4111+        s = int(t)
4112+        if s == 1:
4113+            return "1 second"
4114+        return "%d seconds"%s
4115+    if t < 3600:
4116+        m = int(t/60)
4117+        if m == 1:
4118+            return "1 minute"
4119+        return "%d minutes"%m
4120+    if t < 3600*24:
4121+        h = int(t/3600)
4122+        if h == 1:
4123+            return "1 hour"
4124+        return "%d hours"%h
4125+    d = int(t/(3600*24))
4126+    if d == 1:
4127+        return "1 day"
4128+    return "%d days"%d
4129+
4130+def clean_name(name):
4131+    """
4132+    Converts a string to a safe/clean name by converting non-alphanumeric characters to underscores.
4133 
4134     INPUT:
4135 
4136-    - ``container`` - a container, e.g., a list or dictionary
4137+    - name -- a string
4138 
4139     EXAMPLES::
4140 
4141-        sage: from sagenb.notebook.template import contained_in
4142-        sage: f = contained_in([1,2,3])
4143-        sage: f(None, None, 2)
4144-        True
4145-        sage: f(None, None, 4)
4146-        False
4147+        sage: from sagenb.notebook.template import clean_name
4148+        sage: print clean_name('this!is@bad+string')
4149+        this_is_bad_string
4150     """
4151-    def wrapped(env, context, value):
4152-        return value in container
4153-    return wrapped
4154-
4155+    return ''.join([x if x.isalnum() else '_' for x in name])
4156 
4157 env.filters['css_escape'] = css_escape
4158-env.tests['contained_in'] = contained_in
4159-
4160-#A dictionary containing the default context
4161-#The values in this dictionary will be updated
4162-#by the
4163-default_context = {'sitename': 'Sage Notebook',
4164-                   'sage_version': SAGE_VERSION}
4165+env.filters['number_of_rows'] = simplefilter(number_of_rows)
4166+env.filters['clean_name'] = stringfilter(clean_name)
4167+env.filters['prettify_time_ago'] = simplefilter(prettify_time_ago)
4168+env.filters['math_parse'] = stringfilter(math_parse)
4169 
4170 def template(filename, **user_context):
4171     """
4172@@ -136,6 +155,14 @@
4173         sage: 'Gr\xc3\xb6bner' in s
4174         True
4175     """
4176+    from sagenb.notebook.notebook import JSMATH, JEDITABLE_TINYMCE
4177+    from twist import notebook
4178+    #A dictionary containing the default context
4179+    default_context = {'sitename': 'Sage Notebook',
4180+                       'sage_version': SAGE_VERSION,
4181+                       'JSMATH': JSMATH,
4182+                       'JEDITABLE_TINYMCE': JEDITABLE_TINYMCE,
4183+                       'conf': notebook.conf() if notebook else None}
4184     try:
4185         tmpl = env.get_template(filename)
4186     except jinja.exceptions.TemplateNotFound:
4187@@ -143,4 +170,4 @@
4188     context = dict(default_context)
4189     context.update(user_context)
4190     r = tmpl.render(**context)
4191-    return r.encode('utf-8')
4192+    return r
4193diff -r 8afee2ec056a sagenb/notebook/twist.py
4194--- a/sagenb/notebook/twist.py  Sat Oct 24 18:17:19 2009 +0800
4195+++ b/sagenb/notebook/twist.py  Sun Jan 03 03:07:50 2010 +0800
4196@@ -135,6 +135,25 @@
4197     return template(os.path.join('html', 'error_message.html'),
4198                     **template_dict)
4199 
4200+class Response(http.Response):
4201+    """
4202+    An adapter for ``twisted.web2.http.Response`` that automatically
4203+    encodes its stream into UTF-8.
4204+
4205+    INPUT:
4206+
4207+    - code -- HTTP status code for the response
4208+
4209+    - headers -- headers to be sent
4210+
4211+    - stream -- content body to send
4212+    """
4213+    def __init__(self, code=None, headers=None, stream=None):
4214+        if stream is not None:
4215+            if isinstance(stream, unicode):
4216+                stream = stream.encode('utf-8', 'ignore')
4217+        super(Response, self).__init__(code, headers, stream)
4218+
4219 def HTMLResponse(*args, **kwds):
4220     """
4221     Returns an HTMLResponse object whose 'Content-Type' header has been set
4222@@ -148,7 +167,7 @@
4223         <Headers: Raw: {'content-type': ['text/html; charset=utf-8']} Parsed: {'content-type': <RecalcNeeded>}>
4224 
4225     """
4226-    response = http.Response(*args, **kwds)
4227+    response = Response(*args, **kwds)
4228     response.headers.addRawHeader('Content-Type', 'text/html; charset=utf-8')
4229     return response
4230 
4231@@ -1008,7 +1027,7 @@
4232 
4233         td['admin'] = nu.is_admin()
4234 
4235-        s = template(os.path.join('html', 'account_settings.html'), **td)
4236+        s = template(os.path.join('html', 'settings', 'account_settings.html'), **td)
4237         return HTMLResponse(stream = s)
4238 
4239 
4240@@ -1023,9 +1042,11 @@
4241 
4242         template_dict = {}
4243         template_dict['auto_table'] = notebook.conf().html_table(updated)
4244-        s = template(os.path.join('html', 'notebook_settings.html'),
4245+        template_dict['admin'] = notebook.user(self.username).is_admin()
4246+        template_dict['username'] = self.username
4247+        s = template(os.path.join('html', 'settings', 'notebook_settings.html'),
4248                      **template_dict)
4249-        return http.Response(stream = s)
4250+        return Response(stream = s)
4251 
4252 
4253 ########################################################
4254@@ -1312,17 +1333,7 @@
4255 class Worksheet_rating_info(WorksheetResource, resource.Resource):
4256     def render(self, ctx):
4257         s = self.worksheet.html_ratings_info()
4258-        return HTMLResponse(stream=message('''
4259-        <h2 align=center>Ratings for %s</h2>
4260-        <h3 align=center><a href='/home/%s'>Go to the worksheet.</a>
4261-        <br><br>
4262-        <table width=70%%align=center border=1 cellpadding=10 cellspacing=0>
4263-        <tr bgcolor="#7799bb"><td width=30em>User</td><td width=10em align=center>Rating</td><td width=10em align=center width=60em>Comment</td></tr>
4264-        %s
4265-        </table>
4266-        <br><br>
4267-        '''%(self.worksheet.name(), self.worksheet.filename(), s)))
4268-
4269+        return HTMLResponse(stream=s)
4270 
4271 class Worksheet_rate(WorksheetResource, resource.Resource):
4272     def render(self, ctx):
4273@@ -1427,11 +1438,6 @@
4274         s = self.worksheet.interrupt()
4275         return HTMLResponse(stream='ok' if s else 'failed')
4276 
4277-class Worksheet_plain(WorksheetResource, resource.Resource):
4278-    def render(self, ctx):
4279-        s = notebook.plain_text_worksheet_html(self.name)
4280-        return HTMLResponse(stream=s)
4281-
4282 class Worksheet_hide_all(WorksheetResource, resource.Resource):
4283     def render(self, ctx):
4284         self.worksheet.hide_all()
4285@@ -1454,7 +1460,7 @@
4286 
4287 class Worksheet_print(WorksheetResource, resource.Resource):
4288     def render(self, ctx):
4289-        s = notebook.worksheet_html(self.name, do_print=True)
4290+        s = notebook.html(self.name, do_print=True)
4291         return HTMLResponse(stream=s)
4292 
4293 
4294@@ -1786,7 +1792,7 @@
4295     def render(self, ctx):
4296         s = css.css()
4297         gzip_handler(ctx)
4298-        response = http.Response(stream=s)
4299+        response = Response(stream=s)
4300         response.headers.addRawHeader('Content-Type', 'text/css; charset=utf-8')
4301         return response
4302 
4303@@ -1794,7 +1800,7 @@
4304     def render(self, ctx):
4305         s = template(os.path.join('css', 'reset.css'))
4306         gzip_handler(ctx)
4307-        return http.Response(stream=s)
4308+        return Response(stream=s)
4309 
4310 class CSS(resource.Resource):
4311     addSlash = True
4312@@ -1824,13 +1830,13 @@
4313                      jsmath_macros = jsmath_macros,
4314                      jsmath_image_fonts = jsmath_image_fonts)
4315 
4316-        return http.Response(stream=s)
4317+        return Response(stream=s)
4318 
4319 class Main_js(resource.Resource):
4320     def render(self, ctx):
4321         gzip_handler(ctx)
4322         s = js.javascript()
4323-        return http.Response(stream=s)
4324+        return Response(stream=s)
4325 
4326 class Keyboard_js_specific(resource.Resource):
4327     def __init__(self, browser_os):
4328@@ -1838,7 +1844,7 @@
4329 
4330     def render(self, ctx):
4331         gzip_handler(ctx)
4332-        return http.Response(stream = self.s)
4333+        return Response(stream = self.s)
4334 
4335 class Keyboard_js(resource.Resource):
4336     def childFactory(self, request, browser_os):
4337@@ -2148,7 +2154,7 @@
4338         # VALIDATE OVERALL.
4339         if empty == required:
4340             # All required fields are empty.  Not really an error.
4341-            form = template(os.path.join('html', 'registration.html'),
4342+            form = template(os.path.join('html', 'accounts', 'registration.html'),
4343                             **empty_form_dict)
4344             return HTMLResponse(stream = form)
4345         elif validated != required:
4346@@ -2156,7 +2162,7 @@
4347             errors = len(required) - len(validated)
4348             template_dict['error'] = 'E ' if errors == 1 else 'Es '
4349 
4350-            form = template(os.path.join('html', 'registration.html'),
4351+            form = template(os.path.join('html', 'accounts', 'registration.html'),
4352                             **template_dict)
4353             return HTMLResponse(stream = form)
4354 
4355@@ -2167,7 +2173,7 @@
4356             template_dict['username_taken'] = True
4357             template_dict['error'] = 'E '
4358 
4359-            form = template(os.path.join('html', 'registration.html'),
4360+            form = template(os.path.join('html', 'accounts', 'registration.html'),
4361                             **template_dict)
4362             return HTMLResponse(stream = form)
4363 
4364@@ -2248,7 +2254,7 @@
4365 
4366             return HTMLResponse(stream=message("A new password has been sent to your e-mail address.", '/'))
4367         else:
4368-            s = template(os.path.join('html', 'account_recovery.html'))
4369+            s = template(os.path.join('html', 'accounts', 'account_recovery.html'))
4370         return HTMLResponse(stream=s)
4371 
4372 class ListOfUsers(resource.Resource):
4373@@ -2285,29 +2291,36 @@
4374         users = sorted(notebook.valid_login_names())
4375         del users[users.index('admin')]
4376         template_dict['users'] = [notebook.user(i) for i in users]
4377-        return HTMLResponse(stream = template(os.path.join('html', 'user_management.html'), **template_dict))
4378+        template_dict['admin'] = notebook.user(self.username).is_admin()
4379+        template_dict['username'] = self.username
4380+        return HTMLResponse(stream = template(os.path.join('html', 'settings', 'user_management.html'), **template_dict))
4381 
4382 class AdminAddUser(resource.PostableResource):
4383-    def __init__(self, userdb):
4384-        self.userdb = userdb
4385+    def __init__(self, username):
4386+        self.username = username
4387 
4388     def render(self, request):
4389-
4390+        template_dict = {'admin': notebook.user(self.username).is_admin(),
4391+                         'username': self.username}
4392         if 'username' in request.args:
4393             username = request.args['username'][0]
4394             if not is_valid_username(username):
4395-                return HTMLResponse(stream=template(os.path.join('html', 'admin_add_user.html'), error='username_invalid', username=username))
4396+                return HTMLResponse(stream=template(os.path.join('html', 'settings', 'admin_add_user.html'),
4397+                                                    error='username_invalid', username=username, **template_dict))
4398 
4399             from random import choice
4400             import string
4401             chara = string.letters + string.digits
4402             password = ''.join([choice(chara) for i in range(8)])
4403             if username in notebook.usernames():
4404-                return HTMLResponse(stream=template(os.path.join('html', 'admin_add_user.html'), error='username_taken', username=username))
4405+                return HTMLResponse(stream=template(os.path.join('html', 'settings', 'admin_add_user.html'),
4406+                                                    error='username_taken', username_input=username, **template_dict))
4407             notebook.add_user(username, password, '', force=True)
4408-            return HTMLResponse(stream=message('The temporary password for the new user <em>%s</em> is <em>%s</em>' % (username, password), '/adduser'))
4409+            return HTMLResponse(stream=message('The temporary password for the new user <em>%s</em> is <em>%s</em>' %
4410+                                               (username, password), '/adduser'))
4411         else:
4412-            return HTMLResponse(stream=template(os.path.join('html', 'admin_add_user.html')))
4413+           
4414+            return HTMLResponse(stream=template(os.path.join('html', 'settings', 'admin_add_user.html'), **template_dict))
4415 
4416 class InvalidPage(resource.Resource):
4417     addSlash = True
4418@@ -2463,8 +2476,8 @@
4419     # better call userchildFactory it in the base class (Toplevel)!
4420     def userchildFactory(self, request, name):
4421         try:
4422-            return UserToplevel.__dict__['userchild_%s'%name](username = self.username)
4423-        except KeyError:
4424+            return getattr(self.__class__, 'userchild_%s' % name )(username = self.username)
4425+        except AttributeError:
4426             pass
4427 
4428     userchild_doc = Doc
4429@@ -2506,11 +2519,11 @@
4430 
4431 class AdminToplevel(UserToplevel):
4432     addSlash = True
4433-
4434+   
4435     userchild_home = WorksheetsAdmin
4436-    child_users = ListOfUsers
4437-    child_adduser = AdminAddUser
4438-    child_notebooksettings = NotebookSettingsPage
4439+    userchild_users = ListOfUsers
4440+    userchild_adduser = AdminAddUser
4441+    userchild_notebooksettings = NotebookSettingsPage
4442 
4443 def user_type(username):
4444     # one of admin, guest, user
4445diff -r 8afee2ec056a sagenb/notebook/worksheet.py
4446--- a/sagenb/notebook/worksheet.py      Sat Oct 24 18:17:19 2009 +0800
4447+++ b/sagenb/notebook/worksheet.py      Sun Jan 03 03:07:50 2010 +0800
4448@@ -43,7 +43,7 @@
4449 
4450 # Imports specifically relevant to the sage notebook
4451 from   cell import Cell, TextCell
4452-from template import template
4453+from template import template, clean_name, prettify_time_ago
4454 
4455 # Set some constants that will be used for regular expressions below.
4456 whitespace = re.compile('\s')  # Match any whitespace character
4457@@ -110,7 +110,7 @@
4458         sage: sagenb.notebook.worksheet.worksheet_filename('Example#%&! work\\sheet 3', 'sage10')
4459         'sage10/Example_____work_sheet_3'
4460     """
4461-    return os.path.join(owner, _notebook.clean_name(name))
4462+    return os.path.join(owner, clean_name(name))
4463 
4464 def Worksheet_from_basic(obj, notebook_worksheet_directory):
4465     """
4466@@ -1184,7 +1184,7 @@
4467                 del self.__published_version
4468                 raise ValueError
4469         except AttributeError:
4470-            raise ValueError, "no published version"
4471+            raise ValueError("no published version")
4472 
4473     def set_worksheet_that_was_published(self, W):
4474         """
4475@@ -1319,19 +1319,10 @@
4476             sage: W.rate(0, 'this lacks content', 'riemann')
4477             sage: W.rate(3, 'this is great', 'hilbert')
4478             sage: W.html_ratings_info()
4479-            '<tr><td>hilbert</td><td align=center>3</td><td>this is great</td></tr>\n<tr><td>riemann</td><td align=center>0</td><td>this lacks content</td></tr>'
4480+            u'...hilbert...3...this is great...this lacks content...'
4481         """
4482-        ratings = self.ratings()
4483-        lines = []
4484-        for z in sorted(ratings):
4485-            if len(z) == 2:
4486-                person, rating = z
4487-                comment = ''
4488-            else:
4489-                person, rating, comment = z
4490-            lines.append('<tr><td>%s</td><td align=center>%s</td><td>%s</td></tr>'%(
4491-                person, rating, '&nbsp;' if not comment else comment))
4492-        return '\n'.join(lines)
4493+        return template(os.path.join('html', 'worksheet', 'ratings_info.html'),
4494+                        worksheet = self)
4495 
4496     def rating(self):
4497         """
4498@@ -1972,7 +1963,7 @@
4499         filenames = os.listdir(self.snapshot_directory())
4500         filenames.sort()
4501         t = time.time()
4502-        v = [(convert_seconds_to_meaningful_time_span(t - float(os.path.splitext(x)[0]))+ self._saved_by_info(x), x)  \
4503+        v = [(prettify_time_ago(t - float(os.path.splitext(x)[0]))+ self._saved_by_info(x), x)  \
4504              for x in filenames]
4505         self.__snapshot_data = v
4506         return v
4507@@ -2268,8 +2259,7 @@
4508                 print msg
4509         return cells_html
4510 
4511-    def html(self, include_title=True, do_print=False,
4512-             confirm_before_leave=False, read_only=False):
4513+    def html(self, do_print=False, publish=False):
4514         r"""
4515         INPUT:
4516 
4517@@ -2286,14 +2276,10 @@
4518             sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb')
4519             sage: W = nb.create_new_worksheet('Test', 'admin')
4520             sage: W.html()
4521-            '\n\n\n<div class="cell_input_active" id="cell_resizer"></div>\n\n<div class="worksheet_cell_list" id...'
4522+            u'...class="cell_input_active"..."worksheet_cell_list"...id="cell_1"...id="cell_output_html_1"'
4523         """
4524-        return template(os.path.join("html", "worksheet", "worksheet.html"),
4525-                        published = self.is_published(),
4526-                        do_print = do_print, confirm_before_leave = confirm_before_leave,
4527-                        cells_html = self.html_cell_list(do_print=do_print),
4528-                        cell_id_list = self.cell_id_list(),
4529-                        state_number = self.state_number())
4530+        return template(os.path.join("html", "notebook", "worksheet.html"),
4531+                        do_print=do_print, publish=publish, worksheet=self)
4532 
4533     def truncated_name(self, max=30):
4534         name = self.name()
4535@@ -2310,96 +2296,6 @@
4536     def set_is_doc_worksheet(self, value):
4537         self.__is_doc_worksheet = value
4538 
4539-    def html_save_discard_buttons(self):
4540-        r"""
4541-        OUTPUT:
4542-
4543-        - string -- the HTML for the save, discard, etc. buttons
4544-
4545-        EXAMPLES::
4546-
4547-            sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb')
4548-            sage: W = nb.create_new_worksheet('Test', 'admin')
4549-            sage: W.html_save_discard_buttons()
4550-            '\n\n<button name="button_save" title="Save changes" onClick="save_worksheet();">Save<...'
4551-        """
4552-        return template(os.path.join("html", "worksheet", "save_discard_buttons.html"),
4553-                        doc_worksheet = self.is_doc_worksheet())
4554-
4555-    def html_share_publish_buttons(self, select=None, backwards=False):
4556-        r"""
4557-        INPUT:
4558-
4559-        - select - a boolean
4560-
4561-        - backwards - a boolean
4562-
4563-        OUTPUT:
4564-
4565-        - string -- the HTML for the share, publish, etc. buttons
4566-
4567-        EXAMPLES::
4568-
4569-            sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb')
4570-            sage: W = nb.create_new_worksheet('Test', 'admin')
4571-            sage: W.html_share_publish_buttons()
4572-            '...Print...Worksheet...Edit...Undo...Share...Publish...'
4573-        """
4574-        return template(os.path.join("html", "worksheet", "share_publish_buttons.html"),
4575-                        worksheet = self, select = select, backwards = backwards)
4576-
4577-    def html_menu(self):
4578-        r"""
4579-        OUTPUT:
4580-
4581-        - string -- the HTML for the menus of the worksheet
4582-
4583-        EXAMPLES::
4584-
4585-            sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb')
4586-            sage: W = nb.create_new_worksheet('Test', 'admin')
4587-            sage: W.html_menu()
4588-            '...File...Action...Data...pretty_print...'
4589-        """
4590-        return template(os.path.join("html", "worksheet", "menu.html"),
4591-                        name = _notebook.clean_name(self.name()),
4592-                        filename_ = self.filename(), data = sorted(self.attached_data_files()),
4593-                        systems_enumerated = enumerate(self.notebook().systems()),
4594-                        system_names = self.notebook().system_names(),
4595-                        current_system_index = self.system_index(),
4596-                        pretty_print = self.pretty_print(),
4597-                        doc_worksheet = self.is_doc_worksheet())
4598-
4599-    def html_worksheet_body(self, do_print, publish=False):
4600-        r"""
4601-        INPUT:
4602-
4603-        - publish - a boolean stating whether the worksheet is published
4604-
4605-        - do_print - a boolean
4606-
4607-        OUTPUT:
4608-
4609-        - string -- the HTML for the File menu of the worksheet
4610-
4611-        EXAMPLES::
4612-
4613-            sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb')
4614-            sage: W = nb.create_new_worksheet('Test', 'admin')
4615-            sage: W.html_worksheet_body(false)
4616-            '\n\n<div class="cell_input_active" id="cell_resizer"></div>\n\n<div class="worksheet_cell_list" id...'
4617-        """
4618-        published = self.is_published() or publish
4619-        ncols = self.notebook().conf()['word_wrap_cols']
4620-        cells_html = ""
4621-        for cell in self.cell_list():
4622-            cells_html += cell.html(ncols, do_print=do_print) + '\n'
4623-
4624-        return template(os.path.join("html", "worksheet", "worksheet_body.html"),
4625-                        cells_html = cells_html,
4626-                        published = published,
4627-                        do_print = do_print)
4628-
4629 
4630     ##########################################################
4631     # Last edited
4632@@ -2445,7 +2341,7 @@
4633             sage: W.last_to_edit()
4634             'john'
4635             sage: W.date_edited()
4636-            time.struct_time(tm_year=2009, tm_mon=10, tm_mday=8, tm_hour=12, tm_min=23, tm_sec=20, tm_wday=3, tm_yday=281, tm_isdst=1)
4637+            time.struct_time(tm_year=2009, tm_mon=10, tm_mday=..., tm_hour=..., tm_min=23, tm_sec=20, tm_wday=..., tm_yday=..., tm_isdst=...)
4638             sage: t = W.time_since_last_edited() # just test that call works
4639         """
4640         username = str(username); tm = float(tm)
4641@@ -2514,7 +2410,7 @@
4642 
4643     def html_time_since_last_edited(self):
4644         t = self.time_since_last_edited()
4645-        tm = convert_seconds_to_meaningful_time_span(t)
4646+        tm = prettify_time_ago(t)
4647         return template(os.path.join("html", "worksheet", "time_since_last_edited.html"),
4648                         last_editor = self.last_to_edit(),
4649                         time = tm)
4650@@ -4115,28 +4011,6 @@
4651     return i
4652 
4653 
4654-def convert_seconds_to_meaningful_time_span(t):
4655-    if t < 60:
4656-        s = int(t)
4657-        if s == 1:
4658-            return "1 second"
4659-        return "%d seconds"%s
4660-    if t < 3600:
4661-        m = int(t/60)
4662-        if m == 1:
4663-            return "1 minute"
4664-        return "%d minutes"%m
4665-    if t < 3600*24:
4666-        h = int(t/3600)
4667-        if h == 1:
4668-            return "1 hour"
4669-        return "%d hours"%h
4670-    d = int(t/(3600*24))
4671-    if d == 1:
4672-        return "1 day"
4673-    return "%d days"%d
4674-
4675-
4676 def convert_time_to_string(t):
4677     return time.strftime('%B %d, %Y %I:%M %p', time.localtime(float(t)))
4678 
4679diff -r 8afee2ec056a sagenb/testing/notebook_test_case.py
4680--- a/sagenb/testing/notebook_test_case.py      Sat Oct 24 18:17:19 2009 +0800
4681+++ b/sagenb/testing/notebook_test_case.py      Sun Jan 03 03:07:50 2010 +0800
4682@@ -145,7 +145,7 @@
4683         """
4684         sel = self.selenium
4685         sel.click("//button[@name='button_save' and @onclick='save_worksheet_and_close();']")
4686-        self.wait_for_title('Active Worksheets')
4687+        self.wait_for_title('Active Worksheets -- Sage')
4688         sel.wait_for_page_to_load("30000")
4689 
4690     def wait_for_title(self, title):
4691@@ -176,14 +176,14 @@
4692         sel = self.selenium
4693         sel.click("id=register-link")
4694         sel.wait_for_page_to_load(30000)
4695-        self.wait_for_title("Sign up")
4696+        self.wait_for_title("Sign up -- Sage")
4697 
4698         sel.type("username", username)
4699         sel.type("password", password)
4700         sel.type("retype_password", password)
4701         sel.click("id=create-account-button")
4702         sel.wait_for_page_to_load(30000)
4703-        self.wait_for_title('Sign in')
4704+        self.wait_for_title('Sign in -- Sage')
4705         self.assertTrue(sel.is_text_present('regexp:Congratulations '))
4706 
4707     def login_as(self, username, password='asdfasdf'):
4708@@ -248,7 +248,7 @@
4709         sel = self.selenium
4710         sel.click("link=Publish")
4711         sel.wait_for_page_to_load("30000")
4712-        sel.click("//input[@value='Yes']")
4713+        sel.click("//button[text()='Yes']")
4714         sel.wait_for_page_to_load("30000")
4715         sel.click("link=Worksheet")
4716         sel.wait_for_page_to_load("30000")
4717@@ -261,7 +261,7 @@
4718         sel = self.selenium
4719         sel.click("link=Publish")
4720         sel.wait_for_page_to_load("30000")
4721-        sel.click("//input[@value='Re-publish worksheet']")
4722+        sel.click("//button[text()='Re-publish worksheet']")
4723         sel.wait_for_page_to_load("30000")
4724         sel.click("link=Worksheet")
4725         sel.wait_for_page_to_load("30000")
4726diff -r 8afee2ec056a sagenb/testing/tests/test_accounts.py
4727--- a/sagenb/testing/tests/test_accounts.py     Sat Oct 24 18:17:19 2009 +0800
4728+++ b/sagenb/testing/tests/test_accounts.py     Sun Jan 03 03:07:50 2010 +0800
4729@@ -89,7 +89,7 @@
4730 
4731 
4732         self.assertEqual(sel.get_location(), 'http://localhost:%d/home/chris/1/' % self.sagenb_port)
4733-        self.assertEqual(sel.get_title(), 'Copy of Shared Worksheet (Sage)')
4734+        self.assertEqual(sel.get_title(), u'Copy of Shared Worksheet -- Sage')
4735         self.assert_(sel.is_text_present('by chris'), 'chris does not own the worksheet')
4736         self.assertEqual(self.get_cell_output(1), '4')
4737         
4738diff -r 8afee2ec056a sagenb/testing/tests/test_worksheet.py
4739--- a/sagenb/testing/tests/test_worksheet.py    Sat Oct 24 18:17:19 2009 +0800
4740+++ b/sagenb/testing/tests/test_worksheet.py    Sun Jan 03 03:07:50 2010 +0800
4741@@ -144,7 +144,7 @@
4742         sel.click("link=(Empty Trash)")
4743         self.failUnless(re.search(r"^Emptying the trash will permanently delete all items in the trash\. Continue[\s\S]$", sel.get_confirmation()))
4744 
4745-        self.wait_for_title('Deleted Worksheets')
4746+        self.wait_for_title('Deleted Worksheets -- Sage')
4747         sel.wait_for_page_to_load("30000")
4748         #Leave and make sure that the file was actually deleted
4749 
4750diff -r 8afee2ec056a sagenb/testing/tests/test_worksheet_list.py
4751--- a/sagenb/testing/tests/test_worksheet_list.py       Sat Oct 24 18:17:19 2009 +0800
4752+++ b/sagenb/testing/tests/test_worksheet_list.py       Sun Jan 03 03:07:50 2010 +0800
4753@@ -95,7 +95,7 @@
4754             self.goto_published_worksheets()
4755             self.assertEqual(sel.get_text('css=td.worksheet_link'), title,
4756                              '%s-published worksheet %s not listed first' % (prefix, title))
4757-            lastedit = sel.get_text('css=span.lastedit')
4758+            lastedit = sel.get_text('css=.lastedit')
4759             self.assert_(self.username in lastedit,
4760                          '%s-published worksheet has wrong last edited field %s' % (prefix, lastedit))
4761 
4762diff -r 8afee2ec056a sass/src/_accounts.sass
4763--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
4764+++ b/sass/src/_accounts.sass   Sun Jan 03 03:07:50 2010 +0800
4765@@ -0,0 +1,55 @@
4766+.accounts-page
4767
4768+  #wrapper
4769+    :margin 0 auto
4770+    :max-width 600px
4771+
4772+
4773+  h1, h2, h3, h4, h5
4774+    :font-weight normal
4775+
4776+
4777+  h1
4778+    :border-bottom 1px solid #696969
4779+    :font-size 2em
4780+    :padding 10px 0
4781+
4782+
4783+  h2
4784+    :font-weight bold
4785+
4786+
4787+  h1, h2, p, li
4788+    :margin-bottom 10px
4789+
4790+
4791+  .entry
4792+    :margin-bottom 10px
4793+    :border 1px solid #999
4794+    :padding 3px
4795+    :width 200
4796+
4797+
4798+  li
4799+    :border-bottom 1px solid #CCC
4800+
4801+
4802+  .error
4803+    :color red
4804+
4805+
4806+  .error_found
4807+    :color red
4808+    :font-size 1.5em
4809+
4810+
4811+  button
4812+    :margin-right 1em
4813+
4814+  form 
4815+    label
4816+      :display block
4817+    div
4818+      :margin-bottom 1em
4819+    a
4820+      :text-decoration none
4821\ No newline at end of file
4822diff -r 8afee2ec056a sass/src/_guest_worksheet.sass
4823--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
4824+++ b/sass/src/_guest_worksheet.sass    Sun Jan 03 03:07:50 2010 +0800
4825@@ -0,0 +1,5 @@
4826+#guest-worksheet-page
4827+  h1, h2
4828+    :text-align center
4829+  ul.controls
4830+    +horizontal-list(0.5em)
4831\ No newline at end of file
4832diff -r 8afee2ec056a sass/src/_login.sass
4833--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
4834+++ b/sass/src/_login.sass      Sun Jan 03 03:07:50 2010 +0800
4835@@ -0,0 +1,32 @@
4836+#login-page
4837+  h2
4838+    :font-size 1.5em
4839+    :margin-bottom 0.375em
4840+
4841+  h1,h2,h3,h4,h5,h6
4842+    :line-height 1em
4843+
4844+  p
4845+    :margin-bottom 1em
4846+
4847+  strong
4848+    :font-weight bold
4849+
4850+  #desc
4851+    :float left
4852+    :margin-right 400px
4853+
4854+  div
4855+    :padding 0.5em 1em
4856+
4857+  #sign-in-box
4858+    :background-color #efefff
4859+    :float left
4860+    :margin-left -400px
4861+    :width 350px
4862+   
4863+    form
4864+      label
4865+        :display block
4866+    a
4867+      :font-size 0.875em
4868\ No newline at end of file
4869diff -r 8afee2ec056a sass/src/_print_worksheet.sass
4870--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
4871+++ b/sass/src/_print_worksheet.sass    Sun Jan 03 03:07:50 2010 +0800
4872@@ -0,0 +1,3 @@
4873+#print-page
4874+  h1
4875+    :text-align center
4876\ No newline at end of file
4877diff -r 8afee2ec056a sass/src/_pygment.sass
4878--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
4879+++ b/sass/src/_pygment.sass    Sun Jan 03 03:07:50 2010 +0800
4880@@ -0,0 +1,226 @@
4881+.hll
4882+  :background-color #ffffcc
4883+
4884+
4885+.c
4886+  :color #408090
4887+  :font-style italic
4888+
4889+
4890+.err
4891+  :border 1px solid #FF0000
4892+
4893+
4894+.k
4895+  :color #007020
4896+  :font-weight bold
4897+
4898+
4899+.o
4900+  :color #666666
4901+
4902+
4903+.cm
4904+  :color #408090
4905+  :font-style italic
4906+
4907+
4908+.cp
4909+  :color #007020
4910+
4911+
4912+.c1
4913+  :color #408090
4914+  :font-style italic
4915+
4916+
4917+.cs
4918+  :color #408090
4919+  :background-color #fff0f0
4920+
4921+
4922+.gd
4923+  :color #A00000
4924+
4925+
4926+.ge
4927+  :font-style italic
4928+
4929+
4930+.gr
4931+  :color #FF0000
4932+
4933+
4934+.gh
4935+  :color #000080
4936+  :font-weight bold
4937+
4938+
4939+.gi
4940+  :color #00A000
4941+
4942+
4943+.go
4944+  :color #0000aa
4945+
4946+
4947+.gp
4948+  :color #c65d09
4949+  :font-weight bold
4950+
4951+
4952+.gs
4953+  :font-weight bold
4954+
4955+
4956+.gu
4957+  :color #800080
4958+  :font-weight bold
4959+
4960+
4961+.gt
4962+  :color #0040D0
4963+
4964+
4965+.kc, .kd, .kn
4966+  :color #007020
4967+  :font-weight bold
4968+
4969+
4970+.kp
4971+  :color #007020
4972+
4973+
4974+.kr
4975+  :color #007020
4976+  :font-weight bold
4977+
4978+
4979+.kt
4980+  :color #902000
4981+
4982+
4983+.m
4984+  :color #208050
4985+
4986+
4987+.s, .na
4988+  :color #4070a0
4989+
4990+
4991+.nb
4992+  :color #007020
4993+
4994+
4995+.nc
4996+  :color #0e84b5
4997+  :font-weight bold
4998+
4999+
5000+.no
5001+  :color #60add5
5002+
5003+
5004+.nd
5005+  :color #555555
5006+  :font-weight bold
5007+
5008+
5009+.ni
5010+  :color #d55537
5011+  :font-weight bold
5012+
5013+
5014+.ne
5015+  :color #007020
5016+
5017+
5018+.nf
5019+  :color #06287e
5020+
5021+
5022+.nl
5023+  :color #002070
5024+  :font-weight bold
5025+
5026+
5027+.nn
5028+  :color #0e84b5
5029+  :font-weight bold
5030+
5031+
5032+.nt
5033+  :color #062873
5034+  :font-weight bold
5035+
5036+
5037+.nv
5038+  :color #bb60d5
5039+
5040+
5041+.ow
5042+  :color #007020
5043+  :font-weight bold
5044+
5045+
5046+.w
5047+  :color #bbbbbb
5048+
5049+
5050+.mf, .mh, .mi, .mo
5051+  :color #208050
5052+
5053+
5054+.sb, .sc
5055+  :color #4070a0
5056+
5057+
5058+.sd
5059+  :color #4070a0
5060+  :font-style italic
5061+
5062+
5063+.s2
5064+  :color #4070a0
5065+
5066+
5067+.se
5068+  :color #4070a0
5069+  :font-weight bold
5070+
5071+
5072+.sh
5073+  :color #4070a0
5074+
5075+
5076+.si
5077+  :color #70a0d0
5078+  :font-style italic
5079+
5080+
5081+.sx
5082+  :color #c65d09
5083+
5084+
5085+.sr
5086+  :color #235388
5087+
5088+
5089+.s1
5090+  :color #4070a0
5091+
5092+
5093+.ss
5094+  :color #517918
5095+
5096+
5097+.bp
5098+  :color #007020
5099+
5100+
5101+.vc, .vg, .vi
5102+  :color #bb60d5
5103+
5104+
5105+.il
5106+  :color #208050
5107\ No newline at end of file
5108diff -r 8afee2ec056a sass/src/_settings.sass
5109--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
5110+++ b/sass/src/_settings.sass   Sun Jan 03 03:07:50 2010 +0800
5111@@ -0,0 +1,63 @@
5112+.settings-page
5113+  :line-height 1.4
5114+
5115+  h1
5116+    :font-size 2em
5117+    :padding 0 5px
5118+
5119+  label
5120+    :display block
5121+
5122+  #buttons
5123+    :padding 5px
5124
5125+    button
5126+      :margin-right 1em
5127+    a
5128+      :text-decoration none
5129+
5130+  h2
5131+    :font-size 1.5em
5132+    :margin 0 0 0.75em
5133+
5134+
5135+  .section
5136+    :border-bottom 1px solid #CCC
5137+    :padding 5px
5138+    :margin 0.5em 0
5139+
5140+    div
5141+      :margin-bottom 0.5em
5142+
5143+  .error, .error_found
5144+    :color red
5145+
5146+  .error_found
5147+    :font-size 1.2em
5148+
5149+  .updated
5150+    :color green
5151+
5152+  input.c1
5153+    :width 200px
5154+
5155+#settings-nav
5156+  +horizontal-list(0.5em)
5157+  li
5158+    :border-right 1px solid #ccc
5159+    &:last-child, &.last
5160+      :border-right none
5161+
5162+#user-management-page
5163+  table
5164+    :border-collapse collapse
5165+  th, td
5166+    :border 1px solid #696969
5167+    :padding 0.25em
5168+
5169+  th
5170+    :background #CCC
5171+
5172+  a:link, a:visited
5173+    :color = !link_color
5174+       
5175diff -r 8afee2ec056a sass/src/_worksheet_aux.sass
5176--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
5177+++ b/sass/src/_worksheet_aux.sass      Sun Jan 03 03:07:50 2010 +0800
5178@@ -0,0 +1,18 @@
5179+#before-publish-page
5180+  form
5181+    a
5182+      :text-decoration none
5183+    button
5184+      :margin-left 1em
5185+      :margin-bottom 0.5em
5186+    input
5187+      :margin-left 1em
5188+
5189+#after-publish-page
5190+  input
5191+    :margin-top 1em
5192+
5193+#edit-page
5194+  .sharebar
5195+    span
5196+      :margin-right 2em
5197\ No newline at end of file
5198diff -r 8afee2ec056a sass/src/account_settings.sass
5199--- a/sass/src/account_settings.sass    Sat Oct 24 18:17:19 2009 +0800
5200+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
5201@@ -1,46 +0,0 @@
5202-@import compass/reset.sass
5203-
5204-html
5205-  :font-size 100.1%
5206-
5207-
5208-body
5209-  :font 100%/1.4 Arial, Helvetica, sans-serif
5210-
5211-
5212-h1
5213-  :background #DCDCDC
5214-  :border-bottom 1px solid #CCC
5215-  :font-size 2em
5216-  :padding 0 5px
5217-
5218-label
5219-  :display block
5220-
5221-#buttons
5222-  :background #DCDCDC
5223-  :padding 5px
5224
5225-  button
5226-    :margin-right 1em
5227-
5228-h2
5229-  :font-size 1.5em
5230-
5231-
5232-.section
5233-  :border-bottom 1px solid #CCC
5234-  :padding 5px
5235-
5236-  div
5237-    :margin-bottom 0.5em
5238-
5239-.error
5240-  :color red
5241-
5242-.updated
5243-  :color green
5244-
5245-
5246-input.c1
5247-  :width 200px
5248diff -r 8afee2ec056a sass/src/main.sass
5249--- a/sass/src/main.sass        Sat Oct 24 18:17:19 2009 +0800
5250+++ b/sass/src/main.sass        Sun Jan 03 03:07:50 2010 +0800
5251@@ -1,14 +1,18 @@
5252 @import compass/utilities/general.sass
5253 @import compass/utilities/lists.sass
5254+@import partials/base.sass
5255 @import partials/mixins.sass
5256 @import typography/base.sass
5257 
5258+
5259 body
5260   :background-color white
5261+  +sans-serif-stack
5262 
5263   &.worksheet-online
5264     :margin-bottom 80%
5265 
5266+
5267 .hidden
5268   :display none
5269 
5270@@ -48,7 +52,7 @@
5271     :text-indent 13px
5272     :color black
5273 
5274-#controls
5275+#main-controls
5276   :float right
5277   :width 65%
5278 
5279@@ -99,7 +103,7 @@
5280 
5281 
5282 div
5283-  &#usercontrols
5284+  &#user-controls
5285     +clearfix
5286     :clear both
5287     :border-bottom 1px solid #c9d7f1
5288@@ -274,7 +278,7 @@
5289     :border-left 2px solid #c0c0c0
5290 
5291   &.introspection
5292-    :font-family monospace
5293+    +monospace-stack
5294     :font-size 15px
5295     :background-color #f1f1f1
5296     :color blue
5297@@ -291,7 +295,7 @@
5298   :border solid 1px black
5299   :display inline
5300   :margin 5px
5301-  :font-family monospace
5302+  +monospace-stack
5303   :font-size 15px
5304   :padding 5px
5305 
5306@@ -326,7 +330,7 @@
5307 span.search_doc_topbar
5308   :z-index 12
5309   :height 24px
5310-  :font-family monospace
5311+  +monospace-stack
5312   :font-size 12px
5313   :width 158px
5314   :top 40px
5315@@ -361,7 +365,7 @@
5316   :width 160px
5317   :padding 4px
5318   :z-index 12
5319-  :font-family monospace
5320+  +monospace-stack
5321   :font-size 14px
5322   :color #222222
5323   :color #808080
5324@@ -446,7 +450,7 @@
5325 span
5326   &.pane
5327     :z-index 30
5328-    :font-family monospace
5329+    +monospace-stack
5330     :font-size 12px
5331     :position fixed
5332     :left 5px
5333@@ -462,7 +466,7 @@
5334   &.plusminus
5335     :color black
5336     :font-size 8pt
5337-    :font-family monospace
5338+    +monospace-stack
5339 
5340     &:hover
5341       :cursor pointer
5342@@ -695,12 +699,6 @@
5343 
5344 
5345 div
5346-  &.worksheet_bottom_padding
5347-    :height 50%
5348-
5349-  &.worksheet_top_padding
5350-    :height 5%
5351-
5352   &.worksheet_menu
5353     :top 50px
5354 
5355@@ -848,7 +846,7 @@
5356 
5357 span.control
5358   :border 1px solid white
5359-  :font-family monospace
5360+  +monospace-stack
5361   :font-size 14pt
5362   :font-weight bold
5363 
5364@@ -867,6 +865,7 @@
5365   &.worksheet
5366     :background-color white
5367     :border 1px solid #aaa
5368+    :padding .75em 0.2em
5369 
5370   &.banner
5371     :background-color white
5372@@ -894,7 +893,7 @@
5373   &:hover
5374 
5375 input.btn
5376-  :font-family monospace
5377+  +monospace-stack
5378   :font-size 13pt
5379   :font-weight bold
5380   :color #808080
5381@@ -962,7 +961,7 @@
5382   :color #000000
5383   :background-color white
5384   :border 1px solid  #a8a8a8
5385-  :font-family monospace
5386+  +monospace-stack
5387   :font-size 12pt
5388   :overflow hidden
5389   :padding-bottom 1px
5390@@ -979,7 +978,7 @@
5391   :color #000000
5392   :background-color white
5393   :border 1px solid  #a8a8a8
5394-  :font-family monospace
5395+  +monospace-stack
5396   :font-size 12pt
5397   :padding-bottom 1px
5398   :padding-left 6px
5399@@ -996,7 +995,7 @@
5400 textarea.cell_input_hide
5401   :background-color white
5402   :border 0px solid white
5403-  :font-family monospace
5404+  +monospace-stack
5405   :font-size 12pt
5406   :color #888888
5407   :overflow hidden
5408@@ -1011,7 +1010,7 @@
5409 pre.cell_input_hide
5410   :background-color white
5411   :border 2px solid #e8e8e8
5412-  :font-family monospace
5413+  +monospace-stack
5414   :font-size 12pt
5415   :overflow hidden
5416   :padding-bottom 0px
5417@@ -1028,7 +1027,7 @@
5418 textarea.cell_input_active
5419   :background-color white
5420   :border 2px solid  #8888fe
5421-  :font-family monospace
5422+  +monospace-stack
5423   :font-size 12pt
5424   :overflow hidden
5425   :padding-bottom 0px
5426@@ -1045,7 +1044,7 @@
5427   &.cell_input_active
5428     :background-color white
5429     :border 2px solid  #8888fe
5430-    :font-family monospace
5431+    +monospace-stack
5432     :font-size 12pt
5433     :padding-bottom 0px
5434     :padding-left 5px
5435@@ -1062,7 +1061,7 @@
5436   &.cell_input_print
5437     :background-color white
5438     :border 1px solid  #a8a8a8
5439-    :font-family monospace
5440+    +monospace-stack
5441     :font-size 12pt
5442     :padding-bottom 1px
5443     :padding-left 6px
5444@@ -1072,6 +1071,7 @@
5445     :margin-bottom 0px
5446     :line-height 1.2em
5447     :width 97%
5448+    :whitespace pre-wrap
5449 
5450 
5451 textarea.cell_input:hover
5452@@ -1094,7 +1094,7 @@
5453 
5454 div
5455   &.cell_div_output
5456-    :font-family monospace
5457+    +monospace-stack
5458     :font-size 12pt
5459     :margin-top -5px
5460     :margin-bottom 5px
5461@@ -1166,14 +1166,14 @@
5462     :display none
5463 
5464   &.cell_output_html_wrap, &.cell_output_html_nowrap
5465-    :font-family monospace
5466+    +monospace-stack
5467     :font-size 12pt
5468 
5469   &.cell_output_html_hidden
5470     :display none
5471 
5472   &.cell_div_output_running
5473-    :font-family monospace
5474+    +monospace-stack
5475     :font-size 12pt
5476     :margin 0px
5477     :background-color #ffffff
5478@@ -1234,7 +1234,7 @@
5479   &.debug_output
5480     :background-color white
5481     :border 0px
5482-    :font-family monospace
5483+    +monospace-stack
5484     :font-size 10pt
5485     :overflow scroll
5486     :padding-left 3px
5487@@ -1246,7 +1246,7 @@
5488 textarea.debug_input
5489   :background-color white
5490   :border 1px solid #8888fe
5491-  :font-family monospace
5492+  +monospace-stack
5493   :font-size 12pt
5494   :overflow scroll
5495   :padding-left 3px
5496@@ -1289,17 +1289,16 @@
5497 
5498 /************ User Home (Worksheet listing) **************************/
5499 
5500-span
5501-  &.ratingmsg
5502-    :color #112abb
5503-    :padding 0.3em
5504-    :font-size 14px
5505+.ratingmsg
5506+  :color #112abb
5507+  :padding 0.3em
5508+  :font-size 14px
5509 
5510-  &.pubmsg
5511-    :font-family sans-serif
5512-    :color #112abb
5513-    :padding 0.3em
5514-    :font-size 12px
5515+.pubmsg
5516+  :font-family sans-serif
5517+  :color #112abb
5518+  :padding 0.3em
5519+  :font-size 12px
5520 
5521 #worksheet-list
5522   :clear both
5523@@ -1309,29 +1308,30 @@
5524   td.checkbox
5525     :padding 4px
5526 
5527-a.usercontrol
5528+.controls a, .usercontrol
5529   :color #112abb
5530-  :padding 0.3em
5531   :font-size 14px
5532   :text-decoration underline
5533 
5534   &:hover
5535     :cursor pointer
5536 
5537+.controls
5538+  span
5539+    :color #112abb
5540+    :padding 0.3em
5541+    :font-size 14px
5542 
5543-span.usercontrol
5544+
5545+.user-controls a, .boldusercontrol
5546   :color #112abb
5547-  :padding 0.3em
5548+  :font-weight bold
5549   :font-size 14px
5550 
5551+.user-controls a, .controls a, .controls span
5552+  :padding 0.3em
5553 
5554 a
5555-  &.boldusercontrol
5556-    :color #112abb
5557-    :padding 0.5em
5558-    :font-weight bold
5559-    :font-size 14px
5560-
5561   &.control, &.control-select
5562     :background-color #7799bb
5563     :font-family sans-serif
5564@@ -1354,17 +1354,14 @@
5565       :cursor pointer
5566 
5567 
5568-span.sharebar
5569+.sharebar
5570   :background-color #4477aa
5571   :font-family sans-serif
5572   :color #ffffff
5573-  :position absolute
5574-  :left 0.5em
5575-  :right 0ex
5576   :padding-top 0.5em
5577   :padding-bottom 0.5em
5578   :padding-left 2em
5579-  :font-size 18px
5580+  :font-size 1.25em
5581   :font-weight bold
5582 
5583 
5584@@ -1451,22 +1448,21 @@
5585   :height 0px
5586 
5587 
5588-span
5589-  &.lastedit
5590-    :font-family sans-serif
5591-    :font-size 10px
5592-    :color #717171
5593+.lastedit
5594+  :font-family sans-serif
5595+  :font-size 10px
5596+  :color #717171
5597 
5598-  &.revs
5599-    :font-family sans-serif
5600-    :font-size 12px
5601-    :font-weight bold
5602-    :color #333333
5603+.revs
5604+  :font-family sans-serif
5605+  :font-size 12px
5606+  :font-weight bold
5607+  :color #333333
5608 
5609-  &.users
5610-    :font-family sans-serif
5611-    :font-size 13px
5612-    :color #222222
5613+.users
5614+  :font-family sans-serif
5615+  :font-size 13px
5616+  :color #222222
5617 
5618 
5619 a.share
5620@@ -1553,234 +1549,12 @@
5621     :font-weight bold
5622     :color white
5623     :background-color #990000
5624+    :margin-left 1em
5625 
5626-/* These have been scraped directly from pygment. */
5627-
5628-.hll
5629-  :background-color #ffffcc
5630-
5631-
5632-.c
5633-  :color #408090
5634-  :font-style italic
5635-
5636-
5637-.err
5638-  :border 1px solid #FF0000
5639-
5640-
5641-.k
5642-  :color #007020
5643-  :font-weight bold
5644-
5645-
5646-.o
5647-  :color #666666
5648-
5649-
5650-.cm
5651-  :color #408090
5652-  :font-style italic
5653-
5654-
5655-.cp
5656-  :color #007020
5657-
5658-
5659-.c1
5660-  :color #408090
5661-  :font-style italic
5662-
5663-
5664-.cs
5665-  :color #408090
5666-  :background-color #fff0f0
5667-
5668-
5669-.gd
5670-  :color #A00000
5671-
5672-
5673-.ge
5674-  :font-style italic
5675-
5676-
5677-.gr
5678-  :color #FF0000
5679-
5680-
5681-.gh
5682-  :color #000080
5683-  :font-weight bold
5684-
5685-
5686-.gi
5687-  :color #00A000
5688-
5689-
5690-.go
5691-  :color #0000aa
5692-
5693-
5694-.gp
5695-  :color #c65d09
5696-  :font-weight bold
5697-
5698-
5699-.gs
5700-  :font-weight bold
5701-
5702-
5703-.gu
5704-  :color #800080
5705-  :font-weight bold
5706-
5707-
5708-.gt
5709-  :color #0040D0
5710-
5711-
5712-.kc, .kd, .kn
5713-  :color #007020
5714-  :font-weight bold
5715-
5716-
5717-.kp
5718-  :color #007020
5719-
5720-
5721-.kr
5722-  :color #007020
5723-  :font-weight bold
5724-
5725-
5726-.kt
5727-  :color #902000
5728-
5729-
5730-.m
5731-  :color #208050
5732-
5733-
5734-.s, .na
5735-  :color #4070a0
5736-
5737-
5738-.nb
5739-  :color #007020
5740-
5741-
5742-.nc
5743-  :color #0e84b5
5744-  :font-weight bold
5745-
5746-
5747-.no
5748-  :color #60add5
5749-
5750-
5751-.nd
5752-  :color #555555
5753-  :font-weight bold
5754-
5755-
5756-.ni
5757-  :color #d55537
5758-  :font-weight bold
5759-
5760-
5761-.ne
5762-  :color #007020
5763-
5764-
5765-.nf
5766-  :color #06287e
5767-
5768-
5769-.nl
5770-  :color #002070
5771-  :font-weight bold
5772-
5773-
5774-.nn
5775-  :color #0e84b5
5776-  :font-weight bold
5777-
5778-
5779-.nt
5780-  :color #062873
5781-  :font-weight bold
5782-
5783-
5784-.nv
5785-  :color #bb60d5
5786-
5787-
5788-.ow
5789-  :color #007020
5790-  :font-weight bold
5791-
5792-
5793-.w
5794-  :color #bbbbbb
5795-
5796-
5797-.mf, .mh, .mi, .mo
5798-  :color #208050
5799-
5800-
5801-.sb, .sc
5802-  :color #4070a0
5803-
5804-
5805-.sd
5806-  :color #4070a0
5807-  :font-style italic
5808-
5809-
5810-.s2
5811-  :color #4070a0
5812-
5813-
5814-.se
5815-  :color #4070a0
5816-  :font-weight bold
5817-
5818-
5819-.sh
5820-  :color #4070a0
5821-
5822-
5823-.si
5824-  :color #70a0d0
5825-  :font-style italic
5826-
5827-
5828-.sx
5829-  :color #c65d09
5830-
5831-
5832-.sr
5833-  :color #235388
5834-
5835-
5836-.s1
5837-  :color #4070a0
5838-
5839-
5840-.ss
5841-  :color #517918
5842-
5843-
5844-.bp
5845-  :color #007020
5846-
5847-
5848-.vc, .vg, .vi
5849-  :color #bb60d5
5850-
5851-
5852-.il
5853-  :color #208050
5854-
5855-/* end stuff scraped from pygment */
5856+@import print_worksheet.sass
5857+@import guest_worksheet.sass
5858+@import worksheet_aux.sass
5859+@import settings.sass
5860+@import accounts.sass
5861+@import login.sass
5862+@import pygment.sass
5863diff -r 8afee2ec056a sass/src/master.sass
5864--- a/sass/src/master.sass      Sat Oct 24 18:17:19 2009 +0800
5865+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
5866@@ -1,70 +0,0 @@
5867-@import compass/reset.sass
5868-
5869-html
5870-  :font-size 100.1%
5871-
5872-body
5873-  :font .9em/1.2em Arial, Helvetica, sans-serif
5874-
5875-div
5876-  :padding 0.5em 1em
5877-
5878-#desc
5879-  :float left
5880-  :margin-right 400px
5881-
5882-#sign-in-box
5883-  :float left
5884-  :margin-left -400px
5885-  :width 350px
5886-  :background-color #efefff
5887-  form
5888-    label
5889-      :display block
5890-     
5891-
5892-p
5893-  :margin-bottom 1em
5894-
5895-h1,h2,h3,h4,h5,h6
5896-  :line-height 1em
5897-
5898-h2
5899-  :font-size 1.5em
5900-  :margin-bottom 0.375em
5901-
5902-#banner
5903-  :font-size 1.2em
5904-  :float left
5905-  :clear both
5906-  :margin-bottom 0.25em
5907-  a.banner
5908-    :text-decoration none
5909-    :border none
5910-    :margin-top 2px
5911-    :float left
5912-    &:visited
5913-      :color #1950c8
5914-  #ping
5915-    :display none
5916-  div.version
5917-    :float left
5918-    :clear left
5919-    :font-size xx-small
5920-    :text-indent 13px
5921-    :color black
5922-
5923-.section
5924-  :border-bottom 1px solid #CCC
5925-  :padding 5px
5926-
5927-  > div
5928-    :max-width 350px
5929-    :text-align right
5930-
5931-input.c1
5932-  :width 200px
5933-
5934-
5935-strong
5936-  :font-weight bold
5937diff -r 8afee2ec056a sass/src/partials/_base.sass
5938--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
5939+++ b/sass/src/partials/_base.sass      Sun Jan 03 03:07:50 2010 +0800
5940@@ -0,0 +1,2 @@
5941+!subdued_blue = #112abb
5942+!link_color = !subdued_blue
5943\ No newline at end of file
5944diff -r 8afee2ec056a sass/src/partials/_mixins.sass
5945--- a/sass/src/partials/_mixins.sass    Sat Oct 24 18:17:19 2009 +0800
5946+++ b/sass/src/partials/_mixins.sass    Sun Jan 03 03:07:50 2010 +0800
5947@@ -2,4 +2,10 @@
5948   :height = !height
5949   :position absolute
5950   :top 50%
5951-  :margin-top -!height/2
5952\ No newline at end of file
5953+  :margin-top -!height/2
5954+
5955+=sans-serif-stack
5956+  :font-family "Gill Sans", "Gill Sans MT", "Myriad Pro", Myriad, "Liberation Sans", "Nimbus Sans L", Tahoma, Geneva, "Helvetica Neue", Helvetica, Arial, sans-serif
5957+
5958+=monospace-stack
5959+  :font-family monospace
5960diff -r 8afee2ec056a sass/src/registration.sass
5961--- a/sass/src/registration.sass        Sat Oct 24 18:17:19 2009 +0800
5962+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
5963@@ -1,73 +0,0 @@
5964-html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, dl, dt, dd, ol, ul, li, table, caption, tbody, tfoot, thead, tr, th, td
5965-  :border 0
5966-  :font-family inherit
5967-  :font-size 100%
5968-  :font-style inherit
5969-  :font-weight inherit
5970-  :margin 0
5971-  :outline 0
5972-  :padding 0
5973-  :text-decoration none
5974-  :vertical-align baseline
5975-
5976-
5977-html
5978-  :font-size 100.1%
5979-
5980-
5981-body
5982-  :font 0.88em/1.4 Arial, Helvetica, sans-serif
5983-
5984-
5985-#wrapper
5986-  :margin 0 auto
5987-  :max-width 600px
5988-
5989-
5990-h1, h2, h3, h4, h5
5991-  :font-wieght normal
5992-
5993-
5994-h1
5995-  :border-bottom 1px solid #696969
5996-  :font-size 2em
5997-  :padding 10px 0
5998-
5999-
6000-h2
6001-  :font-weight bold
6002-
6003-
6004-h1, h2, p, li
6005-  :margin-bottom 10px
6006-
6007-
6008-.entry
6009-  :margin-bottom 10px
6010-  :border 1px solid #999
6011-  :padding 3px
6012-  :width 200
6013-
6014-
6015-li
6016-  :border-bottom 1px solid #CCC
6017-
6018-
6019-.error
6020-  :color red
6021-
6022-
6023-.error_found
6024-  :color red
6025-  :font-size 1.5em
6026-
6027-
6028-button
6029-  :margin-right 1em
6030-
6031-form 
6032-  label
6033-    :display block
6034-  div
6035-    :margin-bottom 1em
6036-
6037diff -r 8afee2ec056a sass/src/user_management.sass
6038--- a/sass/src/user_management.sass     Sat Oct 24 18:17:19 2009 +0800
6039+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
6040@@ -1,3 +0,0 @@
6041-@import master.sass
6042-body
6043-  :margin 10px