def convert_definition_list(node, context): """Convert a list of term/definition pairs to styled paragraphs. The "Definition List Term" style is looked for term paragraphs, and the "Definition List Definition" style is looked for definition paragraphs. """ styles = context['styles'] term_style = _get_term_style(context).get_name() definition_style = _get_definition_style(context).get_name() for item in node: if item.tagname != "definition_list_item": printwarn('node "%s" not supported in definition_list' % (item.tagname)) continue for child in item: tagname = child.tagname if tagname == "term": paragraph = odf_create_paragraph(style=term_style) context['top'].append(paragraph) push_convert_pop(child, paragraph, context) elif tagname == "definition": # Push a style on the stack for next paragraphs to use styles['paragraph'] = definition_style for subchildren in child: convert_node(subchildren, context) # Pop the paragraph style (may already be popped) styles.pop('paragraph', None) else: printwarn('node "%s" not supported in definition_list_item' % tagname)
def __set_header_or_footer(self, text_or_element, name='header', style=u"Header"): if name == 'header': header_or_footer = self.get_header() else: header_or_footer = self.get_footer() if header_or_footer is None: header_or_footer = odf_create_element('style:' + name) self.append(header_or_footer) else: header_or_footer.clear() if not isiterable(text_or_element): # Already a header or footer? if (isinstance(text_or_element, odf_element) and text_or_element.get_tag() == 'style:%s' % name): self.delete(header_or_footer) self.append(text_or_element) return text_or_element = [text_or_element] # FIXME cyclic import from paragraph import odf_create_paragraph for item in text_or_element: if type(item) is unicode: paragraph = odf_create_paragraph(item, style=style) header_or_footer.append(paragraph) elif isinstance(item, odf_element): header_or_footer.append(item)
def convert_definition_list(node, context): """Convert a list of term/definition pairs to styled paragraphs. The "Definition List Term" style is looked for term paragraphs, and the "Definition List Definition" style is looked for definition paragraphs. """ styles = context['styles'] term_style = _get_term_style(context).get_name() definition_style = _get_definition_style(context).get_name() for item in node: if item.tagname != "definition_list_item": printwarn('node "%s" not supported in definition_list' % ( item.tagname)) continue for child in item: tagname = child.tagname if tagname == "term": paragraph = odf_create_paragraph(style=term_style) context['top'].append(paragraph) push_convert_pop(child, paragraph, context) elif tagname == "definition": # Push a style on the stack for next paragraphs to use styles['paragraph'] = definition_style for subchildren in child: convert_node(subchildren, context) # Pop the paragraph style (may already be popped) styles.pop('paragraph', None) else: printwarn('node "%s" not supported in definition_list_item' % tagname)
def set_header(self, text_or_element): if not isinstance(text_or_element, (list, tuple)): text_or_element = [text_or_element] # Remove existing header for element in self.get_element_list('text:p'): self.delete(element) for paragraph in reversed(text_or_element): if type(paragraph) is unicode: paragraph = odf_create_paragraph(paragraph) self.insert(paragraph, FIRST_CHILD)
def set_header(self, text_or_element): if not isiterable(text_or_element): text_or_element = [text_or_element] # Remove existing header for element in self.get_elements("text:p"): self.delete(element) for paragraph in reversed(text_or_element): if type(paragraph) is unicode: paragraph = odf_create_paragraph(paragraph) self.insert(paragraph, FIRST_CHILD)
def set_text_box(self, text_or_element=None, text_style=None): text_box = self.get_text_box() if text_box is None: text_box = odf_create_element('draw:text-box') self.append(text_box) else: text_box.clear() if not isiterable(text_or_element): text_or_element = [text_or_element] for item in text_or_element: if isinstance(item, unicode): item = odf_create_paragraph(item, style=text_style) text_box.append(item) return text_box
def set_comments(self, text=u'', replace=True): """Set the text content of the comments. If replace is True (default), the new text replace old comments, else it is added at the end. Arguments: text -- unicode replace -- boolean """ if replace: for para in self.get_paragraphs(): self.delete(para) para = odf_create_paragraph() para.append_plain_text(text) self.insert(para, xmlposition=LAST_CHILD)
def convert_paragraph(node, context): # Search for a default style style = context['styles'].get('paragraph') paragraph = odf_create_paragraph(style=style) context["top"].append(paragraph) # Save the current top old_top = context["top"] # Convert context["top"] = paragraph for child in node: convert_node(child, context) # And restore the top context["top"] = old_top
def convert_literal_block(node, context): paragraph = odf_create_paragraph(style="Preformatted_20_Text") context['top'].append(paragraph) # Convert for child in node: # Only text if child.tagname != "#text": printwarn('node "%s" not supported in literal block' % ( child.tagname)) continue text = child.astext() tmp = [] spaces = 0 for c in text: if c == '\n': if tmp: tmp = u"".join(tmp) paragraph.append(tmp) tmp = [] spaces = 0 paragraph.append(odf_create_line_break()) elif c == '\r': continue elif c == ' ': spaces += 1 elif c == '\t': # Tab = 4 spaces spaces += 4 else: if spaces >= 2: if tmp: tmp = u"".join(tmp) paragraph.append(tmp) tmp = [] paragraph.append(' ') paragraph.append( odf_create_spaces(spaces - 1)) spaces = 0 elif spaces == 1: tmp.append(' ') spaces = 0 tmp.append(c) if tmp: tmp = u"".join(tmp) paragraph.append(tmp)
def odf_create_text_frame(text_or_element, size=('1cm', '1cm'), anchor_type='paragraph', page_number=None, position=None, style=None, text_style=None): """Create a ready-to-use text box, since it must be embedded in a frame. Size is a (width, height) tuple and position is a (left, top) tuple; items are strings including the unit, e.g. ('21cm', '29.7cm'). Arguments: text_or_element -- unicode or odf_element size -- (str, str) anchor_type -- 'page', 'frame', 'paragraph', 'char' or 'as-char' page_number -- int (when anchor_type == 'page') position -- (str, str) style -- unicode text_style -- unicode Return: odf_element """ frame = odf_create_frame(size=size, anchor_type=anchor_type, page_number=page_number, position=position, style=style) if text_style: frame.set_attribute('draw:text-style-name', text_style) text_box = odf_create_element('draw:text-box') if not isinstance(text_or_element, (list, tuple)): text_or_element = [text_or_element] for item in text_or_element: if type(item) is unicode: item = odf_create_paragraph(item, style=text_style) text_box.append(item) frame.append(text_box) return frame
def odf_create_index_title(title=None, name=None, style=None, text_style=None): """Create an index title Arguments: title -- unicode Return: odf_element """ element = odf_create_element('text:index-title') if title or text_style: title = odf_create_paragraph(title, style=text_style) element.append(title) if name: element.set_attribute('text:name', name) if style: element.set_text_style(style) return element
def odf_create_index_title(title=None, name=None, style=None, text_style=None): """Create an index title Arguments: title -- unicode Return: odf_element """ element = odf_create_element("text:index-title") if title or text_style: title = odf_create_paragraph(title, style=text_style) element.append(title) if name: element.set_attribute("text:name", name) if style: element.set_text_style(style) return element
def set_title(self, title, style=None, text_style=None): index_body = self.get_body() if index_body is None: index_body = self.set_body() index_title = index_body.get_element("text:index-title") if index_title is None: name = u"%s_Head" % self.get_name() index_title = odf_create_index_title(title, name=name, style=style, text_style=text_style) index_body.append(index_title) else: if style: index_title.set_text_style(style) paragraph = index_title.get_paragraph() if paragraph is None: paragraph = odf_create_paragraph() index_title.append(paragraph) if text_style: paragraph.set_text_style(text_style) paragraph.set_text(title)
def set_title(self, title, style=None, text_style=None): index_body = self.get_body() if index_body is None: index_body = self.set_body() index_title = index_body.get_element('text:index-title') if index_title is None: name = u"%s_Head" % self.get_name() index_title = odf_create_index_title(title, name=name, style=style, text_style=text_style) index_body.append(index_title) else: if style: index_title.set_text_style(style) paragraph = index_title.get_paragraph() if paragraph is None: paragraph = odf_create_paragraph() index_title.append(paragraph) if text_style: paragraph.set_text_style(text_style) paragraph.set_text(title)
def convert_paragraph(node, context): # Search for a default style style = context['styles'].get('paragraph') paragraph = odf_create_paragraph(style=style) context['top'].append(paragraph) push_convert_pop(node, paragraph, context)
def fill(self, document=None, use_default_styles=True): """Fill the TOC with the titles found in the document. A TOC is not contextual so it will catch all titles before and after its insertion. If the TOC is not attached to a document, attach it beforehand or provide one as argument. For having a pretty TOC, let use_default_styles by default. Arguments: document -- odf_document use_default_styles -- bool """ # Find the body if document is not None: body = document.get_body() else: body = self.get_document_body() if body is None: raise ValueError, "the TOC must be related to a document somehow" # Save the title index_body = self.get_body() title = index_body.get_element('text:index-title') # Clean the old index-body index_body = self.set_body() # Restore the title index_body.insert(title, position=0) # Insert default TOC style if use_default_styles: automatic_styles = body.get_element('//office:automatic-styles') for level in range(1, 11): if automatic_styles.get_style( 'paragraph', TOC_ENTRY_STYLE_PATTERN % level) is None: level_style = odf_create_toc_level_style(level) automatic_styles.append(level_style) # Auto-fill the index outline_level = self.get_outline_level() or 10 level_indexes = {} for heading in body.get_headings(): level = heading.get_outline_level() if level > outline_level: continue number = [] # 1. l < level for l in range(1, level): index = level_indexes.setdefault(l, 1) number.append(unicode(index)) # 2. l == level index = level_indexes.setdefault(level, 0) + 1 level_indexes[level] = index number.append(unicode(index)) # 3. l > level for l in range(level + 1, 11): if level_indexes.has_key(l): del level_indexes[l] number = u'.'.join(number) + u'.' # Make the title with "1.2.3. Title" format title = u"%s %s" % (number, heading.get_text()) paragraph = odf_create_paragraph(title) if use_default_styles: paragraph.set_text_style(TOC_ENTRY_STYLE_PATTERN % level) index_body.append(paragraph)
def fill(self, document=None, use_default_styles=True): """Fill the TOC with the titles found in the document. A TOC is not contextual so it will catch all titles before and after its insertion. If the TOC is not attached to a document, attach it beforehand or provide one as argument. For having a pretty TOC, let use_default_styles by default. Arguments: document -- odf_document use_default_styles -- bool """ # Find the body if document is not None: body = document.get_body() else: body = self.get_document_body() if body is None: raise ValueError, "the TOC must be related to a document somehow" # Save the title index_body = self.get_body() title = index_body.get_element('text:index-title') # Clean the old index-body index_body = self.set_body() # Restore the title index_body.insert(title, position=0) # Insert default TOC style if use_default_styles: automatic_styles = body.get_element('//office:automatic-styles') for level in range(1, 11): if automatic_styles.get_style('paragraph', TOC_ENTRY_STYLE_PATTERN % level) is None: level_style = odf_create_toc_level_style(level) automatic_styles.append(level_style) # Auto-fill the index outline_level = self.get_outline_level() or 10 level_indexes = {} for heading in body.get_headings(): level = heading.get_outline_level() if level > outline_level: continue number = [] # 1. l < level for l in range(1, level): index = level_indexes.setdefault(l, 1) number.append(unicode(index)) # 2. l == level index = level_indexes.setdefault(level, 0) + 1 level_indexes[level] = index number.append(unicode(index)) # 3. l > level for l in range(level + 1, 11): if level_indexes.has_key(l): del level_indexes[l] number = u'.'.join(number) + u'.' # Make the title with "1.2.3. Title" format title = u"%s %s" % (number, heading.get_text()) paragraph = odf_create_paragraph(title) if use_default_styles: paragraph.set_text_style(TOC_ENTRY_STYLE_PATTERN % level) index_body.append(paragraph)
# If the information is not present, we assume a width of 640 px width = 640 height = int(width / (float(size[0]) / float(size[1]))) size = ("%sin" % (width / DPI), "%sin" % (height / DPI)) # Add the image local_uri = context['doc'].add_file(image) # Frame style for the caption frame caption_style = _get_caption_style(context).get_name() # Frame style for the image frame image_style = _get_image_style(context).get_name() # In text application, image must be inserted in a paragraph if context['top'].get_tag() == "office:text": container = odf_create_paragraph() context['top'].append(container) else: container = context['top'] if caption: paragraph = odf_create_paragraph() image_frame = odf_create_image_frame(local_uri, size=size, style=image_style) paragraph.append(image_frame) paragraph.append(caption) # A new frame, we fix only the width text_frame = odf_create_text_frame(paragraph, size=(size[0], None), style=caption_style)
width = 640 height = int(width / (float(size[0]) / float(size[1]))) size = ( "%sin" % (width / DPI), "%sin" % (height / DPI) ) # Add the image local_uri = context['doc'].add_file(image) # Frame style for the caption frame caption_style = _get_caption_style(context).get_name() # Frame style for the image frame image_style = _get_image_style(context).get_name() # In text application, image must be inserted in a paragraph if context['top'].get_tag() == "office:text": container = odf_create_paragraph() context['top'].append(container) else: container = context['top'] if caption: paragraph = odf_create_paragraph() image_frame = odf_create_image_frame(local_uri, size=size, style=image_style) paragraph.append(image_frame) paragraph.append(caption) # A new frame, we fix only the width text_frame = odf_create_text_frame(paragraph, size=(size[0], None), style=caption_style) container.append(text_frame) else: