# A Worksheet

A Worksheet

A worksheet is embedded in a web page that is served by the Sage server. It is a linearly-ordered collections of numbered cells, where a cell is a single input/output block.

The worksheet module is responsible for running calculations in a worksheet, spawning Sage processes that do all of the actual work and are controlled via pexpect, and reporting on results of calculations. The state of the cells in a worksheet is stored on the file system (not in the notebook pickle sobj).

AUTHORS:

- William Stein

class `sagenb.notebook.worksheet.``Worksheet`(name=None, id_number=None, notebook_worksheet_directory=None, system=None, owner=None, pretty_print=False, auto_publish=False, create_directories=True, live_3D=False)

  Bases: `object`

  `add_collaborator`(user)

    Add the given user as a collaborator on this worksheet.

    INPUT:

    - `user` - a string

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: nb.user_manager().add_user('diophantus','sage','sage@sagemath.org',force=True)
        sage: W = nb.create_new_worksheet('Collaborator test', 'admin')
        sage: W.collaborators()
        []
        sage: W.add_collaborator('diophantus')
        sage: W.collaborators()
        ['diophantus']

  `add_viewer`(user)

    Add the given user as an allowed viewer of this worksheet.

    INPUT:

    - `user` - string (username)

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: nb.user_manager().add_user('diophantus','sage','sage@sagemath.org',force=True)
        sage: W = nb.create_new_worksheet('Viewer test', 'admin')
        sage: W.add_viewer('diophantus')
        sage: W.viewers()
        ['diophantus']

  `append`(L)
  `append_new_cell`()

    Creates and appends a new compute cell to this worksheet’s list of cells.

    OUTPUT:

    - a new `sagenb.notebook.cell.Cell` instance

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('Test Edit Save', 'admin')
        sage: W
        admin/0: [Cell 1: in=, out=]
        sage: W.append_new_cell()
        Cell 2: in=, out=
        sage: W
        admin/0: [Cell 1: in=, out=, Cell 2: in=, out=]

  `attach`(filename)
  `attached_data_files`()

    Return a list of the file names of files in the worksheet data directory.

    OUTPUT: list of strings

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
        sage: W.attached_data_files()
        []
        sage: open('%s/foo.data'%W.data_directory(),'w').close()
        sage: W.attached_data_files()
        ['foo.data']

  `attached_files`()
  `attached_html`(username=None)
  `autosave`(username)
  `basic`()

    Output a dictionary of basic Python objects that defines the configuration of this worksheet, except the actual cells and the data files in the DATA directory and images and other data in the individual cell directories.

    EXAMPLES:

        sage: import sagenb.notebook.worksheet
        sage: W = sagenb.notebook.worksheet.Worksheet('test', 0, tmp_dir(), owner='sage')
        sage: sorted((W.basic().items()))
        [('auto_publish', False), ('collaborators', []), ('id_number', 0), ('last_change', ('sage', ...)), ('live_3D', False), ('name', u'test'), ('owner', 'sage'), ('pretty_print', False), ('published_id_number', None), ('ratings', []), ('saved_by_info', {}), ('system', None), ('tags', {'sage': [1]}), ('viewers', []), ('worksheet_that_was_published', ('sage', 0))]

  `best_completion`(s, word)
  `body`()

    OUTPUT:

    > – `string` – Plain text representation of the body of
    >   the worksheet.

  `body_is_loaded`()

    Return True if the body if this worksheet has been loaded from disk.

  `cell_directory`(C)
  `cell_id_list`()

    Returns a list of ID’s of all cells in this worksheet.

    OUTPUT:

    - a new list of integers and/or strings

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('Test Edit Save', 'admin')

    Now we set the worksheet to have two cells with the default id of 0 and another with id 10.

        sage: W.edit_save('{{{\n2+3\n///\n5\n}}}\n{{{id=10|\n2+8\n///\n10\n}}}')
        sage: W.cell_id_list()
        [0, 10]

  `cell_list`()

    Returns a reference to the list of this worksheet’s cells.

    OUTPUT:

    - a list of `sagenb.notebook.cell.Cell_generic` instances

    Note

    This function loads the cell list from disk (the file worksheet.html) if it isn’t available in memory.

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('Test Edit Save', 'admin')
        sage: W.edit_save('{{{\n2+3\n///\n5\n}}}\n{{{\n2+8\n///\n10\n}}}')
        sage: v = W.cell_list(); v
        [Cell 0: in=2+3, out=
        5, Cell 1: in=2+8, out=
        10]
        sage: v[0]
        Cell 0: in=2+3, out=
        5

  `cells_directory`()

    Return the directory in which the cells of this worksheet are evaluated.

    OUTPUT: string

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
        sage: W.cells_directory()
        '.../home/admin/0/cells'

  `check_cell`(id)

    Checks the status of a given compute cell.

    INPUT:

    - `id` - an integer or a string; the cell’s ID.

    OUTPUT:

    - a (string, `sagenb.notebook.cell.Cell`)-tuple; the cell’s status (‘d’ for “done” or ‘w’ for “working”) and the cell itself.
  `check_comp`(wait=0.2)

    Check on currently computing cells in the queue.

    INPUT:

    - `wait` - float (default: 0.2); how long to wait for output.

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.load_notebook(tmp_dir(ext='.sagenb'))
        sage: nb.user_manager().add_user('sage','sage','sage@sagemath.org',force=True)
        sage: W = nb.create_new_worksheet('Test', 'sage')
        sage: W.edit_save('{{{\n3^20\n}}}')
        sage: W.cell_list()[0].evaluate()
        sage: W.check_comp()     # random output -- depends on computer speed
        ('d', Cell 0: in=3^20, out=
        3486784401
        )
        sage: W.quit()
        sage: nb.delete()

  `check_for_system_switching`(input, cell)

    Check for input cells that start with `%foo`, where `foo` is an object with an eval method.

    INPUT:

    - `s` - a string of the code from the cell to be executed
    - `C` - the cell object

    EXAMPLES: First, we set up a new notebook and worksheet.

        sage: nb = sagenb.notebook.notebook.load_notebook(tmp_dir(ext='.sagenb'))
        sage: nb.user_manager().add_user('sage','sage','sage@sagemath.org',force=True)
        sage: W = nb.create_new_worksheet('Test', 'sage')

    We first test running a native command in ‘sage’ mode and then a GAP cell within Sage mode.

        sage: W.edit_save('{{{\n2+3\n}}}\n\n{{{\n%gap\nSymmetricGroup(5)\n}}}')
        sage: c0, c1 = W.cell_list()
        sage: W.check_for_system_switching(c0.cleaned_input_text(), c0)
        (False, u'2+3')
        sage: W.check_for_system_switching(c1.cleaned_input_text(), c1)
        (True, u"print(_support_.syseval(gap, u'SymmetricGroup(5)', __SAGE_TMP_DIR__))")

        sage: c0.evaluate()
        sage: W.check_comp()  #random output -- depends on the computer's speed
        ('d', Cell 0: in=2+3, out=
        5
        )
        sage: c1.evaluate()
        sage: W.check_comp()  #random output -- depends on the computer's speed
        ('d', Cell 1: in=%gap
        SymmetricGroup(5), out=
        Sym( [ 1 .. 5 ] )
        )

    Next, we run the same commands but from ‘gap’ mode.

        sage: W.edit_save('{{{\n%sage\n2+3\n}}}\n\n{{{\nSymmetricGroup(5)\n}}}')
        sage: W.set_system('gap')
        sage: c0, c1 = W.cell_list()
        sage: W.check_for_system_switching(c0.cleaned_input_text(), c0)
        (False, u'2+3')
        sage: W.check_for_system_switching(c1.cleaned_input_text(), c1)
        (True, u"print(_support_.syseval(gap, u'SymmetricGroup(5)', __SAGE_TMP_DIR__))")
        sage: c0.evaluate()
        sage: W.check_comp()  #random output -- depends on the computer's speed
        ('d', Cell 0: in=%sage
        2+3, out=
        5
        )
        sage: c1.evaluate()
        sage: W.check_comp()  #random output -- depends on the computer's speed
        ('d', Cell 1: in=SymmetricGroup(5), out=
        Sym( [ 1 .. 5 ] )
        )
        sage: W.quit()
        sage: nb.delete()

  `clear`()
  `clear_queue`()
  `collaborator_names`(max=None)

    Returns a string of the non-owner collaborators on this worksheet.

    INPUT:

    - `max` - an integer. If this is specified, then only max number of collaborators are shown.

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('test1', 'admin')
        sage: C = W.collaborators(); C
        []
        sage: C.append('sage')
        sage: C.append('wstein')
        sage: W.collaborator_names()
        'sage, wstein'
        sage: W.collaborator_names(max=1)
        'sage, ...'

  `collaborators`()

    Return a (reference to the) list of the collaborators who can also view and modify this worksheet.

    OUTPUT: list

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('test1', 'admin')
        sage: C = W.collaborators(); C
        []
        sage: C.append('sage')
        sage: W.collaborators()
        ['sage']

  `completions_html`(id, s, cols=3)
  `compute_cell_id_list`()

    Returns a list of ID’s of all compute cells in this worksheet.

    OUTPUT:

    - a new list of integers and/or strings
  `compute_cell_list`()

    Returns a list of this worksheet’s compute cells.

    OUTPUT:

    - a list of `sagenb.notebook.cell.Cell` instances

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('Test', 'admin')
        sage: W.edit_save('foo\n{{{\n2+3\n///\n5\n}}}bar\n{{{\n2+8\n///\n10\n}}}')
        sage: v = W.compute_cell_list(); v
        [Cell 1: in=2+3, out=
        5, Cell 3: in=2+8, out=
        10]
        sage: v[0]
        Cell 1: in=2+3, out=
        5

  `compute_process_has_been_started`()

    Return True precisely if the compute process has been started, irregardless of whether or not it is currently churning away on a computation.

  `computing`()

    Return whether or not a cell is currently being run in the worksheet Sage process.

  `create_directories`()
  `cython_import`(cmd, cell)
  `data_directory`()

    Return path to directory where worksheet data is stored.

    OUTPUT: string

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
        sage: W.data_directory()
        '.../home/admin/0/data'

  `date_edited`()

    Returns the date the worksheet was last edited.

  `delete_all_output`(username)

    Delete all the output, files included, in all the worksheet cells.

    INPUT:

    - `username` - name of the user requesting the deletion.

    EXAMPLES: We create a new notebook, user, and a worksheet:

        sage: nb = sagenb.notebook.notebook.load_notebook(tmp_dir(ext='.sagenb'))
        sage: nb.user_manager().add_user('sage','sage','sage@sagemath.org',force=True)
        sage: W = nb.create_new_worksheet('Test', 'sage')
        sage: W.edit_save("{{{\n2+3\n///\n5\n}}}\n{{{\nopen('afile', 'w').write('some text')\nprint('hello')\n///\n\n}}}")

    We have two cells:

        sage: W.cell_list()
        [Cell 0: in=2+3, out=
        5, Cell 1: in=open('afile', 'w').write('some text')
        print('hello'), out=
        ]
        sage: C0 = W.cell_list()[1]
        sage: open(os.path.join(C0.directory(), 'xyz'), 'w').write('bye')
        sage: C0.files()
        ['xyz']
        sage: C1 = W.cell_list()[1]
        sage: C1.evaluate()
        sage: W.check_comp()     # random output -- depends on computer speed
        ('w', Cell 1: in=open('afile', 'w').write('some text')
        print('hello'), out=)
        sage: W.check_comp()     # random output -- depends on computer speed
        ('d', Cell 1: in=open('afile', 'w').write('some text')
        print('hello'), out=
        hello
        )
        sage: W.check_comp()     # random output -- depends on computer speed
        ('e', None)
        sage: C1.files()         # random output -- depends on computer speed
        ['afile']

    We now delete the output, observe that it is gone:

        sage: W.delete_all_output('sage')
        sage: W.cell_list()
        [Cell 0: in=2+3, out=, Cell 1: in=open('afile', 'w').write('some text')
        print('hello'), out=]
        sage: C0.files(), C1.files()
        ([], [])

    If an invalid user tries to delete all output, a ValueError is raised:

        sage: W.delete_all_output('hacker')
        Traceback (most recent call last):
        ...
        ValueError: user 'hacker' not allowed to edit this worksheet

    Clean up:

        sage: W.quit()
        sage: nb.delete()

  `delete_cell_with_id`(id)

    Deletes a cell from this worksheet’s cell list. This also deletes the cell’s output and files.

    INPUT:

    - `id` - an integer or string; the cell’s ID

    OUTPUT:

    - an integer or string; ID of the preceding cell

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('Test Delete Cell', 'admin')
        sage: W.edit_save('{{{id=foo|\n2+3\n///\n5\n}}}\n{{{id=9|\n2+8\n///\n10\n}}}{{{id=dont_delete_me|\n2*3\n///\n6\n}}}\n')
        sage: W.cell_id_list()
        ['foo', 9, 'dont_delete_me']
        sage: C = W.cell_list()[1]           # save a reference to the cell
        sage: C.output_text(raw=True)
        u'\n10'
        sage: open(os.path.join(C.directory(), 'bar'), 'w').write('hello')
        sage: C.files()
        ['bar']
        sage: C.files_html('')
        u'<a target="_new" href=".../cells/9/bar" class="file_link">bar</a>'
        sage: W.delete_cell_with_id(C.id())
        'foo'
        sage: C.output_text(raw=True)
        u''
        sage: C.files()
        []
        sage: W.cell_id_list()
        ['foo', 'dont_delete_me']

  `delete_cells_directory`()

    Delete the directory in which all the cell computations occur.

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: nb.user_manager().add_user('sage','sage','sage@sagemath.org',force=True)
        sage: W = nb.create_new_worksheet('Test', 'sage')
        sage: W.edit_save('{{{\n3^20\n}}}')
        sage: W.cell_list()[0].evaluate()
        sage: W.check_comp()    # random output -- depends on computer speed
        sage: sorted(os.listdir(W.directory()))
        ['cells', 'data', 'worksheet.html', 'worksheet_conf.pickle']
        sage: W.save_snapshot('admin')
        sage: sorted(os.listdir(W.directory()))
        ['cells', 'data', 'snapshots', 'worksheet.html', 'worksheet_conf.pickle']
        sage: W.delete_cells_directory()
        sage: sorted(os.listdir(W.directory()))
        ['data', 'snapshots', 'worksheet.html', 'worksheet_conf.pickle']
        sage: W.quit()
        sage: nb.delete()

  `delete_notebook_specific_data`()

    Delete data from this worksheet this is specific to a certain notebook. This means deleting the attached files, collaborators, and viewers.

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: nb.user_manager().add_user('hilbert','sage','sage@sagemath.org',force=True)
        sage: W = nb.create_new_worksheet('test1', 'admin')
        sage: W.add_viewer('hilbert')
        sage: W.delete_notebook_specific_data()
        sage: W.viewers()
        []
        sage: W.add_collaborator('hilbert')
        sage: W.collaborators()
        ['admin', 'hilbert']
        sage: W.delete_notebook_specific_data()
        sage: W.collaborators()
        ['admin']

  `delete_user`(user)

    Delete a user from having any view or ownership of this worksheet.

    INPUT:

    - `user` - string; the name of a user

    EXAMPLES: We create a notebook with 2 users and 1 worksheet that both view.

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.user_manager().add_user('wstein','sage','wstein@sagemath.org',force=True)
        sage: nb.user_manager().add_user('sage','sage','sage@sagemath.org',force=True)
        sage: W = nb.new_worksheet_with_title_from_text('Sage', owner='sage')
        sage: W.add_viewer('wstein')
        sage: W.owner()
        'sage'
        sage: W.viewers()
        ['wstein']

    We delete the sage user from the worksheet W. This makes wstein the new owner.

        sage: W.delete_user('sage')
        sage: W.viewers()
        ['wstein']
        sage: W.owner()
        'wstein'

    Then we delete wstein from W, which makes the owner None.

        sage: W.delete_user('wstein')
        sage: W.owner() is None
        True
        sage: W.viewers()
        []

    Finally, we clean up.

        sage: nb.delete()

  `detach`(filename)
  `directory`()

    Return the full path to the directory where this worksheet is stored.

    OUTPUT: string

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
        sage: W.directory()
        '.../home/admin/0'

  `docbrowser`()

    Return True if this is a docbrowser worksheet.

    OUTPUT: bool

    EXAMPLES: We first create a standard worksheet for which docbrowser is of course False:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('test1', 'admin')
        sage: W.docbrowser()
        False

    We create a worksheet for which docbrowser is True:

        sage: W = nb.create_new_worksheet('doc_browser_0', '_sage_')
        sage: W.docbrowser()
        True

  `download_name`()

    Return the download name of this worksheet.

  `edit_save`(text, ignore_ids=False)

    Set the contents of this worksheet to the worksheet defined by the plain text string text, which should be a sequence of HTML and code blocks.

    INPUT:

    - `text` - a string
    - `ignore_ids` - bool (default: False); if True ignore all the IDs in the {{{}}} code block.

    EXAMPLES:

    We create a new test notebook and a worksheet.

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.user_manager().add_user('sage','sage','sage@sagemath.org',force=True)
        sage: W = nb.create_new_worksheet('Test Edit Save', 'sage')

    We set the contents of the worksheet using the edit_save command.

        sage: W.edit_save('{{{\n2+3\n///\n5\n}}}\n{{{\n2+8\n///\n10\n}}}')
        sage: W
        sage/0: [Cell 0: in=2+3, out=
        5, Cell 1: in=2+8, out=
        10]
        sage: W.name()
        u'Test Edit Save'

    We check that loading a worksheet whose last cell is a `TextCell` properly increments the worksheet’s cell count (see Sage trac ticket #8443).

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.user_manager().add_user('sage', 'sage', 'sage@sagemath.org', force=True)
        sage: W = nb.create_new_worksheet('Test trac #8443', 'sage')
        sage: W.edit_save('{{{\n1+1\n///\n}}}')
        sage: W.cell_id_list()
        [0]
        sage: W.next_id()
        1
        sage: W.edit_save("{{{\n1+1\n///\n}}}\n\n<p>a text cell</p>")
        sage: len(set(W.cell_id_list())) == 3
        True
        sage: W.cell_id_list()
        [0, 1, 2]
        sage: W.next_id()
        3

  `edit_save_old_format`(text, username=None)
  `edit_text`()

    Returns a plain-text version of the worksheet with {{{}}} wiki-formatting, suitable for hand editing.

  `enqueue`(C, username=None, next=False)

    Queue a cell for evaluation in this worksheet.

    INPUT:

    - `C` - a `sagenb.notebook.cell.Cell` instance
    - `username` - a string (default: None); the name of the
        user evaluating this cell (mainly used for login)
    - `next` - a boolean (default: False); ignored

    Note

    If `C.is_asap()` is True, then we put `C` as close to the beginning of the queue as possible, but after all “asap” cells. Otherwise, `C` goes at the end of the queue.

  `eval_asap_no_output`(cmd, username=None)
  `everyone_has_deleted_this_worksheet`()

    Return True if all users have deleted this worksheet, so we know we can safely purge it from disk.

    OUTPUT: bool

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('Publish Test', 'admin')
        sage: W.everyone_has_deleted_this_worksheet()
        False
        sage: W.move_to_trash('admin')
        sage: W.everyone_has_deleted_this_worksheet()
        True

  `filename`()

    Return the filename (really directory) where the files associated to this worksheet are stored.

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
        sage: W.filename()
        'admin/0'
        sage: os.path.isdir(os.path.join(nb._dir, 'home', W.filename()))
        True

  `filename_without_owner`()

    Return the part of the worksheet filename after the last /, i.e., without any information about the owner of this worksheet.

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
        sage: W.filename_without_owner()
        '0'
        sage: W.filename()
        'admin/0'

  `get_cell_system`(cell)

    Returns the system that will run the input in cell. This defaults to worksheet’s system if there is not one specifically given in the cell.

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.user_manager().add_user('sage','sage','sage@sagemath.org',force=True)
        sage: W = nb.create_new_worksheet('Test', 'sage')
        sage: W.edit_save('{{{\n2+3\n}}}\n\n{{{\n%gap\nSymmetricGroup(5)\n}}}')
        sage: c0, c1 = W.cell_list()
        sage: W.get_cell_system(c0)
        'sage'
        sage: W.get_cell_system(c1)
        u'gap'
        sage: W.edit_save('{{{\n%sage\n2+3\n}}}\n\n{{{\nSymmetricGroup(5)\n}}}')
        sage: W.set_system('gap')
        sage: c0, c1 = W.cell_list()
        sage: W.get_cell_system(c0)
        u'sage'
        sage: W.get_cell_system(c1)
        'gap'

  `get_cell_with_id`(id)

    Get a pre-existing cell with this id, or creates a new one with it.

  `get_cell_with_id_or_none`(id)

    Gets a pre-existing cell with this id, or returns None.

  `get_snapshot_text_filename`(name)
  `has_published_version`()

    Return True if there is a published version of this worksheet.

    OUTPUT: bool

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('Publish Test', 'admin')
        sage: P = nb.publish_worksheet(W, 'admin')
        sage: P.has_published_version()
        False
        sage: W.has_published_version()
        True

  `hide_all`()
  `html`(do_print=False, publish=False, username=None)

    INPUT:

    - publish - a boolean stating whether the worksheet is published
    - do_print - a boolean

    OUTPUT:

    - string – the HTML for the worksheet

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('Test', 'admin')
        sage: W.html()
        u'...cell_input_active...worksheet_cell_list...cell_1...cell_output_html_1...'

  `html_cell_list`(do_print=False, username=None)

    INPUT:

    > - do_print - a boolean

    OUTPUT:

    > - string – the HTML for the list of cells

  `html_ratings_info`(username=None)

    Return html that renders to give a summary of how this worksheet has been rated.

    OUTPUT:

    - `string` – a string of HTML as a bunch of table rows.

    EXAMPLES:

        sage: from sagenb.flask_version import base # random output -- depends on warnings issued by other sage packages
        sage: app = base.create_app(tmp_dir(ext='.sagenb'))
        sage: ctx = app.app_context()
        sage: ctx.push()
        sage: nb = base.notebook
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('Publish Test', 'admin')
        sage: W.rate(0, 'this lacks content', 'riemann')
        sage: W.rate(3, 'this is great', 'hilbert')
        sage: W.html_ratings_info()
        u'...hilbert...3...this is great...this lacks content...'

  `html_time_last_edited`(username=None)
  `html_time_nice_edited`(username=None)

    Returns a “nice” html time since last edit.

    If the last edit was in the last 24 hours, return a “x hours ago”. Otherwise, return a specific date.

  `html_time_since_last_edited`(username=None)
  `hunt_file`(filename)
  `id_number`()

    Return the id number of this worksheet, which is an integer.

    EXAMPLES:

        sage: from sagenb.notebook.worksheet import Worksheet
        sage: W = Worksheet('test', 2, tmp_dir(), owner='sageuser')
        sage: W.id_number()
        2
        sage: type(W.id_number())
        <type 'int'>

  `increase_state_number`()
  `initialize_sage`()
  `input_text`()

    Return text version of the input to the worksheet.

  `interrupt`(callback=None, timeout=1)

    Interrupt all currently queued up calculations.

    INPUT:

    - `timeout` – time to wait for interruption to succeed
    - `callback` – callback to be called. Called with True if interrupt succeeds, else called with False.

    OUTPUT:

    - `deferred` - a Deferred object with the given callbacks and errbacks

    EXAMPLES: We create a worksheet and start a large factorization going:

        sage: nb = sagenb.notebook.notebook.load_notebook(tmp_dir(ext='.sagenb'))
        sage: nb.user_manager().add_user('sage','sage','sage@sagemath.org',force=True)
        sage: W = nb.create_new_worksheet('Test', 'sage')
        sage: W.edit_save('{{{\nfactor(2^997-1)\n}}}')
        sage: W.cell_list()[0].evaluate()

    It’s running still:

        sage: W.check_comp()
        ('w', Cell 0: in=factor(2^997-1), out=...)

    We interrupt it successfully.

        sage: W.interrupt()         # not tested -- needs running reactor
        True

    Now we check and nothing is computing.

        sage: W.check_comp()        # random -- could fail on heavily loaded machine
        ('e', None)

    Clean up.

        sage: W.quit()
        sage: nb.delete()

  `is_active`(user)

    Return True if this worksheet is active for the given user.

    INPUT:

    - `user` - string

    OUTPUT: bool

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('Active Test', 'admin')
        sage: W.is_active('admin')
        True
        sage: W.move_to_archive('admin')
        sage: W.is_active('admin')
        False

  `is_archived`(user)

    Return True if this worksheet is archived for the given user.

    INPUT:

    - `user` - string

    OUTPUT: bool

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('Archived Test', 'admin')
        sage: W.is_archived('admin')
        False
        sage: W.move_to_archive('admin')
        sage: W.is_archived('admin')
        True

  `is_auto_publish`()

    Returns True if this worksheet should be automatically published.

  `is_collaborator`(user)
  `is_last_id_and_previous_is_nonempty`(id)
  `is_only_viewer`(user)
  `is_owner`(username)
  `is_published`()

    Return True if this worksheet is a published worksheet.

    OUTPUT:

    - `bool` - whether or not owner is ‘pub’

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('Publish Test', 'admin')
        sage: W.is_published()
        False
        sage: W.set_owner('pub')
        sage: W.is_published()
        True

  `is_publisher`(username)

    Return True if username is the username of the publisher of this worksheet, assuming this worksheet was published.

    INPUT:

    - `username` - string

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.load_notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('Publish Test', 'admin')
        sage: P = nb.publish_worksheet(W, 'admin')
        sage: P.is_publisher('hearst')
        False
        sage: P.is_publisher('admin')
        True

  `is_rater`(username)

    Return True is the user with given username has rated this worksheet.

    INPUT:

    - `username` - string

    OUTPUT: bool

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('Publish Test', 'admin')
        sage: W.rate(0, 'this lacks content', 'riemann')
        sage: W.is_rater('admin')
        False
        sage: W.is_rater('riemann')
        True

  `is_trashed`(user)

    Return True if this worksheet is in the trash for the given user.

    INPUT:

    - `user` - string

    OUTPUT: bool

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('Trash Test', 'admin')
        sage: W.is_trashed('admin')
        False
        sage: W.move_to_trash('admin')
        sage: W.is_trashed('admin')
        True

  `is_viewer`(user)
  `last_change`()

    Return information about when this worksheet was last changed and by whom.

    OUTPUT:

    > - `username` – string of username who last edited this worksheet
    > - `float` – seconds since epoch of the time when this worksheet was last edited

  `last_compute_walltime`()
  `last_edited`()
  `last_to_edit`()
  `limit_snapshots`()

    This routine will limit the number of snapshots of a worksheet, as specified by a hard-coded value below.

    Prior behavior was to allow unlimited numbers of snapshots and so this routine will not delete files created prior to this change.

    This assumes snapshot names correspond to the `time.time()` method used to create base filenames in seconds in UTC time, and that there are no other extraneous files in the directory.

  `live_3D`()

    Return True if the 3-D plots should be loaded live (interactive) by default.

    OUTPUT:

    - `bool` - True of False

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
        sage: W.live_3D()
        False
        sage: W.quit()
        sage: nb.delete()

  `load_any_changed_attached_files`(s)

    Modify `s` by prepending any necessary load commands corresponding to attached files that have changed.

  `load_path`()
  `move_out_of_trash`(user)

    Exactly the same as set_active(user).

    INPUT:

    - `user` - string

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('Active Test', 'admin')
        sage: W.move_to_trash('admin')
        sage: W.is_active('admin')
        False
        sage: W.move_out_of_trash('admin')
        sage: W.is_active('admin')
        True

  `move_to_archive`(user)

    Move this worksheet to be archived for the given user.

    INPUT:

    - `user` - string

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('Archive Test', 'admin')
        sage: W.move_to_archive('admin')
        sage: W.is_archived('admin')
        True

  `move_to_trash`(user)

    Move this worksheet to the trash for the given user.

    INPUT:

    - `user` - string

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('Trash Test', 'admin')
        sage: W.move_to_trash('admin')
        sage: W.is_trashed('admin')
        True

  `name`(username=None)

    Return the name of this worksheet.

    OUTPUT: string

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
        sage: W.name()
        u'A Test Worksheet'
        sage: W = nb.create_new_worksheet('ěščřžýáíéďĎ', 'admin')
        sage: W.name()
        u'\u011b\u0161\u010d\u0159\u017e\xfd\xe1\xed\xe9\u010f\u010e'

  `new_cell_after`(id, input='')

    Inserts a new compute cell into this worksheet’s cell list after the cell with the given ID. If the ID does not match any cell, it inserts the new cell at the end of the list.

    INPUT:

    - `id` - an integer or a string; the ID of the cell to find
    - `input` - a string (default: ‘’); the new cell’s input text

    OUTPUT:

    - a new `sagenb.notebook.cell.Cell` instance
  `new_cell_before`(id, input='')

    Inserts a new compute cell before a cell with the given ID. If the ID does not match any cell in this worksheet’s list, it inserts a new cell at the end.

    INPUT:

    - `id` - an integer or a string; the ID of the cell to find
    - `input` - a string (default: ‘’); the new cell’s input text

    OUTPUT:

    - a new `sagenb.notebook.cell.Cell` instance
  `new_text_cell_after`(id, input='')

    Inserts a new text cell into this worksheet’s cell list after the cell with the given ID. If the ID does not match any cell, it inserts the new cell at the end of the list.

    INPUT:

    - `id` - an integer or a string; the ID of the cell to find
    - `input` - a string (default: ‘’); the new cell’s input text

    OUTPUT:

    - a new `sagenb.notebook.cell.TextCell` instance
  `new_text_cell_before`(id, input='')

    Inserts a new text cell before the cell with the given ID. If the ID does not match any cell in this worksheet’s list, it inserts a new cell at the end.

    INPUT:

    - `id` - an integer or a string; the ID of the cell to find
    - `input` - a string (default: ‘’); the new cell’s input text

    OUTPUT:

    - a new `sagenb.notebook.cell.TextCell` instance
  `next_block_id`()
  `next_hidden_id`()
  `next_id`()
  `notebook`()

    Return the notebook that contains this worksheet.

    OUTPUT: a Notebook object.

    Note

    This really returns the Notebook object that is set as a global variable of the misc module. This is done even in the Flask version of the notebook as it is set in func:sagenb.notebook.notebook.load_notebook.

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
        sage: W.notebook()
        <...sagenb.notebook.notebook.Notebook...>
        sage: W.notebook() is sagenb.notebook.misc.notebook
        True

  `onload_id_list`()

    Returns a list of ID’s of cells the remote client should evaluate after the worksheet loads. Unlike ‘%auto’ cells, which the server chooses to evaluate, onload cells fire only after the client sends a request. Currently, we use onload cells to set up published interacts.

    OUTPUT:

    - a new list of integer and/or string IDs
  `owner`()
  `ping`(username)
  `plain_text`(prompts=False, banner=True)

    Return a plain-text version of the worksheet.

    INPUT:

    - `prompts` - if True format for inclusion in docstrings.
  `postprocess_output`(out, C)
  `preparse`(s)

    Return preparsed version of input code `s`, ready to be sent to the Sage process for evaluation. The output is a “safe string” (no funny characters).

    INPUT:

    > - `s` – a string

    OUTPUT:

    > - a string

  `preparse_input`(input, C)
  `preparse_introspection_input`(input, C, introspect)
  `preparse_nonswitched_input`(input)

    Preparse the input to a Sage Notebook cell.

    INPUT:

    > - `input` – a string

    OUTPUT:

    > - a string

  `pretty_print`()

    Return True if output should be pretty printed by default.

    OUTPUT:

    - `bool` - True of False

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
        sage: W.pretty_print()
        False
        sage: W.set_pretty_print('true')
        sage: W.pretty_print()
        True
        sage: W.quit()
        sage: nb.delete()

  `published_version`()

    If this worksheet was published, return the published version of this worksheet. Otherwise, raise a ValueError.

    OUTPUT: a worksheet (or raise a ValueError)

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.load_notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('Publish Test', 'admin')
        sage: P = nb.publish_worksheet(W, 'admin')
        sage: W.published_version() is P
        True

  `publisher`()

    Return username of user that published this worksheet.

    OUTPUT: string

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('Publish Test', 'admin')
        sage: S = nb.publish_worksheet(W, 'admin')
        sage: S.publisher()
        'admin'

  `queue`()
  `queue_id_list`()
  `quit`()
  `quit_if_idle`(timeout)

    Quit the worksheet process if it has been “idle” for more than `timeout` seconds, where idle is by definition that the worksheet has not reported back that it is actually computing. I.e., an ignored worksheet process (since the user closed their browser) is also considered idle, even if code is running.

  `rate`(x, comment, username)

    Set the rating on this worksheet by the given user to x and also set the given comment.

    INPUT:

    - `x` - integer
    - `comment` - string
    - `username` - string

    EXAMPLES: We create a worksheet and rate it, then look at the ratings.

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('Publish Test', 'admin')
        sage: W.rate(3, 'this is great', 'hilbert')
        sage: W.ratings()
        [('hilbert', 3, 'this is great')]

    Note that only the last rating by a user counts:

        sage: W.rate(1, 'this lacks content', 'riemann')
        sage: W.rate(0, 'this lacks content', 'riemann')
        sage: W.ratings()
        [('hilbert', 3, 'this is great'), ('riemann', 0, 'this lacks content')]

  `rating`()

    Return overall average rating of self.

    OUTPUT: float or the int -1 to mean “not rated”

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('Publish Test', 'admin')
        sage: W.rating()
        -1
        sage: W.rate(0, 'this lacks content', 'riemann')
        sage: W.rate(3, 'this is great', 'hilbert')
        sage: W.rating()
        1.5

  `ratings`()

    Return all the ratings of this worksheet.

    OUTPUT:

    - `list` - a reference to the list of ratings.

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('Publish Test', 'admin')
        sage: W.ratings()
        []
        sage: W.rate(0, 'this lacks content', 'riemann')
        sage: W.rate(3, 'this is great', 'hilbert')
        sage: W.ratings()
        [('riemann', 0, 'this lacks content'), ('hilbert', 3, 'this is great')]

  `reconstruct_from_basic`(obj, notebook_worksheet_directory=None)

    Reconstruct as much of the worksheet’s configuration as possible from the properties that happen to be set in the basic dictionary obj.

    INPUT:

    > - `obj` – a dictionary of basic Python objects
    > - `notebook_worksheet_directory` – must be given if `id_number` is a key of obj; otherwise not.

    EXAMPLES:

        sage: import sagenb.notebook.worksheet
        sage: W = sagenb.notebook.worksheet.Worksheet('test', 0, tmp_dir(), system='gap', owner='sageuser', pretty_print=True, auto_publish=True)
        sage: W.new_cell_after(0)
        Cell 1: in=, out=
        sage: b = W.basic()
        sage: W0 = sagenb.notebook.worksheet.Worksheet()
        sage: W0.reconstruct_from_basic(b, tmp_dir())
        sage: W0.basic() == W.basic()
        True

  `record_edit`(user)
  `reset_interact_state`()

    Reset the interact state of this worksheet.

  `restart_sage`()

    Restart Sage kernel.

  `revert_to_last_saved_state`()
  `revert_to_snapshot`(name)
  `sage`()

    Return a started up copy of Sage initialized for computations.

    If this is a published worksheet, just return None, since published worksheets must not have any compute functionality.

    OUTPUT: a Sage interface

  `satisfies_search`(search)

    Return True if all words in search are in the saved text of the worksheet.

    INPUT:

    - `search` - a string that describes a search query, i.e., a space-separated collections of words.

    OUTPUT:

    - a boolean
  `save`(conf_only=False)
  `save_snapshot`(user, E=None)
  `set_active`(user)

    Set his worksheet to be active for the given user.

    INPUT:

    - `user` - string

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('Active Test', 'admin')
        sage: W.move_to_archive('admin')
        sage: W.is_active('admin')
        False
        sage: W.set_active('admin')
        sage: W.is_active('admin')
        True

  `set_auto_publish`(x)
  `set_body`(body)
  `set_cell_counter`()
  `set_collaborators`(v)

    Set the list of collaborators to those listed in the list v of strings.

    INPUT:

    - `v` - a list of strings

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.load_notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: nb.user_manager().add_user('sage','sage','sage@sagemath.org',force=True)
        sage: nb.user_manager().add_user('hilbert','sage','sage@sagemath.org',force=True)
        sage: W = nb.create_new_worksheet('test1', 'admin')
        sage: W.set_collaborators(['sage', 'admin', 'hilbert', 'sage'])

    Note that repeats are not added multiple times and admin - the owner - isn’t added:

        sage: W.collaborators()
        ['hilbert', 'sage']

  `set_filename`(filename)

    Set the worksheet filename (actually directory).

    INPUT:

    - `filename` - string

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.load_notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
        sage: W.filename()
        'admin/0'
        sage: W.set_filename('admin/10')
        sage: W.filename()
        'admin/10'

  `set_filename_without_owner`(nm)

    Set this worksheet filename (actually directory) by getting the owner from the pre-stored owner via `self.owner()`.

    INPUT:

    - `nm` - string

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.load_notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
        sage: W.filename()
        'admin/0'
        sage: W.set_filename_without_owner('5')
        sage: W.filename()
        'admin/5'

  `set_last_change`(username, tm)

    Set the time and who last changed this worksheet.

    INPUT:

    > - `username` – (string) name of a user
    > - `tm` – (float) seconds since epoch

    EXAMPLES:

        sage: W = sagenb.notebook.worksheet.Worksheet('test', 0, tmp_dir(), owner='sage')
        sage: W.last_change()
        ('sage', ...)
        sage: W.set_last_change('john', 1255029800)
        sage: W.last_change()
        ('john', 1255029800.0)

    We make sure these other functions have been correctly updated:

        sage: W.last_edited()
        1255029800.0
        sage: W.last_to_edit()
        'john'
        sage: W.date_edited() # Output depends on timezone
        time.struct_time(tm_year=2009, tm_mon=10, ...)
        sage: t = W.time_since_last_edited() # just test that call works

  `set_live_3D`(check=False)

    Set whether or not 3-D plots should be live by default. Not a good idea for worksheets with more than 1 or 2 3-D plots.

    INPUT:

    - `check` - boolean

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
        sage: W.set_live_3D(False)
        sage: W.live_3D()
        False
        sage: W.set_live_3D(True)
        sage: W.live_3D()
        True
        sage: W.quit()
        sage: nb.delete()

  `set_name`(name)

    Set the name of this worksheet.

    INPUT:

    - `name` - string

    EXAMPLES: We create a worksheet and change the name:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
        sage: W.set_name('A renamed worksheet')
        sage: W.name()
        u'A renamed worksheet'

  `set_not_computing`()
  `set_owner`(owner)
  `set_pretty_print`(check='false')

    Set whether or not output should be pretty printed by default.

    INPUT:

    - `check` - string (default: ‘false’); either ‘true’ or ‘false’.

    Note

    The reason the input is a string and lower case instead of a Python bool is because this gets called indirectly from JavaScript. (And, Jason Grout wrote this and didn’t realize how unpythonic this design is - it should be redone to use True/False.)

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
        sage: W.set_pretty_print('false')
        sage: W.pretty_print()
        False
        sage: W.set_pretty_print('true')
        sage: W.pretty_print()
        True
        sage: W.quit()
        sage: nb.delete()

  `set_published_version`(filename)

    Set the published version of this worksheet to be the worksheet with given filename.

    INPUT:

    - `filename` - string

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('Publish Test', 'admin')
        sage: P = nb.publish_worksheet(W, 'admin')  # indirect test
        sage: W._Worksheet__published_version
        'pub/0'
        sage: W.set_published_version('pub/1')
        sage: W._Worksheet__published_version
        'pub/1'

  `set_system`(system='sage')

    Set the math software system in which input is evaluated by default.

    INPUT:

    - `system` - string (default: ‘sage’)

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
        sage: W.set_system('magma')
        sage: W.system()
        'magma'

  `set_tags`(tags)

    Set the tags – for now we ignore everything except ACTIVE, ARCHIVED, TRASH.

    INPUT:

    > - `tags` – dictionary with keys usernames and values a list of tags, where a tag is a string or ARCHIVED, ACTIVE, TRASH.

  `set_user_view`(user, x)

    Set the view on this worksheet for the given user.

    INPUT:

    - `user` - a string
    - `x` - int, one of the variables ACTIVE, ARCHIVED, TRASH in worksheet.py

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('Publish Test', 'admin')
        sage: W.set_user_view('admin', sagenb.notebook.worksheet.ARCHIVED)
        sage: W.user_view('admin') == sagenb.notebook.worksheet.ARCHIVED
        True

  `set_worksheet_that_was_published`(W)

    Set the owner and id_number of the worksheet that was published to get self.

    INPUT:

    > - `W` – worksheet or 2-tuple (‘owner’, id_number)

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.load_notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('Publish Test', 'admin')
        sage: P = nb.publish_worksheet(W, 'admin')
        sage: P.worksheet_that_was_published() is W
        True

    We fake things and make it look like P published itself:

        sage: P.set_worksheet_that_was_published(P)
        sage: P.worksheet_that_was_published() is P
        True

  `show_all`()
  `snapshot_data`()
  `snapshot_directory`()
  `start_next_comp`()
  `state_number`()
  `synchro`()
  `synchronize`(s)
  `system`()

    Return the math software system in which by default all input to the notebook is evaluated.

    OUTPUT: string

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
        sage: W.system()
        'sage'
        sage: W.set_system('mathematica')
        sage: W.system()
        'mathematica'

  `system_index`()

    Return the index of the current system into the Notebook’s list of systems. If the current system isn’t in the list, then change to the default system. This can happen if, e.g., the list changes, e.g., when changing from a notebook with Sage installed to running a server from the same directory without Sage installed. We might as well support this.

    OUTPUT: integer

  `tags`()

    A temporary trivial tags implementation.

  `time_idle`()
  `time_since_last_edited`()
  `truncated_name`(max=30)
  `uncache_snapshot_data`()
  `user_autosave_interval`(username)
  `user_can_edit`(user)

    Return True if the user with given name is allowed to edit this worksheet.

    INPUT:

    - `user` - string

    OUTPUT: bool

    EXAMPLES: We create a notebook with one worksheet and two users.

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.user_manager().add_user('sage','sage','sage@sagemath.org',force=True)
        sage: nb.user_manager().add_user('william', 'william', 'wstein@sagemath.org', force=True)
        sage: W = nb.create_new_worksheet('Test', 'sage')
        sage: W.user_can_edit('sage')
        True

    At first the user ‘william’ can’t edit this worksheet:

        sage: W.user_can_edit('william')
        False

    After adding ‘william’ as a collaborator he can edit the worksheet.

        sage: W.add_collaborator('william')
        sage: W.user_can_edit('william')
        True

    Clean up:

        sage: nb.delete()

  `user_view`(user)

    Return the view that the given user has of this worksheet. If the user currently doesn’t have a view set it to ACTIVE and return ACTIVE.

    INPUT:

    - `user` - a string

    OUTPUT:

    - `Python int` - one of ACTIVE, ARCHIVED, TRASH, which are defined in worksheet.py

    EXAMPLES: We create a new worksheet and get the view, which is ACTIVE:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('Publish Test', 'admin')
        sage: W.user_view('admin')
        1
        sage: sagenb.notebook.worksheet.ACTIVE
        1

    Now for the admin user we move W to the archive:

        sage: W.move_to_archive('admin')

    The view is now archive.

        sage: W.user_view('admin')
        0
        sage: sagenb.notebook.worksheet.ARCHIVED
        0

    For any other random viewer the view is set by default to ACTIVE.

        sage: W.user_view('foo')
        1

  `user_view_is`(user, x)

    Return True if the user view of user is x.

    INPUT:

    - `user` - a string
    - `x` - int, one of the variables ACTIVE, ARCHIVED, TRASH in worksheet.py

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('Publish Test', 'admin')
        sage: W.user_view_is('admin', sagenb.notebook.worksheet.ARCHIVED)
        False
        sage: W.user_view_is('admin', sagenb.notebook.worksheet.ACTIVE)
        True

  `viewer_names`(max=None)

    Returns a string of the non-owner viewers on this worksheet.

    INPUT:

    - `max` - an integer. If this is specified, then only max number of viewers are shown.

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('test1', 'admin')
        sage: C = W.viewers(); C
        []
        sage: C.append('sage')
        sage: C.append('wstein')
        sage: W.viewer_names()
        'sage, wstein'
        sage: W.viewer_names(max=1)
        'sage, ...'

  `viewers`()

    Return list of viewers of this worksheet.

    OUTPUT:

    - `list` - of string

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: nb.user_manager().add_user('sage','sage','sage@sagemath.org',force=True)
        sage: nb.user_manager().add_user('hilbert','sage','sage@sagemath.org',force=True)
        sage: W = nb.create_new_worksheet('test1', 'admin')
        sage: W.add_viewer('hilbert')
        sage: W.viewers()
        ['hilbert']
        sage: W.add_viewer('sage')
        sage: W.viewers()
        ['hilbert', 'sage']

  `warn_about_other_person_editing`(username, threshold=100)

    Check to see if another user besides username was the last to edit this worksheet during the last `threshold` seconds. If so, return True and that user name. If not, return False.

    INPUT:

    - `username` - user who would like to edit this file.
    - `threshold` - number of seconds, so if there was no activity on this worksheet for this many seconds, then editing is considered safe.
  `worksheet_command`(cmd)
  `worksheet_html_filename`()

    Return path to the underlying plane text file that defines the worksheet.

  `worksheet_that_was_published`()

    Return a fresh copy of the worksheet that was published to get this worksheet, if this worksheet was published. Otherwise just return this worksheet.

    OUTPUT: Worksheet

    EXAMPLES:

        sage: nb = sagenb.notebook.notebook.load_notebook(tmp_dir(ext='.sagenb'))
        sage: nb.create_default_users('password')
        sage: W = nb.create_new_worksheet('Publish Test', 'admin')
        sage: W.worksheet_that_was_published() is W
        True
        sage: S = nb.publish_worksheet(W, 'admin')
        sage: S.worksheet_that_was_published() is S
        False
        sage: S.worksheet_that_was_published() is W
        True

`sagenb.notebook.worksheet.``Worksheet_from_basic`(obj, notebook_worksheet_directory)

  INPUT:

  > - `obj` – a dictionary (a basic Python objet) from which a
  >     worksheet can be reconstructed.
  > - `notebook_worksheet_directory` - string; the directory in
  >     which the notebook object that contains this worksheet stores worksheets, i.e., nb.worksheet_directory().

  OUTPUT:

  > - a worksheet

  EXAMPLES:

      sage: import sagenb.notebook.worksheet
      sage: W = sagenb.notebook.worksheet.Worksheet('test', 0, tmp_dir(), system='gap', owner='sageuser', pretty_print=True, auto_publish=True)
      sage: _=W.new_cell_after(0); B = W.basic()
      sage: W0 = sagenb.notebook.worksheet.Worksheet_from_basic(B, tmp_dir())
      sage: W0.basic() == B
      True

`sagenb.notebook.worksheet.``after_first_word`(s)

  Return everything after the first whitespace in the string s. Returns the empty string if there is nothing after the first whitespace.

  INPUT:

  - `s` - string

  OUTPUT: a string

  EXAMPLES:

      sage: from sagenb.notebook.worksheet import after_first_word
      sage: after_first_word("\%gap\n2+2\n")
      '2+2\n'
      sage: after_first_word("2+2")
      ''

`sagenb.notebook.worksheet.``convert_time_to_string`(t)

  Converts `t` (in Unix time) to a locale-specific string describing the time and date.

`sagenb.notebook.worksheet.``dictify`(s)

  INPUT:

  - `s` - a string like ‘in=5, out=7’

  OUTPUT:

  - `dict` - such as ‘in’:5, ‘out’:7

`sagenb.notebook.worksheet.``extract_first_compute_cell`(text)

  INPUT: a block of wiki-like marked up text OUTPUT:

  - `meta` - meta information about the cell (as a dictionary)
  - `input` - string, the input text
  - `output` - string, the output text
  - `end` - integer, first position after }}} in text.

