Blame lib/dbtexmf/core/xmlparser.py

Packit Service 76cb02
import os
Packit Service 76cb02
import re
Packit Service 76cb02
import xml.etree.ElementTree as ET
Packit Service cd7d79
from dbtexmf.core.txtparser import texinputs_parse
Packit Service 76cb02
Packit Service 76cb02
class BaseOption:
Packit Service 76cb02
    def __init__(self, config, optname):
Packit Service 76cb02
        self.config = config
Packit Service 76cb02
        self.optname = optname
Packit Service 76cb02
        self._value = None
Packit Service 76cb02
Packit Service 76cb02
    def optvalue(self):
Packit Service 76cb02
        return self._value
Packit Service 76cb02
Packit Service 76cb02
    def get(self, what, default=None):
Packit Service 76cb02
        return None
Packit Service 76cb02
Packit Service 76cb02
    def options(self):
Packit Service 76cb02
        value = self.optvalue()
Packit Service 76cb02
        if self.optname and value:
Packit Service 76cb02
            return ["%s=%s" % (self.optname, value)]
Packit Service 76cb02
        else:
Packit Service 76cb02
            return []
Packit Service 76cb02
Packit Service 76cb02
    def fromnode(self, xmlnode):
Packit Service 76cb02
        self._value = xmlnode.text
Packit Service 76cb02
Packit Service 76cb02
    def modules(self):
Packit Service 76cb02
        return {}
Packit Service 76cb02
Packit Service 76cb02
class CommandConfig:
Packit Service 76cb02
    def __init__(self, config, type="command"):
Packit Service 76cb02
        self.config = config
Packit Service 76cb02
        self.type = type
Packit Service 76cb02
        self.args = []
Packit Service 76cb02
        self.stdin = None
Packit Service 76cb02
        self.stdout = None
Packit Service 76cb02
        self.shell = False
Packit Service 76cb02
Packit Service 76cb02
    def options(self):
Packit Service 76cb02
        return self.args
Packit Service 76cb02
Packit Service 76cb02
    def modules(self):
Packit Service 76cb02
        return {}
Packit Service 76cb02
Packit Service 76cb02
    def fromnode(self, xmlnode):
Packit Service 76cb02
        self.stdin = xmlnode.get("input")
Packit Service 76cb02
        self.stdout = xmlnode.get("output")
Packit Service 76cb02
        self.shell = xmlnode.get("shell")
Packit Service 76cb02
        args = (xmlnode.text or "").split()
Packit Service 76cb02
        for arg in xmlnode:
Packit Service 76cb02
            if arg.text: args.append(arg.text)
Packit Service 76cb02
            args.extend((arg.tail or "").split())
Packit Service 76cb02
        self.args = args
Packit Service 76cb02
Packit Service 76cb02
class TexStyle(BaseOption):
Packit Service 76cb02
    def __init__(self, config, optname):
Packit Service 76cb02
        BaseOption.__init__(self, config, optname)
Packit Service 76cb02
        self.filepath = ""
Packit Service 76cb02
Packit Service 76cb02
    def optvalue(self):
Packit Service 76cb02
        return self.filepath
Packit Service 76cb02
Packit Service 76cb02
    def fromnode(self, xmlnode):
Packit Service 76cb02
        self.filepath = xmlnode.get("fileref") or xmlnode.get("use")
Packit Service 76cb02
Packit Service 76cb02
class TexPath(BaseOption):
Packit Service 76cb02
    def __init__(self, config, optname):
Packit Service 76cb02
        BaseOption.__init__(self, config, optname)
Packit Service 76cb02
        self.paths = []
Packit Service 76cb02
Packit Service 76cb02
    def optvalue(self):
Packit Service 76cb02
        return os.pathsep.join(self.paths)
Packit Service 76cb02
Packit Service 76cb02
    def fromnode(self, xmlnode):
Packit Service 76cb02
        if not(xmlnode.text): return
Packit Service 76cb02
        self.paths = texinputs_parse(xmlnode.text, self.config.basedir)
Packit Service 76cb02
Packit Service 76cb02
class FilePath(BaseOption):
Packit Service 76cb02
    def __init__(self, config, optname):
Packit Service 76cb02
        BaseOption.__init__(self, config, optname)
Packit Service 76cb02
        self.filepath = ""
Packit Service 76cb02
Packit Service 76cb02
    def optvalue(self):
Packit Service 76cb02
        return self.filepath
Packit Service 76cb02
Packit Service 76cb02
    def fromnode(self, xmlnode):
Packit Service 76cb02
        filepath = xmlnode.get("fileref")
