def list_get_number_n_level(self, iter_first_paragraph): """Number < 0 if bulleted list, > 0 if numbered list, 0 if TODO list, None if not a list""" iter_start = iter_first_paragraph.copy() level = 0 while iter_start: char = iter_start.get_char() if char in self.dad.chars_listbul: if iter_start.forward_char() and iter_start.get_char() == cons.CHAR_SPACE: num = (self.dad.chars_listbul.index(char) + 1)*(-1) return {"num":num, "level":level, "aux":None} break if char in [cons.CHAR_LISTTODO, cons.CHAR_LISTDONEOK, cons.CHAR_LISTDONEFAIL]: if iter_start.forward_char() and iter_start.get_char() == cons.CHAR_SPACE: return {"num":0, "level":level, "aux":None} break if char == cons.CHAR_SPACE: if support.get_next_chars_from_iter_are(iter_start, [3*cons.CHAR_SPACE]): iter_start.forward_chars(3) level += 1 else: break else: match = re.match('[1-9]', char) if not match: break number_str = char while iter_start.forward_char() and re.match('[0-9]', iter_start.get_char()): number_str += iter_start.get_char() char = iter_start.get_char() if char in cons.CHARS_LISTNUM and iter_start.forward_char() and iter_start.get_char() == cons.CHAR_SPACE: num = int(number_str) aux = cons.CHARS_LISTNUM.index(char) return {"num":num, "level":level, "aux":aux} break return {"num":None, "level":level, "aux":None}
def get_paragraph_list_info(self, iter_start): """Returns a dictionary indicating List Element Number, List Level and List Element Start Offset""" buffer_start = False # let's search for the paragraph start if iter_start.get_char() == cons.CHAR_NEWLINE: if not iter_start.backward_char(): buffer_start = True # if we are exactly on the paragraph end if not buffer_start: while iter_start: if iter_start.get_char() == cons.CHAR_NEWLINE: break # we got the previous paragraph start elif not iter_start.backward_char(): buffer_start = True break # we reached the buffer start if not buffer_start: iter_start.forward_char() # get the number of the paragraph starting with iter_start number_n_level = self.list_get_number_n_level(iter_start) if number_n_level["num"] != None: return { "num": number_n_level["num"], "level": number_n_level["level"], "aux": number_n_level["aux"], "startoffs": iter_start.get_offset(), } if not buffer_start and support.get_next_chars_from_iter_are(iter_start, [3 * cons.CHAR_SPACE]): # we are inside of a list paragraph but after a shift+return iter_start.backward_char() list_info = self.get_paragraph_list_info(iter_start) return list_info return None # this paragraph is not a list
def list_handler(self, target_list_num_id, text_buffer=None): """Unified Handler of Lists""" if not text_buffer: text_buffer = self.dad.curr_buffer if text_buffer.get_has_selection(): iter_start, sel_end = text_buffer.get_selection_bounds() end_offset = sel_end.get_offset() - 2 else: end_offset = 0 iter_start = text_buffer.get_iter_at_mark(text_buffer.get_insert()) # get info about the paragraph starting with iter_start ([Number, Whether multiple line, List Start Iter Offset]) list_info = self.get_paragraph_list_info(iter_start) leading_num_count = 0 while leading_num_count == 0 or new_par_offset < end_offset: leading_num_count += 1 iter_start, iter_end = self.get_paragraph_iters(text_buffer=text_buffer, force_iter=iter_start) if not iter_start: # empty line if leading_num_count == 1: # this is the first iteration if not list_info or list_info["num"] != target_list_num_id: # the target list type differs from this paragraph list type iter_start = text_buffer.get_iter_at_mark(text_buffer.get_insert()) if target_list_num_id == 0: text_buffer.insert(iter_start, cons.CHAR_LISTTODO + cons.CHAR_SPACE) elif target_list_num_id < 0: text_buffer.insert(iter_start, cons.CHARS_LISTBUL[0] + cons.CHAR_SPACE) else: text_buffer.insert(iter_start, "1. ") break if support.get_next_chars_from_iter_are(iter_start, [3 * cons.CHAR_SPACE]): new_par_offset = iter_end.get_offset() leading_num_count -= 1 else: iter_start, iter_end, chars_rm = self.list_check_n_remove_old_list_type_leading( iter_start, iter_end, text_buffer ) end_offset -= chars_rm if not list_info or list_info["num"] != target_list_num_id: # the target list type differs from this paragraph list type if target_list_num_id == 0: new_par_offset = iter_end.get_offset() + 2 end_offset += 2 text_buffer.insert(iter_start, cons.CHAR_LISTTODO + cons.CHAR_SPACE) elif target_list_num_id < 0: new_par_offset = iter_end.get_offset() + 2 end_offset += 2 text_buffer.insert(iter_start, cons.CHARS_LISTBUL[0] + cons.CHAR_SPACE) else: leading_str = "%s. " % leading_num_count new_par_offset = iter_end.get_offset() + len(leading_str) end_offset += len(leading_str) text_buffer.insert(iter_start, leading_str) else: new_par_offset = iter_end.get_offset() iter_start = text_buffer.get_iter_at_offset(new_par_offset + 1) if not iter_start: break
def get_paragraph_list_info(self, iter_start): """Returns [Number, Whether multiple line, List Start Iter Offset] Number == 0 if bulleted list, >=1 if numbered list or None if not a list""" buffer_start = False # let's search for the paragraph start if iter_start.get_char() == cons.CHAR_NEWLINE: if not iter_start.backward_char(): buffer_start = True # if we are exactly on the paragraph end if not buffer_start: while iter_start: if iter_start.get_char() == cons.CHAR_NEWLINE: break # we got the previous paragraph start elif not iter_start.backward_char(): buffer_start = True break # we reached the buffer start if not buffer_start: iter_start.forward_char() # get the number of the paragraph starting with iter_start number = self.list_get_number(iter_start) if number != None: return [number, False, iter_start.get_offset()] # multiple line = False elif not buffer_start and support.get_next_chars_from_iter_are(iter_start, [3*cons.CHAR_SPACE]): # we are inside of a list paragraph but after a shift+return iter_start.backward_char() list_info = self.get_paragraph_list_info(iter_start) return [list_info[0], True, list_info[2]] # multiple line = True return [None, None, None] # this paragraph is not a list
def list_handler(self, target_list_num_id, text_buffer=None): """Unified Handler of Lists""" if not text_buffer: text_buffer = self.dad.curr_buffer if text_buffer.get_has_selection(): iter_start, sel_end = text_buffer.get_selection_bounds() end_offset = sel_end.get_offset() - 2 else: end_offset = 0 iter_start = text_buffer.get_iter_at_mark(text_buffer.get_insert()) new_par_offset = -1 leading_num_count = [] while new_par_offset < end_offset: #print new_par_offset, end_offset iter_start, iter_end = self.get_paragraph_iters( text_buffer=text_buffer, force_iter=iter_start) if not iter_start: # empty line if not leading_num_count: # this is the first iteration iter_start = text_buffer.get_iter_at_mark( text_buffer.get_insert()) if target_list_num_id == 0: text_buffer.insert( iter_start, self.dad.chars_todo[0] + cons.CHAR_SPACE) elif target_list_num_id < 0: text_buffer.insert( iter_start, self.dad.chars_listbul[0] + cons.CHAR_SPACE) else: text_buffer.insert(iter_start, "1. ") break list_info = self.get_paragraph_list_info(iter_start) #print list_info if list_info and iter_start.get_offset() != list_info["startoffs"]: new_par_offset = iter_end.get_offset() else: iter_start, iter_end, chars_rm = self.list_check_n_remove_old_list_type_leading( iter_start, iter_end, text_buffer) end_offset -= chars_rm if not list_info or self.get_list_type( list_info["num"]) != self.get_list_type( target_list_num_id): # the target list type differs from this paragraph list type while support.get_next_chars_from_iter_are( iter_start, [3 * cons.CHAR_SPACE]): iter_start.forward_chars(3) if target_list_num_id == 0: new_par_offset = iter_end.get_offset() + 2 end_offset += 2 text_buffer.insert( iter_start, self.dad.chars_todo[0] + cons.CHAR_SPACE) elif target_list_num_id < 0: new_par_offset = iter_end.get_offset() + 2 end_offset += 2 if not list_info: bull_idx = 0 else: bull_idx = list_info["level"] % len( self.dad.chars_listbul) text_buffer.insert( iter_start, self.dad.chars_listbul[bull_idx] + cons.CHAR_SPACE) else: if not list_info: index = 0 if not leading_num_count: leading_num_count = [[0, 1]] else: leading_num_count = [[ 0, leading_num_count[0][1] + 1 ]] else: level = list_info["level"] index = level % cons.NUM_CHARS_LISTNUM if not leading_num_count: leading_num_count = [[level, 1]] else: while True: if level == leading_num_count[-1][0]: leading_num_count[-1][1] += 1 break if level > leading_num_count[-1][0]: leading_num_count.append([level, 1]) break if len(leading_num_count) == 1: leading_num_count = [[level, 1]] break del leading_num_count[-1] leading_str = str( leading_num_count[-1] [1]) + cons.CHARS_LISTNUM[index] + cons.CHAR_SPACE new_par_offset = iter_end.get_offset() + len( leading_str) end_offset += len(leading_str) text_buffer.insert(iter_start, leading_str) else: new_par_offset = iter_end.get_offset() iter_start = text_buffer.get_iter_at_offset(new_par_offset + 1) if not iter_start: break
def list_handler(self, target_list_num_id, text_buffer=None): """Unified Handler of Lists""" if not text_buffer: text_buffer = self.dad.curr_buffer if text_buffer.get_has_selection(): iter_start, sel_end = text_buffer.get_selection_bounds() end_offset = sel_end.get_offset() - 2 else: end_offset = 0 iter_start = text_buffer.get_iter_at_mark(text_buffer.get_insert()) new_par_offset = -1 leading_num_count = [] while new_par_offset < end_offset: # print new_par_offset, end_offset iter_start, iter_end = self.get_paragraph_iters(text_buffer=text_buffer, force_iter=iter_start) if not iter_start: # empty line if not leading_num_count: # this is the first iteration iter_start = text_buffer.get_iter_at_mark(text_buffer.get_insert()) if target_list_num_id == 0: text_buffer.insert(iter_start, cons.CHAR_LISTTODO + cons.CHAR_SPACE) elif target_list_num_id < 0: text_buffer.insert(iter_start, cons.CHARS_LISTBUL[0] + cons.CHAR_SPACE) else: text_buffer.insert(iter_start, "1. ") break list_info = self.get_paragraph_list_info(iter_start) # print list_info if list_info and iter_start.get_offset() != list_info["startoffs"]: new_par_offset = iter_end.get_offset() else: iter_start, iter_end, chars_rm = self.list_check_n_remove_old_list_type_leading( iter_start, iter_end, text_buffer ) end_offset -= chars_rm if not list_info or self.get_list_type(list_info["num"]) != self.get_list_type(target_list_num_id): # the target list type differs from this paragraph list type while support.get_next_chars_from_iter_are(iter_start, [3 * cons.CHAR_SPACE]): iter_start.forward_chars(3) if target_list_num_id == 0: new_par_offset = iter_end.get_offset() + 2 end_offset += 2 text_buffer.insert(iter_start, cons.CHAR_LISTTODO + cons.CHAR_SPACE) elif target_list_num_id < 0: new_par_offset = iter_end.get_offset() + 2 end_offset += 2 if not list_info: bull_idx = 0 else: bull_idx = list_info["level"] % cons.NUM_CHARS_LISTBUL text_buffer.insert(iter_start, cons.CHARS_LISTBUL[bull_idx] + cons.CHAR_SPACE) else: if not list_info: index = 0 if not leading_num_count: leading_num_count = [[0, 1]] else: leading_num_count = [[0, leading_num_count[0][1]]] else: level = list_info["level"] index = level % cons.NUM_CHARS_LISTNUM if not leading_num_count: leading_num_count = [[level, 1]] else: while True: if level == leading_num_count[-1][0]: leading_num_count[-1][1] += 1 break if level > leading_num_count[-1][0]: leading_num_count.append([level, 1]) break if len(leading_num_count) == 1: leading_num_count = [[level, 1]] break del leading_num_count[-1] leading_str = str(leading_num_count[-1][1]) + cons.CHARS_LISTNUM[index] + cons.CHAR_SPACE new_par_offset = iter_end.get_offset() + len(leading_str) end_offset += len(leading_str) text_buffer.insert(iter_start, leading_str) else: new_par_offset = iter_end.get_offset() iter_start = text_buffer.get_iter_at_offset(new_par_offset + 1) if not iter_start: break