def odf_create_span(text=None, style=None): """Create a span element of the given style containing the optional given text. Arguments: style -- unicode text -- unicode Return: odf_element """ element = odf_create_element('text:span') if text: element.set_text(text) if style: element.set_text_style(style) return element class odf_span(odf_paragraph): pass register_element_class('text:span', odf_span)
anim_page.append(anim_begin) anim_begin.append(transition) # Replace when already a transition: # anim:seq => After the frame's transition # cf page 349 of OpenDocument-v1.0-os.pdf # Conclusion: We must delete the first child 'anim:par' existing = self.get_element('anim:par') if existing: self.delete(existing) self.append(anim_page) def get_formatted_text(self, context): result = [] for element in self.get_children(): if element.get_tag() == 'presentation:notes': # No need for an advanced odf_notes.get_formatted_text() # because the text seems to be only contained in paragraphs # and frames, that we already handle for child in element.get_children(): result.append(child.get_formatted_text(context)) result.append(u"\n") result.append(element.get_formatted_text(context)) result.append(u"\n") return u"".join(result) register_element_class('draw:page', odf_draw_page)
# You should have received a copy of the GNU General Public License # along with Lpod. If not, see <http://www.gnu.org/licenses/>. # # b) the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # # Import from lpod from element import register_element_class, odf_element from utils import _get_element_list, _get_element class odf_tracked_changes(odf_element): def get_changed_region_list(self, creator=None, date=None, content=None): return _get_element_list(self, 'text:changed-region', dc_creator=creator, dc_date=date, content=content) def get_changed_region(self, position=0, text_id=None, creator=None, date=None, content=None): return _get_element(self, 'text:changed-region', position, text_id=text_id, dc_creator=creator, dc_date=date, content=content) register_element_class('text:tracked-changes', odf_tracked_changes)
self._insert(start, position=limits[0]) # End end = odf_create_bookmark_end(name) self._insert(end, position=limits[1]) return start, end # Without "content" and "limits" if content is not None or limits is not None: raise ValueError, "bad arguments" # Role if role is None: bookmark = odf_create_bookmark(name) elif role == "start": bookmark = odf_create_bookmark_start(name) elif role == "end": bookmark = odf_create_bookmark_end(name) else: raise ValueError, "bad arguments" # Insert self._insert(bookmark, before=before, after=after, position=position) return bookmark register_element_class('text:p', odf_paragraph)
'annotations': [], 'rst_mode': False, 'img_counter': 0, 'images': [], 'no_img_level': 0} context['no_img_level'] += 1 title = odf_paragraph.get_formatted_text(self, context) context['no_img_level'] -= 1 title = title.strip() title = sub(r'\s+', ' ', title) # No rst_mode ? if not context["rst_mode"]: return title # If here in rst_mode! # Get the level, max 5! LEVEL_STYLES = u"#=-~`+^°'." level = self.get_outline_level() if level > len(LEVEL_STYLES): raise ValueError, "Too many levels of heading" # And return the result result = [u'\n', title, u'\n', LEVEL_STYLES[level - 1] * len(title), u'\n'] return u''.join(result) register_element_class('text:h', odf_heading)
rst_mode = context["rst_mode"] result = [] if rst_mode: result.append("\n") for list_item in self.get_elements("text:list-item"): textbuf = [] for child in list_item.get_children(): text = child.get_formatted_text(context) tag = child.get_tag() if tag == "text:h": # A title in a list is a bug return text elif tag == "text:list": if not text.lstrip().startswith(u"-"): # If the list didn't indent, don't either # (inner title) return text textbuf.append(text) textbuf = u"".join(textbuf) textbuf = textbuf.strip("\n") # Indent the text textbuf = u"- %s\n" % textbuf.replace(u"\n", u"\n ") result.append(textbuf) if rst_mode: result.append("\n") return u"".join(result) register_element_class("text:list", odf_list)
return image class odf_image(odf_element): def get_url(self): return self.get_attribute('xlink:href') def set_url(self, url): return self.set_attribute('xlink:href', url) def get_type(self): return self.get_attribute('xlink:type') def set_type(self, type): return self.set_attribute('xlink:type', type) def get_show(self): return self.get_attribute('xlink:show') def set_show(self, show): return self.set_attribute('xlink:show', show) def get_actuate(self): return self.get_attribute('xlink:actuate') def set_actuate(self, actuate): return self.set_attribute('xlink:actuate', actuate) register_element_class('draw:image', odf_image)
Nota : using the .delete() on the reference mark will delete inner content. """ strip = ('text:reference-mark', 'text:reference-mark-start', 'text:reference-mark-end') return element.strip_tags(strip) def remove_reference_mark(element, position=0, name=None): """Remove the 'text:reference-mark', 'text:reference-mark-start', and 'text:reference-mark-end' tags of the element, identified by name or position, keeping inner sub elements. Nota : using the .delete() on the reference mark will delete inner content. """ start = element.get_reference_mark(position=position, name=name) end = element.get_reference_mark_end(position=position, name=name) target = [] if start: target.append(start) if end: target.append(end) element.strip_elements(target) register_element_class('text:reference-mark', odf_reference_mark) register_element_class('text:reference-mark-start', odf_reference_mark_start) register_element_class('text:reference-mark-end', odf_reference_mark_end) register_element_class('text:reference-ref', odf_reference)
smil_type=type, smil_subtype=subtype) anim_page.append(anim_begin) anim_begin.append(transition) # Replace when already a transition: # anim:seq => After the frame's transition # cf page 349 of OpenDocument-v1.0-os.pdf # Conclusion: We must delete the first child 'anim:par' existing = self.get_element('anim:par') if existing: self.delete(existing) self.append(anim_page) def get_formatted_text(self, context): result = [] for element in self.get_children(): if element.get_tag() == 'presentation:notes': # No need for an advanced odf_notes.get_formatted_text() # because the text seems to be only contained in paragraphs # and frames, that we already handle for child in element.get_children(): result.append(child.get_formatted_text(context)) result.append(u"\n") result.append(element.get_formatted_text(context)) result.append(u"\n") return u"".join(result) register_element_class('draw:page', odf_draw_page)
def append_item(self, item): # Check if the item is already a list-item tag_name = item.get_tag() if isinstance(item, odf_element) else None if tag_name != 'text:list-item': item = odf_create_list_item(item) self.append(item) def get_formatted_text(self, context): rst_mode = context["rst_mode"] result = [] if rst_mode: result.append('\n') for list_item in self.get_element_list('text:list-item'): text = [] for children in list_item.get_children(): text.append(children.get_formatted_text(context)) text = u''.join(text) text = text.strip('\n') # Indent the text text = u'- %s\n' % text.replace(u'\n', u'\n ') result.append(text) if rst_mode: result.append('\n') return u''.join(result) register_element_class('text:list', odf_list)
return image class odf_image(odf_element): def get_url(self): return self.get_attribute("xlink:href") def set_url(self, url): return self.set_attribute("xlink:href", url) def get_type(self): return self.get_attribute("xlink:type") def set_type(self, type): return self.set_attribute("xlink:type", type) def get_show(self): return self.get_attribute("xlink:show") def set_show(self, show): return self.set_attribute("xlink:show", show) def get_actuate(self): return self.get_attribute("xlink:actuate") def set_actuate(self, actuate): return self.set_attribute("xlink:actuate", actuate) register_element_class("draw:image", odf_image)
return odf_create_element( """<number:currency-style style:name="lpod-default-currency-style"> <number:text>-</number:text> <number:number number:decimal-places="2" number:min-integer-digits="1" number:grouping="true"/> <number:text> </number:text> <number:currency-symbol number:language="fr" number:country="FR">€</number:currency-symbol> </number:currency-style>""") # FIXME there are (many) more for name in ('style:style', 'style:default-style', 'style:header-style', 'style:footer-style', 'text:list-level-style-number', 'text:list-level-style-bullet', 'text:list-level-style-image'): register_element_class(name, odf_style) register_element_class('text:list-style', odf_list_style) register_element_class('text:outline-style', odf_outline_style) register_element_class('style:page-layout', odf_page_layout) register_element_class('style:master-page', odf_master_page) register_element_class('style:font-face', odf_font_style) register_element_class('number:number-style', odf_number_style) register_element_class('number:percentage-style', odf_percentage_style) register_element_class('number:time-style', odf_time_style) register_element_class('number:date-style', odf_date_style) register_element_class('number:currency-style', odf_currency_style) register_element_class('style:presentation-page-layout', odf_presentation_page_layout_style)
# Replace when already a transition: # anim:seq => After the frame's transition # cf page 349 of OpenDocument-v1.0-os.pdf # Conclusion: We must delete the first child 'anim:par' existing = self.get_element("anim:par") if existing: self.delete(existing) self.append(anim_page) def get_shapes(self): query = "(descendant::" + "|descendant::".join(registered_shapes) + ")" return self.get_elements(query) def get_formatted_text(self, context): result = [] for element in self.get_children(): if element.get_tag() == "presentation:notes": # No need for an advanced odf_notes.get_formatted_text() # because the text seems to be only contained in paragraphs # and frames, that we already handle for child in element.get_children(): result.append(child.get_formatted_text(context)) result.append(u"\n") result.append(element.get_formatted_text(context)) result.append(u"\n") return u"".join(result) register_element_class("draw:page", odf_draw_page)
# Auto-fill the index outline_level = self.get_toc_outline_level() or 10 level_indexes = {} for heading in body.get_heading_list(): 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) register_element_class('text:table-of-content', odf_toc)
def register_style(tagname, cls): register_element_class(tagname, cls) registered_styles.append(tagname)
def get_formatted_text(self, context): result = [] for child in self.get_children(): result.append(child.get_formatted_text(context)) result.append(u"\n") return u"".join(result) # XXX better place? class draw_group(odf_element): def get_name(self): return self.get_attribute('draw:name') def set_name(self, name): return self.set_attribute('draw:name', name) registered_shapes = [] def register_shape(tagname, cls): register_element_class(tagname, cls) registered_shapes.append(tagname) for name in ('draw:custom-shape', 'draw:line', 'draw:polyline', 'draw:polygon', 'draw:regular-polygon', 'draw:path', 'draw:rect', 'draw:ellipse', 'draw:circle', 'draw:connector'): register_shape(name, odf_shape) register_element_class('draw:g', draw_group)
class odf_heading(odf_paragraph): """Specialised element for headings, which themselves are Specialised paragraphs. """ def get_formatted_text(self, context): context['no_img_level'] += 1 title = odf_paragraph.get_formatted_text(self, context) context['no_img_level'] -= 1 title = title.strip() title = sub(r'\s+', ' ', title) # No rst_mode ? if not context["rst_mode"]: return title # If here in rst_mode! # Get the level, max 5! LEVEL_STYLES = u"#=-~`+^°'." level = self.get_outline_level() if level > len(LEVEL_STYLES): raise ValueError, "Too many levels of heading" # And return the result result = [ u'\n', title, u'\n', LEVEL_STYLES[level - 1] * len(title), u'\n' ] return u''.join(result) register_element_class('text:h', odf_heading)
Arguments: style -- unicode Return: odf_element """ element = odf_create_element('text:section') if style: element.set_style(style) return element class odf_section(odf_element): """Specialised element for sections. """ def get_style(self): return self.get_attribute('text:style-name') def set_style(self, style): self.set_style_attribute('text:style-name', style) def get_formatted_text(self, context): result = [] for element in self.get_children(): result.append(element.get_formatted_text(context)) result.append(u'\n') return u''.join(result) register_element_class('text:section', odf_section)
#toc_fill = obsolete('toc_fill', fill) class odf_index_title_template(odf_element): def get_style(self): return self.get_attribute('text:style-name') def set_style(self, name): return self.set_style_attribute('text:style-name', name) class odf_toc_entry_template(odf_element): def get_style(self): return self.get_attribute('text:style-name') def set_style(self, name): return self.set_style_attribute('text:style-name', name) register_element_class('text:table-of-content', odf_toc) register_element_class('text:index-title-template', odf_index_title_template) register_element_class('text:table-of-content-entry-template', odf_toc_entry_template)
def remove_all_reference_marks(element): """Remove all the 'text:reference-mark', 'text:reference-mark-start', and 'text:reference-mark-end' tags of the element, keeping inner sub elements. Nota : using the .delete() on the reference mark will delete inner content. """ strip = ('text:reference-mark', 'text:reference-mark-start', 'text:reference-mark-end') return element.strip_tags(strip) def remove_reference_mark(element, position=0, name=None): """Remove the 'text:reference-mark', 'text:reference-mark-start', and 'text:reference-mark-end' tags of the element, identified by name or position, keeping inner sub elements. Nota : using the .delete() on the reference mark will delete inner content. """ start = element.get_reference_mark(position=position, name=name) end = element.get_reference_mark_end(position=position, name=name) target = [] if start: target.append(start) if end: target.append(end) element.strip_elements(target) register_element_class('text:reference-mark', odf_reference_mark) register_element_class('text:reference-mark-start', odf_reference_mark_start) register_element_class('text:reference-mark-end', odf_reference_mark_end) register_element_class('text:reference-ref', odf_reference)
# 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) #toc_fill = obsolete('toc_fill', fill) class odf_index_title_template(odf_element): def get_style(self): return self.get_attribute('text:style-name') def set_style(self, name): return self.set_style_attribute('text:style-name', name) class odf_toc_entry_template(odf_element): def get_style(self): return self.get_attribute('text:style-name') def set_style(self, name): return self.set_style_attribute('text:style-name', name) register_element_class('text:table-of-content', odf_toc) register_element_class('text:index-title-template', odf_index_title_template) register_element_class('text:table-of-content-entry-template', odf_toc_entry_template)
class odf_annotation(odf_element): def get_body(self): return self.get_text_content() def set_body(self, text_or_element): if type(text_or_element) is unicode: self.set_text_content(text_or_element) elif isinstance(text_or_element, odf_element): self.clear() self.append(text_or_element) else: raise TypeError, 'expected unicode or odf_element' # # Shortcuts expected to be reusable over several elements # def check_validity(self): if not self.get_body(): raise ValueError, "annotation must have a body" if not self.get_dc_creator(): raise ValueError, "annotation must have a creator" if not self.get_dc_date(): self.set_dc_date(datetime.now()) register_element_class('text:note', odf_note) register_element_class('office:annotation', odf_annotation)
def get_target_frame(self): return self.get_attribute('office:target-frame-name') def set_target_frame(self, name): return self.set_style_attribute('office:target-frame-name', name) def get_show(self): return self.get_attribute('xlink:show') def set_show(self, value): """'new' or 'replace' """ return self.set_attribute('xlink:show', value) def get_visited_style(self): return self.get_attribute('text:visited-style-name') def set_visited_style(self, name): attribute = 'text:visited-style-name' return self.set_style_attribute(attribute, name) register_element_class('text:a', odf_link)
automatic_styles.append_element(level_style) # Auto-fill the index level_indexes = {} for heading in body.get_heading_list(): level = heading.get_outline_level() 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_element(paragraph) register_element_class('text:table-of-content', odf_toc)
and content is None and type(position) is tuple): # Start start = odf_create_bookmark_start(name) self._insert(start, position=position[0]) # End end = odf_create_bookmark_end(name) self._insert(end, position=position[1]) return start, end # Without "content" nor "position" if content is not None or type(position) is not int: raise ValueError, "bad arguments" # Role if role is None: bookmark = odf_create_bookmark(name) elif role == "start": bookmark = odf_create_bookmark_start(name) elif role == "end": bookmark = odf_create_bookmark_end(name) else: raise ValueError, "bad arguments" # Insert self._insert(bookmark, before=before, after=after, position=position) return bookmark register_element_class('text:p', odf_paragraph)
def set_url(self, url): return self.set_attribute('xlink:href', url) def get_type(self): return self.get_attribute('xlink:type') def set_type(self, type): return self.set_attribute('xlink:type', type) def get_show(self): return self.get_attribute('xlink:show') def set_show(self, show): return self.set_attribute('xlink:show', show) def get_actuate(self): return self.get_attribute('xlink:actuate') def set_actuate(self, actuate): return self.set_attribute('xlink:actuate', actuate) register_element_class('draw:image', odf_image)
def odf_create_span(text=None, style=None): """Create a span element of the given style containing the optional given text. Arguments: style -- unicode text -- unicode Return: odf_element """ element = odf_create_element('text:span') if text: element.set_text(text) if style: element.set_style(style) return element class odf_span(odf_paragraph): pass register_element_class('text:span', odf_span)
element.set_attribute('draw:start-shape', start_shape_id) element.set_attribute('draw:end-shape', end_shape_id) if glue_points: element.set_attribute('draw:start-glue-point', str(glue_points[0])) element.set_attribute('draw:end-glue-point', str(glue_points[1])) if p1: element.set_attribute('svg:x1', p1[0]) element.set_attribute('svg:y1', p1[1]) if p2: element.set_attribute('svg:x2', p2[0]) element.set_attribute('svg:y2', p2[1]) return element class odf_shape(odf_element): def get_formatted_text(self, context): result = [] for child in self.get_children(): result.append(child.get_formatted_text(context)) result.append(u"\n") return u"".join(result) for name in ('draw:custom-shape', 'draw:line', 'draw:polyline', 'draw:polygon', 'draw:regular-polygon', 'draw:path', 'draw:rect', 'draw:ellipse', 'draw:circle', 'draw:connector'): register_element_class(name, odf_shape)
def get_body(self): return self.get_text_content() def set_body(self, text_or_element): if type(text_or_element) is unicode: self.set_text_content(text_or_element) elif isinstance(text_or_element, odf_element): self.clear() self.append(text_or_element) else: raise TypeError, 'expected unicode or odf_element' # # Shortcuts expected to be reusable over several elements # def check_validity(self): if not self.get_body(): raise ValueError, "annotation must have a body" if not self.get_dc_creator(): raise ValueError, "annotation must have a creator" if not self.get_dc_date(): self.set_dc_date(datetime.now()) register_element_class('text:note', odf_note) register_element_class('office:annotation', odf_annotation)
result.append(u"\n") return u"".join(result) # XXX better place? class draw_group(odf_element): def get_name(self): return self.get_attribute('draw:name') def set_name(self, name): return self.set_attribute('draw:name', name) registered_shapes = [] def register_shape(tagname, cls): register_element_class(tagname, cls) registered_shapes.append(tagname) for name in ('draw:custom-shape', 'draw:line', 'draw:polyline', 'draw:polygon', 'draw:regular-polygon', 'draw:path', 'draw:rect', 'draw:ellipse', 'draw:circle', 'draw:connector'): register_shape(name, odf_shape) register_element_class('draw:g', draw_group)
"""Create a section element of the given style. Arguments: style -- unicode Return: odf_element """ element = odf_create_element('text:section') if style: element.set_text_style(style) return element class odf_section(odf_element): """Specialised element for sections. """ def get_formatted_text(self, context): result = [] for element in self.get_children(): result.append(element.get_formatted_text(context)) result.append(u'\n') return u''.join(result) register_element_class('text:section', odf_section)
if context['no_img_level']: context['img_counter'] += 1 ref = u'|img%d|' % context['img_counter'] result.append(ref) context['images'].append( (ref, filename, (width, height))) else: result.append(u'\n.. image:: %s\n' % filename) if width is not None: result.append(u' :width: %s\n' % width) if height is not None: result.append(u' :height: %s\n' % height) else: result.append(u'[Image %s]\n' % element.get_attribute('xlink:href')) elif tag == 'draw:text-box': subresult = [u' '] for element in element.get_children(): subresult.append(element.get_formatted_text(context)) subresult = u''.join(subresult) subresult = subresult.replace(u'\n', u'\n ') subresult.rstrip(' ') result.append(subresult) else: result.append(element.get_formatted_text(context)) result.append(u'\n') return u''.join(result) register_element_class('draw:frame', odf_frame)
def get_title(self): return self.get_attribute('office:title') def set_title(self, title): return self.set_attribute('office:title', title) def get_target_frame(self): return self.get_attribute('office:target-frame-name') def set_target_frame(self, name): return self.set_style_attribute('office:target-frame-name', name) def get_show(self): return self.get_attribute('xlink:show') def set_show(self, value): """'new' or 'replace' """ return self.set_attribute('xlink:show', value) def get_visited_style(self): return self.get_attribute('text:visited-style-name') def set_visited_style(self, name): attribute = 'text:visited-style-name' return self.set_style_attribute(attribute, name) register_element_class('text:a', odf_link)
raise ValueError, "position must be defined" def append_item(self, item): # Check if the item is already a list-item tag_name = item.get_tag() if isinstance(item, odf_element) else None if tag_name != 'text:list-item': item = odf_create_list_item(item) self.append(item) def get_formatted_text(self, context): rst_mode = context["rst_mode"] result = [] if rst_mode: result.append('\n') for list_item in self.get_element_list('text:list-item'): text = [] for children in list_item.get_children(): text.append(children.get_formatted_text(context)) text = u''.join(text) text = text.strip('\n') # Indent the text text = u'- %s\n' % text.replace(u'\n', u'\n ') result.append(text) if rst_mode: result.append('\n') return u''.join(result) register_element_class('text:list', odf_list)
context['img_counter'] += 1 ref = u'|img%d|' % context['img_counter'] result.append(ref) context['images'].append( (ref, filename, (width, height) ) ) else: result.append(u'\n.. image:: %s\n' % filename) if width is not None: result.append(u' :width: %s\n' % width) if height is not None: result.append(u' :height: %s\n' % height) else: result.append(u'[Image %s]\n' % element.get_attribute('xlink:href')) elif tag == 'draw:text-box': subresult = [u' '] for element in element.get_children(): subresult.append(element.get_formatted_text(context)) subresult = u''.join(subresult) subresult = subresult.replace(u'\n', u'\n ') subresult.rstrip(' ') result.append(subresult) else: result.append(element.get_formatted_text(context)) result.append(u'\n') return u''.join(result) register_element_class('draw:frame', odf_frame)
keep_tail -- boolean (default to True), True for most usages. """ if child is not None: # act like normal delete return super(odf_text_change_start, self).delete(child, keep_tail) idx = self.get_id() parent = self.get_parent() if parent is None: raise ValueError("cannot delete the root element") body = self.get_document_body() if not body: body = parent end = body.get_text_change_end(idx=idx) if end: end.delete() # act like normal delete return super(odf_text_change_start, self).delete() register_element_class('text:change', odf_text_change) register_element_class('text:change-end', odf_text_change_end) register_element_class('text:change-start', odf_text_change_start) register_element_class('office:change-info', odf_change_info) register_element_class('text:insertion', odf_text_insertion) register_element_class('text:deletion', odf_text_deletion) register_element_class('text:format-change', odf_text_format_change) register_element_class('text:changed-region', odf_text_changed_region) register_element_class('text:tracked-changes', odf_tracked_changes)