xref: /trunk/test/odf-validate/make-controls.py (revision 0e16a31d78a652c56c5c0fc79c752f48b9048df9)
1*0e16a31dSJim Jagielski#**************************************************************
2*0e16a31dSJim Jagielski#
3*0e16a31dSJim Jagielski#  Licensed to the Apache Software Foundation (ASF) under one
4*0e16a31dSJim Jagielski#  or more contributor license agreements.  See the NOTICE file
5*0e16a31dSJim Jagielski#  distributed with this work for additional information
6*0e16a31dSJim Jagielski#  regarding copyright ownership.  The ASF licenses this file
7*0e16a31dSJim Jagielski#  to you under the Apache License, Version 2.0 (the
8*0e16a31dSJim Jagielski#  "License"); you may not use this file except in compliance
9*0e16a31dSJim Jagielski#  with the License.  You may obtain a copy of the License at
10*0e16a31dSJim Jagielski#
11*0e16a31dSJim Jagielski#    http://www.apache.org/licenses/LICENSE-2.0
12*0e16a31dSJim Jagielski#
13*0e16a31dSJim Jagielski#  Unless required by applicable law or agreed to in writing,
14*0e16a31dSJim Jagielski#  software distributed under the License is distributed on an
15*0e16a31dSJim Jagielski#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*0e16a31dSJim Jagielski#  KIND, either express or implied.  See the License for the
17*0e16a31dSJim Jagielski#  specific language governing permissions and limitations
18*0e16a31dSJim Jagielski#  under the License.
19*0e16a31dSJim Jagielski#
20*0e16a31dSJim Jagielski#**************************************************************
21*0e16a31dSJim Jagielski
22*0e16a31dSJim Jagielski# usage: make-controls.py -- (re)generate the validator's negative-control packages in fixtures/control/
23*0e16a31dSJim Jagielskiimport os, zipfile
24*0e16a31dSJim Jagielski
25*0e16a31dSJim JagielskiC = os.path.join(os.path.dirname(os.path.abspath(__file__)), "fixtures", "control")
26*0e16a31dSJim JagielskiMANI = ('<?xml version="1.0" encoding="UTF-8"?>\n<manifest:manifest xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0" manifest:version="1.2">'
27*0e16a31dSJim Jagielski        '<manifest:file-entry manifest:full-path="/" manifest:version="1.2" manifest:media-type="application/vnd.oasis.opendocument.text"/>'
28*0e16a31dSJim Jagielski        '<manifest:file-entry manifest:full-path="content.xml" manifest:media-type="text/xml"/></manifest:manifest>\n')
29*0e16a31dSJim JagielskiMATH = ('<?xml version="1.0" encoding="UTF-8"?>\n<!DOCTYPE math:math PUBLIC "-//OpenOffice.org//DTD Modified W3C MathML 1.01//EN" "math.dtd">\n'
30*0e16a31dSJim Jagielski        '<math:math xmlns:math="http://www.w3.org/1998/Math/MathML"><math:semantics><math:mi>x</math:mi></math:semantics></math:math>\n')
31*0e16a31dSJim Jagielski
32*0e16a31dSJim Jagielski
33*0e16a31dSJim Jagielskidef mk(name, ver, body, extra=None):
34*0e16a31dSJim Jagielski    content = ('<?xml version="1.0" encoding="UTF-8"?>\n<office:document-content xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" '
35*0e16a31dSJim Jagielski               'xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" office:version="%s"><office:body><office:text>%s</office:text></office:body></office:document-content>\n') % (ver, body)
36*0e16a31dSJim Jagielski    with zipfile.ZipFile(os.path.join(C, name + ".odt"), "w") as z:
37*0e16a31dSJim Jagielski        z.writestr(zipfile.ZipInfo("mimetype"), "application/vnd.oasis.opendocument.text", compress_type=zipfile.ZIP_STORED)
38*0e16a31dSJim Jagielski        z.writestr("content.xml", content, compress_type=zipfile.ZIP_DEFLATED)
39*0e16a31dSJim Jagielski        z.writestr("META-INF/manifest.xml", MANI, compress_type=zipfile.ZIP_DEFLATED)
40*0e16a31dSJim Jagielski        for n, t in (extra or {}).items():
41*0e16a31dSJim Jagielski            z.writestr(n, t, compress_type=zipfile.ZIP_DEFLATED)
42*0e16a31dSJim Jagielski
43*0e16a31dSJim Jagielski
44*0e16a31dSJim JagielskiOFFNS = ('xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" '
45*0e16a31dSJim Jagielski         'xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" '
46*0e16a31dSJim Jagielski         'xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" '
47*0e16a31dSJim Jagielski         'xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0"')
48*0e16a31dSJim Jagielski
49*0e16a31dSJim Jagielski
50*0e16a31dSJim Jagielskidef mkdoc(name, ext, mime, streams):
51*0e16a31dSJim Jagielski    """A package whose streams are given whole: {"content.xml": (root element, body)}, written with office:version 1.2."""
52*0e16a31dSJim Jagielski    mani = MANI.replace("application/vnd.oasis.opendocument.text", mime)
53*0e16a31dSJim Jagielski    with zipfile.ZipFile(os.path.join(C, name + "." + ext), "w") as z:
54*0e16a31dSJim Jagielski        z.writestr(zipfile.ZipInfo("mimetype"), mime, compress_type=zipfile.ZIP_STORED)
55*0e16a31dSJim Jagielski        for n, (root, body) in streams.items():
56*0e16a31dSJim Jagielski            z.writestr(n, '<?xml version="1.0" encoding="UTF-8"?>\n<%s %s office:version="1.2">%s</%s>\n' % (root, OFFNS, body, root), compress_type=zipfile.ZIP_DEFLATED)
57*0e16a31dSJim Jagielski        z.writestr("META-INF/manifest.xml", mani, compress_type=zipfile.ZIP_DEFLATED)
58*0e16a31dSJim Jagielski
59*0e16a31dSJim Jagielski
60*0e16a31dSJim Jagielskios.makedirs(C, exist_ok=True)
61*0e16a31dSJim Jagielskimk("good", "1.2", "<text:p>hi</text:p>")
62*0e16a31dSJim Jagielskimk("bad", "1.2", "<text:bogus/>")
63*0e16a31dSJim Jagielskimk("wrongver", "1.1", "<text:p>hi</text:p>")
64*0e16a31dSJim Jagielski# text:drop-down is new in ODF 1.3 (OFFICE-3881): invalid in 1.2, valid in 1.3 and 1.4
65*0e16a31dSJim Jagielskimk("new13", "1.2", '<text:p><text:drop-down text:name="d"><text:label text:value="a"/></text:drop-down></text:p>')
66*0e16a31dSJim Jagielski# ODF 1.2 Part 1 2.2.1 B.4: an embedded object whose content.xml is MathML
67*0e16a31dSJim Jagielskimk("mathobj", "1.2", "<text:p>hi</text:p>", {"Object 1/content.xml": MATH})
68*0e16a31dSJim Jagielski# ODF 1.2 Part 1 2.2.1 D.1/D.2: checked by idcheck.py, not by the schema
69*0e16a31dSJim Jagielskimk("goodid", "1.2", '<text:p xml:id="a1">x</text:p><text:p xml:id=" b-2.c ">y</text:p>')
70*0e16a31dSJim Jagielskimk("dupid", "1.2", '<text:p xml:id="a1">x</text:p><text:p xml:id=" a1 ">y</text:p>')
71*0e16a31dSJim Jagielskimk("badid", "1.2", '<text:p xml:id="1abc">x</text:p>')
72*0e16a31dSJim Jagielskimk("badid2", "1.2", '<text:p xml:id="a b">x</text:p>')
73*0e16a31dSJim Jagielskimk("badns", "1.2", "<text:p><zz:span/></text:p>")
74*0e16a31dSJim Jagielski# Part 3 2.2.1 F: signature files are held to the same rules (validate.py does not look at them)
75*0e16a31dSJim Jagielskimk("badsig", "1.2", "<text:p>hi</text:p>", {"META-INF/documentsignatures.xml": '<a><b xml:id="x"/><b xml:id="x"/></a>'})
76*0e16a31dSJim Jagielski# Part 1 2.2.2 B.1: valid as an extended document only (foreign attribute, foreign element in a paragraph, foreign element elsewhere)
77*0e16a31dSJim Jagielskimk("extforeign", "1.2", '<text:p xmlns:foo="urn:foo" foo:x="1">a<foo:y>b</foo:y>c</text:p><foo:w xmlns:foo="urn:foo">z<text:p>q</text:p></foo:w>')
78*0e16a31dSJim JagielskiTEXT = "application/vnd.oasis.opendocument.text"
79*0e16a31dSJim Jagielski# meta:creator-initials in office:annotation is new in ODF 1.3; baseinit is the same note without it
80*0e16a31dSJim JagielskiANN = '<office:body><office:text><text:p><office:annotation><dc:creator>A</dc:creator>%s<text:p>n</text:p></office:annotation>x</text:p></office:text></office:body>'
81*0e16a31dSJim Jagielskifor n, ini in (("baseinit", ""), ("newinit", "<meta:creator-initials>AB</meta:creator-initials>")):
82*0e16a31dSJim Jagielski    mkdoc(n, "odt", TEXT, {"content.xml": ("office:document-content", ANN % ini)})
83*0e16a31dSJim Jagielski# chart:coordinate-region (inner plot position) is new in 1.3; baseregion is the same chart without it
84*0e16a31dSJim JagielskiCHART = "application/vnd.oasis.opendocument.chart"
85*0e16a31dSJim Jagielskifor n, region in (("baseregion", ""), ("newregion", '<chart:coordinate-region svg:x="1cm" svg:y="1cm" svg:width="5cm" svg:height="4cm"/>')):
86*0e16a31dSJim Jagielski    mkdoc(n, "odc", CHART, {"content.xml": ("office:document-content", '<office:body><office:chart><chart:chart chart:class="chart:bar"><chart:plot-area>%s</chart:plot-area></chart:chart></office:chart></office:body>' % region)})
87*0e16a31dSJim Jagielski# 1.3 makes style:scale-to, style:scale-to-pages and the pair scale-to-X/scale-to-Y mutually exclusive (OFFICE-3857); 1.2 has no scale-to-X/Y
88*0e16a31dSJim Jagielskifor n, attrs in (("scaleone", 'style:scale-to="80%"'), ("scalexy", 'style:scale-to-X="2" style:scale-to-Y="3"'), ("scaleboth", 'style:scale-to-X="2" style:scale-to-Y="3" style:scale-to="80%"')):
89*0e16a31dSJim Jagielski    mkdoc(n, "odt", TEXT, {"content.xml": ("office:document-content", "<office:body><office:text><text:p>hi</text:p></office:text></office:body>"),
90*0e16a31dSJim Jagielski                          "styles.xml": ("office:document-styles", '<office:automatic-styles><style:page-layout style:name="pm1"><style:page-layout-properties %s/></style:page-layout></office:automatic-styles>' % attrs)})
91