1#!/usr/local/bin/python3.8
2#
3# This file is part of the LibreOffice project.
4#
5# This Source Code Form is subject to the terms of the Mozilla Public
6# License, v. 2.0. If a copy of the MPL was not distributed with this
7# file, You can obtain one at http://mozilla.org/MPL/2.0/.
8#
9
10from xml.dom import minidom
11import sys
12
13
14def prefixForGrammar(namespace):
15    ns = namespace.getElementsByTagName("grammar")[0].getAttribute("ns")
16    return ooxUrlAliases[ns]
17
18
19def parseNamespaceAliases(node):
20    ret = {}
21    for k, v in list(node.attributes.items()):
22        if k.startswith("xmlns:"):
23            ret[k.replace('xmlns:', '')] = v
24    return ret
25
26
27def parseNamespaces(fro):
28    sock = open(fro)
29    for i in sock.readlines():
30        line = i.strip()
31        alias, url = line.split(' ')[1:]
32        ooxUrlAliases[url] = alias
33    sock.close()
34
35
36def check(model):
37    defines = [i.getAttribute("name") for i in model.getElementsByTagName("define")]
38    for reference in [i.getAttribute("name") for i in model.getElementsByTagName("ref")]:
39        if reference not in defines:
40            raise Exception("Unknown define element with name '%s'" % reference)
41    for start in [i.getAttribute("name") for i in model.getElementsByTagName("start")]:
42        if start not in defines:
43            raise Exception("Unknown start element with name '%s'" % start)
44
45
46def preprocess(model):
47    modelNode = [i for i in model.childNodes if i.localName == "model"][0]
48    # Alias -> URL, based on "xmlns:" attributes.
49    modelNamespaceAliases = parseNamespaceAliases(modelNode)
50    for i in modelNode.getElementsByTagName("namespace"):
51        grammarprefix = prefixForGrammar(i)
52
53        grammar = i.getElementsByTagName("grammar")[0]
54
55        for j in i.getElementsByTagName("element") + i.getElementsByTagName("attribute"):
56            # prefix
57            prefix = ""
58            if ":" in j.getAttribute("name"):
59                nameprefix = j.getAttribute("name").split(':')[0]
60                prefix = ooxUrlAliases[modelNamespaceAliases[nameprefix]]
61            elif j.localName == "attribute":
62                if grammar.getAttribute("attributeFormDefault") == "qualified":
63                    prefix = grammarprefix
64            else:
65                prefix = grammarprefix
66
67            # localname
68            if ":" in j.getAttribute("name"):
69                localname = j.getAttribute("name").split(':')[1]
70            else:
71                localname = j.getAttribute("name")
72
73            # set the attributes
74            j.setAttribute("prefix", prefix)
75            j.setAttribute("localname", localname)
76
77
78namespacesPath = sys.argv[1]
79modelPath = sys.argv[2]
80
81# URL -> alias, from oox
82ooxUrlAliases = {}
83parseNamespaces(namespacesPath)
84
85model = minidom.parse(modelPath)
86check(model)
87preprocess(model)
88model.writexml(sys.stdout)
89
90# vim:set shiftwidth=4 softtabstop=4 expandtab:
91