#!/usr/bin/env python # # This file is part of the LibreOffice project. # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # from xml.dom import minidom import sys def getElementsByTagNamesNS(parent, ns, names, ret=minidom.NodeList()): for node in parent.childNodes: if node.nodeType == minidom.Node.ELEMENT_NODE and node.namespaceURI == ns and node.tagName in names: ret.append(node) getElementsByTagNamesNS(node, ns, names, ret) return ret def createFastChildContextFromFactory(model): print("""uno::Reference OOXMLFactory::createFastChildContextFromFactory (OOXMLFastContextHandler* pHandler, OOXMLFactory_ns::Pointer_t pFactory, Token_t Element) { uno::Reference aResult; const Id nDefine = pHandler->getDefine(); if (pFactory.get() != NULL) { ResourceType nResource; Id nElementId; if (pFactory->getElementId(nDefine, Element, nResource, nElementId)) { const Id nId = pFactory->getResourceId(nDefine, Element); switch (nResource) {""") resources = [ "List", "Integer", "Hex", "HexColor", "String", "TwipsMeasure_asSigned", "TwipsMeasure_asZero", "HpsMeasure", "Boolean", "MeasurementOrPercent", ] for resource in [r.getAttribute("resource") for r in model.getElementsByTagName("resource")]: if resource not in resources: resources.append(resource) print(""" case ResourceType::%s: aResult.set(OOXMLFastHelper::createAndSetParentAndDefine(pHandler, Element, nId, nElementId)); break;""" % (resource, resource)) print(""" case ResourceType::Any: aResult.set(createFastChildContextFromStart(pHandler, Element)); break; default: break; } } } return aResult; } """) def getFactoryForNamespace(model): print("""OOXMLFactory_ns::Pointer_t OOXMLFactory::getFactoryForNamespace(Id nId) { OOXMLFactory_ns::Pointer_t pResult; switch (oox::getNamespace(nId)) {""") for namespace in [ns.getAttribute("name") for ns in model.getElementsByTagName("namespace")]: id = namespace.replace('-', '_') print(""" case NN_%s: pResult = OOXMLFactory_%s::getInstance(); break;""" % (id, id)) print(""" default: break; } return pResult; } """) def createFastChildContextFromStart(model): print("""uno::Reference OOXMLFactory::createFastChildContextFromStart (OOXMLFastContextHandler* pHandler, Token_t Element) { uno::Reference aResult; OOXMLFactory_ns::Pointer_t pFactory; """) for namespace in [ns.getAttribute("name") for ns in model.getElementsByTagName("namespace")]: id = namespace.replace('-', '_') print(""" if (!aResult.is()) { pFactory = getFactoryForNamespace(NN_%s); aResult.set(createFastChildContextFromFactory(pHandler, pFactory, Element)); }""" % id) print(""" return aResult; } """) def fastTokenToId(model): print(""" std::string fastTokenToId(sal_uInt32 nToken) { std::string sResult; #ifdef DBG_UTIL switch (oox::getNamespace(nToken)) {""") aliases = [] for alias in sorted(ooxUrlAliases.values()): if alias not in aliases: aliases.append(alias) print(""" case oox::NMSP_%s: sResult += "%s:"; break;""" % (alias, alias)) print(""" } switch (nToken & 0xffff) {""") tokens = [""] for token in [t.getAttribute("localname") for t in getElementsByTagNamesNS(model, "http://relaxng.org/ns/structure/1.0", ["element", "attribute"])]: if token not in tokens: tokens.append(token) print(""" case oox::XML_%s: sResult += "%s"; break;""" % (token, token)) print(""" } #else (void)nToken; #endif return sResult; } """) def getFastParser(): print("""uno::Reference OOXMLStreamImpl::getFastParser() { if (!mxFastParser.is()) { mxFastParser = css::xml::sax::FastParser::create(mxContext); // the threaded parser is about 20% slower loading writer documents css::uno::Reference< css::lang::XInitialization > xInit( mxFastParser, css::uno::UNO_QUERY_THROW ); css::uno::Sequence< css::uno::Any > args{ css::uno::Any(OUString("DisableThreadedParser")) }; xInit->initialize(args); """) for url in sorted(ooxUrlAliases.keys()): print(""" mxFastParser->registerNamespace("%s", oox::NMSP_%s);""" % (url, ooxUrlAliases[url])) print(""" } return mxFastParser; } /// @endcond }}""") def createImpl(model): print(""" #include #include #include "ooxml/OOXMLFactory.hxx" #include "ooxml/OOXMLFastHelper.hxx" #include "ooxml/OOXMLStreamImpl.hxx" """) for namespace in [ns.getAttribute("name") for ns in model.getElementsByTagName("namespace")]: print('#include "OOXMLFactory_%s.hxx"' % namespace) print("""namespace writerfilter { namespace ooxml { using namespace com::sun::star; /// @cond GENERATED """) createFastChildContextFromFactory(model) getFactoryForNamespace(model) createFastChildContextFromStart(model) fastTokenToId(model) getFastParser() def parseNamespaces(fro): sock = open(fro) for i in sock.readlines(): line = i.strip() alias, url = line.split(' ')[1:] # first column is ID, not interesting for us ooxUrlAliases[url] = alias sock.close() namespacesPath = sys.argv[1] ooxUrlAliases = {} parseNamespaces(namespacesPath) modelPath = sys.argv[2] model = minidom.parse(modelPath) createImpl(model) # vim:set shiftwidth=4 softtabstop=4 expandtab: