def _fix_invalid_ranges(self): if not (self.invalid_index_ranges): return f = open(self.idxfile, "rt", encoding="latin-1") lines = f.readlines() f.close() # Track the lines with the wrong index ranges for i, line in enumerate(lines): for entry in self.invalid_index_ranges: if entry.index_key in line: entry.add_line(i, line) # Summary of the lines to remove in order to fix the ranges skip_lines = [] for entry in self.invalid_index_ranges: skip_lines.extend(entry.skip_lines) entry.reinit() if not (skip_lines): return # Remove the lines starting from the end to always have valid line num msg.debug("xindy: lines to remove from %s to fix ranges: %s" %\ (self.idxfile, skip_lines)) skip_lines.sort() skip_lines.reverse() for line_num in skip_lines: del lines[line_num] f = open(self.idxfile, "wt", encoding="latin-1") f.writelines(lines) f.close()
def run (self): cmd = [self.cmdexec] msg.progress(_("running %s on %s") % (cmd[0], self.source)) for opt in self.doc.paper.split(): cmd.extend(["-t", opt]) cmd.extend(self.options + ["-o", self.target, self.source]) msg.debug(" ".join(cmd)) rc = subprocess.call(cmd, stdout=msg.stdout) if rc != 0: msg.error(_("%s failed on %s") % (cmd[0], self.source)) return 1 return 0
def update(self): """ Update the MD5 sums of all files watched, and return the name of one of the files that changed, or None of they didn't change. """ changed = [] for file in self.files.keys(): if os.path.exists(file): new = md5_file(file) if self.files[file] != new: msg.debug(_("%s MD5 checksum changed") % \ os.path.basename(file)) changed.append(file) self.files[file] = new return changed
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 name in self: 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 name in self.commands: 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
def _sanitize_idxfile(self): # # Remove the 'hyperindexformat' of the new hyperref that makes a mess # with Xindy. If not, the following error is raised by Xindy: # "WARNING: unknown cross-reference-class `hyperindexformat'! (ignored)" # f = open(self.idxfile, "rt", encoding="latin-1") data = f.read() f.close() data, nsub = self._re_hyperindex.subn(r"\1}{", data) if not (nsub): return msg.debug("Remove %d unsupported 'hyperindexformat' calls" % nsub) f = open(self.idxfile, "wt", encoding="latin-1") f.write(data) f.close()
def run(self): cmd = self.command() 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 # because it puts in the headings the first 8bits char of the words # under the heading which can be an invalid character in UTF-8 if (self.style and self.doc.encoding == "utf8"): if not (self._index_is_unicode()): # Retry without style to avoid headings msg.warn(_("makeindex on UTF8 failed. Retry...")) self.style = "" return self.run() return rc
def run(self): self._sanitize_idxfile() self._fix_invalid_ranges() cmd = self.command() msg.debug(" ".join(cmd)) # Collect the script output, and errors logname = join(dirname(self.target), "xindy.log") logfile = open(logname, "wb") p = Popen(cmd, stdout=logfile, stderr=PIPE) errdata = p.communicate()[1] if isinstance(errdata, bytes): errdata = errdata.decode(sys.getdefaultencoding()) rc = p.wait() if msg.stdout: msg.stdout.write(errdata) else: msg.warn(_(errdata.strip())) logfile.close() if (rc != 0): msg.error(_("could not make index %s") % self.target) return 1 self._detect_invalid_ranges(errdata) # Now convert the built index to UTF-8 if required if cmd[0] == "texindy" and self.doc.encoding == "utf8": if not (self._index_is_unicode()): encoding = self._find_index_encoding(logname) tmpindex = join(dirname(self.target), "new.ind") cmd = [ "iconv", "-f", encoding, "-t", "utf8", "-o", tmpindex, self.target ] msg.debug(" ".join(cmd)) rc = subprocess.call(cmd) if rc == 0: os.rename(tmpindex, self.target) return rc
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()
def recompile_needed(self): """ Returns true if another compilation is needed. This method is used when a compilation has already been done. """ changed = self.watcher.update() if self.must_compile: return 1 if self.log.errors(): msg.debug(_("last compilation failed")) return 1 # if self.deps_modified(os.path.getmtime(self.outfile)): # msg.debug(_("dependencies were modified")) # return 1 if changed and (len(changed) > 1 or changed[0] != self.auxfile): msg.debug(_("the %s file has changed") % changed[0]) return 1 if self.log.run_needed(): msg.debug(_("LaTeX asks to run again")) if (not (changed)): msg.debug(_("but the aux files are unchanged")) return 0 return 1 if changed: msg.debug(_("the %s file has changed but no re-run required?") \ % changed[0]) if self.program == "xelatex": msg.debug(_("force recompilation (XeTeX engine)")) return 1 msg.debug(_("no new compilation is needed")) return 0