Packit Service 76cb02
        if not(filepath):
Packit Service 76cb02
            return
Packit Service 76cb02
        if not(os.path.isabs(filepath)):
Packit Service 76cb02
            filepath = os.path.normpath(os.path.join(self.config.basedir,
Packit Service 76cb02
                                                     filepath))
Packit Service 76cb02
        self.filepath = filepath
Packit Service 76cb02
Packit Service 76cb02
Packit Service 76cb02
class ModuleConfig(BaseOption):
Packit Service 76cb02
    def __init__(self, config, optname):
Packit Service 76cb02
        BaseOption.__init__(self, config, optname)
Packit Service 76cb02
        self.commands = []
Packit Service 76cb02
        self.extra_args = None
Packit Service 76cb02
        self.module_name = ""
Packit Service 76cb02
        self.module_file = ""
Packit Service 76cb02
Packit Service 76cb02
    def optvalue(self):
Packit Service 76cb02
        return self.module_name or self.module_file
Packit Service 76cb02
Packit Service 76cb02
    def modules(self):
Packit Service 76cb02
        if self.module_name:
Packit Service 76cb02
            return {self.module_name: self}
Packit Service 76cb02
        else:
Packit Service 76cb02
            return {}
Packit Service 76cb02
Packit Service 76cb02
    def fromnode(self, xmlnode):
Packit Service 76cb02
        ns = { "x": self.config.xmlns }
Packit Service 76cb02
        self._handle_location(xmlnode)
Packit Service 76cb02
        xmlopts = xmlnode.find("x:options", ns)
Packit Service 76cb02
        xmlcmds = xmlnode.find("x:command", ns)
Packit Service 76cb02
        xmlchain = xmlnode.find("x:commandchain", ns)
Packit Service 76cb02
        if not(xmlchain is None):
Packit Service 76cb02
            xmlcmds = xmlchain.findall("x:command", ns)
Packit Service 76cb02
            for cmd in xmlcmds:
Packit Service 76cb02
                args = CommandConfig(self.config)
Packit Service 76cb02
                args.fromnode(cmd)
Packit Service 76cb02
                self.commands.append(args)
Packit Service 76cb02
        elif not(xmlcmds is None):
Packit Service 76cb02
            args = CommandConfig(self.config)
Packit Service 76cb02
            args.fromnode(xmlcmds)
Packit Service 76cb02
            self.commands.append(args)
Packit Service 76cb02
        elif not(xmlopts is None):
Packit Service 76cb02
            # FIXME
Packit Service 76cb02
            self.extra_args = CommandConfig(self.config, type="option")
Packit Service 76cb02
            self.extra_args.fromnode(xmlopts)
Packit Service 76cb02
Packit Service 76cb02
    def _handle_location(self, xmlnode):
Packit Service 76cb02
        self.module_name = xmlnode.get("use")
Packit Service 76cb02
        self.module_file = xmlnode.get("fileref")
Packit Service 76cb02
        if not(self.module_name) and self.module_file:
Packit Service 76cb02
            p = FilePath(self.config, "")
Packit Service 76cb02
            p.fromnode(xmlnode)
Packit Service 76cb02
            self.module_file = p.filepath
Packit Service 76cb02
Packit Service 76cb02
class ImageConverterConfig(ModuleConfig):
Packit Service 76cb02
    def __init__(self, config, optname):
Packit Service 76cb02
        ModuleConfig.__init__(self, config, optname)
Packit Service 76cb02
Packit Service 76cb02
    def __repr__(self):
Packit Service 76cb02
        return self.module_name
Packit Service 76cb02
Packit Service 76cb02
    def fromnode(self, xmlnode):
Packit Service 76cb02
        self.imgsrc = xmlnode.get("src")
Packit Service 76cb02
        self.imgdst = xmlnode.get("dst")
Packit Service 76cb02
        self.docformat = xmlnode.get("docformat") or "*"
Packit Service 76cb02
        self.backend = xmlnode.get("backend") or "*"
Packit Service 76cb02
        ModuleConfig.fromnode(self, xmlnode)
Packit Service 76cb02
        name = "%s/%s/%s/%s" % (self.imgsrc, self.imgdst,
Packit Service 76cb02
                                self.docformat, self.backend)
Packit Service 76cb02
        self.module_name = name
Packit Service 76cb02
Packit Service 76cb02
class ImageFormatConfig(BaseOption):
Packit Service 76cb02
    def __init__(self, config, optname):
Packit Service 76cb02
        BaseOption.__init__(self, config, optname)
Packit Service 76cb02
        self.imgsrc = ""
Packit Service 76cb02
        self.imgdst = ""
