Beispiel #1
0
    def externaldocument (self, dict):
        # .aux document needed to cross-ref with xr
        auxfile = dict["arg"] + ".aux"
        texfile = dict["arg"] + ".tex"

        # Ignore the dependency if no tex source found
        if not(os.path.isfile(texfile)):
            msg.log(_("file %s is required by xr package but not found")\
                    % texfile, pkg="xr")
            return

        # Ask to compile the related .tex file to have the .aux 
        texdep = Latex(self.env)
        texdep.set_source(texfile)
        texdep.batch = self.doc.batch
        texdep.encoding = self.doc.encoding
        texdep.draft_only = True # Final output not required here
        for m in self.texmodules:
            texdep.modules.register(m)
        # Load other modules from source, except xr to avoid loops
        texdep.prepare(exclude_mods=["xr-hyper"])

        # Add the .aux as an expected input for compiling the doc
        self.doc.sources[auxfile] = texdep
        msg.log(_(
            "dependency %s added for external references") % auxfile, pkg="xr")
Beispiel #2
0
 def clean (self):
     """
     Remove all generated files related to the index.
     """
     for file in self.source, self.target, self.transcript:
         if exists(file):
             msg.log(_("removing %s") % file, pkg="index")
             os.unlink(file)
Beispiel #3
0
 def post_compile (self):
     """
     This method runs BibTeX if needed to solve undefined citations. If it
     was run, then force a new LaTeX compilation.
     """
     if not self.bibtex_needed():
         msg.log(_("no BibTeXing needed"), pkg="bibtex")
         return 0
     return self.run()
Beispiel #4
0
 def post_compile(self):
     """
     This method runs BibTeX if needed to solve undefined citations. If it
     was run, then force a new LaTeX compilation.
     """
     if not self.bibtex_needed():
         msg.log(_("no BibTeXing needed"), pkg="bibtex")
         return 0
     return self.run()
Beispiel #5
0
 def remove_suffixes (self, list):
     """
     Remove all files derived from the main source with one of the
     specified suffixes.
     """
     for suffix in list:
         file = self.src_base + suffix
         if os.path.exists(file):
             msg.log(_("removing %s") % file)
             os.unlink(file)
Beispiel #6
0
 def remove_suffixes(self, list):
     """
     Remove all files derived from the main source with one of the
     specified suffixes.
     """
     for suffix in list:
         file = self.src_base + suffix
         if os.path.exists(file):
             msg.log(_("removing %s") % file)
             os.unlink(file)
Beispiel #7
0
 def newindex (self, dict):
     """
     Register a new index.
     """
     m = re_newindex.match(dict["line"])
     if not m:
         return
     index = dict["arg"]
     d = m.groupdict()
     self.register(index, d["idx"], d["ind"], "ilg")
     msg.log(_("index %s registered") % index, pkg="index")
Beispiel #8
0
 def clean (self):
     """
     Remove the files produced by this rule and recursively clean all
     dependencies.
     """
     for file in self.prods:
         if os.path.exists(file):
             msg.log(_("removing %s") % file)
             os.unlink(file)
     for src in self.sources.values():
         src.clean()
     self.date = None
Beispiel #9
0
    def last_compile(self):
        """
        Run the module-specific operations that are to be performed after
        the last compilation of the main source. Returns true on failure.
        """
        msg.log(_("running last-compilation scripts..."))

        for mod in self.modules.objects.values():
            if mod.last_compile():
                self.failed_module = mod
                return 1
        return 0
Beispiel #10
0
    def last_compile(self):
        """
        Run the module-specific operations that are to be performed after
        the last compilation of the main source. Returns true on failure.
        """
        msg.log(_("running last-compilation scripts..."))

        for mod in self.modules.objects.values():
            if mod.last_compile():
                self.failed_module = mod
                return 1
        return 0
Beispiel #11
0
    def clean(self):
        """
        Remove all files that are produced by compilation.
        """
        self.remove_suffixes([".log", ".aux", ".toc", ".lof", ".lot",
                              ".out", ".glo", ".cb"])

        msg.log(_("cleaning additional files..."))
        # for dep in self.sources.values():
        #     dep.clean()

        for mod in self.modules.objects.values():
            mod.clean()
Beispiel #12
0
    def clean(self):
        """
        Remove all files that are produced by compilation.
        """
        self.remove_suffixes(
            [".log", ".aux", ".toc", ".lof", ".lot", ".out", ".glo", ".cb"])

        msg.log(_("cleaning additional files..."))
        # for dep in self.sources.values():
        #     dep.clean()

        for mod in self.modules.objects.values():
            mod.clean()
