diff --git a/src/calibre/ebooks/pml/pmlconverter.py b/src/calibre/ebooks/pml/pmlconverter.py index 7d1e74e3f4..d55a45ee94 100644 --- a/src/calibre/ebooks/pml/pmlconverter.py +++ b/src/calibre/ebooks/pml/pmlconverter.py @@ -70,7 +70,7 @@ class PML_HTMLizer(object): 'c': ('
', '
'), 'r': ('
', '
'), 't': ('
', '
'), - 'T': ('
', '
'), + 'T': ('
', '
'), 'i': ('', ''), 'u': ('', ''), 'd': ('', ''), @@ -499,7 +499,13 @@ class PML_HTMLizer(object): self.toc = [] self.file_name = file_name - indent_state = {'t': False, 'T': False} + # t: Are we in an open \t tag set? + # T: Are we in an open \T? + # st: Did the \t start the line? + # sT: Did the \T start the line? + # et: Did the \t end the line? + indent_state = {'t': False, 'T': False, 'st': False, 'sT': False, 'et': False} + basic_indent = False adv_indent_val = '' # Keep track of the number of empty lines # between paragraphs. When we reach a set number @@ -512,8 +518,26 @@ class PML_HTMLizer(object): for line in pml.splitlines(): parsed = [] empty = True + basic_indent = indent_state['t'] - adv_indent = indent_state['T'] + indent_state['T'] = False + # Determine if the \t starts the line or if we are + # in an open \t block. + if line.lstrip().startswith('\\t') or basic_indent: + basic_indent = True + indent_state['st'] = True + else: + indent_state['st'] = False + # Determine if the \T starts the line. + if line.lstrip().startswith('\\T'): + indent_state['sT'] = True + else: + indent_state['sT'] = False + # Determine if the \t ends the line. + if line.rstrip().endswith('\\t'): + indent_state['et'] = True + else: + indent_state['et'] = False # Must use StringIO, cStringIO does not support unicode line = StringIO.StringIO(line) @@ -575,13 +599,10 @@ class PML_HTMLizer(object): empty = False text = '
' % self.code_value(line) elif c == 't': - indent_state[c] = not indent_state[c] - if indent_state[c]: - basic_indent = True + indent_state['t'] = not indent_state['t'] elif c == 'T': # Ensure we only store the value on the first T set for the line. if not indent_state['T']: - adv_indent = True adv_indent_val = self.code_value(line) else: # We detected a T previously on this line. @@ -610,10 +631,23 @@ class PML_HTMLizer(object): text = self.end_line() parsed.append(text) + # Basic indent will be set if the \t starts the line or + # if we are in a continuing \t block. if basic_indent: - parsed.insert(0, self.STATES_TAGS['t'][0]) - parsed.append(self.STATES_TAGS['t'][1]) - elif adv_indent: + # if the \t started the line and either it ended the line or the \t + # block is still open use a left margin. + if indent_state['st'] and (indent_state['et'] or indent_state['t']): + parsed.insert(0, self.STATES_TAGS['t'][0]) + parsed.append(self.STATES_TAGS['t'][1]) + # Use a text indent instead of a margin. + # This handles cases such as: + # \tO\tne upon a time... + else: + parsed.insert(0, self.STATES_TAGS['T'][0] % '5%') + parsed.append(self.STATES_TAGS['T'][1]) + # \t will override \T's on the line. + # We only handle \T's that started the line. + elif indent_state['T'] and indent_state['sT']: parsed.insert(0, self.STATES_TAGS['T'][0] % adv_indent_val) parsed.append(self.STATES_TAGS['T'][1]) indent_state['T'] = False