Ticket #7249: trac_7249_jinja2_v3.patch
File trac_7249_jinja2_v3.patch, 36.1 KB (added by , 10 years ago) |
---|
-
sagenb/data/sage/html/base.html
# HG changeset patch # User Mitesh Patel <qed777@gmail.com> # Date 1262813598 28800 # Node ID c6ea40a1660c8effb509bcaeea18827d30ac3baf # Parent f20b011f30dc307d9f79627a78f01150005db3d3 [mq]: trac_7249_jinja2.patch diff --git a/sagenb/data/sage/html/base.html b/sagenb/data/sage/html/base.html
a b 1 {%- macro render_title -%}{% block title %}{% endblock %}{%- endmacro -%}1 {%- macro render_title() -%}{% block title %}{% endblock %}{%- endmacro -%} 2 2 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> 3 3 <html lang="en"> 4 4 <head> -
sagenb/data/sage/html/notebook/cell.html
diff --git a/sagenb/data/sage/html/notebook/cell.html b/sagenb/data/sage/html/notebook/cell.html
a b INPUT: 12 12 print or not. 13 13 #} 14 14 {% if do_print %} 15 {% set wrap = 68 %} 16 {% set div_wrap = true %} 15 {% set wrap_ = 68 %} 16 {% set div_wrap_ = true %} 17 {% else %} 18 {% set wrap_ = wrap %} 19 {% set div_wrap_ = div_wrap %} 17 20 {% endif %} 18 21 {% set cell_cls = "cell_evaluated" if cell.evaluated() or do_print else "cell_not_evaluated" %} 19 22 20 {% if div_wrap %}23 {% if div_wrap_ %} 21 24 <div id="cell_outer_{{ cell.id() }}" class="cell_visible"> 22 25 <div id="cell_{{ cell.id() }}" class="{{ cell_cls }}"> 23 26 {% endif %} … … INPUT: 52 55 onFocus="cell_focused(this, {{ cell.id() }}); return true;">{{ cell.input_text().rstrip() }}</textarea> 53 56 <a href="javascript:evaluate_cell({{ cell.id() }},0)" 54 57 class="eval_button" 55 id="eval_button{{ cell.id() }}" 58 id="eval_button{{ cell.id() }}" 56 59 alt="Click here or press shift-return to evaluate"> 57 60 evaluate 58 61 </a> … … INPUT: 81 84 {% if cell.introspect() %} 82 85 {{ cell.output_text(0, html=true) }} 83 86 {% else %} 84 {{ cell.output_text(wrap , html=true) }}87 {{ cell.output_text(wrap_, html=true) }} 85 88 {% endif %} 86 89 </div> 87 90 {% if not do_print %} … … INPUT: 101 104 </div> 102 105 {% endif %} 103 106 104 {% if div_wrap %}107 {% if div_wrap_ %} 105 108 </div> 106 109 </div> 107 110 {% endif %} -
sagenb/interfaces/expect.py
diff --git a/sagenb/interfaces/expect.py b/sagenb/interfaces/expect.py
a b class WorksheetProcess_ExpectImplementat 241 241 # The magic comment at the very start of the file allows utf8 characters. 242 242 open(self._filename,'w').write( 243 243 '# -*- coding: utf_8 -*-\nimport sys;sys.ps1="%s";print "START%s"\n'%( 244 self._prompt, self._number) + displayhook_hack(string) )244 self._prompt, self._number) + displayhook_hack(string).encode('utf-8', 'ignore')) 245 245 try: 246 246 self._expect.sendline('\nimport os;os.chdir("%s");\nexecfile("%s")'%( 247 247 remote, sage_input)) 248 except OSError ,msg:248 except OSError as msg: 249 249 self._is_computing = False 250 250 self._so_far = str(msg) 251 251 -
sagenb/misc/sageinspect.py
diff --git a/sagenb/misc/sageinspect.py b/sagenb/misc/sageinspect.py
a b def sage_getdoc(obj, obj_name=''): 483 483 484 484 if r is None: 485 485 return '' 486 487 s = format(str(r), embedded=EMBEDDED_MODE) 486 if isinstance(r, unicode): 487 r = r.encode('utf-8', 'ignore') 488 else: 489 r = str(r) 490 s = format(r, embedded=EMBEDDED_MODE) 488 491 489 492 # If there is a Cython embedded position, it needs to be stripped 490 493 pos = _extract_embedded_position(s) -
sagenb/misc/support.py
diff --git a/sagenb/misc/support.py b/sagenb/misc/support.py
a b def source_code(s, globs, system='sage') 331 331 filename = sageinspect.sage_getfile(obj) 332 332 try: 333 333 lines, lineno = sageinspect.sage_getsourcelines(obj, is_binary=False) 334 except IOError ,msg:334 except IOError as msg: 335 335 return html_markup(str(msg)) 336 336 src = indent.join(lines) 337 337 src = indent + format_src(src) … … def syseval(system, cmd, dir=None): 467 467 if dir: 468 468 if hasattr(system.__class__, 'chdir'): 469 469 system.chdir(dir) 470 if isinstance(cmd, unicode): 471 cmd = cmd.encode('utf-8', 'ignore') 470 472 return system.eval(cmd, sage_globals, locals = sage_globals) 471 473 472 474 ###################################################################### -
sagenb/notebook/cell.py
diff --git a/sagenb/notebook/cell.py b/sagenb/notebook/cell.py
a b class TextCell(Cell_generic): 91 91 sage: C == loads(dumps(C)) 92 92 True 93 93 """ 94 if isinstance(text, str): 95 text = text.decode('utf-8', 'ignore') 94 96 self.__id = int(id) 95 97 self.__text = text 96 98 self.__worksheet = worksheet … … class TextCell(Cell_generic): 103 105 104 106 sage: C = sagenb.notebook.cell.TextCell(0, '2+3', None) 105 107 sage: C.__repr__() 106 'TextCell 0: 2+3'108 u'TextCell 0: 2+3' 107 109 """ 108 110 return "TextCell %s: %s"%(self.__id, self.__text) 109 111 … … class TextCell(Cell_generic): 136 138 sage: C 137 139 TextCell 0: 3+2 138 140 """ 141 if isinstance(input_text, str): 142 input_text = input_text.decode('utf-8', 'ignore') 139 143 self.__text = input_text 140 144 141 145 def set_worksheet(self, worksheet, id=None): … … class TextCell(Cell_generic): 179 183 - ``wrap`` -- number of columns to wrap at (not used) 180 184 181 185 - ``div_wrap`` -- whether to wrap in a div (not used) 182 186 183 187 - ``do_math_parse`` - bool (default: True) 184 188 If True, call math_parse (defined in cell.py) 185 189 on the html. … … class TextCell(Cell_generic): 192 196 193 197 EXAMPLES:: 194 198 195 sage: C = sagenb.notebook.cell.TextCell(0, '2+3', None) 199 sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb') 200 sage: nb.add_user('sage','sage','sage@sagemath.org',force=True) 201 sage: W = nb.create_new_worksheet('Test', 'sage') 202 sage: C = sagenb.notebook.cell.TextCell(0, '2+3', W) 196 203 sage: C.html() 197 204 u'...text_cell...2+3...' 198 205 sage: C.set_input_text("$2+3$") … … class TextCell(Cell_generic): 214 221 215 222 sage: C = sagenb.notebook.cell.TextCell(0, '2+3', None) 216 223 sage: C.plain_text() 217 '2+3'224 u'2+3' 218 225 """ 219 226 return self.__text 220 227 … … class TextCell(Cell_generic): 226 233 227 234 sage: C = sagenb.notebook.cell.TextCell(0, '2+3', None) 228 235 sage: C.edit_text() 229 '2+3'236 u'2+3' 230 237 """ 231 238 return self.__text 232 239 … … class Cell(Cell_generic): 297 304 sage: C == loads(dumps(C)) 298 305 True 299 306 """ 307 if isinstance(out, str): 308 out = out.encode('utf-8', 'ignore') 309 else: 310 out = unicode(out) 311 if isinstance(input, str): 312 input = input.encode('utf-8', 'ignore') 313 else: 314 input = unicode(input) 315 300 316 self.__id = int(id) 301 self.__out = str(out).replace('\r','')317 self.__out = out.replace('\r','') 302 318 self.__worksheet = worksheet 303 319 self.__interrupted = False 304 320 self.__completions = False … … class Cell(Cell_generic): 355 371 sage: C 356 372 Cell 0; in=2+3, out= 357 373 """ 358 self.__out = ''359 self.__out_html = ''374 self.__out = u'' 375 self.__out_html = u'' 360 376 self.__evaluated = False 361 377 362 378 def evaluated(self): … … class Cell(Cell_generic): 555 571 sage: nb.delete() 556 572 """ 557 573 if self.is_interactive_cell(): 558 self.__out_html = ""574 self.__out_html = u"" 559 575 else: 560 576 self.__out_html = self.files_html(output) 561 577 … … class Cell(Cell_generic): 735 751 """ 736 752 if ncols == 0: 737 753 ncols = self.word_wrap_cols() 738 s = '' 754 s = u'' 755 756 if isinstance(self.__in, str): 757 self.__in = self.__in.decode('utf-8', 'ignore') 739 758 740 759 input_lines = self.__in 760 741 761 pr = 'sage: ' 742 762 743 763 if prompts: … … class Cell(Cell_generic): 810 830 811 831 sage: C = sagenb.notebook.cell.Cell(0, '2+3', '5', None) 812 832 sage: C.edit_text() 813 '{{{id=0|\n2+3\n///\n5\n}}}'833 u'{{{id=0|\n2+3\n///\n5\n}}}' 814 834 """ 815 835 s = self.plain_text(ncols, prompts, max_out) 816 return '{{{id=%s|\n%s\n}}}'%(self.id(), s)836 return u'{{{id=%s|\n%s\n}}}'%(self.id(), s) 817 837 818 838 def is_last(self): 819 839 """ … … class Cell(Cell_generic): 988 1008 0 989 1009 sage: C.set_input_text('3+3') 990 1010 sage: C.input_text() 991 '3+3'1011 u'3+3' 992 1012 sage: C.evaluated() 993 1013 False 994 1014 sage: C.version() … … class Cell(Cell_generic): 997 1017 sage: nb.delete() 998 1018 """ 999 1019 # Stuff to deal with interact 1020 if isinstance(input, str): 1021 input = input.decode('utf-8', 'ignore') 1022 1000 1023 if input.startswith('%__sage_interact__'): 1001 1024 self.interact = input[len('%__sage_interact__')+1:] 1002 1025 self.__version = self.version() + 1 … … class Cell(Cell_generic): 1028 1051 1029 1052 sage: C = sagenb.notebook.cell.Cell(0, '2+3', '5', None) 1030 1053 sage: C.input_text() 1031 '2+3'1054 u'2+3' 1032 1055 """ 1033 1056 return self.__in 1034 1057 … … class Cell(Cell_generic): 1042 1065 1043 1066 sage: C = sagenb.notebook.cell.Cell(0, '%hide\n%maxima\n2+3', '5', None) 1044 1067 sage: C.cleaned_input_text() 1045 '2+3'1068 u'2+3' 1046 1069 """ 1047 1070 if self.is_interacting(): 1048 1071 return self.interact … … class Cell(Cell_generic): 1060 1083 1061 1084 sage: C = sagenb.notebook.cell.Cell(0, '%hide\n%maxima\n2+3', '5', None) 1062 1085 sage: C.parse_percent_directives() 1063 '2+3'1086 u'2+3' 1064 1087 sage: C.percent_directives() 1065 [ 'hide','maxima']1088 [u'hide', u'maxima'] 1066 1089 """ 1067 1090 self._system = None 1068 1091 text = self.input_text().splitlines() … … class Cell(Cell_generic): 1097 1120 1098 1121 sage: C = sagenb.notebook.cell.Cell(0, '%hide\n%maxima\n2+3', '5', None) 1099 1122 sage: C.percent_directives() 1100 [ 'hide','maxima']1123 [u'hide', u'maxima'] 1101 1124 """ 1102 1125 return self._percent_directives 1103 1126 … … class Cell(Cell_generic): 1115 1138 1116 1139 sage: C = sagenb.notebook.cell.Cell(0, '%maxima\n2+3', '5', None) 1117 1140 sage: C.system() 1118 'maxima'1141 u'maxima' 1119 1142 sage: prefixes = ['%hide', '%time', ''] 1120 1143 sage: cells = [sagenb.notebook.cell.Cell(0, '%s\n2+3'%prefix, '5', None) for prefix in prefixes] 1121 1144 sage: [(C, C.system()) for C in cells if C.system() is not None] … … class Cell(Cell_generic): 1155 1178 '' 1156 1179 sage: C.set_changed_input_text('3+3') 1157 1180 sage: C.input_text() 1158 '3+3'1181 u'3+3' 1159 1182 sage: C.changed_input_text() 1160 '3+3'1183 u'3+3' 1161 1184 sage: C.changed_input_text() 1162 1185 '' 1163 1186 sage: C.version() … … class Cell(Cell_generic): 1180 1203 sage: C = sagenb.notebook.cell.Cell(0, '2+3', '5', None) 1181 1204 sage: C.set_changed_input_text('3+3') 1182 1205 sage: C.input_text() 1183 '3+3'1206 u'3+3' 1184 1207 sage: C.changed_input_text() 1185 '3+3'1208 u'3+3' 1186 1209 """ 1210 if isinstance(new_text,str): 1211 new_text = new_text.decode('utf-8', 'ignore') 1187 1212 self.__changed_input = new_text 1188 1213 self.__in = new_text 1189 1214 … … class Cell(Cell_generic): 1200 1225 sage: len(C.plain_text()) 1201 1226 12 1202 1227 """ 1228 if isinstance(output, str): 1229 output = output.decode('utf-8', 'ignore') 1230 if isinstance(html, str): 1231 html = html.decode('utf-8', 'ignore') 1203 1232 if output.count('<?__SAGE__TEXT>') > 1: 1204 html = '<h3><font color="red">WARNING: multiple @interacts in one cell disabled (not yet implemented).</font></h3>'1205 output = ''1233 html = u'<h3><font color="red">WARNING: multiple @interacts in one cell disabled (not yet implemented).</font></h3>' 1234 output = u'' 1206 1235 1207 1236 # In interacting mode, we just save the computed output 1208 1237 # (do not overwrite). … … class Cell(Cell_generic): 1222 1251 url = "" 1223 1252 if not self.computing(): 1224 1253 file = os.path.join(self.directory(), "full_output.txt") 1225 open(file,"w").write(output )1254 open(file,"w").write(output.encode('utf-8', 'ignore')) 1226 1255 url = "<a target='_new' href='%s/full_output.txt' class='file_link'>full_output.txt</a>"%( 1227 1256 self.url_to_self()) 1228 1257 html+="<br>" + url … … class Cell(Cell_generic): 1265 1294 '' 1266 1295 sage: C.set_output_text('5', '<strong>5</strong>') 1267 1296 sage: C.output_html() 1268 '<strong>5</strong>'1297 u'<strong>5</strong>' 1269 1298 """ 1270 1299 try: 1271 1300 return self.__out_html … … class Cell(Cell_generic): 1320 1349 sage: W = nb.create_new_worksheet('Test', 'sage') 1321 1350 sage: C = sagenb.notebook.cell.Cell(0, '2+3', '5', W) 1322 1351 sage: C.output_text() 1323 '<pre class="shrunk">5</pre>'1352 u'<pre class="shrunk">5</pre>' 1324 1353 sage: C.output_text(html=False) 1325 '<pre class="shrunk">5</pre>'1354 u'<pre class="shrunk">5</pre>' 1326 1355 sage: C.output_text(raw=True) 1327 '5'1356 u'5' 1328 1357 """ 1329 1358 if allow_interact and hasattr(self, '_interact_output'): 1330 1359 # Get the input template … … class Cell(Cell_generic): 1348 1377 # during interact. 1349 1378 return '' 1350 1379 1380 if isinstance(self.__out, str): 1381 self.__out = self.__out.decode('utf-8', 'ignore') 1382 1351 1383 is_interact = self.is_interactive_cell() 1352 1384 if is_interact and ncols == 0: 1353 1385 if 'Traceback (most recent call last)' in self.__out: 1354 1386 s = self.__out.replace('cell-interact','') 1355 1387 is_interact=False 1356 1388 else: 1357 return '<h2>Click to the left again to hide and once more to show the dynamic interactive window</h2>'1389 return u'<h2>Click to the left again to hide and once more to show the dynamic interactive window</h2>' 1358 1390 else: 1359 1391 s = self.__out 1360 1392 … … class Cell(Cell_generic): 1448 1480 1449 1481 sage: C = sagenb.notebook.cell.Cell(0, "%html\nTest HTML", None, None) 1450 1482 sage: C.system() 1451 'html'1483 u'html' 1452 1484 sage: C.is_html() 1453 1485 True 1454 1486 sage: C = sagenb.notebook.cell.Cell(0, "Test HTML", None, None) … … class Cell(Cell_generic): 1495 1527 ('d', Cell 0; in=sage?, out=) 1496 1528 sage: C.set_introspect_html('foobar') 1497 1529 sage: C.introspect_html() 1498 'foobar'1530 u'foobar' 1499 1531 sage: C.set_introspect_html('`foobar`') 1500 1532 sage: C.introspect_html() 1501 '`foobar`'1533 u'`foobar`' 1502 1534 sage: W.quit() 1503 1535 sage: nb.delete() 1504 1536 """ 1537 if isinstance(html, str): 1538 html = html.decode('utf-8', 'ignore') 1505 1539 self.__introspect_html = html 1506 1540 self.introspection_status = 'done' 1507 1541 … … class Cell(Cell_generic): 1542 1576 try: 1543 1577 return self.__introspect_html 1544 1578 except AttributeError: 1545 self.__introspect_html = ''1546 return ''1579 self.__introspect_html = u'' 1580 return u'' 1547 1581 1548 1582 def introspect(self): 1549 1583 """ … … class Cell(Cell_generic): 1561 1595 sage: W.check_comp(9999) # random output -- depends on computer speed 1562 1596 ('d', Cell 0; in=sage?, out=) 1563 1597 sage: C.introspect() 1564 [ 'sage?', '']1598 [u'sage?', ''] 1565 1599 sage: W.quit() 1566 1600 sage: nb.delete() 1567 1601 """ … … class Cell(Cell_generic): 1586 1620 sage: W.check_comp(9999) # random output -- depends on computer speed 1587 1621 ('d', Cell 0; in=sage?, out=) 1588 1622 sage: C.introspect() 1589 [ 'sage?', '']1623 [u'sage?', ''] 1590 1624 sage: C.unset_introspect() 1591 1625 sage: C.introspect() 1592 1626 False … … class Cell(Cell_generic): 1735 1769 1736 1770 if wrap is None: 1737 1771 wrap = self.notebook().conf()['word_wrap_cols'] 1738 1772 1739 1773 return template(os.path.join('html', 'notebook', 'cell.html'), 1740 1774 cell=self, wrap=wrap, 1741 1775 div_wrap=div_wrap, do_print=do_print) … … class Cell(Cell_generic): 1908 1942 files = '' 1909 1943 else: 1910 1944 files = (' '*3).join(files) 1945 if isinstance(files, str): 1946 files = files.decode('utf-8', 'ignore') 1947 if isinstance(images, str): 1948 images = images.decode('utf-8', 'ignore') 1911 1949 return images + files 1912 1950 1913 1951 ######## -
sagenb/notebook/notebook.py
diff --git a/sagenb/notebook/notebook.py b/sagenb/notebook/notebook.py
a b class Notebook(object): 1052 1052 W is our newly-created worksheet, with the 2+3 cell in it:: 1053 1053 1054 1054 sage: W.name() 1055 'foo'1055 u'foo' 1056 1056 sage: W.cell_list() 1057 1057 [TextCell 0: foo, Cell 1; in=2+3, out=] 1058 1058 """ … … class Notebook(object): 1266 1266 sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb') 1267 1267 sage: W = nb.create_new_worksheet('Test', 'admin') 1268 1268 sage: W.body() 1269 '\n\n{{{id=1|\n\n///\n}}}'1269 u'\n\n{{{id=1|\n\n///\n}}}' 1270 1270 sage: W.save_snapshot('admin') 1271 1271 sage: nb.html_worksheet_revision_list('admin', W) 1272 1272 u'...Revision...Last Edited...seconds...ago...' … … class Notebook(object): 1275 1275 1276 1276 return template(os.path.join("html", "notebook", "worksheet_revision_list.html"), 1277 1277 data = data, worksheet = worksheet, 1278 worksheet_filename = worksheet.filename(),1278 notebook = self, 1279 1279 username = username) 1280 1280 1281 1281 … … class Notebook(object): 1347 1347 1348 1348 return template(os.path.join("html", "notebook", "worksheet_share.html"), 1349 1349 worksheet = worksheet, 1350 worksheet_filename = worksheet.filename(),1350 notebook = self, 1351 1351 username = username, other_users = other_users) 1352 1352 1353 1353 def html_download_or_delete_datafile(self, ws, username, filename): … … class Notebook(object): 1384 1384 text_file_content = open(os.path.join(ws.data_directory(), filename)).read() 1385 1385 1386 1386 return template(os.path.join("html", "notebook", "download_or_delete_datafile.html"), 1387 worksheet = ws, worksheet_filename = ws.filename(),1387 worksheet = ws, notebook = self, 1388 1388 username = username, 1389 1389 filename_ = filename, 1390 1390 file_is_image = file_is_image, … … class Notebook(object): 1504 1504 1505 1505 return template(os.path.join("html", "notebook", "plain_text_window.html"), 1506 1506 worksheet = worksheet, 1507 worksheet_filename = worksheet.filename(),1507 notebook = self, 1508 1508 username = username, plain_text = plain_text, 1509 1509 JSMATH = JSMATH, JEDITABLE_TINYMCE = JEDITABLE_TINYMCE) 1510 1510 … … class Notebook(object): 1532 1532 1533 1533 return template(os.path.join("html", "notebook", "edit_window.html"), 1534 1534 worksheet = worksheet, 1535 worksheet_filename = worksheet.filename(),1535 notebook = self, 1536 1536 username = username) 1537 1537 1538 1538 def html_beforepublish_window(self, worksheet, username): … … class Notebook(object): 1569 1569 """ 1570 1570 return template(os.path.join("html", "notebook", "beforepublish_window.html"), 1571 1571 worksheet = worksheet, 1572 worksheet_filename = worksheet.filename(), 1573 username = username, 1574 JSMATH = JSMATH, JEDITABLE_TINYMCE = JEDITABLE_TINYMCE) 1572 notebook = self, 1573 username = username) 1575 1574 1576 1575 def html_afterpublish_window(self, worksheet, username, url, dtime): 1577 1576 r""" … … class Notebook(object): 1598 1597 1599 1598 return template(os.path.join("html", "notebook", "afterpublish_window.html"), 1600 1599 worksheet = worksheet, 1601 worksheet_filename = worksheet.filename(), 1602 username = username, url = url, time = time, 1603 JSMATH = JSMATH, JEDITABLE_TINYMCE = JEDITABLE_TINYMCE) 1600 notebook = self, 1601 username = username, url = url, time = time) 1604 1602 1605 1603 def html_upload_data_window(self, ws, username): 1606 1604 r""" -
sagenb/notebook/template.py
diff --git a/sagenb/notebook/template.py b/sagenb/notebook/template.py
a b AUTHORS: 15 15 # http://www.gnu.org/licenses/ 16 16 ############################################################################# 17 17 18 import jinja 19 20 from jinja.filters import stringfilter, simplefilter 18 import jinja2 21 19 22 20 import os, re, sys 23 21 … … from sagenb.notebook.jsmath import math_ 27 25 28 26 29 27 TEMPLATE_PATH = os.path.join(DATA, 'sage') 30 env = jinja .Environment(loader=jinja.FileSystemLoader(TEMPLATE_PATH))28 env = jinja2.Environment(loader=jinja2.FileSystemLoader(TEMPLATE_PATH)) 31 29 32 30 css_illegal_re = re.compile(r'[^-A-Za-z_0-9]') 33 31 34 @stringfilter35 32 def css_escape(string): 36 33 r""" 37 34 Returns a string with all characters not legal in a css name … … def css_escape(string): 43 40 44 41 EXAMPLES:: 45 42 46 sage: from sagenb.notebook.template import env, css_escape 47 sage: escaper = css_escape() 48 sage: print(escaper(env, {}, '12abcd')) 49 12abcd 50 sage: print(escaper(env, {}, 'abcd')) 51 abcd 52 sage: print(escaper(env, {}, r'\'"abcd\'"')) 53 ---abcd--- 54 sage: print(escaper(env, {}, 'my-invalid/identifier')) 55 my-invalid-identifier 56 sage: print(escaper(env, {}, r'quotes"mustbe!escaped')) 57 quotes-mustbe-escaped 58 59 The following doctests originally accompanied #7269's support for 60 Jinja2. 61 62 sage: from sagenb.notebook.template import css_escape # not tested 63 sage: css_escape('abcd') # not tested 43 sage: from sagenb.notebook.template import css_escape 44 sage: css_escape('abcd') 64 45 'abcd' 65 sage: css_escape('12abcd') # not tested46 sage: css_escape('12abcd') 66 47 '12abcd' 67 sage: css_escape(r'\'"abcd\'"') # not tested48 sage: css_escape(r'\'"abcd\'"') 68 49 '---abcd---' 69 sage: css_escape('my-invalid/identifier') # not tested50 sage: css_escape('my-invalid/identifier') 70 51 'my-invalid-identifier' 71 sage: css_escape(r'quotes"mustbe!escaped') # not tested52 sage: css_escape(r'quotes"mustbe!escaped') 72 53 'quotes-mustbe-escaped' 73 54 """ 74 55 return css_illegal_re.sub('-', string) … … def clean_name(name): 119 100 return ''.join([x if x.isalnum() else '_' for x in name]) 120 101 121 102 env.filters['css_escape'] = css_escape 122 env.filters['number_of_rows'] = simplefilter(number_of_rows)123 env.filters['clean_name'] = stringfilter(clean_name)124 env.filters['prettify_time_ago'] = simplefilter(prettify_time_ago)125 env.filters['math_parse'] = stringfilter(math_parse)126 env.filters['max'] = simplefilter(max)103 env.filters['number_of_rows'] = number_of_rows 104 env.filters['clean_name'] = clean_name 105 env.filters['prettify_time_ago'] = prettify_time_ago 106 env.filters['math_parse'] = math_parse 107 env.filters['max'] = max 127 108 128 109 def template(filename, **user_context): 129 110 """ … … def template(filename, **user_context): 139 120 the file's template variables 140 121 141 122 OUTPUT: 142 123 143 124 - a string - the rendered HTML, CSS, etc. 144 125 145 126 EXAMPLES:: … … def template(filename, **user_context): 164 145 'conf': notebook.conf() if notebook else None} 165 146 try: 166 147 tmpl = env.get_template(filename) 167 except jinja .exceptions.TemplateNotFound:148 except jinja2.exceptions.TemplateNotFound: 168 149 return "Notebook Bug -- missing template %s"%filename 169 150 context = dict(default_context) 170 151 context.update(user_context) -
sagenb/notebook/twist.py
diff --git a/sagenb/notebook/twist.py b/sagenb/notebook/twist.py
a b def word_wrap_cols(): 82 82 SEP = '___S_A_G_E___' 83 83 84 84 def encode_list(v): 85 return SEP.join([str(x) for x in v]) 85 seq = [] 86 for x in v: 87 if isinstance(x, unicode): 88 x = x.encode('utf-8', 'ignore') 89 else: 90 x = str(x) 91 seq.append(x) 92 return SEP.join(seq) 86 93 87 94 88 95 … … class Worksheet_new_cell_before(Workshee 1090 1097 def render(self, ctx): 1091 1098 id = self.id(ctx) 1092 1099 if not ctx.args.has_key('input'): 1093 input = ''1100 input = u'' 1094 1101 else: 1095 1102 input = ctx.args['input'][0] 1103 if isinstance(input, str): 1104 input = input.decode('utf-8') 1096 1105 1097 1106 cell = self.worksheet.new_cell_before(id, input=input) 1098 1107 self.worksheet.increase_state_number() … … class Worksheet_new_text_cell_before(Wor 1109 1118 input = '' 1110 1119 else: 1111 1120 input = ctx.args['input'][0] 1121 if isinstance(input, str): 1122 input = input.decode('utf-8') 1112 1123 1113 1124 cell = self.worksheet.new_text_cell_before(id, input=input) 1114 1125 s = encode_list([cell.id(), cell.html(editing=True), id]) … … class Worksheet_new_cell_after(Worksheet 1125 1136 input = '' 1126 1137 else: 1127 1138 input = ctx.args['input'][0] 1139 if isinstance(input, str): 1140 input = input.decode('utf-8') 1128 1141 cell = self.worksheet.new_cell_after(id, input=input) 1129 1142 s = encode_list([cell.id(), cell.html(div_wrap=False), id]) 1130 1143 return HTMLResponse(stream = s) … … class Worksheet_new_text_cell_after(Work 1139 1152 input = '' 1140 1153 else: 1141 1154 input = ctx.args['input'][0] 1155 if isinstance(input, str): 1156 input = input.decode('utf-8') 1142 1157 1143 1158 cell = self.worksheet.new_text_cell_after(id, input=input) 1144 1159 s = encode_list([cell.id(), cell.html(editing=True), id]) … … class Worksheet_cell_update(WorksheetRes 1200 1215 if status == 'd': 1201 1216 new_input = cell.changed_input_text() 1202 1217 out_html = cell.output_html() 1203 try: 1204 H = "Worksheet '%s' (%s)\n"%(worksheet.name(), time.strftime("%Y-%m-%d at %H:%M",time.localtime(time.time()))) 1205 H += cell.edit_text(ncols=HISTORY_NCOLS, prompts=False, 1206 max_out=HISTORY_MAX_OUTPUT) 1207 notebook.add_to_user_history(H, self.username) 1208 except UnicodeDecodeError: 1209 pass 1218 H = "Worksheet '%s' (%s)\n"%(worksheet.name(), time.strftime("%Y-%m-%d at %H:%M",time.localtime(time.time()))) 1219 H += cell.edit_text(ncols=HISTORY_NCOLS, prompts=False, 1220 max_out=HISTORY_MAX_OUTPUT) 1221 notebook.add_to_user_history(H, self.username) 1210 1222 else: 1211 1223 new_input = '' 1212 1224 out_html = '' … … class Worksheet_eval(WorksheetResource, 1252 1264 def render(self, ctx): 1253 1265 id = self.id(ctx) 1254 1266 if not ctx.args.has_key('input'): 1255 input_text = ''1267 input_text = u'' 1256 1268 else: 1257 1269 input_text = ctx.args['input'][0] 1258 1270 input_text = input_text.replace('\r\n', '\n') # DOS 1271 if isinstance(input_text, str): 1272 input_text = input_text.decode('utf-8') 1273 1259 1274 1260 1275 W = self.worksheet 1261 1276 W.increase_state_number() -
sagenb/notebook/worksheet.py
diff --git a/sagenb/notebook/worksheet.py b/sagenb/notebook/worksheet.py
a b class Worksheet(object): 271 271 sage: import sagenb.notebook.worksheet 272 272 sage: W = sagenb.notebook.worksheet.Worksheet('test', 0, tmp_dir(), owner='sage') 273 273 sage: sorted((W.basic().items())) 274 [('auto_publish', False), 275 ('collaborators', []), 276 ('id_number', 0), 277 ('last_change', ('sage', ...)), 278 ('name', 'test'), 279 ('owner', 'sage'), 280 ('pretty_print', False), 281 ('published_id_number', None), 282 ('ratings', []), 283 ('system', None), 284 ('tags', {'sage': [1]}), 285 ('viewers', []), 286 ('worksheet_that_was_published', ('sage', 0))] 274 [('auto_publish', False), ('collaborators', []), ('id_number', 0), ('last_change', ('sage', ...)), ('name', u'test'), ('owner', 'sage'), ('pretty_print', False), ('published_id_number', None), ('ratings', []), ('system', None), ('tags', {'sage': [1]}), ('viewers', []), ('worksheet_that_was_published', ('sage', 0))] 287 275 """ 288 276 try: 289 277 published_id_number = int(os.path.split(self.__published_version)[1]) … … class Worksheet(object): 690 678 sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb') 691 679 sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin') 692 680 sage: W.name() 693 'A Test Worksheet'681 u'A Test Worksheet' 694 682 """ 695 683 try: 696 684 return self.__name … … class Worksheet(object): 712 700 sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin') 713 701 sage: W.set_name('A renamed worksheet') 714 702 sage: W.name() 715 'A renamed worksheet'703 u'A renamed worksheet' 716 704 """ 717 705 if len(name.strip()) == 0: 718 name = 'Untitled' 706 name = u'Untitled' 707 if isinstance(name, str): 708 name = name.decode('utf-8', 'ignore') 719 709 self.__name = name 720 710 721 711 def set_filename_without_owner(self, nm): … … class Worksheet(object): 1913 1903 if os.path.exists(worksheet_html) and open(worksheet_html).read() == E: 1914 1904 # we already wrote it out... 1915 1905 return 1916 open(filename, 'w').write(bz2.compress(E ))1917 open(worksheet_html, 'w').write(self.body() )1906 open(filename, 'w').write(bz2.compress(E.encode('utf-8', 'ignore'))) 1907 open(worksheet_html, 'w').write(self.body().encode('utf-8', 'ignore')) 1918 1908 self.limit_snapshots() 1919 1909 try: 1920 1910 X = self.__saved_by_info … … class Worksheet(object): 2141 2131 5, Cell 1; in=2+8, out= 2142 2132 10] 2143 2133 sage: W.name() 2144 'Test Edit Save'2134 u'Test Edit Save' 2145 2135 """ 2146 2136 # Clear any caching. 2147 2137 try: … … from sagenb.notebook.all import * 3439 3429 """ 3440 3430 # The extra newline below is necessary, since otherwise source 3441 3431 # code introspection doesn't include the last line. 3442 return 'open("%s","w").write("# -*- coding: utf-8 -*-\\n" + _support_.preparse_worksheet_cell(base64.b64decode("%s"),globals())+"\\n"); execfile(os.path.abspath("%s"))'%(CODE_PY, base64.b64encode(s ), CODE_PY)3432 return 'open("%s","w").write("# -*- coding: utf-8 -*-\\n" + _support_.preparse_worksheet_cell(base64.b64decode("%s"),globals())+"\\n"); execfile(os.path.abspath("%s"))'%(CODE_PY, base64.b64encode(s.encode('utf-8', 'ignore')), CODE_PY) 3443 3433 3444 3434 ########################################################## 3445 3435 # Loading and attaching files … … from sagenb.notebook.all import * 3596 3586 sage: W.get_cell_system(c0) 3597 3587 'sage' 3598 3588 sage: W.get_cell_system(c1) 3599 'gap'3589 u'gap' 3600 3590 sage: W.edit_save('{{{\n%sage\n2+3\n}}}\n\n{{{\nSymmetricGroup(5)\n}}}') 3601 3591 sage: W.set_system('gap') 3602 3592 sage: c0, c1 = W.cell_list() 3603 3593 sage: W.get_cell_system(c0) 3604 'sage'3594 u'sage' 3605 3595 sage: W.get_cell_system(c1) 3606 3596 'gap' 3607 3597 """ … … from sagenb.notebook.all import * 3626 3616 os.makedirs(code) 3627 3617 spyx = os.path.abspath(os.path.join(code, 'sage%s.spyx'%id)) 3628 3618 if not (os.path.exists(spyx) and open(spyx).read() == cmd): 3629 open(spyx,'w').write(cmd )3619 open(spyx,'w').write(cmd.encode('utf-8', 'ignore')) 3630 3620 return '_support_.cython_import_all("%s", globals())'%spyx 3631 3621 3632 3622 def check_for_system_switching(self, input, cell): … … from sagenb.notebook.all import * 3653 3643 sage: W.edit_save('{{{\n2+3\n}}}\n\n{{{\n%gap\nSymmetricGroup(5)\n}}}') 3654 3644 sage: c0, c1 = W.cell_list() 3655 3645 sage: W.check_for_system_switching(c0.cleaned_input_text(), c0) 3656 (False, '2+3')3646 (False, u'2+3') 3657 3647 sage: W.check_for_system_switching(c1.cleaned_input_text(), c1) 3658 (True, "print _support_.syseval(gap, ur'''SymmetricGroup(5)''', '...')")3648 (True, u"print _support_.syseval(gap, ur'''SymmetricGroup(5)''', '...')") 3659 3649 3660 3650 :: 3661 3651 … … from sagenb.notebook.all import * 3677 3667 sage: W.set_system('gap') 3678 3668 sage: c0, c1 = W.cell_list() 3679 3669 sage: W.check_for_system_switching(c0.cleaned_input_text(), c0) 3680 (False, '2+3')3670 (False, u'2+3') 3681 3671 sage: W.check_for_system_switching(c1.cleaned_input_text(), c1) 3682 (True, 3683 "print _support_.syseval(gap, ur'''SymmetricGroup(5)''', '...')") 3672 (True, u"print _support_.syseval(gap, ur'''SymmetricGroup(5)''', '...')") 3684 3673 sage: c0.evaluate() 3685 3674 sage: W.check_comp() #random output -- depends on the computer's speed 3686 3675 ('d', Cell 0; in=%sage -
sagenb/storage/filesystem_storage.py
diff --git a/sagenb/storage/filesystem_storage.py b/sagenb/storage/filesystem_storage.py
a b class FilesystemDatastore(Datastore): 291 291 # only save if loaded 292 292 # todo -- add check if changed 293 293 filename = self._worksheet_html_filename(username, id_number) 294 open(self._abspath(filename),'w').write(worksheet.body() )294 open(self._abspath(filename),'w').write(worksheet.body().encode('utf-8', 'ignore')) 295 295 296 296 def load_worksheet(self, username, id_number): 297 297 """ … … class FilesystemDatastore(Datastore): 339 339 if title: 340 340 # change the title 341 341 basic['name'] = title 342 342 if isinstance(basic['name'], unicode): 343 basic['name'] = basic['name'].encode('utf-8', 'ignore') 343 344 # Remove metainformation that perhaps shouldn't be distributed 344 345 for k in ['owner', 'ratings', 'worksheet_that_was_published', 'viewers', 'tags', 'published_id_number', 345 346 'collaborators', 'auto_publish']: … … class FilesystemDatastore(Datastore): 397 398 398 399 worksheet_txt = members[0].name 399 400 W = self.load_worksheet(username, id_number) 400 W.edit_save_old_format(T.extractfile(worksheet_txt).read() )401 W.edit_save_old_format(T.extractfile(worksheet_txt).read().decode('utf-8', 'ignore')) 401 402 # '/' is right, since old worksheets always unix 402 403 dir = worksheet_txt.split('/')[0] 403 404