Beispiel #13
0
 def compile(self):
     self.must_compile = 0
     cmd = [self.program] + self.opts + [os.path.basename(self.srcfile)]
     msg.log(" ".join(cmd))
     rc = subprocess.call(cmd, stdout=msg.stdout)
     if rc != 0:
         msg.error(_("%s failed") % self.program)
     # Whatever the result is, read the log file
     if self.log.read(self.logfile):
         msg.error(_("Could not run %s.") % self.program)
         return 1
     if self.log.errors():
         return 1
     return rc
Beispiel #14
0
 def compile(self):
     self.must_compile = 0
     cmd = [self.program] + self.opts + [os.path.basename(self.srcfile)]
     msg.log(" ".join(cmd))
     rc = subprocess.call(cmd, stdout=msg.stdout)
     if rc != 0:
         msg.error(_("%s failed") % self.program)
     # Whatever the result is, read the log file
     if self.log.read(self.logfile):
         msg.error(_("Could not run %s.") % self.program)
         return 1
     if self.log.errors():
         return 1
     return rc
Beispiel #15
0
    def register(self, name, dict={}):
        """
        Attempt to register a package with the specified name. If a module is
        found, create an object from the module's class called `Module',
        passing it the environment and `dict' as arguments, and execute all
        delayed commands for this module. The dictionary describes the
        command that caused the registration.
        """
        if self.has_key(name):
            msg.debug(_("module %s already registered") % name)
            return 2

        # First look for a script

        moddir = ""
        mod = None
        for path in "", join(moddir, "modules"):
            file = join(path, name + ".rub")
            if exists(file):
                mod = ScriptModule(self.env, file)
                msg.log(_("script module %s registered") % name)
                break

        # Then look for a Python module

        if not mod:
            if Plugins.register(self, name) == 0:
                msg.debug(_("no support found for %s") % name)
                return 0
            mod = self.modules[name].Module(self.env, dict)
            msg.log(_("built-in module %s registered") % name)

        # Run any delayed commands.

        if self.commands.has_key(name):
            for (cmd, args, vars) in self.commands[name]:
                msg.push_pos(vars)
                try:
                    mod.command(cmd, args)
                except AttributeError:
                    msg.warn(_("unknown directive '%s.%s'") % (name, cmd))
                except TypeError:
                    msg.warn(_("wrong syntax for '%s.%s'") % (name, cmd))
                msg.pop_pos()
            del self.commands[name]

        self.objects[name] = mod
        return 1
Beispiel #16
0
    def register (self, name, dict={}):
        """
        Attempt to register a package with the specified name. If a module is
        found, create an object from the module's class called `Module',
        passing it the environment and `dict' as arguments, and execute all
        delayed commands for this module. The dictionary describes the
        command that caused the registration.
        """
        if self.has_key(name):
            msg.debug(_("module %s already registered") % name)
            return 2

        # First look for a script

        moddir = ""
        mod = None
        for path in "", join(moddir, "modules"):
            file = join(path, name + ".rub")
            if exists(file):
                mod = ScriptModule(self.env, file)
                msg.log(_("script module %s registered") % name)
                break

        # Then look for a Python module

        if not mod:
            if Plugins.register(self, name) == 0:
                msg.debug(_("no support found for %s") % name)
                return 0
            mod = self.modules[name].Module(self.env, dict)
            msg.log(_("built-in module %s registered") % name)

        # Run any delayed commands.

        if self.commands.has_key(name):
            for (cmd, args, vars) in self.commands[name]:
                msg.push_pos(vars)
                try:
                    mod.command(cmd, args)
                except AttributeError:
                    msg.warn(_("unknown directive '%s.%s'") % (name, cmd))
                except TypeError:
                    msg.warn(_("wrong syntax for '%s.%s'") % (name, cmd))
                msg.pop_pos()
            del self.commands[name]

        self.objects[name] = mod
        return 1
Beispiel #17
0
    def pre_compile(self, force):
        """
        Prepare the source for compilation using package-specific functions.
        This function must return true on failure. This function sets
        `must_compile' to 1 if we already know that a compilation is needed,
        because it may avoid some unnecessary preprocessing (e.g. BibTeXing).
        """
        # Watch for the changes of these working files
        for ext in ("aux", "toc", "lot", "lof"):
            self.watcher.watch(self.srcbase + "." + ext)

        msg.log(_("building additional files..."))
        for mod in self.modules.objects.values():
            if mod.pre_compile():
                self.failed_module = mod
                return 1
        return 0
