[Python-modules-commits] [python-odf] 84/118: Fixed an issue where namespaces used in formulas were not preserved

Wolfgang Borgert debacle at moszumanska.debian.org
Fri Oct 3 21:27:26 UTC 2014


This is an automated email from the git hooks/post-receive script.

debacle pushed a commit to reference refs/remotes/upstream/master
in repository python-odf.

commit c4879d93c1a567684170099cf853e778db47e483
Author: Søren Roug <soren.roug at eea.europa.eu>
Date:   Sun Apr 25 14:58:27 2010 +0000

    Fixed an issue where namespaces used in formulas were not preserved
---
 odf/attrconverters.py                 |  56 +++++++++++++++++++++++++---------
 odf/element.py                        |   8 ++++-
 odf/namespaces.py                     |  11 ++++++-
 tests/examples/pythagoras-kspread.ods | Bin 0 -> 5037 bytes
 tests/examples/pythagoras.ods         | Bin 0 -> 6837 bytes
 tests/testload.py                     |  19 ++++++++++++
 tests/teststyles.py                   |   4 +--
 7 files changed, 80 insertions(+), 18 deletions(-)

diff --git a/odf/attrconverters.py b/odf/attrconverters.py
index 0117324..d84a958 100644
--- a/odf/attrconverters.py
+++ b/odf/attrconverters.py
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-# Copyright (C) 2006-2008 Søren Roug, European Environment Agency
+# Copyright (C) 2006-2010 Søren Roug, European Environment Agency
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -40,6 +40,9 @@ def cnv_boolean(attribute, arg, element):
 
 # Potentially accept color values
 def cnv_color(attribute, arg, element):
+    """ A RGB color in conformance with §5.9.11 of [XSL], that is a RGB color in notation “#rrggbb”, where
+        rr, gg and bb are 8-bit hexadecimal digits.
+    """
     return str(arg)
 
 def cnv_configtype(attribute, arg, element):
@@ -55,9 +58,15 @@ def cnv_data_source_has_labels(attribute, arg, element):
 
 # Understand different date formats
 def cnv_date(attribute, arg, element):
+    """ A dateOrDateTime value is either an [xmlschema-2] date value or an [xmlschema-2] dateTime
+        value.
+    """
     return str(arg)
 
 def cnv_dateTime(attribute, arg, element):
+    """ A dateOrDateTime value is either an [xmlschema-2] date value or an [xmlschema-2] dateTime
+        value.
+    """
     return str(arg)
 
 def cnv_double(attribute, arg, element):
@@ -72,6 +81,22 @@ def cnv_family(attribute, arg, element):
         raise ValueError, "'%s' not allowed" % str(arg)
     return str(arg)
 
+def cnv_formula(attribute, arg, element):
+    """ A string containing a formula. Formulas do not have a predefined syntax, but the string should
+        begin with a namespace prefix, followed by a “:” (COLON, U+003A) separator, followed by the text
+        of the formula. The namespace bound to the prefix determines the syntax and semantics of the
+        formula.
+    """
+    prefix = arg.split(':',1)[0]
+    if prefix == arg:
+        return unicode(arg)
+    namespace = element.get_knownns(prefix)
+    if namespace is None:
+        #raise ValueError, "'%s' is an unknown prefix" % str(prefix)
+        return unicode(arg)
+    p = element.get_nsprefix(namespace)
+    return unicode(arg)
+
 def cnv_ID(attribute, arg, element):
     return str(arg)
 
@@ -89,6 +114,9 @@ def cnv_legend_position(attribute, arg, element):
 pattern_length = re.compile(r'-?([0-9]+(\.[0-9]*)?|\.[0-9]+)((cm)|(mm)|(in)|(pt)|(pc)|(px))')
 
 def cnv_length(attribute, arg, element):
+    """ A (positive or negative) physical length, consisting of magnitude and unit, in conformance with the
+        Units of Measure defined in §5.9.13 of [XSL].
+    """
     global pattern_length
     if not pattern_length.match(arg):
         raise ValueError, "'%s' is not a valid length" % arg
@@ -122,10 +150,10 @@ def cnv_namespacedToken(attribute, arg, element):
         raise ValueError, "'%s' is not a valid namespaced token" % arg
     return arg
 
-# Must accept string as argument
-# NCName is defined in http://www.w3.org/TR/REC-xml-names/#NT-NCName
-# Essentially an XML name minus ':'
 def cnv_NCName(attribute, arg, element):