Packit Service 76cb02
        self.docformat = ""
Packit Service 76cb02
        self.backend = ""
Packit Service 76cb02
Packit Service 76cb02
    def fromnode(self, xmlnode):
Packit Service 76cb02
        self.imgsrc = xmlnode.get("src")
Packit Service 76cb02
        self.imgdst = xmlnode.get("dst")
Packit Service 76cb02
        self.docformat = xmlnode.get("docformat") or "*"
Packit Service 76cb02
        self.backend = xmlnode.get("backend") or "*"
Packit Service 76cb02
Packit Service 76cb02
class XsltEngineConfig(ModuleConfig):
Packit Service 76cb02
    def __init__(self, config, optname):
Packit Service 76cb02
        ModuleConfig.__init__(self, config, optname)
Packit Service 76cb02
Packit Service 76cb02
    def __repr__(self):
Packit Service 76cb02
        return self.module_name
Packit Service 76cb02
Packit Service 76cb02
    def fromnode(self, xmlnode):
Packit Service 76cb02
        self.param_format = xmlnode.get("param-format")
Packit Service 76cb02
        ModuleConfig.fromnode(self, xmlnode)
Packit Service 76cb02
        if not(self.module_name or self.module_file):
Packit Service 76cb02
            self.module_name = "xsltconf"
Packit Service 76cb02
Packit Service 76cb02
class XmlConfigGroup:
Packit Service 76cb02
    node_parsers = {}
Packit Service 76cb02
Packit Service 76cb02
    def __init__(self, config):
Packit Service 76cb02
        self.config = config
Packit Service 76cb02
        self.tagname = ""
Packit Service 76cb02
        self.infos = {}
Packit Service 76cb02
Packit Service 76cb02
    def get(self, tag, default=""):
Packit Service 76cb02
        if default == "": default = BaseOption(self, "")
Packit Service 76cb02
        return self.infos.get(tag, default)
Packit Service 76cb02
Packit Service 76cb02
    def _register(self, xmlnode, info):
Packit Service 76cb02
        tag = self.strip_ns(xmlnode.tag)
Packit Service 76cb02
        taglist = self.infos.get(tag, [])
Packit Service 76cb02
        taglist.append(info)
Packit Service 76cb02
        self.infos[tag] = taglist
Packit Service 76cb02
Packit Service 76cb02
    def strip_ns(self, tag):
Packit Service 76cb02
        return self.config.strip_ns(tag)
Packit Service 76cb02
Packit Service 76cb02
    def options(self):
Packit Service 76cb02
        opts = []
Packit Service 76cb02
        for parsers in self.infos.values():
Packit Service 76cb02
            for parser in parsers:
Packit Service 76cb02
                opts.extend(parser.options())
Packit Service 76cb02
        return opts
Packit Service 76cb02
Packit Service 76cb02
    def modules(self):
Packit Service 76cb02
        mods = {}
Packit Service 76cb02
        for parsers in self.infos.values():
Packit Service 76cb02
            for parser in parsers:
Packit Service 76cb02
                mods.update(parser.modules())
Packit Service 76cb02
        return mods
Packit Service 76cb02
Packit Service 76cb02
    def fromnode(self, xmlnode):
Packit Service 76cb02
        self.tagname = xmlnode.tag
Packit Service 76cb02
        for child in xmlnode:
Packit Service 76cb02
            found = self.node_parsers.get(self.strip_ns(child.tag))
Packit Service 76cb02
            if found:
Packit Service 76cb02
                optname, parser_cls = found
Packit Service 76cb02
                parser = parser_cls(self.config, optname)
Packit Service 76cb02
                parser.fromnode(child)
Packit Service 76cb02
                self._register(child, parser)
Packit Service 76cb02
Packit Service 76cb02
class LatexConfig(XmlConfigGroup):
Packit Service 76cb02
    node_parsers = {
Packit Service 76cb02
        "texinputs":  ("--texinputs", TexPath),
Packit Service 76cb02
        "bibinputs":  ("--bib-path", TexPath),
Packit Service 76cb02
        "bstinputs":  ("--bst-path", TexPath),
Packit Service 76cb02
        "texstyle":   ("--texstyle", TexStyle),
Packit Service 76cb02
        "indexstyle": ("--indexstyle", FilePath),
Packit Service 76cb02
        "backend":    ("--backend", ModuleConfig),
Packit Service 76cb02
        "texpost":    ("--texpost", ModuleConfig)
Packit Service 76cb02
    }
