Changeset 5041:c94d1336fcc4


Ignore:
Timestamp:
06/18/07 16:24:41 (6 years ago)
Author:
William Stein <wstein@…>
Branch:
default
Children:
5042:2ef6ae624621, 5050:c4b38e5530da
Message:

Cleaned up the code in worksheet.py substantially (e.g., use startswith).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sage/server/notebook/worksheet.py

    r5038 r5041  
    107107 
    108108        self.clear() 
    109          
     109 
     110    def __cmp__(self, other): 
     111        try: 
     112            return cmp(self.__filename, other.__filename) 
     113        except AttributeError: 
     114            return cmp(type(self), type(other)) 
     115 
     116    def __repr__(self): 
     117        return str(self.__cells) 
     118 
     119    def __len__(self): 
     120        return len(self.__cells) 
     121 
     122    ########################################################## 
     123    # Basic properties 
     124    # TODO: Need to create a worksheet configuration object 
     125    ########################################################## 
     126    def notebook(self): 
     127        return self.__notebook 
     128 
     129    def name(self): 
     130        return self.__name 
     131 
     132    def set_name(self, name): 
     133        self.__name = name 
     134        dir = list(name) 
     135        for i in range(len(dir)): 
     136            if not dir[i].isalnum() and dir[i] != '_': 
     137                dir[i] = '_' 
     138        dir = ''.join(dir) 
     139        self.__filename = dir 
     140 
     141    def filename(self): 
     142        return self.__filename 
     143 
     144    def directory(self): 
     145        if not os.path.exists(self.__dir): 
     146            # prevent "rm -rf" accidents. 
     147            os.makedirs(self.__dir) 
     148        return self.__dir 
     149 
     150    def DIR(self): 
     151        return self.__notebook.DIR() 
     152 
     153    def system(self): 
     154        try: 
     155            return self.__system 
     156        except AttributeError: 
     157            self.__system = None 
     158            return None 
     159 
     160    def set_system(self, system=None): 
     161        self.__system = system 
     162 
     163    ########################################################## 
     164    # Owner/viewer/user management 
     165    ########################################################## 
    110166 
    111167    def owner(self): 
     
    152208            self.__collaborators = [user] 
    153209 
    154     def clear(self): 
    155         self.__comp_is_running = False 
    156         if not os.path.exists(self.__dir): 
    157             os.makedirs(self.__dir) 
    158         self.__queue = [] 
    159         self.__cells = [ ] 
    160         for i in range(INITIAL_NUM_CELLS): 
    161             self.append_new_cell() 
    162  
     210    ########################################################## 
     211    # Setting and  
     212    ########################################################## 
    163213    def set_notebook(self, notebook): 
    164214        owner = self.owner() 
    165215        self.__notebook = notebook 
    166216        self.__dir = '%s/%s/%s'%(notebook.worksheet_directory(), owner, self.__filename) 
    167  
    168     def filename(self): 
    169         return self.__filename 
    170217 
    171218    def save(self, filename=None): 
     
    175222            save(self, filename) 
    176223         
    177     def __cmp__(self, other): 
    178         try: 
    179             return cmp(self.__filename, other.__filename) 
    180         except AttributeError: 
    181             return cmp(type(self), type(other)) 
    182  
    183     def computing(self): 
    184         try: 
    185             return self.__comp_is_running 
    186         except AttributeError: 
    187             return False 
    188  
    189     def set_not_computing(self): 
    190         self.__comp_is_running = False 
    191         self.__queue = [] 
    192  
     224    # The following setstate method is here 
     225    # so that when this object is pickled and 
     226    # unpickled, the self.__sage attribute 
     227    # will not be set, so it will properly initialized. 
     228    def __setstate__(self, state): 
     229        self.__dict__ = state 
     230        try: 
     231            del self.__sage 
     232            del self.__variables 
     233            self.__queue = [] 
     234        except AttributeError: 
     235            pass 
     236 
     237    ########################################################## 
     238    # Exporting the worksheet in plain text command-line format 
     239    ########################################################## 
    193240    def plain_text(self, prompts=False): 
    194241        """ 
     
    206253        return s 
    207254 
     255    def input_text(self): 
     256        """ 
     257        Return text version of the input to the worksheet.  
     258        """ 
     259        return '\n\n---\n\n'.join([C.input_text() for C in self.__cells]) 
     260 
     261    ########################################################## 
     262    # Editing the worksheet in plain text format (export and import) 
     263    ########################################################## 
    208264    def edit_text(self, prompts=False): 
    209265        """ 
     
    241297        self.__cells = cells 
    242298 
    243     def input_text(self): 
    244         """ 
    245         Return text version of the input to the worksheet.  
    246         """ 
    247         return '\n\n---\n\n'.join([C.input_text() for C in self.__cells]) 
    248  
    249     # The following setstate method is here 
    250     # so that when this object is pickled and 
    251     # unpickled, the self.__sage attribute 
    252     # will not be set, so it will properly initialized. 
    253     def __setstate__(self, state): 
    254         self.__dict__ = state 
    255         try: 
    256             del self.__sage 
    257             del self.__variables 
    258             self.__queue = [] 
    259         except AttributeError: 
    260             pass 
     299    ########################################################## 
     300    # HTML rendering of the whole worksheet 
     301    ########################################################## 
     302    def html(self, include_title=True, do_print=False, 
     303             confirm_before_leave=False, read_only=False): 
     304        n = len(self.__cells) 
     305        s = '' 
     306        if include_title: 
     307            if self.computing(): 
     308                interrupt_class = "interrupt" 
     309            else: 
     310                interrupt_class = "interrupt_grey" 
     311            S = self.system() 
     312            if not (S is None): 
     313                system = ' (%s mode)'%S 
     314            else: 
     315                system ='' 
     316 
     317            vbar = '<span class="vbar"></span>' 
     318 
     319            name = self.filename() 
     320            menu  = '  <span class="worksheet_control_commands">' 
     321            menu += '    <a class="%s" onClick="interrupt()" id="interrupt">Interrupt</a>'%interrupt_class + vbar 
     322            menu += '    <a class="restart_sage" onClick="restart_sage()" id="restart_sage">Restart</a>' +vbar 
     323            menu += '    <a class="plain_text" href="%s">Edit</a>'%self.worksheet_command('edit') + vbar 
     324            #menu += '    <a class="doctest_text" onClick="doctest_window(\'%s\')">Text</a>'%name + vbar 
     325            menu += '    <a class="doctest_text" href="%s">Text</a>'%self.worksheet_command('plain') + vbar 
     326            #menu += '    <a class="doctest_text" onClick="print_window(\'%s\')">Print</a>'%name + vbar 
     327            menu += '    <a class="doctest_text" href="%s">Printable</a>'%self.worksheet_command('print') + vbar 
     328            menu += '    <a class="evaluate" onClick="evaluate_all()">Eval All</a>' + vbar 
     329            menu += '    <a class="hide" onClick="hide_all()">Hide</a>/<a class="hide" onClick="show_all()">Show</a>' + vbar 
     330            menu += '    <a class="slide_mode" onClick="slide_mode()">Focus</a>' + vbar 
     331            menu += '    <a class="download_sws" href="download/%s.sws">Download</a>'%self.filename() + vbar 
     332            menu += '    <a class="delete" href="delete">Delete</a>' 
     333            menu += '  </span>' 
     334 
     335            s += '<div class="worksheet_title">' 
     336            s += '%s%s%s%s</div>\n'%(self.name(), ' (read only) ' if read_only else '', system, menu) 
     337 
     338        D = self.__notebook.defaults() 
     339        ncols = D['word_wrap_cols'] 
     340        s += '<div class="worksheet_cell_list" id="worksheet_cell_list">\n' 
     341        for i in range(n): 
     342            cell = self.__cells[i] 
     343            s += cell.html(ncols,do_print=do_print) + '\n' 
     344 
     345        s += '\n</div>\n' 
     346        s += '\n<div class="insert_new_cell" id="insert_last_cell" onmousedown="insert_new_cell_after(cell_id_list[cell_id_list.length-1]);"> </div>\n' 
     347        s += '<div class="worksheet_bottom_padding"></div>\n' 
     348 
     349        if not do_print: 
     350            s += '<script language=javascript>cell_id_list=%s;\n'%self.compute_cell_id_list() 
     351            s += 'for(i=0;i<cell_id_list.length;i++) prettify_cell(cell_id_list[i]);</script>\n' 
     352        else: 
     353            s += '<script language=javascript>jsMath.ProcessBeforeShowing();</script>\n' 
     354 
     355        if not do_print and confirm_before_leave: 
     356            s += """<script type="text/javascript"> 
     357            window.onbeforeunload = confirmBrowseAway; 
     358            function confirmBrowseAway() 
     359            { 
     360            return "Unsubmitted cells will be lost."; 
     361            } 
     362            </script> 
     363            """ 
     364        return s 
     365 
     366    ########################################################## 
     367    # Managing cells and groups of cells in this worksheet 
     368    ########################################################## 
    261369 
    262370    def cell_id_list(self): 
     
    329437        return cells[0].id() 
    330438 
    331     def directory(self): 
     439    ########################################################## 
     440    # Managing whether computing is happening: stop, start, clear, etc. 
     441    ########################################################## 
     442    def clear(self): 
     443        self.__comp_is_running = False 
    332444        if not os.path.exists(self.__dir): 
    333             # prevent "rm -rf" accidents. 
    334445            os.makedirs(self.__dir) 
    335         return self.__dir 
    336  
    337     def DIR(self): 
    338         return self.__notebook.DIR() 
     446        self.__queue = [] 
     447        self.__cells = [ ] 
     448        for i in range(INITIAL_NUM_CELLS): 
     449            self.append_new_cell() 
     450 
     451    def computing(self): 
     452        try: 
     453            return self.__comp_is_running 
     454        except AttributeError: 
     455            return False 
     456 
     457    def set_not_computing(self): 
     458        self.__comp_is_running = False 
     459        self.__queue = [] 
    339460 
    340461    def quit(self): 
     
    370491        # We do this to avoid getting a stale SAGE that uses old code.  
    371492        self.clear_queue() 
    372          
    373493 
    374494    def next_block_id(self): 
     
    433553        self.initialize_sage() 
    434554        return self.__sage 
    435  
    436     def _enqueue_auto_cells(self): 
    437         for c in self.__cells: 
    438             if c.is_auto_cell(): 
    439                 self.enqueue(c) 
    440  
    441     def _new_text_cell(self, plain_text, id=None): 
    442         if id is None: 
    443             id = self.__next_id 
    444             self.__next_id += 1 
    445         return TextCell(id, plain_text, self) 
    446  
    447     def _new_cell(self, id=None): 
    448         if id is None: 
    449             id = self.__next_id 
    450             self.__next_id += 1 
    451         return Cell(id, '', '', self) 
    452  
    453     def __repr__(self): 
    454         return str(self.__cells) 
    455  
    456     def __len__(self): 
    457         return len(self.__cells) 
    458  
    459     def __getitem__(self, n): 
    460         try: 
    461             return self.__cells[n] 
    462         except IndexError: 
    463             if n >= 0:  # this should never happen -- but for robustness we cover this case. 
    464                 for k in range(len(self.__cells),n+1): 
    465                     self.__cells.append(self._new_cell()) 
    466                 return self.__cells[n] 
    467             raise IndexError 
    468              
    469  
    470     def get_cell_with_id(self, id): 
    471         for c in self.__cells: 
    472             if c.id() == id: 
    473                 return c 
    474         return self._new_cell(id) 
    475  
    476     def queue(self): 
    477         return list(self.__queue) 
    478  
    479     def queue_id_list(self): 
    480         return [c.id() for c in self.__queue] 
    481  
    482     def _enqueue_auto(self): 
    483         for c in self.__cells: 
    484             if c.is_auto_cell(): 
    485                 self.__queue.append(c) 
    486  
    487  
    488     def enqueue(self, C): 
    489         if not isinstance(C, Cell): 
    490             raise TypeError 
    491         if C.worksheet() != self: 
    492             raise ValueError, "C must be have self as worksheet." 
    493         # If the SAGE server hasn't started and the queue is empty, 
    494         # first enqueue the auto cells: 
    495         if len(self.__queue) == 0: 
    496             try: 
    497                 self.__sage             
    498             except AttributeError: 
    499                 self._enqueue_auto() 
    500              
    501         # Now enqueue the requested cell. 
    502         if not (C in self.__queue): 
    503             self.__queue.append(C) 
    504         self.start_next_comp() 
    505  
    506  
    507     def synchronize(self, s): 
    508         try: 
    509             i = (self.__synchro + 1)%65536 
    510         except AttributeError: 
    511             i = 0 
    512         self.__synchro = i 
    513         return 'print "%s%s"\n'%(SAGE_BEGIN,i) + s + '\nprint "%s%s"\n'%(SAGE_END,i) 
    514  
    515     def synchro(self): 
    516         try: 
    517             return self.__synchro 
    518         except AttributeError: 
    519             return 0 
    520  
    521     def delete_cell_input_files(self): 
    522         """ 
    523         Delete all the files code_%s.py and code_%s.spyx that are created 
    524         when evaluating cells.  We do this when we first start the notebook 
    525         to get rid of clutter.  
    526         """ 
    527         D = self.directory() + '/code/' 
    528         if os.path.exists(D): 
    529             for X in os.listdir(D): 
    530                 os.unlink('%s/%s'%(D,X)) 
    531         else: 
    532             os.makedirs(D) 
    533555 
    534556    def start_next_comp(self): 
     
    554576                C.set_output_text('Exited %s process'%S,'') 
    555577                return 
    556             if I[:5] == '%time': 
     578            if I.startswith('%time'): 
    557579                C.do_time() 
    558                 I = I[5:].lstrip() 
    559             elif I[:5] in ['time ', 'time\n', 'time\t'] and not 'time' in V: 
     580                I = after_first_word(I).lstrip() 
     581            elif first_word(I) == 'time' and not 'time' in V: 
    560582                C.do_time() 
    561                 I = I[5:].lstrip() 
     583                I = after_first_word(I).lstrip() 
    562584        else: 
    563585            I = C.introspect()[0] 
     
    580602        if C.time(): 
    581603            input += '__SAGE_t__=cputime()\n__SAGE_w__=walltime()\n' 
    582         if I[-1:] == '?': 
     604        if I.endswith('?'): 
    583605            C.set_introspect(I, '') 
    584606        I = I.replace('\\\n','') 
     
    634656            C.set_output_text('The SAGE compute process quit (possibly SAGE crashed?).\nPlease retry your calculation.','') 
    635657                 
    636              
    637  
    638     def check_cell(self, id): 
    639         """ 
    640         Check the status on computation of the cell with given id. 
    641  
    642         INPUT: 
    643             id -- an integer 
    644  
    645         OUTPUT: 
    646             status -- a string, either 'd' (done) or 'w' (working) 
    647             cell -- the cell with given id 
    648         """ 
    649         cell = self.get_cell_with_id(id) 
    650  
    651         if cell in self.__queue: 
    652             status = 'w' 
    653         else: 
    654             status = 'd' 
    655         return status, cell 
    656  
    657658    def check_comp(self): 
    658659        if len(self.__queue) == 0: 
     
    707708        return 'd', C 
    708709 
     710    def interrupt(self): 
     711        """ 
     712        Interrupt all currently queued up calculations. 
     713 
     714        OUTPUT: 
     715            bool -- return True if no problems interrupting calculation 
     716                    return False if the SAGE interpreter had to be restarted. 
     717        """ 
     718        if len(self.__queue) == 0: 
     719            # nothing to do 
     720            return True 
     721 
     722        success = False 
     723        # stop the current computation in the running SAGE 
     724        try: 
     725            S = self.__sage 
     726        except AttributeError: 
     727            pass 
     728        else: 
     729            success = S.interrupt(INTERRUPT_TRIES, timeout=0.3, quit_on_fail=False) 
     730 
     731        if success: 
     732            self.clear_queue() 
     733             
     734        return success 
     735 
     736    def clear_queue(self): 
     737        # empty the queue 
     738        for C in self.__queue: 
     739            C.interrupt() 
     740        self.__queue = [] 
     741        self.__comp_is_running = False 
     742 
     743    def restart_sage(self): 
     744        """ 
     745        Restart SAGE kernel. 
     746        """ 
     747        self.quit() 
     748 
     749        self.__sage = initialized_sage(server = self.notebook().get_server(), 
     750                                       ulimit = self.notebook().get_ulimit()) 
     751        self.initialize_sage() 
     752        self._enqueue_auto_cells() 
     753        self.start_next_comp() 
     754         
     755 
     756    def worksheet_command(self, cmd): 
     757        return '/home/%s/%s'%(self.filename(), cmd) 
     758 
     759    ########################################################## 
     760    # Enqueuing cells 
     761    ########################################################## 
     762    def queue(self): 
     763        return list(self.__queue) 
     764 
     765    def queue_id_list(self): 
     766        return [c.id() for c in self.__queue] 
     767 
     768    def _enqueue_auto(self): 
     769        for c in self.__cells: 
     770            if c.is_auto_cell(): 
     771                self.__queue.append(c) 
     772 
     773 
     774    def enqueue(self, C): 
     775        if not isinstance(C, Cell): 
     776            raise TypeError 
     777        if C.worksheet() != self: 
     778            raise ValueError, "C must be have self as worksheet." 
     779        # If the SAGE server hasn't started and the queue is empty, 
     780        # first enqueue the auto cells: 
     781        if len(self.__queue) == 0: 
     782            try: 
     783                self.__sage             
     784            except AttributeError: 
     785                self._enqueue_auto() 
     786             
     787        # Now enqueue the requested cell. 
     788        if not (C in self.__queue): 
     789            self.__queue.append(C) 
     790        self.start_next_comp() 
     791 
     792    def _enqueue_auto_cells(self): 
     793        for c in self.__cells: 
     794            if c.is_auto_cell(): 
     795                self.enqueue(c) 
     796 
     797    def _new_text_cell(self, plain_text, id=None): 
     798        if id is None: 
     799            id = self.__next_id 
     800            self.__next_id += 1 
     801        return TextCell(id, plain_text, self) 
     802 
     803    def _new_cell(self, id=None): 
     804        if id is None: 
     805            id = self.__next_id 
     806            self.__next_id += 1 
     807        return Cell(id, '', '', self) 
     808 
     809    def append(self, L): 
     810        self.__cells.append(L) 
     811 
     812    ########################################################## 
     813    # Accessing existing cells 
     814    ########################################################## 
     815    def __getitem__(self, n): 
     816        try: 
     817            return self.__cells[n] 
     818        except IndexError: 
     819            if n >= 0:  # this should never happen -- but for robustness we cover this case. 
     820                for k in range(len(self.__cells),n+1): 
     821                    self.__cells.append(self._new_cell()) 
     822                return self.__cells[n] 
     823            raise IndexError 
     824             
     825    def get_cell_with_id(self, id): 
     826        for c in self.__cells: 
     827            if c.id() == id: 
     828                return c 
     829        return self._new_cell(id) 
     830 
     831    def synchronize(self, s): 
     832        try: 
     833            i = (self.__synchro + 1)%65536 
     834        except AttributeError: 
     835            i = 0 
     836        self.__synchro = i 
     837        return 'print "%s%s"\n'%(SAGE_BEGIN,i) + s + '\nprint "%s%s"\n'%(SAGE_END,i) 
     838 
     839    def synchro(self): 
     840        try: 
     841            return self.__synchro 
     842        except AttributeError: 
     843            return 0 
     844 
     845    def delete_cell_input_files(self): 
     846        """ 
     847        Delete all the files code_%s.py and code_%s.spyx that are created 
     848        when evaluating cells.  We do this when we first start the notebook 
     849        to get rid of clutter.  
     850        """ 
     851        D = self.directory() + '/code/' 
     852        if os.path.exists(D): 
     853            for X in os.listdir(D): 
     854                os.unlink('%s/%s'%(D,X)) 
     855        else: 
     856            os.makedirs(D) 
     857 
     858             
     859 
     860    def check_cell(self, id): 
     861        """ 
     862        Check the status on computation of the cell with given id. 
     863 
     864        INPUT: 
     865            id -- an integer 
     866 
     867        OUTPUT: 
     868            status -- a string, either 'd' (done) or 'w' (working) 
     869            cell -- the cell with given id 
     870        """ 
     871        cell = self.get_cell_with_id(id) 
     872 
     873        if cell in self.__queue: 
     874            status = 'w' 
     875        else: 
     876            status = 'd' 
     877        return status, cell 
     878 
     879    def is_last_id_and_previous_is_nonempty(self, id): 
     880        if self.__cells[-1].id() != id: 
     881            return False 
     882        if len(self.__cells) == 1: 
     883            return False 
     884        if len(self.__cells[-2].output_text(ncols=0)) == 0: 
     885            return False 
     886        return True 
     887 
     888 
     889    ########################################################## 
     890    # (Tab) Completions 
     891    ########################################################## 
    709892    def best_completion(self, s, word): 
    710893        completions = s.split() 
     
    746929        return self.__notebook.format_completions_as_html(id, rows) 
    747930 
     931    ########################################################## 
     932    # Processing of input and output to worksheet process. 
     933    ########################################################## 
     934    def preparse_input(self, input, C): 
     935        C.set_is_html(False) 
     936        introspect = C.introspect() 
     937        if introspect: 
     938            input = self.preparse_introspection_input(input, C) 
     939        else: 
     940            switched, input = self.check_for_system_switching(input, C) 
     941            if not switched: 
     942                input = self.preparse_nonswitched_input(input) 
     943            input += '\n' 
     944        return input 
     945 
     946    def preparse_introspection_input(self, input, C): 
     947        before_prompt, after_prompt = introspect 
     948        i = 0 
     949        while i < len(after_prompt): 
     950            if after_prompt[i] == '?': 
     951                if i < len(after_prompt)-1 and after_prompt[i+1] == '?': 
     952                    i += 1 
     953                before_prompt += after_prompt[:i+1] 
     954                after_prompt = after_prompt[i+1:] 
     955                C.set_introspect(before_prompt, after_prompt) 
     956                break 
     957            elif after_prompt[i] in ['"', "'", ' ', '\t', '\n']: 
     958                break 
     959            i += 1 
     960        if before_prompt.endswith('??'): 
     961            input = self._get_last_identifier(before_prompt[:-2]) 
     962            input = 'print _support_.source_code("%s", globals())'%input 
     963        elif before_prompt.endswith('?'): 
     964            input = self._get_last_identifier(before_prompt[:-1]) 
     965            input = 'print _support_.docstring("%s", globals())'%input 
     966        else: 
     967            input = self._get_last_identifier(before_prompt) 
     968            C._word_being_completed = input 
     969            input = 'print "\\n".join(_support_.completions("%s", globals()))'%(input) 
     970        return input 
     971         
     972    def preparse_nonswitched_input(self, input): 
     973        input = ignore_prompts_and_output(input).rstrip() 
     974        input = self.preparse(input) 
     975        input = self.load_any_changed_attached_files(input) 
     976        input = self.do_sage_extensions_preparsing(input) 
     977        input = input.split('\n') 
     978 
     979        # The following is all so the last line (or single lines) 
     980        # will implicitly print as they should, unless they are 
     981        # an assignment.   "display hook"  It's very complicated, 
     982        # but it has to be... 
     983        i = len(input)-1 
     984        if i >= 0: 
     985            while len(input[i]) > 0 and input[i][0] in ' \t': 
     986                i -= 1 
     987            t = '\n'.join(input[i:]) 
     988            if not t.startswith('def '): 
     989                try: 
     990                    compile(t+'\n', '', 'single') 
     991                    t = t.replace("'", "\\u0027").replace('\n','\\u000a') 
     992                    # IMPORTANT: If you change this line, also change 
     993                    # the function format_exception in cell.py 
     994                    input[i] = "exec compile(ur'%s' + '\\n', '', 'single')"%t 
     995                    input = input[:i+1] 
     996                except SyntaxError, msg: 
     997                    pass 
     998        input = '\n'.join(input) 
     999        return input 
     1000 
     1001         
    7481002    def _strip_synchro_from_start_of_output(self, s): 
    7491003        z = SAGE_BEGIN+str(self.synchro()) 
     
    7711025        return s.replace(SAGE_BEGIN,'').replace(SAGE_END,'').replace(SC,'') 
    7721026 
    773     def is_last_id_and_previous_is_nonempty(self, id): 
    774         if self.__cells[-1].id() != id: 
    775             return False 
    776         if len(self.__cells) == 1: 
    777             return False 
    778         if len(self.__cells[-2].output_text(ncols=0)) == 0: 
    779             return False 
    780         return True 
    781  
    782     def interrupt(self): 
    783         """ 
    784         Interrupt all currently queued up calculations. 
    785  
    786         OUTPUT: 
    787             bool -- return True if no problems interrupting calculation 
    788                     return False if the SAGE interpreter had to be restarted. 
    789         """ 
    790         if len(self.__queue) == 0: 
    791             # nothing to do 
    792             return True 
    793  
    794         success = False 
    795         # stop the current computation in the running SAGE 
    796         try: 
    797             S = self.__sage 
    798         except AttributeError: 
    799             pass 
    800         else: 
    801             success = S.interrupt(INTERRUPT_TRIES, timeout=0.3, quit_on_fail=False) 
    802  
    803         if success: 
    804             self.clear_queue() 
    805              
    806         return success 
    807  
    808     def clear_queue(self): 
    809         # empty the queue 
    810         for C in self.__queue: 
    811             C.interrupt() 
    812         self.__queue = [] 
    813         self.__comp_is_running = False 
    814  
    815     def restart_sage(self): 
    816         """ 
    817         Restart SAGE kernel. 
    818         """ 
    819         self.quit() 
    820  
    821         self.__sage = initialized_sage(server = self.notebook().get_server(), 
    822                                        ulimit = self.notebook().get_ulimit()) 
    823         self.initialize_sage() 
    824         self._enqueue_auto_cells() 
    825         self.start_next_comp() 
    826          
    8271027    def postprocess_output(self, out, C): 
    8281028        i = out.find('\r\n') 
     
    8731073        return s 
    8741074 
     1075    ########################################################## 
     1076    # Loading and attaching files 
     1077    ########################################################## 
    8751078    def load_any_changed_attached_files(self, s): 
    8761079        """ 
     
    9331136                if len(filename) > 0 and filename[0] != '/': 
    9341137                    filename = '%s/%s'%(self.DIR(), filename) 
    935                 if filename[-3:] != '.py' and filename[-5:] != '.sage' and \ 
    936                    filename[-5:] != '.sobj' and not os.path.exists(filename): 
     1138                if not filename.endswith('.py') and not filename.endswith('.sage') and \ 
     1139                       not filename.endswith('.sobj') and not os.path.exists(filename): 
    9371140                    if os.path.exists(filename + '.sage'): 
    9381141                        filename = filename + '.sage' 
     
    9451148 
    9461149    def _load_file(self, filename, files_seen_so_far, this_file): 
    947         if filename[-5:] == '.sobj': 
    948             i = filename.rfind('/') 
    949             if i != -1: 
    950                 name = filename[i+1:-5] 
    951             else: 
    952                 name = filename[:-5] 
     1150        if filename.endswith('.sobj'): 
     1151            name = os.path.splitext(filename)[0] 
     1152            name = os.path.split(name)[-1] 
    9531153            return '%s = load("%s");'%(name, filename) 
    9541154 
     
    9601160            return "print 'Error loading %s -- file not found'"%filename 
    9611161        else: 
    962             if filename[-3:] == '.py': 
     1162            if filename.endswith('.py'): 
    9631163                t = F 
    964             elif filename[-5:] == '.sage': 
     1164            elif filename.endswith('.sage'): 
    9651165                t = self.preparse(F) 
    9661166            else: 
     
    9801180        u = [] 
    9811181        for t in s.split('\n'): 
    982             if t[:5] == 'load ': 
     1182            if t.startswith('load '): 
    9831183                z = '' 
    984                 for filename in self._normalized_filenames(t[5:]): 
     1184                for filename in self._normalized_filenames(after_first_word(t)): 
    9851185                    z += self._load_file(filename, files_seen_so_far, this_file) + '\n' 
    9861186                t = z 
    9871187                 
    988             elif t[:7] == 'attach ': 
     1188            elif t.startswith('attach '): 
    9891189                z = '' 
    990                 for filename in self._normalized_filenames(t[7:]): 
     1190                for filename in self._normalized_filenames(after_first_word(t)): 
    9911191                    if not os.path.exists(filename): 
    9921192                        z += "print 'Error attaching %s -- file not found'\n"%filename 
     
    9961196                t = z 
    9971197                     
    998             elif t[:7]  == 'detach ': 
    999                 for filename in self._normalized_filenames(t[7:]): 
     1198            elif t.startswith('detach '): 
     1199                for filename in self._normalized_filenames(after_first_word(t)): 
    10001200                    self.detach(filename) 
    10011201                t = '' 
    10021202 
    1003             elif t[:12] in ['save_session', 'load_session']: 
    1004                 F = t[12:].strip().strip('(').strip(')').strip("'").strip('"').split(',')[0] 
     1203            elif t.startswith('save_session') or t.startswith('load_session'): 
     1204                F = after_first_word(t).strip().strip('(').strip(')').strip("'").strip('"').split(',')[0] 
    10051205                if len(F) == 0: 
    10061206                    filename = self.__filename 
    10071207                else: 
    10081208                    filename = F 
    1009                 if t[:4] == 'save': 
     1209                if t.startswith('save'): 
    10101210                    t = '_support_.save_session("%s")'%filename 
    10111211                else: 
    10121212                    t = 'load_session(locals(), "%s")'%filename 
    10131213 
    1014             elif t[:5] == 'save ': 
    1015                 t = self._save_objects(t[5:]) 
     1214            elif t.startswith('save '): 
     1215                t = self._save_objects(after_first_word(t)) 
    10161216                 
    10171217            u.append(t) 
     
    10191219        return '\n'.join(u) 
    10201220 
    1021     def system(self): 
    1022         try: 
    1023             return self.__system 
    1024         except AttributeError: 
    1025             self.__system = None 
    1026             return None 
    1027  
    1028     def set_system(self, system=None): 
    1029         self.__system = system 
    1030  
    10311221    def _eval_cmd(self, system, cmd): 
    10321222        cmd = cmd.replace("'", "\\u0027") 
    10331223        return "print _support_.syseval(%s, ur'''%s''')"%(system, cmd) 
     1224 
     1225    ########################################################## 
     1226    # Parsing the %sagex, %jsmath, %python, etc., extension. 
     1227    ########################################################## 
    10341228 
    10351229    def sagex_import(self, cmd, C): 
     
    10561250        S = self.system() 
    10571251        if not (S is None): 
    1058             if s[:5] != '%sage': 
     1252            if s.startswith('%sage'): 
     1253                s = after_first_word(s).lstrip() 
     1254                z = s 
     1255            else: 
    10591256                return True, self._eval_cmd(self.__system, s) 
    1060             else: 
    1061                 s = s[5:].lstrip() 
    1062                 z = s 
    10631257                 
    10641258        if len(s) == 0 or s[0] != '%': 
    10651259            return False, z 
    1066         if s[:5] == '%hide': 
    1067             t = s[5:].lstrip() 
     1260        if s.startswith('%hide'): 
     1261            t = after_first_word(s).lstrip() 
    10681262            if len(t) == 0 or t[0] != '%': 
    10691263                return False, t 
    10701264            s = t 
    1071         if s[:12] == '%save_server': 
     1265        if s.startswith('%save_server'): 
    10721266            self.notebook().save() 
    1073             t = s[12:].lstrip() 
     1267            t = after_first_word(s).lstrip() 
    10741268            if len(t) == 0 or t[0] != '%': 
    10751269                return False, t 
    10761270            s = t 
    1077         if s[:6] == "%pyrex" or s[:6] == "%sagex":  # a block of Sagex code. 
    1078             return True, self.sagex_import(s[6:].lstrip(), C) 
     1271        if s.startswith("%pyrex") or s.startswith("%sagex"):  # a block of Sagex code. 
     1272            return True, self.sagex_import(after_first_word(s).lstrip(), C) 
    10791273             
    10801274        i = s.find('\n') 
     
    10941288        return True, cmd 
    10951289 
    1096     def preparse_input(self, input, C): 
    1097         C.set_is_html(False) 
    1098         introspect = C.introspect() 
    1099         if introspect: 
    1100             before_prompt, after_prompt = introspect 
    1101             i = 0 
    1102             while i < len(after_prompt): 
    1103                 if after_prompt[i] == '?': 
    1104                     if i < len(after_prompt)-1 and after_prompt[i+1] == '?': 
    1105                         i += 1 
    1106                     before_prompt += after_prompt[:i+1] 
    1107                     after_prompt = after_prompt[i+1:] 
    1108                     C.set_introspect(before_prompt, after_prompt) 
    1109                     break 
    1110                 elif after_prompt[i] in ['"', "'", ' ', '\t', '\n']: 
    1111                     break 
    1112                 i += 1 
    1113             if before_prompt[-2:] == '??': 
    1114                 input = self._get_last_identifier(before_prompt[:-2]) 
    1115                 input = 'print _support_.source_code("%s", globals())'%input 
    1116             elif before_prompt[-1:] == '?': 
    1117                 input = self._get_last_identifier(before_prompt[:-1]) 
    1118                 input = 'print _support_.docstring("%s", globals())'%input 
    1119             else: 
    1120                 input = self._get_last_identifier(before_prompt) 
    1121                 C._word_being_completed = input 
    1122                 input = 'print "\\n".join(_support_.completions("%s", globals()))'%(input) 
    1123              
    1124         else: 
    1125             switched, input = self.check_for_system_switching(input, C) 
    1126  
    1127             if not switched: 
    1128                 input = ignore_prompts_and_output(input).rstrip() 
    1129                 input = self.preparse(input) 
    1130                 input = self.load_any_changed_attached_files(input) 
    1131                 input = self.do_sage_extensions_preparsing(input) 
    1132                 input = input.split('\n') 
    1133  
    1134                 # The following is all so the last line (or single lines) 
    1135                 # will implicitly print as they should, unless they are 
    1136                 # an assignment.   "display hook"  It's very complicated, 
    1137                 # but it has to be... 
    1138                 i = len(input)-1 
    1139                 if i >= 0: 
    1140                     while len(input[i]) > 0 and input[i][0] in ' \t': 
    1141                         i -= 1 
    1142                     t = '\n'.join(input[i:]) 
    1143                     if t[:4] != 'def ': 
    1144                         try: 
    1145                             compile(t+'\n', '', 'single') 
    1146                             t = t.replace("'", "\\u0027").replace('\n','\\u000a') 
    1147                             # IMPORTANT: If you change this line, also change 
    1148                             # the function format_exception in cell.py 
    1149                             input[i] = "exec compile(ur'%s' + '\\n', '', 'single')"%t 
    1150                             input = input[:i+1] 
    1151                         except SyntaxError, msg: 
    1152                             pass 
    1153                 input = '\n'.join(input) 
    1154                  
    1155             input += '\n' 
    1156  
    1157         #print input 
    1158         return input 
    1159  
    1160     def notebook(self): 
    1161         return self.__notebook 
    1162  
    1163     def name(self): 
    1164         return self.__name 
    1165  
    1166     def set_name(self, name): 
    1167         self.__name = name 
    1168         dir = list(name) 
    1169         for i in range(len(dir)): 
    1170             if not dir[i].isalnum() and dir[i] != '_': 
    1171                 dir[i] = '_' 
    1172         dir = ''.join(dir) 
    1173         self.__filename = dir 
    1174  
    1175     def append(self, L): 
    1176         self.__cells.append(L) 
    1177  
     1290    ########################################################## 
     1291    # List of defined variables. 
     1292    ########################################################## 
    11781293    def known_variables(self): 
    11791294        try: 
     
    12231338        return s 
    12241339 
    1225     def worksheet_command(self, cmd): 
    1226         return '/home/%s/%s'%(self.filename(), cmd) 
    1227  
    1228     def html(self, include_title=True, do_print=False, 
    1229              confirm_before_leave=False, read_only=False): 
    1230         n = len(self.__cells) 
    1231         s = '' 
    1232         if include_title: 
    1233             if self.computing(): 
    1234                 interrupt_class = "interrupt" 
    1235             else: 
    1236                 interrupt_class = "interrupt_grey" 
    1237             S = self.system() 
    1238             if not (S is None): 
    1239                 system = ' (%s mode)'%S 
    1240             else: 
    1241                 system ='' 
    1242  
    1243             vbar = '<span class="vbar"></span>' 
    1244  
    1245             name = self.filename() 
    1246             menu  = '  <span class="worksheet_control_commands">' 
    1247             menu += '    <a class="%s" onClick="interrupt()" id="interrupt">Interrupt</a>'%interrupt_class + vbar 
    1248             menu += '    <a class="restart_sage" onClick="restart_sage()" id="restart_sage">Restart</a>' +vbar 
    1249             menu += '    <a class="plain_text" href="%s">Edit</a>'%self.worksheet_command('edit') + vbar 
    1250             #menu += '    <a class="doctest_text" onClick="doctest_window(\'%s\')">Text</a>'%name + vbar 
    1251             menu += '    <a class="doctest_text" href="%s">Text</a>'%self.worksheet_command('plain') + vbar 
    1252             #menu += '    <a class="doctest_text" onClick="print_window(\'%s\')">Print</a>'%name + vbar 
    1253             menu += '    <a class="doctest_text" href="%s">Printable</a>'%self.worksheet_command('print') + vbar 
    1254             menu += '    <a class="evaluate" onClick="evaluate_all()">Eval All</a>' + vbar 
    1255             menu += '    <a class="hide" onClick="hide_all()">Hide</a>/<a class="hide" onClick="show_all()">Show</a>' + vbar 
    1256             menu += '    <a class="slide_mode" onClick="slide_mode()">Focus</a>' + vbar 
    1257             menu += '    <a class="download_sws" href="download/%s.sws">Download</a>'%self.filename() + vbar 
    1258             menu += '    <a class="delete" href="delete">Delete</a>' 
    1259             menu += '  </span>' 
    1260  
    1261             s += '<div class="worksheet_title">' 
    1262             s += '%s%s%s%s</div>\n'%(self.name(), ' (read only) ' if read_only else '', system, menu) 
    1263  
    1264         D = self.__notebook.defaults() 
    1265         ncols = D['word_wrap_cols'] 
    1266         s += '<div class="worksheet_cell_list" id="worksheet_cell_list">\n' 
    1267         for i in range(n): 
    1268             cell = self.__cells[i] 
    1269             s += cell.html(ncols,do_print=do_print) + '\n' 
    1270  
    1271         s += '\n</div>\n' 
    1272         s += '\n<div class="insert_new_cell" id="insert_last_cell" onmousedown="insert_new_cell_after(cell_id_list[cell_id_list.length-1]);"> </div>\n' 
    1273         s += '<div class="worksheet_bottom_padding"></div>\n' 
    1274  
    1275         if not do_print: 
    1276             s += '<script language=javascript>cell_id_list=%s;\n'%self.compute_cell_id_list() 
    1277             s += 'for(i=0;i<cell_id_list.length;i++) prettify_cell(cell_id_list[i]);</script>\n' 
    1278         else: 
    1279             s += '<script language=javascript>jsMath.ProcessBeforeShowing();</script>\n' 
    1280  
    1281         if not do_print and confirm_before_leave: 
    1282             s += """<script type="text/javascript"> 
    1283             window.onbeforeunload = confirmBrowseAway; 
    1284             function confirmBrowseAway() 
    1285             { 
    1286             return "Unsubmitted cells will be lost."; 
    1287             } 
    1288             </script> 
    1289             """ 
    1290         return s 
    1291  
     1340    ########################################################## 
     1341    # Showing and hiding all cells 
     1342    ########################################################## 
    12921343    def show_all(self): 
    12931344        for C in self.__cells: 
     
    13171368    for I in t: 
    13181369        I2 = I.lstrip() 
    1319         if I2[:5] == 'sage:' or I2[:3] == '>>>': 
     1370        if I2.startswith('sage:') or I2.startswith('>>>'): 
    13201371            do_strip = True 
    13211372            break 
     
    13251376    for I in t: 
    13261377        I2 = I.lstrip() 
    1327         if I2[:5] == 'sage:': 
    1328             s += I2[5:].lstrip() + '\n' 
    1329         elif I2[:3] == '>>>': 
    1330             s += I2[3:].lstrip() + '\n' 
    1331         elif I2[:3] == '...': 
    1332             s += I2[3:] + '\n' 
     1378        if I2.startswith('sage:'): 
     1379            s += after_first_word(I2).lstrip() + '\n' 
     1380        elif I2.startswith('>>>'): 
     1381            s += after_first_word(I2).lstrip() + '\n' 
     1382        elif I2.startswith('...'): 
     1383            s += after_first_word(I2) + '\n' 
    13331384    return s 
    13341385             
     
    13771428        output = text[k+4:l].strip() 
    13781429    return input.strip(), output, graphics, j+4 
    1379      
     1430 
     1431import re 
     1432whitespace = re.compile('\s')  # Match any whitespace character 
     1433def after_first_word(s): 
     1434    """ 
     1435    Return everything after the first whitespace in the string s. 
     1436    Returns the empty string if there is nothing after the 
     1437    first whitespace. 
     1438 
     1439    INPUT: 
     1440        s -- string 
     1441    OUTPUT: 
     1442        a string 
     1443    """ 
     1444    i = whitespace.search(s) 
     1445    if i is None: 
     1446        return '' 
     1447    return s[i.start()+1:] 
     1448 
     1449def first_word(s): 
     1450    i = whitespace.search(s) 
     1451    if i is None: 
     1452        return s 
     1453    return s[:i.start()] 
Note: See TracChangeset for help on using the changeset viewer.