def get_value(element, value_type=None, try_get_text=True, get_type=False): """Only for "with office:value-type" elements """ if value_type is None: value_type = element.get_attribute('office:value-type') if value_type == 'boolean': value = element.get_attribute('office:boolean-value') if get_type: return (Boolean.decode(value), value_type) return Boolean.decode(value) elif value_type in ('float', 'percentage', 'currency'): value = dec(element.get_attribute('office:value')) # Return 3 instead of 3.0 if possible if int(value) == value: if get_type: return (int(value), value_type) return int(value) if get_type: return (value, value_type) return value elif value_type == 'date': value = element.get_attribute('office:date-value') if 'T' in value: if get_type: return (DateTime.decode(value), value_type) return DateTime.decode(value) else: if get_type: return (Date.decode(value), value_type) return Date.decode(value) elif value_type == 'string': value = element.get_attribute('office:string-value') if value is not None: if get_type: return (unicode(value), value_type) return unicode(value) if try_get_text: value = [] for para in element.get_elements('text:p'): value.append(para.get_text(recursive=True)) if value: if get_type: return (u"\n".join(value), value_type) return u"\n".join(value) if get_type: return (None, value_type) return None elif value_type == 'time': value = Duration.decode(element.get_attribute('office:time-value')) if get_type: return (value, value_type) return value elif value_type is None: if get_type: return (None, None) return None raise ValueError, 'unexpected value type "%s"' % value_type
def get_user_defined_metadata(self): """Return a dict of unicode/value mapping. Value types can be: Decimal, date, time, boolean or unicode. """ result = {} for meta in self.get_elements('//meta:user-defined'): # Read the values name = meta.get_attribute('meta:name') value_type = meta.get_attribute('meta:value-type') if value_type is None: value_type = 'string' value = meta.get_text() # Interpretation if value_type == 'boolean': result[name] = Boolean.decode(value) elif value_type in ('float', 'percentage', 'currency'): result[name] = Decimal(value) elif value_type == 'date': if 'T' in value: result[name] = DateTime.decode(value) else: result[name] = Date.decode(value) elif value_type == 'string': result[name] = value elif value_type == 'time': result[name] = Duration.decode(value) return result
def _get_meta_value(element, full=False): """get_value deicated to the meta data part, for one meta element. """ name = element.get_attribute('meta:name') value_type = element.get_attribute('meta:value-type') if value_type is None: value_type = 'string' text = element.get_text() # Interpretation if value_type == 'boolean': value = Boolean.decode(text) elif value_type in ('float', 'percentage', 'currency'): value = Decimal(text) elif value_type == 'date': if 'T' in text: value = DateTime.decode(text) else: value = Date.decode(text) elif value_type == 'string': value = text elif value_type == 'time': value = Duration.decode(text) if full: return (value, value_type, text) else: return value
def get_user_defined_metadata(self): """Return a dict of unicode/value mapping. Value types can be: Decimal, date, time, boolean or unicode. """ result = {} for meta in self.get_element_list('//meta:user-defined'): # Read the values name = meta.get_attribute('meta:name') value_type = meta.get_attribute('meta:value-type') if value_type is None: value_type = 'string' value = meta.get_text() # Interpretation if value_type == 'boolean': result[name] = Boolean.decode(value) elif value_type in ('float', 'percentage', 'currency'): result[name] = Decimal(value) elif value_type == 'date': if 'T' in value: result[name] = DateTime.decode(value) else: result[name] = Date.decode(value) elif value_type == 'string': result[name] = value elif value_type == 'time': result[name] = Duration.decode(value) return result
def get_value(element, value_type=None, try_get_text=True): """Only for "with office:value-type" elements """ if value_type is None: value_type = element.get_attribute('office:value-type') if value_type == 'boolean': value = element.get_attribute('office:boolean-value') return Boolean.decode(value) elif value_type in ('float', 'percentage', 'currency'): value = dec(element.get_attribute('office:value')) # Return 3 instead of 3.0 if possible if int(value) == value: return int(value) return value elif value_type == 'date': value = element.get_attribute('office:date-value') if 'T' in value: return DateTime.decode(value) else: return Date.decode(value) elif value_type == 'string': value = element.get_attribute('office:string-value') if value is not None: return unicode(value) # XXX: get_text or get_formatted_text ??? if try_get_text: value = element.get_text(recursive=True) if value != '': return value return None elif value_type == 'time': value = element.get_attribute('office:time-value') return Duration.decode(value) elif value_type is None: return None raise ValueError, 'unexpected value type "%s"' % value_type
def _set_value_and_type(element, value=None, value_type=None, text=None, currency=None): # Remove possible previous value and type for name in ('office:value-type', 'office:boolean-value', 'office:value', 'office:date-value', 'office:string-value', 'office:time-value', 'table:formula'): try: element.del_attribute('office:currency') except KeyError: pass if value is None: try: element.del_attribute(name) except KeyError: pass element._erase_text_content() return text if type(value) is bool: if value_type is None: value_type = 'boolean' if text is None: text = u'true' if value else u'false' value = Boolean.encode(value) elif isinstance(value, (int, float, long, dec)): if value_type is 'percentage': text = "%d %%" % int(value * 100) if value_type is None: value_type = 'float' if text is None: text = unicode(value) value = str(value) elif type(value) is date: if value_type is None: value_type = 'date' if text is None: text = unicode(Date.encode(value)) value = Date.encode(value) elif type(value) is datetime: if value_type is None: value_type = 'date' if text is None: text = unicode(DateTime.encode(value)) value = DateTime.encode(value) elif type(value) is str: if value_type is None: value_type = 'string' if text is None: text = unicode(value) elif type(value) is unicode: if value_type is None: value_type = 'string' if text is None: text = value elif type(value) is timedelta: if value_type is None: value_type = 'time' if text is None: text = unicode(Duration.encode(value)) value = Duration.encode(value) elif value is not None: raise TypeError, 'type "%s" is unknown' % type(value) if value_type is not None: element.set_attribute('office:value-type', value_type) if value_type == 'boolean': element.set_attribute('office:boolean-value', value) elif value_type == 'currency': element.set_attribute('office:value', value) element.set_attribute('office:currency', currency) elif value_type == 'date': element.set_attribute('office:date-value', value) elif value_type in ('float', 'percentage'): element.set_attribute('office:value', value) elif value_type == 'string': element.set_attribute('office:string-value', value) elif value_type == 'time': element.set_attribute('office:time-value', value) return text
def odf_create_style(family, name=None, display_name=None, parent=None, # Where properties apply area=None, # For family 'text': color=None, background_color=None, italic=False, bold=False, # For family 'paragraph' master_page=None, # For family 'master-page' page_layout=None, next_style=None, # For family 'table-cell' data_style=None, border=None, border_top=None, border_right=None, border_bottom=None, border_left=None, padding=None, padding_top=None, padding_bottom=None, padding_left=None, padding_right=None, shadow=None, # For family 'table-row' height=None, use_optimal_height=None, # For family 'table-column' width=None, break_before=None, break_after=None, # For family 'graphic' min_height=None, # For family 'font-face' font_name=None, font_family=None, font_family_generic=None, font_pitch=u"variable", # Every other property **kw): """Create a style of the given family. The name is not mandatory at this point but will become required when inserting in a document as a common style. The display name is the name the user sees in an office application. The parent is the name of the style this style will inherit from. To set properties, pass them as keyword arguments. The area properties apply to is optional and defaults to the family. Arguments: family -- 'paragraph', 'text', 'section', 'table', 'table-column', 'table-row', 'table-cell', 'table-page', 'chart', 'drawing-page', 'graphic', 'presentation', 'control', 'ruby', 'list', 'number', 'page-layout' 'font-face', or 'master-page' name -- unicode display_name -- unicode parent -- unicode area -- str 'text' Properties: italic -- bool bold -- bool 'paragraph' Properties: master_page -- unicode 'master-page' Properties: page_layout -- unicode next_style -- unicode 'table-cell' Properties: border, border_top, border_right, border_bottom, border_left -- str, e.g. "0.002cm solid #000000" or 'none' padding, padding_top, padding_right, padding_bottom, padding_left -- str, e.g. "0.002cm" or 'none' shadow -- str, e.g. "#808080 0.176cm 0.176cm" 'table-row' Properties: height -- str, e.g. '5cm' use_optimal_height -- bool 'table-column' Properties: width -- str, e.g. '5cm' break_before -- 'page', 'column' or 'auto' break_after -- 'page', 'column' or 'auto' Return: odf_style """ tagname, famattr = _get_style_tagname(family) element = odf_create_element(tagname) # Common attributes if name: element.set_name(name) if famattr: element.set_family(famattr) if display_name: element.set_display_name(display_name) if parent: element.set_parent_style(parent) # Paragraph if family == 'paragraph': if master_page: element.set_master_page(master_page) # Master Page elif family == 'master-page': if page_layout: element.set_page_layout(page_layout) if next_style: element.set_next_style(next_style) # Font face elif family == 'font-face': element.set_font(font_name, family=font_family, family_generic=font_family_generic, pitch=font_pitch) # Properties if area is None: area = family # Text if area == 'text': if color: kw['fo:color'] = color if background_color: kw['fo:background-color'] = background_color if italic: kw['fo:font-style'] = 'italic' kw['style:font-style-asian'] = 'italic' kw['style:font-style-complex'] = 'italic' if bold: kw['fo:font-weight'] = 'bold' kw['style:font-weight-asian'] = 'bold' kw['style:font-weight-complex'] = 'bold' # Table cell elif area == 'table-cell': if border: kw['fo:border'] = border elif border_top or border_right or border_bottom or border_left: kw['fo:border-top'] = border_top or 'none' kw['fo:border-right'] = border_right or 'none' kw['fo:border-bottom'] = border_bottom or 'none' kw['fo:border-left'] = border_left or 'none' else: # no border_top, ... neither border are defined pass # left untouched if padding: kw['fo:padding'] = padding elif padding_top or padding_right or padding_bottom or padding_left: kw['fo:padding-top'] = padding_top or 'none' kw['fo:padding-right'] = padding_right or 'none' kw['fo:padding-bottom'] = padding_bottom or 'none' kw['fo:padding-left'] = padding_left or 'none' else: # no border_top, ... neither border are defined pass # left untouched if shadow: kw['style:shadow'] = shadow if background_color: kw['fo:background-color'] = background_color # Table row elif area == 'table-row': if height: kw['style:row-height'] = height if use_optimal_height is not None: kw['style:use-optimal-row-height'] = Boolean.encode( use_optimal_height) if background_color: kw['fo:background-color'] = background_color # Table column elif area == 'table-column': if width: kw['style:column-width'] = width if break_before: kw['fo:break-before'] = break_before if break_after: kw['fo:break-after'] = break_after # Graphic elif area == 'graphic': if min_height: kw['fo:min-height'] = min_height # Every other properties if kw: element.set_properties(kw, area=area) return element
def _set_value_and_type(element, value=None, value_type=None, text=None, currency=None): # Remove possible previous value and type for name in ('office:value-type', 'office:boolean-value', 'office:value', 'office:date-value', 'office:string-value', 'office:time-value'): try: element.del_attribute(name) except KeyError: pass if type(value) is bool: if value_type is None: value_type = 'boolean' if text is None: text = u'true' if value else u'false' value = Boolean.encode(value) elif isinstance(value, (int, float, dec)): if value_type is None: value_type = 'float' if text is None: text = unicode(value) value = str(value) elif type(value) is date: if value_type is None: value_type = 'date' if text is None: text = unicode(Date.encode(value)) value = Date.encode(value) elif type(value) is datetime: if value_type is None: value_type = 'date' if text is None: text = unicode(DateTime.encode(value)) value = DateTime.encode(value) elif type(value) is str: if value_type is None: value_type = 'string' if text is None: text = unicode(value) elif type(value) is unicode: if value_type is None: value_type = 'string' if text is None: text = value elif type(value) is timedelta: if value_type is None: value_type = 'time' if text is None: text = unicode(Duration.encode(value)) value = Duration.encode(value) elif value is not None: raise TypeError, 'type "%s" is unknown' % type(value) if value_type is not None: element.set_attribute('office:value-type', value_type) if value_type == 'boolean': element.set_attribute('office:boolean-value', value) elif value_type == 'currency': element.set_attribute('office:value', value) element.set_attribute('office:currency', currency) elif value_type == 'date': element.set_attribute('office:date-value', value) elif value_type in ('float', 'percentage'): element.set_attribute('office:value', value) elif value_type == 'string': element.set_attribute('office:string-value', value) elif value_type == 'time': element.set_attribute('office:time-value', value) return text