+    """ NCName is defined in http://www.w3.org/TR/REC-xml-names/#NT-NCName
+        Essentially an XML name minus ':'
+    """
     if type(arg) in types.StringTypes:
         return make_NCName(arg)
     else:
@@ -288,7 +316,7 @@ attrconverters = {
 	((CHARTNS,u'values-cell-range-address'), None): cnv_string,
 	((CHARTNS,u'vertical'), None): cnv_boolean,
 	((CHARTNS,u'visible'), None): cnv_boolean,
-	((CONFIGNS,u'name'), None): cnv_string,
+	((CONFIGNS,u'name'), None): cnv_formula,
 	((CONFIGNS,u'type'), None): cnv_configtype,
 	((DR3DNS,u'ambient-color'), None): cnv_string,
 	((DR3DNS,u'back-scale'), None): cnv_string,
@@ -800,8 +828,8 @@ attrconverters = {
 	((PRESENTATIONNS,u'user-transformed'), None): cnv_boolean,
 	((PRESENTATIONNS,u'verb'), None): cnv_nonNegativeInteger,
 	((PRESENTATIONNS,u'visibility'), None): cnv_string,
-	((SCRIPTNS,u'event-name'), None): cnv_string,
-	((SCRIPTNS,u'language'), None): cnv_string,
+	((SCRIPTNS,u'event-name'), None): cnv_formula,
+	((SCRIPTNS,u'language'), None): cnv_formula,
 	((SCRIPTNS,u'macro-name'), None): cnv_string,
 	((SMILNS,u'accelerate'), None): cnv_double,
 	((SMILNS,u'accumulate'), None): cnv_string,
@@ -1087,7 +1115,7 @@ attrconverters = {
 	((SVGNS,u'y2'), None): cnv_lengthorpercent,
 	((TABLENS,u'acceptance-state'), None): cnv_string,
 	((TABLENS,u'add-empty-lines'), None): cnv_boolean,
-	((TABLENS,u'algorithm'), None): cnv_string,
+	((TABLENS,u'algorithm'), None): cnv_formula,
 	((TABLENS,u'align'), None): cnv_string,
 	((TABLENS,u'allow-empty-cell'), None): cnv_boolean,
 	((TABLENS,u'application-data'), None): cnv_string,
@@ -1106,7 +1134,7 @@ attrconverters = {
 	((TABLENS,u'cell-range'), None): cnv_string,
 	((TABLENS,u'column'), None): cnv_integer,
 	((TABLENS,u'comment'), None): cnv_string,
-	((TABLENS,u'condition'), None): cnv_string,
+	((TABLENS,u'condition'), None): cnv_formula,
 	((TABLENS,u'condition-source'), None): cnv_string,
 	((TABLENS,u'condition-source-range-address'), None): cnv_string,
 	((TABLENS,u'contains-error'), None): cnv_boolean,
@@ -1144,13 +1172,13 @@ attrconverters = {
 	((TABLENS,u'end-x'), None): cnv_length,
 	((TABLENS,u'end-y'), None): cnv_length,
 	((TABLENS,u'execute'), None): cnv_boolean,
-	((TABLENS,u'expression'), None): cnv_string,
+	((TABLENS,u'expression'), None): cnv_formula,
 	((TABLENS,u'field-name'), None): cnv_string,
 	((TABLENS,u'field-number'), None): cnv_nonNegativeInteger,
 	((TABLENS,u'field-number'), None): cnv_string,
 	((TABLENS,u'filter-name'), None): cnv_string,
 	((TABLENS,u'filter-options'), None): cnv_string,
-	((TABLENS,u'formula'), None): cnv_string,
+	((TABLENS,u'formula'), None): cnv_formula,
 	((TABLENS,u'function'), None): cnv_string,
 	((TABLENS,u'function'), None): cnv_string,
 	((TABLENS,u'grand-total'), None): cnv_string,
@@ -1290,7 +1318,7 @@ attrconverters = {
 	((TEXTNS,u'combine-entries-with-pp'), None): cnv_boolean,
 	((TEXTNS,u'comma-separated'), None): cnv_boolean,
 	((TEXTNS,u'cond-style-name'), None): cnv_StyleNameRef,
-	((TEXTNS,u'condition'), None): cnv_string,
+	((TEXTNS,u'condition'), None): cnv_formula,
 	((TEXTNS,u'connection-name'), None): cnv_string,
 	((TEXTNS,u'consecutive-numbering'), None): cnv_boolean,
 	((TEXTNS,u'continue-numbering'), None): cnv_boolean,
@@ -1321,7 +1349,7 @@ attrconverters = {
 	((TEXTNS,u'first-row-start-column'), None): cnv_string,
 	((TEXTNS,u'fixed'), None): cnv_boolean,
 	((TEXTNS,u'footnotes-position'), None): cnv_string,
-	((TEXTNS,u'formula'), None): cnv_string,
+	((TEXTNS,u'formula'), None): cnv_formula,
 	((TEXTNS,u'global'), None): cnv_boolean,
 	((TEXTNS,u'howpublished'), None): cnv_string,
 	((TEXTNS,u'id'), None): cnv_ID,
@@ -1437,7 +1465,7 @@ attrconverters = {
 
 class AttrConverters:
     def convert(self, attribute, value, element):
-        conversion = attrconverters.get((attribute,element), None)
+        conversion = attrconverters.get((attribute, element.qname), None)
         if conversion is not None:
             return conversion(attribute, value, element)
         else:
diff --git a/odf/element.py b/odf/element.py
index f0938ba..27aec38 100644
--- a/odf/element.py
+++ b/odf/element.py
@@ -310,6 +310,12 @@ class Element(Node):
                 if self.getAttrNS(r[0],r[1]) is None:
                     raise AttributeError, "Required attribute missing: %s in <%s>" % (r[1].lower().replace('-',''), self.tagName)
 
+    def get_knownns(self, prefix):
+        global nsdict
+        for ns,p in nsdict.items():
+            if p == prefix: return ns
+        return None
+        
     def get_nsprefix(self, namespace):
         if namespace is None: namespace = ""
         prefix = _nsassign(namespace)
@@ -403,7 +409,7 @@ class Element(Node):
 #       if allowed_attrs and (namespace, localpart) not in allowed_attrs:
 #           raise AttributeError, "Attribute %s:%s is not allowed in element <%s>" % ( prefix, localpart, self.tagName)
         c = AttrConverters()
-        self.attributes[prefix + ":" + localpart] = c.convert((namespace, localpart), value, self.qname)
+        self.attributes[prefix + ":" + localpart] = c.convert((namespace, localpart), value, self)
 
     def getAttrNS(self, namespace, localpart):
         prefix = self.get_nsprefix(namespace)
diff --git a/odf/namespaces.py b/odf/namespaces.py
index 3109210..ef9fc75 100644
--- a/odf/namespaces.py
+++ b/odf/namespaces.py
@@ -28,6 +28,7 @@ DCNS           = u"http://purl.org/dc/elements/1.1/"
 DOMNS          = u"http://www.w3.org/2001/xml-events"
 DR3DNS         = u"urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0"
 DRAWNS         = u"urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"
+FIELDNS        = u"urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0"
 FONS           = u"urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"
 FORMNS         = u"urn:oasis:names:tc:opendocument:xmlns:form:1.0"
 KOFFICENS      = u"http://www.koffice.org/2005/"
@@ -36,11 +37,13 @@ MATHNS         = u"http://www.w3.org/1998/Math/MathML"
 METANS         = u"urn:oasis:names:tc:opendocument:xmlns:meta:1.0"
 NUMBERNS       = u"urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"
 OFFICENS       = u"urn:oasis:names:tc:opendocument:xmlns:office:1.0"
+OFNS           = u"urn:oasis:names:tc:opendocument:xmlns:of:1.2"
 OOONS          = u"http://openoffice.org/2004/office"
 OOOWNS         = u"http://openoffice.org/2004/writer"
 OOOCNS         = u"http://openoffice.org/2004/calc"
 PRESENTATIONNS = u"urn:oasis:names:tc:opendocument:xmlns:presentation:1.0"
 RDFANS         = u"http://docs.oasis-open.org/opendocument/meta/rdfa#"
+RPTNS          = u"http://openoffice.org/2005/report"
 SCRIPTNS       = u"urn:oasis:names:tc:opendocument:xmlns:script:1.0"
 SMILNS         = u"urn:oasis:names:tc:opendocument:xmlns:smil-compatible:1.0"
 STYLENS        = u"urn:oasis:names:tc:opendocument:xmlns:style:1.0"
@@ -50,7 +53,8 @@ TEXTNS         = u"urn:oasis:names:tc:opendocument:xmlns:text:1.0"
 XFORMSNS       = u"http://www.w3.org/2002/xforms"
 XLINKNS        = u"http://www.w3.org/1999/xlink"
 XMLNS          = u"http://www.w3.org/XML/1998/namespace"
-
+XSDNS          = u"http://www.w3.org/2001/XMLSchema"
+XSINS          = u"http://www.w3.org/2001/XMLSchema-instance"
 
 nsdict = {
    ANIMNS: u'anim',
@@ -61,6 +65,7 @@ nsdict = {
    DOMNS: u'dom',
    DR3DNS: u'dr3d',
    DRAWNS: u'draw',
+   FIELDNS: u'field',
    FONS: u'fo',
    FORMNS: u'form',
    KOFFICENS: u'koffice',
@@ -69,11 +74,13 @@ nsdict = {
    METANS: u'meta',
    NUMBERNS: u'number',
    OFFICENS: u'office',
+   OFNS: u'of',
    OOONS: u'ooo',
    OOOWNS: u'ooow',
    OOOCNS: u'oooc',
    PRESENTATIONNS: u'presentation',
    RDFANS: u'rdfa',
+   RPTNS:  u'rpt',
    SCRIPTNS: u'script',
    SMILNS: u'smil',
    STYLENS: u'style',
@@ -83,4 +90,6 @@ nsdict = {
    XFORMSNS: u'xforms',
    XLINKNS: u'xlink',
    XMLNS: u'xml',
+   XSDNS: u'xsd',
+   XSINS: u'xsi',
 }
diff --git a/tests/examples/pythagoras-kspread.ods b/tests/examples/pythagoras-kspread.ods
new file mode 100644
index 0000000..9115384
Binary files /dev/null and b/tests/examples/pythagoras-kspread.ods differ
diff --git a/tests/examples/pythagoras.ods b/tests/examples/pythagoras.ods
new file mode 100644
index 0000000..a807ce4
Binary files /dev/null and b/tests/examples/pythagoras.ods differ
diff --git a/tests/testload.py b/tests/testload.py
index d50e339..6860b96 100644
--- a/tests/testload.py
+++ b/tests/testload.py
@@ -118,5 +118,24 @@ class TestExampleDocs(unittest.TestCase):
         self.assertNotEqual(-1, result.find(u"""<style:header><text:p text:style-name="MP1">Header<text:tab/>"""))
         self.assertNotEqual(-1, result.find(u"""<style:footer><text:p text:style-name="MP2">Footer<text:tab/>"""))
 
+    def test_formulas_ooo(self):
+        """ Check that formula prefixes are preserved """
+        pythagoras_odt = os.path.join(
+            os.path.dirname(__file__), "examples", "pythagoras.ods")
+        d = load(pythagoras_odt)
+        result = unicode(d.contentxml(),'utf-8')
+        self.assertNotEqual(-1, result.find(u'''xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2"'''))
+        self.assertNotEqual(-1, result.find(u'''table:formula="of:=SQRT([.A1]*[.A1]+[.A2]*[.A2])"'''))
+        self.assertNotEqual(-1, result.find(u'''table:formula="of:=SUM([.A1:.A2])"'''))
+
+    def test_formulas_ooo(self):
+        """ Check that formulas are understood when there are no prefixes"""
+        pythagoras_odt = os.path.join(
+            os.path.dirname(__file__), "examples", "pythagoras-kspread.ods")
+        d = load(pythagoras_odt)
+        result = unicode(d.contentxml(),'utf-8')
+        self.assertNotEqual(-1, result.find(u'''table:formula="=SQRT([.A1]*[.A1]+[.A2]*[.A2])"'''))
+        self.assertNotEqual(-1, result.find(u'''table:formula="=SUM([.A1]:[.A2])"'''))
+
 if __name__ == '__main__':
     unittest.main()
diff --git a/tests/teststyles.py b/tests/teststyles.py
index 57ef7b1..99c33a8 100644
--- a/tests/teststyles.py
+++ b/tests/teststyles.py
@@ -83,8 +83,8 @@ class TestQattributes(unittest.TestCase):
         textdoc.styles.addElement(standard)
         s = unicode(textdoc.stylesxml(),'UTF-8')
         s.index(u"""<?xml version='1.0' encoding='UTF-8'?>\n""")
-        s.index(u'xmlns:ns30="http://foreignuri.com"')
-        s.index(u'<style:paragraph-properties ns30:enable-numbering="true"/>')
+        s.index(u'xmlns:ns35="http://foreignuri.com"')
+        s.index(u'<style:paragraph-properties ns35:enable-numbering="true"/>')
         s.index(u'<office:styles><style:style style:name="Standard" style:display-name="Standard" style:family="paragraph">')
 
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-odf.git



More information about the Python-modules-commits mailing list