Ticket #7249: trac_7249_jinja2_v3.patch

File trac_7249_jinja2_v3.patch, 36.1 KB (added by mpatel, 10 years ago)

Rebased vs. #7835 v2, #7786 v8, etc. Replaces previous.

  • 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 -%}
    22<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
    33<html lang="en">
    44    <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: 
    1212        print or not.
    1313#}
    1414{% 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 %}
    1720{% endif %}
    1821{% set cell_cls = "cell_evaluated" if cell.evaluated() or do_print else "cell_not_evaluated" %}
    1922
    20 {% if div_wrap %}
     23{% if div_wrap_ %}
    2124<div id="cell_outer_{{ cell.id() }}" class="cell_visible">
    2225    <div id="cell_{{ cell.id() }}" class="{{ cell_cls }}">
    2326{% endif %}
    INPUT: 
    5255                          onFocus="cell_focused(this, {{ cell.id() }}); return true;">{{ cell.input_text().rstrip() }}</textarea>
    5356                <a href="javascript:evaluate_cell({{ cell.id() }},0)"
    5457                   class="eval_button"
    55                    id="eval_button{{ cell.id() }}"
     58                   id="eval_button{{ cell.id() }}" 
    5659                   alt="Click here or press shift-return to evaluate">
    5760                    evaluate
    5861                </a>
    INPUT: 
    8184                                {% if cell.introspect() %}
    8285                                    {{ cell.output_text(0, html=true) }}
    8386                                {% else %}
    84                                     {{ cell.output_text(wrap, html=true) }}
     87                                    {{ cell.output_text(wrap_, html=true) }}
    8588                                {% endif %}
    8689                            </div>
    8790                            {% if not do_print %}
    INPUT: 
    101104        </div>
    102105        {% endif %}
    103106       
    104 {% if div_wrap %}
     107{% if div_wrap_ %}
    105108    </div>
    106109</div>
    107110{% endif %}
  • sagenb/interfaces/expect.py

    diff --git a/sagenb/interfaces/expect.py b/sagenb/interfaces/expect.py
    a b class WorksheetProcess_ExpectImplementat 
    241241        # The magic comment at the very start of the file allows utf8 characters.
    242242        open(self._filename,'w').write(
    243243            '# -*- 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'))
    245245        try:
    246246            self._expect.sendline('\nimport os;os.chdir("%s");\nexecfile("%s")'%(
    247247                              remote, sage_input))
    248         except OSError, msg:
     248        except OSError as msg:
    249249            self._is_computing = False
    250250            self._so_far = str(msg)
    251251
  • sagenb/misc/sageinspect.py

    diff --git a/sagenb/misc/sageinspect.py b/sagenb/misc/sageinspect.py
    a b def sage_getdoc(obj, obj_name=''): 
    483483
    484484    if r is None:
    485485        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)
    488491
    489492    # If there is a Cython embedded position, it needs to be stripped
    490493    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') 
    331331        filename = sageinspect.sage_getfile(obj)
    332332        try:
    333333            lines, lineno = sageinspect.sage_getsourcelines(obj, is_binary=False)
    334         except IOError, msg:
     334        except IOError as msg:
    335335            return html_markup(str(msg))
    336336        src = indent.join(lines)
    337337        src = indent + format_src(src)
    def syseval(system, cmd, dir=None): 
    467467    if dir:
    468468        if hasattr(system.__class__, 'chdir'):
    469469            system.chdir(dir)
     470    if isinstance(cmd, unicode):
     471        cmd = cmd.encode('utf-8', 'ignore')
    470472    return system.eval(cmd, sage_globals, locals = sage_globals)
    471473
    472474######################################################################
  • sagenb/notebook/cell.py

    diff --git a/sagenb/notebook/cell.py b/sagenb/notebook/cell.py
    a b class TextCell(Cell_generic): 
    9191            sage: C == loads(dumps(C))
    9292            True
    9393        """
     94        if isinstance(text, str):
     95            text = text.decode('utf-8', 'ignore')
    9496        self.__id = int(id)
    9597        self.__text = text
    9698        self.__worksheet = worksheet
    class TextCell(Cell_generic): 
    103105
    104106            sage: C = sagenb.notebook.cell.TextCell(0, '2+3', None)
    105107            sage: C.__repr__()
    106             'TextCell 0: 2+3'
     108            u'TextCell 0: 2+3'
    107109        """
    108110        return "TextCell %s: %s"%(self.__id, self.__text)
    109111
    class TextCell(Cell_generic): 
    136138            sage: C
    137139            TextCell 0: 3+2
    138140        """
     141        if isinstance(input_text, str):
     142            input_text = input_text.decode('utf-8', 'ignore')
    139143        self.__text = input_text
    140144
    141145    def set_worksheet(self, worksheet, id=None):
    class TextCell(Cell_generic): 
    179183        - ``wrap`` -- number of columns to wrap at (not used)
    180184
    181185        - ``div_wrap`` -- whether to wrap in a div (not used)
    182        
     186
    183187        - ``do_math_parse`` - bool (default: True)
    184188          If True, call math_parse (defined in cell.py)
    185189          on the html.
    class TextCell(Cell_generic): 
    192196
    193197        EXAMPLES::
    194198
    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)
    196203            sage: C.html()
    197204            u'...text_cell...2+3...'
    198205            sage: C.set_input_text("$2+3$")
    class TextCell(Cell_generic): 
    214221
    215222            sage: C = sagenb.notebook.cell.TextCell(0, '2+3', None)
    216223            sage: C.plain_text()
    217             '2+3'
     224            u'2+3'
    218225        """
    219226        return self.__text
    220227
    class TextCell(Cell_generic): 
    226233
    227234            sage: C = sagenb.notebook.cell.TextCell(0, '2+3', None)
    228235            sage: C.edit_text()
    229             '2+3'
     236            u'2+3'
    230237        """
    231238        return self.__text
    232239
    class Cell(Cell_generic): 
    297304            sage: C == loads(dumps(C))
    298305            True
    299306        """
     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
    300316        self.__id    = int(id)
    301         self.__out   = str(out).replace('\r','')
     317        self.__out   = out.replace('\r','')
    302318        self.__worksheet = worksheet
    303319        self.__interrupted = False
    304320        self.__completions = False
    class Cell(Cell_generic): 
    355371            sage: C
    356372            Cell 0; in=2+3, out=
    357373        """
    358         self.__out = ''
    359         self.__out_html = ''
     374        self.__out = u''
     375        self.__out_html = u''
    360376        self.__evaluated = False
    361377
    362378    def evaluated(self):
    class Cell(Cell_generic): 
    555571            sage: nb.delete()
    556572        """
    557573        if self.is_interactive_cell():
    558             self.__out_html = ""
     574            self.__out_html = u""
    559575        else:
    560576            self.__out_html = self.files_html(output)
    561577
    class Cell(Cell_generic): 
    735751        """
    736752        if ncols == 0:
    737753            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')
    739758
    740759        input_lines = self.__in
     760
    741761        pr = 'sage: '
    742762
    743763        if prompts:
    class Cell(Cell_generic): 
    810830
    811831            sage: C = sagenb.notebook.cell.Cell(0, '2+3', '5', None)
    812832            sage: C.edit_text()
    813             '{{{id=0|\n2+3\n///\n5\n}}}'
     833            u'{{{id=0|\n2+3\n///\n5\n}}}'
    814834        """
    815835        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)
    817837
    818838    def is_last(self):
    819839        """
    class Cell(Cell_generic): 
    9881008            0
    9891009            sage: C.set_input_text('3+3')
    9901010            sage: C.input_text()
    991             '3+3'
     1011            u'3+3'
    9921012            sage: C.evaluated()
    9931013            False
    9941014            sage: C.version()
    class Cell(Cell_generic): 
    9971017            sage: nb.delete()
    9981018        """
    9991019        # Stuff to deal with interact
     1020        if isinstance(input, str):
     1021            input = input.decode('utf-8', 'ignore')
     1022
    10001023        if input.startswith('%__sage_interact__'):
    10011024            self.interact = input[len('%__sage_interact__')+1:]
    10021025            self.__version = self.version() + 1
    class Cell(Cell_generic): 
    10281051
    10291052            sage: C = sagenb.notebook.cell.Cell(0, '2+3', '5', None)
    10301053            sage: C.input_text()
    1031             '2+3'
     1054            u'2+3'
    10321055        """
    10331056        return self.__in
    10341057
    class Cell(Cell_generic): 
    10421065
    10431066            sage: C = sagenb.notebook.cell.Cell(0, '%hide\n%maxima\n2+3', '5', None)
    10441067            sage: C.cleaned_input_text()
    1045             '2+3'
     1068            u'2+3'
    10461069        """
    10471070        if self.is_interacting():
    10481071            return self.interact
    class Cell(Cell_generic): 
    10601083
    10611084            sage: C = sagenb.notebook.cell.Cell(0, '%hide\n%maxima\n2+3', '5', None)
    10621085            sage: C.parse_percent_directives()
    1063             '2+3'
     1086            u'2+3'
    10641087            sage: C.percent_directives()
    1065             ['hide', 'maxima']
     1088            [u'hide', u'maxima']
    10661089        """
    10671090        self._system = None
    10681091        text = self.input_text().splitlines()
    class Cell(Cell_generic): 
    10971120
    10981121            sage: C = sagenb.notebook.cell.Cell(0, '%hide\n%maxima\n2+3', '5', None)
    10991122            sage: C.percent_directives()
    1100             ['hide', 'maxima']
     1123            [u'hide', u'maxima']
    11011124        """
    11021125        return self._percent_directives
    11031126
    class Cell(Cell_generic): 
    11151138
    11161139            sage: C = sagenb.notebook.cell.Cell(0, '%maxima\n2+3', '5', None)
    11171140            sage: C.system()
    1118             'maxima'
     1141            u'maxima'
    11191142            sage: prefixes = ['%hide', '%time', '']
    11201143            sage: cells = [sagenb.notebook.cell.Cell(0, '%s\n2+3'%prefix, '5', None) for prefix in prefixes]
    11211144            sage: [(C, C.system()) for C in cells if C.system() is not None]
    class Cell(Cell_generic): 
    11551178            ''
    11561179            sage: C.set_changed_input_text('3+3')
    11571180            sage: C.input_text()
    1158             '3+3'
     1181            u'3+3'
    11591182            sage: C.changed_input_text()
    1160             '3+3'
     1183            u'3+3'
    11611184            sage: C.changed_input_text()
    11621185            ''
    11631186            sage: C.version()
    class Cell(Cell_generic): 
    11801203            sage: C = sagenb.notebook.cell.Cell(0, '2+3', '5', None)
    11811204            sage: C.set_changed_input_text('3+3')
    11821205            sage: C.input_text()
    1183             '3+3'
     1206            u'3+3'
    11841207            sage: C.changed_input_text()
    1185             '3+3'
     1208            u'3+3'
    11861209        """
     1210        if isinstance(new_text,str):
     1211            new_text = new_text.decode('utf-8', 'ignore')
    11871212        self.__changed_input = new_text
    11881213        self.__in = new_text
    11891214
    class Cell(Cell_generic): 
    12001225            sage: len(C.plain_text())
    12011226            12
    12021227        """
     1228        if isinstance(output, str):
     1229            output = output.decode('utf-8', 'ignore')
     1230        if isinstance(html, str):
     1231            html = html.decode('utf-8', 'ignore')
    12031232        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''
    12061235
    12071236        # In interacting mode, we just save the computed output
    12081237        # (do not overwrite).
    class Cell(Cell_generic): 
    12221251            url = ""
    12231252            if not self.computing():
    12241253                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'))
    12261255                url = "<a target='_new' href='%s/full_output.txt' class='file_link'>full_output.txt</a>"%(
    12271256                    self.url_to_self())
    12281257                html+="<br>" + url
    class Cell(Cell_generic): 
    12651294            ''
    12661295            sage: C.set_output_text('5', '<strong>5</strong>')
    12671296            sage: C.output_html()
    1268             '<strong>5</strong>'
     1297            u'<strong>5</strong>'
    12691298        """
    12701299        try:
    12711300            return self.__out_html
    class Cell(Cell_generic): 
    13201349            sage: W = nb.create_new_worksheet('Test', 'sage')
    13211350            sage: C = sagenb.notebook.cell.Cell(0, '2+3', '5', W)
    13221351            sage: C.output_text()
    1323             '<pre class="shrunk">5</pre>'
     1352            u'<pre class="shrunk">5</pre>'
    13241353            sage: C.output_text(html=False)
    1325             '<pre class="shrunk">5</pre>'
     1354            u'<pre class="shrunk">5</pre>'
    13261355            sage: C.output_text(raw=True)
    1327             '5'
     1356            u'5'
    13281357        """
    13291358        if allow_interact and hasattr(self, '_interact_output'):
    13301359            # Get the input template
    class Cell(Cell_generic): 
    13481377                # during interact.
    13491378                return ''
    13501379
     1380        if isinstance(self.__out, str):
     1381            self.__out = self.__out.decode('utf-8', 'ignore')
     1382
    13511383        is_interact = self.is_interactive_cell()
    13521384        if is_interact and ncols == 0:
    13531385            if 'Traceback (most recent call last)' in self.__out:
    13541386                s = self.__out.replace('cell-interact','')
    13551387                is_interact=False
    13561388            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>'
    13581390        else:
    13591391            s = self.__out
    13601392
    class Cell(Cell_generic): 
    14481480
    14491481            sage: C = sagenb.notebook.cell.Cell(0, "%html\nTest HTML", None, None)
    14501482            sage: C.system()
    1451             'html'
     1483            u'html'
    14521484            sage: C.is_html()
    14531485            True
    14541486            sage: C = sagenb.notebook.cell.Cell(0, "Test HTML", None, None)
    class Cell(Cell_generic): 
    14951527            ('d', Cell 0; in=sage?, out=)
    14961528            sage: C.set_introspect_html('foobar')
    14971529            sage: C.introspect_html()
    1498             'foobar'
     1530            u'foobar'
    14991531            sage: C.set_introspect_html('`foobar`')
    15001532            sage: C.introspect_html()
    1501             '`foobar`'
     1533            u'`foobar`'
    15021534            sage: W.quit()
    15031535            sage: nb.delete()
    15041536        """
     1537        if isinstance(html, str):
     1538            html = html.decode('utf-8', 'ignore')
    15051539        self.__introspect_html = html
    15061540        self.introspection_status = 'done'
    15071541
    class Cell(Cell_generic): 
    15421576        try:
    15431577            return self.__introspect_html
    15441578        except AttributeError:
    1545             self.__introspect_html = ''
    1546             return ''
     1579            self.__introspect_html = u''
     1580            return u''
    15471581
    15481582    def introspect(self):
    15491583        """
    class Cell(Cell_generic): 
    15611595            sage: W.check_comp(9999)     # random output -- depends on computer speed
    15621596            ('d', Cell 0; in=sage?, out=)
    15631597            sage: C.introspect()
    1564             ['sage?', '']
     1598            [u'sage?', '']
    15651599            sage: W.quit()
    15661600            sage: nb.delete()
    15671601        """
    class Cell(Cell_generic): 
    15861620            sage: W.check_comp(9999)     # random output -- depends on computer speed
    15871621            ('d', Cell 0; in=sage?, out=)
    15881622            sage: C.introspect()
    1589             ['sage?', '']
     1623            [u'sage?', '']
    15901624            sage: C.unset_introspect()
    15911625            sage: C.introspect()
    15921626            False
    class Cell(Cell_generic): 
    17351769
    17361770        if wrap is None:
    17371771            wrap = self.notebook().conf()['word_wrap_cols']
    1738            
     1772
    17391773        return template(os.path.join('html', 'notebook', 'cell.html'),
    17401774                        cell=self, wrap=wrap,
    17411775                        div_wrap=div_wrap, do_print=do_print)
    class Cell(Cell_generic): 
    19081942            files  = ''
    19091943        else:
    19101944            files  = ('&nbsp'*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')
    19111949        return images + files
    19121950
    19131951########
  • sagenb/notebook/notebook.py

    diff --git a/sagenb/notebook/notebook.py b/sagenb/notebook/notebook.py
    a b class Notebook(object): 
    10521052        W is our newly-created worksheet, with the 2+3 cell in it::
    10531053
    10541054            sage: W.name()
    1055             'foo'
     1055            u'foo'
    10561056            sage: W.cell_list()
    10571057            [TextCell 0: foo, Cell 1; in=2+3, out=]
    10581058        """
    class Notebook(object): 
    12661266            sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb')
    12671267            sage: W = nb.create_new_worksheet('Test', 'admin')
    12681268            sage: W.body()
    1269             '\n\n{{{id=1|\n\n///\n}}}'
     1269            u'\n\n{{{id=1|\n\n///\n}}}'
    12701270            sage: W.save_snapshot('admin')
    12711271            sage: nb.html_worksheet_revision_list('admin', W)
    12721272            u'...Revision...Last Edited...seconds...ago...'
    class Notebook(object): 
    12751275
    12761276        return template(os.path.join("html", "notebook", "worksheet_revision_list.html"),
    12771277                        data = data, worksheet = worksheet,
    1278                         worksheet_filename = worksheet.filename(),
     1278                        notebook = self,
    12791279                        username = username)
    12801280
    12811281
    class Notebook(object): 
    13471347
    13481348        return template(os.path.join("html", "notebook", "worksheet_share.html"),
    13491349                        worksheet = worksheet,
    1350                         worksheet_filename = worksheet.filename(),
     1350                        notebook = self,
    13511351                        username = username, other_users = other_users)
    13521352   
    13531353    def html_download_or_delete_datafile(self, ws, username, filename):
    class Notebook(object): 
    13841384            text_file_content = open(os.path.join(ws.data_directory(), filename)).read()
    13851385
    13861386        return template(os.path.join("html", "notebook", "download_or_delete_datafile.html"),
    1387                         worksheet = ws, worksheet_filename = ws.filename(),
     1387                        worksheet = ws, notebook = self,
    13881388                        username = username,
    13891389                        filename_ = filename,
    13901390                        file_is_image = file_is_image,
    class Notebook(object): 
    15041504
    15051505        return template(os.path.join("html", "notebook", "plain_text_window.html"),
    15061506                        worksheet = worksheet,
    1507                         worksheet_filename = worksheet.filename(),
     1507                        notebook = self,
    15081508                        username = username, plain_text = plain_text,
    15091509                        JSMATH = JSMATH, JEDITABLE_TINYMCE = JEDITABLE_TINYMCE)
    15101510
    class Notebook(object): 
    15321532
    15331533        return template(os.path.join("html", "notebook", "edit_window.html"),
    15341534                        worksheet = worksheet,
    1535                         worksheet_filename = worksheet.filename(),
     1535                        notebook = self,
    15361536                        username = username)
    15371537
    15381538    def html_beforepublish_window(self, worksheet, username):
    class Notebook(object): 
    15691569        """
    15701570        return template(os.path.join("html", "notebook", "beforepublish_window.html"),
    15711571                        worksheet = worksheet,
    1572                         worksheet_filename = worksheet.filename(),
    1573                         username = username,
    1574                         JSMATH = JSMATH, JEDITABLE_TINYMCE = JEDITABLE_TINYMCE)
     1572                        notebook = self,
     1573                        username = username)
    15751574
    15761575    def html_afterpublish_window(self, worksheet, username, url, dtime):
    15771576        r"""
    class Notebook(object): 
    15981597
    15991598        return template(os.path.join("html", "notebook", "afterpublish_window.html"),
    16001599                        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)
    16041602
    16051603    def html_upload_data_window(self, ws, username):
    16061604        r"""
  • sagenb/notebook/template.py

    diff --git a/sagenb/notebook/template.py b/sagenb/notebook/template.py
    a b AUTHORS: 
    1515#                  http://www.gnu.org/licenses/
    1616#############################################################################
    1717
    18 import jinja
    19 
    20 from jinja.filters import stringfilter, simplefilter
     18import jinja2
    2119
    2220import os, re, sys
    2321
    from sagenb.notebook.jsmath import math_ 
    2725
    2826
    2927TEMPLATE_PATH = os.path.join(DATA, 'sage')
    30 env = jinja.Environment(loader=jinja.FileSystemLoader(TEMPLATE_PATH))
     28env = jinja2.Environment(loader=jinja2.FileSystemLoader(TEMPLATE_PATH))
    3129
    3230css_illegal_re = re.compile(r'[^-A-Za-z_0-9]')
    3331
    34 @stringfilter
    3532def css_escape(string):
    3633    r"""
    3734    Returns a string with all characters not legal in a css name
    def css_escape(string): 
    4340
    4441    EXAMPLES::
    4542
    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')
    6445        'abcd'
    65         sage: css_escape('12abcd')                            # not tested
     46        sage: css_escape('12abcd')
    6647        '12abcd'
    67         sage: css_escape(r'\'"abcd\'"')                       # not tested
     48        sage: css_escape(r'\'"abcd\'"')
    6849        '---abcd---'
    69         sage: css_escape('my-invalid/identifier')             # not tested
     50        sage: css_escape('my-invalid/identifier')
    7051        'my-invalid-identifier'
    71         sage: css_escape(r'quotes"mustbe!escaped')            # not tested
     52        sage: css_escape(r'quotes"mustbe!escaped')
    7253        'quotes-mustbe-escaped'
    7354    """
    7455    return css_illegal_re.sub('-', string)
    def clean_name(name): 
    119100    return ''.join([x if x.isalnum() else '_' for x in name])
    120101
    121102env.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)
     103env.filters['number_of_rows'] = number_of_rows
     104env.filters['clean_name'] = clean_name
     105env.filters['prettify_time_ago'] = prettify_time_ago
     106env.filters['math_parse'] = math_parse
     107env.filters['max'] = max
    127108
    128109def template(filename, **user_context):
    129110    """
    def template(filename, **user_context): 
    139120      the file's template variables
    140121
    141122    OUTPUT:
    142    
     123
    143124    - a string - the rendered HTML, CSS, etc.
    144125
    145126    EXAMPLES::
    def template(filename, **user_context): 
    164145                       'conf': notebook.conf() if notebook else None}
    165146    try:
    166147        tmpl = env.get_template(filename)
    167     except jinja.exceptions.TemplateNotFound:
     148    except jinja2.exceptions.TemplateNotFound:
    168149        return "Notebook Bug -- missing template %s"%filename
    169150    context = dict(default_context)
    170151    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(): 
    8282SEP = '___S_A_G_E___'
    8383
    8484def 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)
    8693
    8794
    8895
    class Worksheet_new_cell_before(Workshee 
    10901097    def render(self, ctx):
    10911098        id = self.id(ctx)
    10921099        if not ctx.args.has_key('input'):
    1093             input = ''
     1100            input = u''
    10941101        else:
    10951102            input = ctx.args['input'][0]
     1103            if isinstance(input, str):
     1104                input = input.decode('utf-8')
    10961105
    10971106        cell = self.worksheet.new_cell_before(id, input=input)
    10981107        self.worksheet.increase_state_number()
    class Worksheet_new_text_cell_before(Wor 
    11091118            input = ''
    11101119        else:
    11111120            input = ctx.args['input'][0]
     1121            if isinstance(input, str):
     1122                input = input.decode('utf-8')
    11121123
    11131124        cell = self.worksheet.new_text_cell_before(id, input=input)
    11141125        s = encode_list([cell.id(), cell.html(editing=True), id])
    class Worksheet_new_cell_after(Worksheet 
    11251136            input = ''
    11261137        else:
    11271138            input = ctx.args['input'][0]
     1139            if isinstance(input, str):
     1140                input = input.decode('utf-8')
    11281141        cell = self.worksheet.new_cell_after(id, input=input)
    11291142        s = encode_list([cell.id(), cell.html(div_wrap=False), id])
    11301143        return HTMLResponse(stream = s)
    class Worksheet_new_text_cell_after(Work 
    11391152            input = ''
    11401153        else:
    11411154            input = ctx.args['input'][0]
     1155            if isinstance(input, str):
     1156                input = input.decode('utf-8')
    11421157
    11431158        cell = self.worksheet.new_text_cell_after(id, input=input)
    11441159        s = encode_list([cell.id(), cell.html(editing=True), id])
    class Worksheet_cell_update(WorksheetRes 
    12001215        if status == 'd':
    12011216            new_input = cell.changed_input_text()
    12021217            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)
    12101222        else:
    12111223            new_input = ''
    12121224            out_html = ''
    class Worksheet_eval(WorksheetResource,  
    12521264    def render(self, ctx):
    12531265        id = self.id(ctx)
    12541266        if not ctx.args.has_key('input'):
    1255             input_text = ''
     1267            input_text = u''
    12561268        else:
    12571269            input_text = ctx.args['input'][0]
    12581270            input_text = input_text.replace('\r\n', '\n')   # DOS
     1271            if isinstance(input_text, str):
     1272                input_text = input_text.decode('utf-8')
     1273
    12591274
    12601275        W = self.worksheet
    12611276        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): 
    271271            sage: import sagenb.notebook.worksheet
    272272            sage: W = sagenb.notebook.worksheet.Worksheet('test', 0, tmp_dir(), owner='sage')
    273273            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))]
    287275        """
    288276        try:
    289277            published_id_number = int(os.path.split(self.__published_version)[1])
    class Worksheet(object): 
    690678            sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb')
    691679            sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
    692680            sage: W.name()
    693             'A Test Worksheet'
     681            u'A Test Worksheet'
    694682        """
    695683        try:
    696684            return self.__name
    class Worksheet(object): 
    712700            sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
    713701            sage: W.set_name('A renamed worksheet')
    714702            sage: W.name()
    715             'A renamed worksheet'
     703            u'A renamed worksheet'
    716704        """
    717705        if len(name.strip()) == 0:
    718             name = 'Untitled'
     706            name = u'Untitled'
     707        if isinstance(name, str):
     708            name = name.decode('utf-8', 'ignore')
    719709        self.__name = name
    720710
    721711    def set_filename_without_owner(self, nm):
    class Worksheet(object): 
    19131903        if os.path.exists(worksheet_html) and open(worksheet_html).read() == E:
    19141904            # we already wrote it out...
    19151905            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'))
    19181908        self.limit_snapshots()
    19191909        try:
    19201910            X = self.__saved_by_info
    class Worksheet(object): 
    21412131            5, Cell 1; in=2+8, out=
    21422132            10]
    21432133            sage: W.name()
    2144             'Test Edit Save'
     2134            u'Test Edit Save'
    21452135        """
    21462136        # Clear any caching.
    21472137        try:
    from sagenb.notebook.all import * 
    34393429        """
    34403430        # The extra newline below is necessary, since otherwise source
    34413431        # 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)
    34433433
    34443434    ##########################################################
    34453435    # Loading and attaching files
    from sagenb.notebook.all import * 
    35963586            sage: W.get_cell_system(c0)
    35973587            'sage'
    35983588            sage: W.get_cell_system(c1)
    3599             'gap'
     3589            u'gap'
    36003590            sage: W.edit_save('{{{\n%sage\n2+3\n}}}\n\n{{{\nSymmetricGroup(5)\n}}}')
    36013591            sage: W.set_system('gap')
    36023592            sage: c0, c1 = W.cell_list()
    36033593            sage: W.get_cell_system(c0)
    3604             'sage'
     3594            u'sage'
    36053595            sage: W.get_cell_system(c1)
    36063596            'gap'
    36073597        """
    from sagenb.notebook.all import * 
    36263616            os.makedirs(code)
    36273617        spyx = os.path.abspath(os.path.join(code, 'sage%s.spyx'%id))
    36283618        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'))
    36303620        return '_support_.cython_import_all("%s", globals())'%spyx
    36313621
    36323622    def check_for_system_switching(self, input, cell):
    from sagenb.notebook.all import * 
    36533643            sage: W.edit_save('{{{\n2+3\n}}}\n\n{{{\n%gap\nSymmetricGroup(5)\n}}}')
    36543644            sage: c0, c1 = W.cell_list()
    36553645            sage: W.check_for_system_switching(c0.cleaned_input_text(), c0)
    3656             (False, '2+3')
     3646            (False, u'2+3')
    36573647            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)''', '...')")
    36593649
    36603650        ::
    36613651
    from sagenb.notebook.all import * 
    36773667            sage: W.set_system('gap')
    36783668            sage: c0, c1 = W.cell_list()
    36793669            sage: W.check_for_system_switching(c0.cleaned_input_text(), c0)
    3680             (False, '2+3')
     3670            (False, u'2+3')
    36813671            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)''', '...')")
    36843673            sage: c0.evaluate()
    36853674            sage: W.check_comp()  #random output -- depends on the computer's speed
    36863675            ('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): 
    291291            # only save if loaded
    292292            # todo -- add check if changed
    293293            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'))
    295295
    296296    def load_worksheet(self, username, id_number):
    297297        """
    class FilesystemDatastore(Datastore): 
    339339        if title:
    340340            # change the title
    341341            basic['name'] = title
    342 
     342        if isinstance(basic['name'], unicode):
     343            basic['name'] = basic['name'].encode('utf-8', 'ignore')
    343344        # Remove metainformation that perhaps shouldn't be distributed
    344345        for k in ['owner', 'ratings', 'worksheet_that_was_published', 'viewers', 'tags', 'published_id_number',
    345346                  'collaborators', 'auto_publish']:
    class FilesystemDatastore(Datastore): 
    397398
    398399        worksheet_txt = members[0].name
    399400        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'))
    401402        # '/' is right, since old worksheets always unix
    402403        dir = worksheet_txt.split('/')[0]
    403404