Beispiel #18
0
    def pre_compile(self, force):
        """
        Prepare the source for compilation using package-specific functions.
        This function must return true on failure. This function sets
        `must_compile' to 1 if we already know that a compilation is needed,
        because it may avoid some unnecessary preprocessing (e.g. BibTeXing).
        """
        # Watch for the changes of these working files
        for ext in ("aux", "toc", "lot", "lof"):
            self.watcher.watch(self.srcbase + "." + ext)

        msg.log(_("building additional files..."))
        for mod in self.modules.objects.values():
            if mod.pre_compile():
                self.failed_module = mod
                return 1
        return 0
Beispiel #19
0
 def style_changed (self):
     """
     Read the log file if it exists and check if the style used is the one
     specified in the source. This supposes that the style is mentioned on
     a line with the form 'The style file: foo.bst'.
     """
     if not exists(self.blgfile):
         return 0
     log = open(self.blgfile)
     line = log.readline()
     while line != "":
         if line.startswith("The style file: "):
             if line.rstrip()[16:-4] != self.style:
                 msg.log(_("the bibliography style was changed"), pkg="bibtex")
                 log.close()
                 return 1
         line = log.readline()
     log.close()
     return 0
Beispiel #20
0
 def style_changed(self):
     """
     Read the log file if it exists and check if the style used is the one
     specified in the source. This supposes that the style is mentioned on
     a line with the form 'The style file: foo.bst'.
     """
     if not exists(self.blgfile):
         return 0
     log = open(self.blgfile)
     line = log.readline()
     while line != "":
         if line.startswith("The style file: "):
             if line.rstrip()[16:-4] != self.style:
                 msg.log(_("the bibliography style was changed"),
                         pkg="bibtex")
                 log.close()
                 return 1
         line = log.readline()
     log.close()
     return 0
Beispiel #21
0
    def first_run_needed(self):
        """
        The condition is only on the database files' modification dates, but
        it would be more clever to check if the results have changed.
        BibTeXing is also needed when the last run of BibTeX failed, and in
        the very particular case when the style has changed since last
        compilation.
        """
        if not exists(self.auxfile):
            return 0
        if not exists(self.blgfile):
            return 1

        dtime = getmtime(self.blgfile)
        for db in self.db.values():
            if getmtime(db) > dtime:
                msg.log(_("bibliography database %s was modified") % db,
                        pkg="bibtex")
                return 1

        blg = open(self.blgfile)
        for line in blg.readlines():
            if re_error.search(line):
                blg.close()
                msg.log(_("last BibTeXing failed"), pkg="bibtex")
                return 1
        blg.close()

        if self.style_changed():
            return 1
        if self.bst_file and getmtime(self.bst_file) > dtime:
            msg.log(_("the bibliography style file was modified"),
                    pkg="bibtex")
            return 1
        return 0
Beispiel #22
0
    def first_run_needed (self):
        """
        The condition is only on the database files' modification dates, but
        it would be more clever to check if the results have changed.
        BibTeXing is also needed when the last run of BibTeX failed, and in
        the very particular case when the style has changed since last
        compilation.
        """
        if not exists(self.auxfile):
            return 0
        if not exists(self.blgfile):
            return 1

        dtime = getmtime(self.blgfile)
        for db in self.db.values():
            if getmtime(db) > dtime:
                msg.log(_("bibliography database %s was modified") % db,
                        pkg="bibtex")
                return 1

        blg = open(self.blgfile)
        for line in blg.readlines():
            if re_error.search(line):
                blg.close()
                msg.log(_("last BibTeXing failed"), pkg="bibtex")
                return 1
        blg.close()

        if self.style_changed():
            return 1
        if self.bst_file and getmtime(self.bst_file) > dtime:
            msg.log(_("the bibliography style file was modified"), pkg="bibtex")
            return 1
        return 0