`sagenb.notebook.worksheet.``extract_name`(text)

`sagenb.notebook.worksheet.``extract_system`(text)

`sagenb.notebook.worksheet.``extract_text_before_first_compute_cell`(text)

  OUTPUT: Everything in text up to the first {{{.

`sagenb.notebook.worksheet.``first_word`(s)

  Returns everything before the first whitespace in the string s. If there is no whitespace, then the entire string s is returned.

  EXAMPLES:

      sage: from sagenb.notebook.worksheet import first_word
      sage: first_word("\%gap\n2+2\n")
      '\\%gap'
      sage: first_word("2+2")
      '2+2'

`sagenb.notebook.worksheet.``format_completions_as_html`(cell_id, completions, username=None)

  Returns tabular HTML code for a list of introspection completions.

  INPUT:

  - `cell_id` - an integer or a string; the ID of the ambient cell
  - `completions` - a nested list of completions in row-major order

  OUTPUT:

  - a string

`sagenb.notebook.worksheet.``ignore_prompts_and_output`(aString)

  Given a string s that defines an input block of code, if the first line begins in `sage:` (or `>>>`), strip out all lines that don’t begin in either `sage:` (or `>>>`) or `...`, and remove all `sage:` (or `>>>`) and `...` from the beginning of the remaining lines.

  TESTS:

      sage: test1 = sagenb.notebook.worksheet.__internal_test1
      sage: test1 == sagenb.notebook.worksheet.ignore_prompts_and_output(test1)
      True
      sage: test2 = sagenb.notebook.worksheet.__internal_test2
      sage: sagenb.notebook.worksheet.ignore_prompts_and_output(test2)
      '2 + 2\n'

`sagenb.notebook.worksheet.``next_available_id`(v)

  Return smallest nonnegative integer not in v.

`sagenb.notebook.worksheet.``split_search_string_into_keywords`(s)

  The point of this function is to allow for searches like this:

      "ws 7" foo bar  Modular  '"the" end'

  i.e., where search terms can be in quotes and the different quote types can be mixed.

  INPUT:

  - `s` - a string

  OUTPUT:

  - `list` - a list of strings

`sagenb.notebook.worksheet.``update_worksheets`()

  Iterate through and “update” all the worksheets. This is needed for things like wall timeouts.

`sagenb.notebook.worksheet.``worksheet_filename`(name, owner)

  Return the relative directory name of this worksheet with given name and owner.

  INPUT:

  - `name` - string, which may have spaces and funny characters, which are replaced by underscores.
  - `owner` - string, with no spaces or funny characters

  OUTPUT: string

  EXAMPLES:

      sage: sagenb.notebook.worksheet.worksheet_filename('Example worksheet 3', 'sage10')
      'sage10/Example_worksheet_3'
      sage: sagenb.notebook.worksheet.worksheet_filename('Example#%&! work\sheet 3', 'sage10')
      'sage10/Example_____work_sheet_3'