Packit Service 76cb02
Packit Service 76cb02
class XsltConfig(XmlConfigGroup):
Packit Service 76cb02
    node_parsers = {
Packit Service 76cb02
        "stylesheet": ("--xsl-user", FilePath),
Packit Service 76cb02
        "engine":     ("--xslt", XsltEngineConfig)
Packit Service 76cb02
    }
Packit Service 76cb02
Packit Service 76cb02
class ImageConfig(XmlConfigGroup):
Packit Service 76cb02
    node_parsers = {
Packit Service 76cb02
        "figpath": ("--fig-path", FilePath),
Packit Service 76cb02
        "figformat": ("--fig-format", BaseOption),
Packit Service 76cb02
        "converter": ("", ImageConverterConfig),
Packit Service 76cb02
        "formatrule": ("", ImageFormatConfig)
Packit Service 76cb02
    }
Packit Service 76cb02
Packit Service 76cb02
Packit Service 76cb02
class XmlConfig:
Packit Service 76cb02
    """
Packit Service 76cb02
    Parses an XML configuration file and stores its data in
Packit Service 76cb02
    configuration objects.
Packit Service 76cb02
    """
Packit Service 76cb02
    node_parsers = {
Packit Service 76cb02
        "latex": LatexConfig,
Packit Service 76cb02
        "xslt": XsltConfig,
Packit Service 76cb02
        "imagedata": ImageConfig,
Packit Service 76cb02
        "options": CommandConfig
Packit Service 76cb02
    }
Packit Service 76cb02
    xmlns = "http://dblatex.sourceforge.net/config"
Packit Service 76cb02
    root_tag = "config"
Packit Service 76cb02
Packit Service 76cb02
    def __init__(self):
Packit Service 76cb02
        self.basedir = ""
Packit Service 76cb02
        self.infos = {}
Packit Service 76cb02
Packit Service 76cb02
    def _register(self, xmlnode, info):
Packit Service 76cb02
        self.infos[self.strip_ns(xmlnode.tag)] = info
Packit Service 76cb02
Packit Service 76cb02
    def get(self, tag, default=""):
Packit Service 76cb02
        if default == "": default = BaseOption(self, "")
Packit Service 76cb02
        return self.infos.get(tag, default)
Packit Service 76cb02
Packit Service 76cb02
    def options(self):
Packit Service 76cb02
        opts = []
Packit Service 76cb02
        for parser in self.infos.values():
Packit Service 76cb02
            opts.extend(parser.options())
Packit Service 76cb02
        return opts
Packit Service 76cb02
Packit Service 76cb02
    def modules(self):
Packit Service 76cb02
        mods = {}
Packit Service 76cb02
        for parser in self.infos.values():
Packit Service 76cb02
            mods.update(parser.modules())
Packit Service 76cb02
        return mods
Packit Service 76cb02
Packit Service 76cb02
    def strip_ns(self, tag):
Packit Service 76cb02
        return tag.replace("{%s}" % self.xmlns, "", 1)
Packit Service 76cb02
Packit Service 76cb02
    def fromfile(self, filename):
Packit Service 76cb02
        self.basedir = os.path.dirname(os.path.realpath(filename))
Packit Service 76cb02
Packit Service 76cb02
        document = ET.parse(filename)
Packit Service 76cb02
        root = document.getroot()
Packit Service 76cb02
        self._check_root(root.tag)
Packit Service 76cb02
        for child in root:
Packit Service 76cb02
            parser_cls = self.node_parsers.get(self.strip_ns(child.tag))
Packit Service 76cb02
            if parser_cls:
Packit Service 76cb02
                parser = parser_cls(self)
Packit Service 76cb02
                parser.fromnode(child)
Packit Service 76cb02
                self._register(child, parser)
Packit Service 76cb02
Packit Service 76cb02
    def _check_root(self, root):
Packit Service 76cb02
        xmlns, tag = self._split_xmlns(root)
Packit Service 76cb02
        if tag != self.root_tag:
Packit Service 76cb02
            raise ValueError("Expect the XML config root element being '%s'" % \
Packit Service 76cb02
                             self.root_tag)
Packit Service 76cb02
        if xmlns and xmlns != self.xmlns:
Packit Service 76cb02
            raise ValueError("Invalid XML config xmlns: '%s'" % xmlns)
Packit Service 76cb02
Packit Service 76cb02
    def _split_xmlns(self, tag):
Packit Service 76cb02
        m = re.match("{([^}]+)}(.*)", tag)
Packit Service 76cb02
        if m:
Packit Service 76cb02
            return m.group(1), m.group(2)
Packit Service 76cb02
        else:
Packit Service 76cb02
            return "", tag
Packit Service 76cb02