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