Beispiel #23
0
 def compile_needed (self):
     """
     Returns true if a first compilation is needed. This method supposes
     that no compilation was done (by the script) yet.
     """
     if self.must_compile:
         return 1
     msg.log(_("checking if compiling is necessary..."))
     if not self.draft_support and not os.path.exists(self.outfile):
         msg.debug(_("the output file doesn't exist"))
         return 1
     if not os.path.exists(self.logfile):
         msg.debug(_("the log file does not exist"))
         return 1
     if (not self.draft_support and 
         (os.path.getmtime(self.outfile) < os.path.getmtime(self.srcfile))):
         msg.debug(_("the source is younger than the output file"))
         return 1
     if self.log.read(self.logfile):
         msg.debug(_("the log file is not produced by TeX"))
         return 1
     return self.recompile_needed()
Beispiel #24
0
 def compile_needed(self):
     """
     Returns true if a first compilation is needed. This method supposes
     that no compilation was done (by the script) yet.
     """
     if self.must_compile:
         return 1
     msg.log(_("checking if compiling is necessary..."))
     if not self.draft_support and not os.path.exists(self.outfile):
         msg.debug(_("the output file doesn't exist"))
         return 1
     if not os.path.exists(self.logfile):
         msg.debug(_("the log file does not exist"))
         return 1
     if (not self.draft_support and
         (os.path.getmtime(self.outfile) < os.path.getmtime(self.srcfile))):
         msg.debug(_("the source is younger than the output file"))
         return 1
     if self.log.read(self.logfile):
         msg.debug(_("the log file is not produced by TeX"))
         return 1
     return self.recompile_needed()
Beispiel #25
0
 def run_needed (self):
     """
     Check if makeindex has to be run. This is the case either if the
     target file does not exist or if the source file has changed.
     """
     if os.path.getsize(self.source) == 0:
         msg.log(_("the index file %s is empty") % self.source, pkg="index")
         return 0
     new = md5_file(self.source)
     if not os.path.exists(self.target):
         self.md5 = new
         return 1
     if not self.md5:
         self.md5 = new
         msg.log(_("the index file %s is new") % self.source, pkg="index")
         return 1
     if self.md5 == new:
         msg.log(_("the index %s did not change") % self.source, pkg="index")
         return 0
     self.md5 = new
     msg.log(_("the index %s has changed") % self.source, pkg="index")
     return 1
Beispiel #26
0
    def post_compile (self):
        """
        Run makeindex if needed, with appropriate options and environment.
        """
        if not os.path.exists(self.source):
            msg.log(_("strange, there is no %s") % self.source, pkg="index")
            return 0
        if not self.run_needed():
            return 0

        msg.progress(_("processing index %s") % self.source)

        if self.tool == "makeindex":
            cmd = ["makeindex", "-o", self.target] + self.opts
            cmd.extend(["-t", self.transcript])
            if self.style:
                cmd.extend(["-s", self.style])
            cmd.append(self.source)
            path_var = "INDEXSTYLE"

        elif self.tool == "xindy":
            cmd = ["texindy", "--quiet"]
            for opt in self.opts:
                if opt == "-g":
                    if self.lang != "":
                        msg.warn(_("'language' overrides 'order german'"),
                            pkg="index")
                    else:
                        self.lang = "german-din"
                elif opt == "-l":
                    self.modules.append("letter-ordering")
                    msg.warn(_("use 'module letter-ordering' instead of 'order letter'"),
                        pkg="index")
                else:
                    msg.error("unknown option to xindy: %s" % opt, pkg="index")
            for mod in self.modules:
                cmd.extend(["--module", mod])
            if self.lang:
                cmd.extend(["--language", self.lang])
            cmd.append(self.source)
            path_var = "XINDY_SEARCHPATH"

        if self.path != []:
            env = { path_var:
                string.join(self.path + [os.getenv(path_var, "")], ":") }
        else:
            env = {}

        msg.debug(" ".join(cmd))
        # Makeindex outputs everything to stderr, even progress messages
        rc = subprocess.call(cmd, stderr=msg.stdout)
        if (rc != 0):
            msg.error(_("could not make index %s") % self.target)
            return 1

        # Beware with UTF-8 encoding, makeindex with headings can be messy
        if self.doc.encoding == "utf8" and self.style:
            f = file(self.target, "r")
            error = 0
            for line in f:
                try:
                    line.decode("utf8")
                except:
                    error = 1
                    break
            f.close()
            if error:
                print "here"
                # Retry without style
                msg.log(_("%s on UTF8 failed. Retry...") % self.tool)
                self.style = ""
                self.md5 = None
                return self.post_compile()

        self.doc.must_compile = 1
        return 0
