######################################################################### # # # # # copyright 2002 Paul Henry Tremblay # # # # This program is distributed in the hope that it will be useful, # # but WITHOUT ANY WARRANTY; without even the implied warranty of # # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # # General Public License for more details. # # # # # ######################################################################### import sys, os from ebook_converter.ebooks.rtf2xml import copy from ebook_converter.ptempfile import better_mktemp from . import open_for_read, open_for_write class Sections: """ ================= Purpose ================= Write section tags for a tokenized file. (This module won't be any use to use to you unless you use it as part of the other modules.) --------------- logic --------------- The tags for the first section breaks have already been written. RTF stores section breaks with the \\sect tag. Each time this tag is encountered, add one to the counter. When I encounter the \\sectd tag, I want to collect all the appropriate tokens that describe the section. When I reach a \\pard, I know I an stop collecting tokens and write the section tags. The exception to this method occurs when sections occur in field blocks, such as the index. Normally, two section break occur within the index and other field-blocks. (If less or more section breaks occur, this code may not work.) I want the sections to occur outside of the index. That is, the index should be nested inside one section tag. After the index is complete, a new section should begin. In order to write the sections outside of the field blocks, I have to store all of the field block as a string. When I ecounter the \\sect tag, add one to the section counter, but store this number in a list. Likewise, store the information describing the section in another list. When I reach the end of the field block, choose the first item from the numbered list as the section number. Choose the first item in the description list as the values and attributes of the section. Enclose the field string between the section tags. Start a new section outside the field-block strings. Use the second number in the list; use the second item in the description list. CHANGE (2004-04-26) No longer write sections that occurr in field-blocks. Instead, ingore all section information in a field-block. """ def __init__(self, in_file, bug_handler, copy=None, run_level=1): """ Required: 'file'--file to parse Optional: 'copy'-- whether to make a copy of result for debugging 'temp_dir' --where to output temporary results (default is directory from which the script is run.) Returns: nothing """ self.__file = in_file self.__bug_handler = bug_handler self.__copy = copy self.__run_level = run_level self.__write_to = better_mktemp() def __initiate_values(self): """ Initiate all values. """ self.__mark_start = 'mi 0: for key in keys: my_string += '<%s>%s' % (key, self.__section_values[key]) my_string += '\n' my_string += self.__mark_end # # my_string += line if self.__state == 'body': self.__write_obj.write(my_string) elif self.__state == 'sec_in_field': self.__handle_sec_def(my_string) elif self.__run_level > 3: msg = 'missed a flag\n' raise self.__bug_handler(msg) def __handle_sec_def(self, my_string): """ Requires: my_string -- the string of attributes and values. (Do I need this?) Returns: nothing Logic: I need to append the dictionary of attributes and values to list so I can use it later when I reach the end of the field-block. """ values_dict = self.__section_values self.__list_of_sec_values.append(values_dict) def __body_func(self, line): """ Requires: line --the line to parse Returns: nothing Logic: Look for the beginning of a section. Otherwise, print the line to the output file. """ action = self.__body_dict.get(self.__token_info) if action: action(line) else: self.__write_obj.write(line) def __before_body_func(self, line): """ Requires: line --line to parse Returns: nothing Logic: Look for the beginning of the body. Always print out the line. """ if self.__token_info == 'mi%s' '%s' 'rtf-native' '0\n' % (str(self.__section_num), str(self.__section_num)) ) self.__found_first_sec = 1 elif self.__token_info == 'tx%s' '%s' 'rtf-native' '0\n' % (str(self.__section_num), str(self.__section_num)) ) self.__write_obj.write( 'cw 0: my_string += 'mi%s' % str(num) ) if self.__list_of_sec_values: keys = self.__list_of_sec_values[0].keys() for key in keys: self.__write_obj.write( '<%s>%s\n' % (key, self.__list_of_sec_values[0][key])) self.__list_of_sec_values = self.__list_of_sec_values[1:] self.__write_obj.write('0') self.__write_obj.write('rtf-native') self.__write_obj.write('%s' % str(self.__section_num)) self.__write_obj.write('\n') # Look here def __found_section_in_field_func(self, line): """ Requires: line --line to parse Returns: nothing Logic: I have found a section in a field block. Add one to section counter, and append this number to a list. """ self.__section_num += 1 self.__field_num.append(self.__section_num) self.__sec_in_field_string += line def __found_section_def_in_field_func(self, line): """ Requires: line --line to parse Returns: nothing Logic: I have found a section definition in a filed block. Change the state and clear the values dictionary. """ self.__state = 'section_def' self.__section_values.clear() def make_sections(self): """ Requires: nothing Returns: nothing (changes the original file) Logic: Read one line in at a time. Determine what action to take based on the state. If the state is before the body, look for the beginning of the body. If the state is body, send the line to the body method. """ self.__initiate_values() read_obj = open_for_read(self.__file) self.__write_obj = open_for_write(self.__write_to) line_to_read = 1 while line_to_read: line_to_read = read_obj.readline() line = line_to_read self.__token_info = line[:16] action = self.__state_dict.get(self.__state) if action is None: sys.stderr.write('no matching state in module sections.py\n') sys.stderr.write(self.__state + '\n') action(line) read_obj.close() self.__write_obj.close() copy_obj = copy.Copy(bug_handler=self.__bug_handler) if self.__copy: copy_obj.copy_file(self.__write_to, "sections.data") copy_obj.rename(self.__write_to, self.__file) os.remove(self.__write_to)