Beispiel #27
0
    def bibtex_needed (self):
        """
        Return true if BibTeX must be run.
        """
        if self.run_needed:
            return 1
        msg.log(_("checking if BibTeX must be run..."), pkg="bibtex")

        newcites, dbs = self.parse_aux()

        # If there was a list of used citations, we check if it has
        # changed. If it has, we have to rerun.

        if self.prev_dbs is not None and self.prev_dbs != dbs:
            msg.log(_("the set of databases changed"), pkg="bibtex")
            self.prev_dbs = dbs
            self.used_cites = newcites
            self.undef_cites = self.list_undefs()
            return 1
        self.prev_dbs = dbs

        # If there was a list of used citations, we check if it has
        # changed. If it has, we have to rerun.

        if self.used_cites and newcites != self.used_cites:
            msg.log(_("the list of citations changed"), pkg="bibtex")
            self.used_cites = newcites
            self.undef_cites = self.list_undefs()
            return 1
        self.used_cites = newcites

        # If there was a list of undefined citations, we check if it has
        # changed. If it has and it is not empty, we have to rerun.

        if self.undef_cites:
            new = self.list_undefs()
            if new == []:
                msg.log(_("no more undefined citations"), pkg="bibtex")
                self.undef_cites = new
            else:
                for cite in new:
                    if cite in self.undef_cites:
                        continue
                    msg.log(_("there are new undefined citations"), pkg="bibtex")
                    self.undef_cites = new
                    return 1
                msg.log(_("there is no new undefined citation"), pkg="bibtex")
                self.undef_cites = new
                return 0
        else:
            self.undef_cites = self.list_undefs()

        # At this point we don't know if undefined citations changed. If
        # BibTeX has not been run before (i.e. there is no log file) we know
        # that it has to be run now.

        if not exists(self.blgfile):
            msg.log(_("no BibTeX log file"), pkg="bibtex")
            return 1

        # Here, BibTeX has been run before but we don't know if undefined
        # citations changed.

        if self.undef_cites == []:
            msg.log(_("no undefined citations"), pkg="bibtex")
            return 0

        if getmtime(self.blgfile) < getmtime(self.doc.logfile):
            msg.log(_("BibTeX's log is older than the main log"), pkg="bibtex")
            return 1

        return 0
Beispiel #28
0
    def bibtex_needed(self):
        """
        Return true if BibTeX must be run.
        """
        if self.run_needed:
            return 1
        msg.log(_("checking if BibTeX must be run..."), pkg="bibtex")

        newcites, dbs = self.parse_aux()

        # If there was a list of used citations, we check if it has
        # changed. If it has, we have to rerun.

        if self.prev_dbs is not None and self.prev_dbs != dbs:
            msg.log(_("the set of databases changed"), pkg="bibtex")
            self.prev_dbs = dbs
            self.used_cites = newcites
            self.undef_cites = self.list_undefs()
            return 1
        self.prev_dbs = dbs

        # If there was a list of used citations, we check if it has
        # changed. If it has, we have to rerun.

        if self.used_cites and newcites != self.used_cites:
            msg.log(_("the list of citations changed"), pkg="bibtex")
            self.used_cites = newcites
            self.undef_cites = self.list_undefs()
            return 1
        self.used_cites = newcites

        # If there was a list of undefined citations, we check if it has
        # changed. If it has and it is not empty, we have to rerun.

        if self.undef_cites:
            new = self.list_undefs()
            if new == []:
                msg.log(_("no more undefined citations"), pkg="bibtex")
                self.undef_cites = new
            else:
                for cite in new:
                    if cite in self.undef_cites:
                        continue
                    msg.log(_("there are new undefined citations"),
                            pkg="bibtex")
                    self.undef_cites = new
                    return 1
                msg.log(_("there is no new undefined citation"), pkg="bibtex")
                self.undef_cites = new
                return 0
        else:
            self.undef_cites = self.list_undefs()

        # At this point we don't know if undefined citations changed. If
        # BibTeX has not been run before (i.e. there is no log file) we know
        # that it has to be run now.

        if not exists(self.blgfile):
            msg.log(_("no BibTeX log file"), pkg="bibtex")
            return 1

        # Here, BibTeX has been run before but we don't know if undefined
        # citations changed.

        if self.undef_cites == []:
            msg.log(_("no undefined citations"), pkg="bibtex")
            return 0

        if getmtime(self.blgfile) < getmtime(self.doc.logfile):
            msg.log(_("BibTeX's log is older than the main log"), pkg="bibtex")
            return 1

        return 0