def set_source(self, name, jobname=None): """ Create a main dependency node from the given file name. If this name has an extension that is known of a preprocessor, this preprocessor is used, otherwise the name is that of a LaTeX source. """ path = self.find_file(name, ".tex") if not path: msg.error(_("cannot find %s") % name) return 1 base, ext = os.path.splitext(path) if ext in literate_preprocessors.keys(): src = base + ".tex" self.src_node = literate_preprocessors[ext](self.depends, src, path) else: src = path self.src_node = None from rubber.converters.latex import LaTeXDep self.main = LaTeXDep(self) if os.path.exists(src): if self.main.set_source(src, jobname): return 1 self.final = self.main return 0
def set_source (self, name, jobname=None): """ Create a main dependency node from the given file name. If this name has an extension that is known of a preprocessor, this preprocessor is used, otherwise the name is that of a LaTeX source. """ path = self.find_file(name, ".tex") if not path: msg.error(_("cannot find %s") % name) return 1 base,ext = os.path.splitext(path) if ext in literate_preprocessors.keys(): src = base + ".tex" self.src_node = literate_preprocessors[ext](self.depends, src, path) else: src = path self.src_node = None from rubber.converters.latex import LaTeXDep self.main = LaTeXDep(self) if os.path.exists(src): if self.main.set_source(src, jobname): return 1 self.final = self.main return 0
def run(self): msg.progress(_("running: %s") % ' '.join(self.command)) process = Popen(self.command, stdin=devnull(), stdout=self.stdout) if process.wait() != 0: msg.error(_("execution of %s failed") % self.command[0]) return False return True
def prepare_source(self, filename): """ Dump the standard input in a file, and set up that file the same way we would normally process LaTeX sources. """ assert filename.endswith("-") # filename is ignored try: # Make a temporary on-disk copy of the standard input, # in the current working directory. # The name will have the form "rubtmpXXX.tex. with tempfile.NamedTemporaryFile(suffix='.tex', prefix='rubtmp', dir='.', delete=False) as srcfile: # note the tempfile name so we can remove it later self.pipe_tempfile = srcfile.name # copy stdin into the tempfile msg.progress(_("saving the input in %s") % self.pipe_tempfile) shutil.copyfileobj(sys.stdin, srcfile) except IOError: msg.error( _("cannot create temporary file for the main LaTeX source")) rubber.util.abort_generic_error() return super(Pipe, self).prepare_source(self.pipe_tempfile)
def run (self): msg.progress(_("running: %s") % ' '.join(self.command)) process = Popen(self.command, stdin=devnull(), stdout=self.stdout) if process.wait() != 0: msg.error(_("execution of %s failed") % self.command[0]) return False return True
def hook_bibliography (self, loc, bibs): for name in string.split (bibs, ","): filename = self.find_bib (name) if filename is not None: self.db[name] = filename self.add_source (filename, track_contents=True) else: msg.error (_ ("cannot find bibliography resource %s") % name, pkg="biblio")
def real_make(self, force): rv = UNCHANGED patience = 5 primary_product = self.products[0] msg.debug(_("make %s -> %s") % (primary_product, str(self.sources)), pkg="depend") while patience > 0: # make our sources for source_name in self.sources: source = self.set[source_name] if source.making: # cyclic dependency -- drop for now, we will re-visit # this would happen while trying to remake the .aux in order to make the .bbl, for example msg.debug( _("while making %s: cyclic dependency on %s (pruned)") % (primary_product, source_name), pkg="depend") continue source_rv = source.make(force) if source_rv == ERROR: self.failed_dep = source.failed_dep msg.debug( _("while making %s: dependency %s could not be made") % (primary_product, source_name), pkg="depend") return ERROR elif source_rv == CHANGED: rv = CHANGED must_make = force or self.should_make() if not must_make: return rv # record MD5 hash of source files as we now actually start the build for source_name in self.md5_for_source.keys(): self.md5_for_source[source_name] = rubber.util.md5_file( source_name) # actually make if not self.run(): self.failed_dep = self return ERROR self.date = time.time() rv = CHANGED force = False patience -= 1 self.failed_dep = self msg.error(_("while making %s: file contents does not seem to settle") % self.products[0], pkg="depend") return ERROR
def __init__ (self, document, context): env = document.env if env.final.products[0][-3:] != '.ps': msg.error(_("I can't use ps2pdf when not producing a PS")) rubber.util.abort_generic_error () ps = env.final.products[0] pdf = ps[:-2] + 'pdf' cmd = ['ps2pdf'] cmd.extend([ps, pdf]) dep = Shell (env.depends, cmd) dep.add_product (pdf) dep.add_source (ps) env.final = dep
def real_make(self, force): rv = UNCHANGED patience = 5 primary_product = self.products[0] msg.debug(_("make %s -> %s") % (primary_product, str(self.sources)), pkg="depend") while patience > 0: # make our sources for source_name in self.sources: source = self.set[source_name] if source.making: # cyclic dependency -- drop for now, we will re-visit # this would happen while trying to remake the .aux in order to make the .bbl, for example msg.debug( _("while making %s: cyclic dependency on %s (pruned)") % (primary_product, source_name), pkg="depend", ) continue source_rv = source.make(force) if source_rv == ERROR: self.failed_dep = source.failed_dep msg.debug( _("while making %s: dependency %s could not be made") % (primary_product, source_name), pkg="depend", ) return ERROR elif source_rv == CHANGED: rv = CHANGED must_make = force or self.should_make() if not must_make: return rv # record MD5 hash of source files as we now actually start the build for source_name in self.md5_for_source.keys(): self.md5_for_source[source_name] = rubber.util.md5_file(source_name) # actually make if not self.run(): self.failed_dep = self return ERROR self.date = time.time() rv = CHANGED force = False patience -= 1 self.failed_dep = self msg.error(_("while making %s: file contents does not seem to settle") % self.products[0], pkg="depend") return ERROR
def __init__(self, document, context): env = document.env if env.final.products[0][-3:] != '.ps': msg.error(_("I can't use ps2pdf when not producing a PS")) rubber.util.abort_generic_error() ps = env.final.products[0] pdf = ps[:-2] + 'pdf' cmd = ['ps2pdf'] for opt in document.vars['paper'].split(): cmd.append('-sPAPERSIZE=' + opt) cmd.extend([ps, pdf]) dep = Shell(env.depends, cmd) dep.add_product(pdf) dep.add_source(ps) env.final = dep
def __init__(self, document, context): doc = document options = rubber.util.parse_keyval(context["opt"]) backend = options.setdefault("backend", "biber") if backend not in ("biber", "bibtex", "bibtex8", "bibtexu"): msg.error(_("Garbled biblatex backend: backend=%s (aborting)") % backend) rubber.util.abort_generic_error() # abort rather than guess self.dep = BibLaTeXDep(doc, backend) doc.hook_macro("bibliography", "a", self.dep.add_bibliography) # overwrite the hook which would load the bibtex module doc.hook_macro("bibliographystyle", "a", self.dep.bibliographystyle)
def __init__(self, document, context): doc = document options = rubber.util.parse_keyval(context["opt"]) backend = options.setdefault("backend", "biber") if backend not in ("biber", "bibtex", "bibtex8", "bibtexu"): msg.error( _("Garbled biblatex backend: backend=%s (aborting)") % backend) rubber.util.abort_generic_error() # abort rather than guess self.dep = BibLaTeXDep(doc, backend) doc.hook_macro("bibliography", "a", self.dep.add_bibliography) # overwrite the hook which would load the bibtex module doc.hook_macro("bibliographystyle", "a", self.dep.bibliographystyle)
def __init__(self, document, context): self.asy_environments = 0 self.doc = document document.add_product(document.basename(with_suffix=".pre")) Shell_Restoring_Aux.initialize(document) if (document.vars['engine'] == 'pdfTeX' and document.products[0][-4:] == '.pdf'): self.format = ".pdf" elif (document.vars['engine'] == 'VTeX'): msg.error(_("does not know how to handle VTeX"), pkg="asymptote") else: self.format = ".eps" self.global_inline = inline_option(context['opt'], default=False) document.hook_begin("asy", self.on_begin_asy)
def add_bib_resource(self, doc, opt, name): msg.log(_("bibliography resource discovered: %s" % name), pkg="biblio") options = rubber.util.parse_keyval(opt) # If the file name looks like it contains a control sequence # or a macro argument, forget about this resource. if name.find("\\") > 0 or name.find("#") > 0: return # skip Biber remote resources if "location" in options and options["location"] == "remote": return filename = self.find_bib(name) if filename is None: msg.error(_("cannot find bibliography resource %s") % name, pkg="biblatex") else: self.add_source(filename)
def __init__ (self, document, context): self.asy_environments = 0 self.doc = document document.add_product (document.basename (with_suffix = ".pre")) Shell_Restoring_Aux.initialize (document) if (document.vars ['engine'] == 'pdfTeX' and document.products [0] [-4:] == '.pdf'): self.format = ".pdf" elif (document.vars ['engine'] == 'VTeX'): msg.error(_("does not know how to handle VTeX"), pkg="asymptote") else: self.format = ".eps" self.global_inline = inline_option (context ['opt'], default=False) document.hook_begin ("asy", self.on_begin_asy)
def add_bib_resource(self, doc, opt, name): msg.log(_("bibliography resource discovered: %s" % name), pkg="biblio") options = rubber.util.parse_keyval(opt) # If the file name looks like it contains a control sequence # or a macro argument, forget about this resource. if name.find('\\') > 0 or name.find('#') > 0: return # skip Biber remote resources if "location" in options and options["location"] == "remote": return filename = self.find_bib(name) if filename is None: msg.error(_("cannot find bibliography resource %s") % name, pkg="biblatex") else: self.add_source(filename)
def process_source (self, env): """ Build the document, and dump the result on stdout. """ try: self.build (env) filename = env.final.products[0] try: # dump the results on standard output with open (filename, "r") as output: shutil.copyfileobj (output, sys.stdout) except IOError: msg.error (_("error copying the product '%s' to stdout") % filename) rubber.util.abort_generic_error () finally: # clean the intermediate files if not self.keep_temp: self.clean (env) rubber.util.verbose_remove (self.pipe_tempfile)
def run (self): # check if the input file exists. if not, refuse to run. if not os.path.exists (self.sources[0]): msg.info (_("input file for %s does not yet exist, deferring") % self.tool, pkg="biblio") return True # command might have been updated in the mean time, so get it now self.environ["BIBINPUTS"] = ":".join (self.bib_paths) self.environ["BSTINPUTS"] = ":".join (self.bst_paths) command = self.build_command () msg.progress (_("running: %s") % " ".join (command)) process = subprocess.Popen (command, stdin = self.devnull, stdout = self.devnull, env = self.environ) if process.wait() != 0: msg.error (_("There were errors running %s.") % self.tool, pkg="biblio") return False return True
def build(self, env): """ Build the final product. """ srcname = env.main.sources[0] # FIXME unindent, untangle if True: if self.force: ret = env.main.make(True) if ret != ERROR and env.final is not env.main: ret = env.final.make() else: # This is a hack for the call to get_errors() below # to work when compiling failed when using -f. env.final.failed_dep = env.main.failed_dep else: ret = env.final.make(self.force) if ret == ERROR: msg.info(_("There were errors compiling %s.") % srcname) number = self.max_errors for err in env.final.failed().get_errors(): if number == 0: msg.info(_("More errors.")) break msg.display(**err) number -= 1 rubber.util.abort_generic_error() if ret == UNCHANGED: msg(1, _("nothing to be done for %s") % srcname) if self.warn: # FIXME log = env.main.log if not env.main.parse_log(): msg.error(_("cannot read the log file")) return 1 msg.display_all( log.parse(boxes=self.warn_boxes, refs=self.warn_refs, warnings=self.warn_misc))
def process_source(self, env): """ Build the document, and dump the result on stdout. """ try: self.build(env) filename = env.final.products[0] try: # dump the results on standard output with open(filename, "r") as output: shutil.copyfileobj(output, sys.stdout) except IOError: msg.error( _("error copying the product '%s' to stdout") % filename) rubber.util.abort_generic_error() finally: # clean the intermediate files if not self.keep_temp: self.clean(env) rubber.util.verbose_remove(self.pipe_tempfile)
def info_log(self, act): """ Check for a log file and extract information from it if it exists, accroding to the argument's value. """ log = self.env.main.log ret = log.read(self.env.main.target + ".log") if ret == 1: msg.error(_("The log file is invalid.")) return 1 elif ret == 2: msg.error(_("There is no log file")) return 1 if act == "boxes": if not msg.display_all(log.get_boxes()): msg.info(_("There is no bad box.")) elif act == "check": if msg.display_all(log.get_errors()): return 0 msg.info(_("There was no error.")) if msg.display_all(log.get_references()): return 0 msg.info(_("There is no undefined reference.")) if not msg.display_all(log.get_warnings()): msg.info(_("There is no warning.")) if not msg.display_all(log.get_boxes()): msg.info(_("There is no bad box.")) elif act == "errors": if not msg.display_all(log.get_errors()): msg.info(_("There was no error.")) elif act == "refs": if not msg.display_all(log.get_references()): msg.info(_("There is no undefined reference.")) elif act == "warnings": if not msg.display_all(log.get_warnings()): msg.info(_("There is no warning.")) else: sys.stderr.write( _("\ I don't know the action `%s'. This should not happen.\n") % act) return 1 return 0
def info_log (self, act): """ Check for a log file and extract information from it if it exists, accroding to the argument's value. """ log = self.env.main.log ret = log.read(self.env.main.target + ".log") if ret == 1: msg.error(_("The log file is invalid.")) return 1 elif ret == 2: msg.error(_("There is no log file")) return 1 if act == "boxes": if not msg.display_all(log.get_boxes()): msg.info(_("There is no bad box.")) elif act == "check": if msg.display_all(log.get_errors()): return 0 msg.info(_("There was no error.")) if msg.display_all(log.get_references()): return 0 msg.info(_("There is no undefined reference.")) if not msg.display_all(log.get_warnings()): msg.info(_("There is no warning.")) if not msg.display_all(log.get_boxes()): msg.info(_("There is no bad box.")) elif act == "errors": if not msg.display_all(log.get_errors()): msg.info(_("There was no error.")) elif act == "refs": if not msg.display_all(log.get_references()): msg.info(_("There is no undefined reference.")) elif act == "warnings": if not msg.display_all(log.get_warnings()): msg.info(_("There is no warning.")) else: sys.stderr.write(_("\ I don't know the action `%s'. This should not happen.\n") % act) return 1 return 0
def build (self, env): """ Build the final product. """ srcname = env.main.sources[0] # FIXME unindent, untangle if True: if self.force: ret = env.main.make(True) if ret != ERROR and env.final is not env.main: ret = env.final.make() else: # This is a hack for the call to get_errors() below # to work when compiling failed when using -f. env.final.failed_dep = env.main.failed_dep else: ret = env.final.make(self.force) if ret == ERROR: msg.info(_("There were errors compiling %s.") % srcname) number = self.max_errors for err in env.final.failed().get_errors(): if number == 0: msg.info(_("More errors.")) break msg.display(**err) number -= 1 rubber.util.abort_generic_error () if ret == UNCHANGED: msg(1, _("nothing to be done for %s") % srcname) if self.warn: # FIXME log = env.main.log if not env.main.parse_log (): msg.error(_("cannot read the log file")) return 1 msg.display_all(log.parse(boxes=self.warn_boxes, refs=self.warn_refs, warnings=self.warn_misc))
def prepare_source (self, filename): """ Dump the standard input in a file, and set up that file the same way we would normally process LaTeX sources. """ assert filename.endswith ("-") # filename is ignored try: # Make a temporary on-disk copy of the standard input, # in the current working directory. # The name will have the form "rubtmpXXX.tex. with tempfile.NamedTemporaryFile (suffix='.tex', prefix='rubtmp', dir='.', delete=False) as srcfile: # note the tempfile name so we can remove it later self.pipe_tempfile = srcfile.name # copy stdin into the tempfile msg.progress (_("saving the input in %s") % self.pipe_tempfile) shutil.copyfileobj (sys.stdin, srcfile) except IOError: msg.error (_("cannot create temporary file for the main LaTeX source")) rubber.util.abort_generic_error () return super (Pipe, self).prepare_source (self.pipe_tempfile)
def parse_opts(self, cmdline): try: long = [ "module=", "readopts=", "short", "verbose", "boxes", "check", "deps", "errors", "help", "refs", "rules", "version", "warnings" ] args = rubber.cmdline.Main.parse_opts(self, cmdline, long=long) opts, args = getopt(args, "", long) self.max_errors = -1 except GetoptError as e: msg.error(e) sys.exit(1) for (opt, arg) in opts: if opt in ("-h", "--help"): self.help() sys.exit(0) elif opt in ("-m", "--module"): self.modules.append(arg) elif opt in ("-o", "--readopts"): file = open(arg) opts2 = file.read().split() file.close() args = self.parse_opts(opts2) + args elif opt in ("-s", "--short"): msg.short = 1 elif opt in ("-v", "--verbose"): msg.level = msg.level + 1 elif opt == "--version": msg(0, version) sys.exit(0) else: if self.act: sys.stderr.write(_("You must specify only one action.\n")) sys.exit(1) self.act = opt[2:] return args
def info_log(self, act): """ Check for a log file and extract information from it if it exists, accroding to the argument's value. """ log = self.env.main.log if not self.env.main.parse_log(): msg.error(_("Parsing the log file failed")) rubber.util.abort_generic_error() if act == "boxes": if not msg.display_all(log.get_boxes()): msg.info(_("There is no bad box.")) elif act == "check": if msg.display_all(log.get_errors()): return 0 msg.info(_("There was no error.")) if msg.display_all(log.get_references()): return 0 msg.info(_("There is no undefined reference.")) if not msg.display_all(log.get_warnings()): msg.info(_("There is no warning.")) if not msg.display_all(log.get_boxes()): msg.info(_("There is no bad box.")) elif act == "errors": if not msg.display_all(log.get_errors()): msg.info(_("There was no error.")) elif act == "refs": if not msg.display_all(log.get_references()): msg.info(_("There is no undefined reference.")) elif act == "warnings": if not msg.display_all(log.get_warnings()): msg.info(_("There is no warning.")) else: sys.stderr.write( _("\ I don't know the action `%s'. This should not happen.\n") % act) return 1 return 0
def read_ini(self, filename): """ Read a set of rules from a file. The file has the form of an INI file, each section describes a rule. """ cp = ConfigParser() try: cp.read(filename) except ParsingError: msg.error(_("parse error, ignoring this file"), file=filename) return for name in cp.sections(): dict = {'name': name} for key in cp.options(name): dict[key] = cp.get(name, key) try: dict['cost'] = cp.getint(name, 'cost') except NoOptionError: msg.warn(_("ignoring rule `%s' (no cost found)") % name, file=filename) continue except ValueError: msg.warn(_("ignoring rule `%s' (invalid cost)") % name, file=filename) continue if 'target' not in dict: msg.warn(_("ignoring rule `%s' (no target found)") % name, file=filename) continue if 'rule' not in dict: msg.warn(_("ignoring rule `%s' (no module found)") % name, file=filename) if not self.load_module(dict['rule']): msg.warn(_("ignoring rule `%s' (module `%s' not found)") % (name, dict['rule']), file=filename) self.rules[name] = Rule(None, dict)
def parse_opts (self, cmdline): try: long = [ "module=", "readopts=", "short", "verbose", "boxes", "check", "deps", "errors", "help", "refs", "rules", "version", "warnings" ] args = rubber.cmdline.Main.parse_opts(self, cmdline, long=long) opts, args = getopt(args, "", long) self.max_errors = -1 except GetoptError as e: msg.error(e) sys.exit(1) for (opt,arg) in opts: if opt in ("-h", "--help"): self.help() sys.exit(0) elif opt in ("-m", "--module"): self.modules.append(arg) elif opt in ("-o" ,"--readopts"): file = open(arg) opts2 = file.read().split() file.close() args = self.parse_opts(opts2) + args elif opt in ("-s", "--short"): msg.short = 1 elif opt in ("-v", "--verbose"): msg.level = msg.level + 1 elif opt == "--version": msg(0, version) sys.exit(0) else: if self.act: sys.stderr.write(_("You must specify only one action.\n")) sys.exit(1) self.act = opt[2:] return args
def info_log (self, act): """ Check for a log file and extract information from it if it exists, accroding to the argument's value. """ log = self.env.main.log if not self.env.main.parse_log (): msg.error(_("Parsing the log file failed")) rubber.util.abort_generic_error () if act == "boxes": if not msg.display_all(log.get_boxes()): msg.info(_("There is no bad box.")) elif act == "check": if msg.display_all(log.get_errors()): return 0 msg.info(_("There was no error.")) if msg.display_all(log.get_references()): return 0 msg.info(_("There is no undefined reference.")) if not msg.display_all(log.get_warnings()): msg.info(_("There is no warning.")) if not msg.display_all(log.get_boxes()): msg.info(_("There is no bad box.")) elif act == "errors": if not msg.display_all(log.get_errors()): msg.info(_("There was no error.")) elif act == "refs": if not msg.display_all(log.get_references()): msg.info(_("There is no undefined reference.")) elif act == "warnings": if not msg.display_all(log.get_warnings()): msg.info(_("There is no warning.")) else: sys.stderr.write(_("\ I don't know the action `%s'. This should not happen.\n") % act) return 1 return 0
def read_ini (self, filename): """ Read a set of rules from a file. The file has the form of an INI file, each section describes a rule. """ cp = ConfigParser() try: cp.read(filename) except ParsingError: msg.error(_("parse error, ignoring this file"), file=filename) return for name in cp.sections(): dict = { 'name': name } for key in cp.options(name): dict[key] = cp.get(name, key) try: dict['cost'] = cp.getint(name, 'cost') except NoOptionError: msg.warn(_("ignoring rule `%s' (no cost found)") % name, file=filename) continue except ValueError: msg.warn(_("ignoring rule `%s' (invalid cost)") % name, file=filename) continue if 'target' not in dict: msg.warn(_("ignoring rule `%s' (no target found)") % name, file=filename) continue if 'rule' not in dict: msg.warn(_("ignoring rule `%s' (no module found)") % name, file=filename) if not self.load_module(dict['rule']): msg.warn(_("ignoring rule `%s' (module `%s' not found)") % (name, dict['rule']), file=filename) self.rules[name] = Rule(None, dict)
def prepare_source(self, filename): """ Prepare the dependency node for the main LaTeX run. Returns the filename of the main LaTeX source file, which might change for various reasons (adding a .tex suffix; preprocessors; pipe dumping). When this is done, the file must exist on disk, otherwise this function must exit(1) or exit(2). """ path = rubber.util.find_resource(filename, suffix=".tex") if not path: msg.error(_("Main document not found: '%s'") % filename) rubber.util.abort_generic_error() base, ext = os.path.splitext(path) from rubber.converters.literate import literate_preprocessors as lpp if ext in lpp.keys(): src = base + ".tex" # FIXME kill src_node src_node = lpp[ext](self.env.depends, src, path) if self.rubber_mode == "build": if not self.unsafe: msg.error( _("Running external commands requires --unsafe.")) rubber.util.abort_rubber_syntax_error() # Produce the source from its dependency rules, if needed. if src_node.make() == ERROR: msg.error (_("Producing the main LaTeX file failed: '%s'") \ % src) rubber.util.abort_generic_error() else: src = path from rubber.converters.latex import LaTeXDep self.env.final = self.env.main = LaTeXDep(self.env, src, self.jobname) return src
def prepare_source (self, filename): """ Prepare the dependency node for the main LaTeX run. Returns the filename of the main LaTeX source file, which might change for various reasons (adding a .tex suffix; preprocessors; pipe dumping). When this is done, the file must exist on disk, otherwise this function must exit(1) or exit(2). """ path = rubber.util.find_resource (filename, suffix=".tex") if not path: msg.error (_("Main document not found: '%s'") % filename) rubber.util.abort_generic_error () base, ext = os.path.splitext (path) from rubber.converters.literate import literate_preprocessors as lpp if ext in lpp.keys (): src = base + ".tex" # FIXME kill src_node src_node = lpp[ext] (self.env.depends, src, path) if self.rubber_mode == "build": if not self.unsafe: msg.error (_("Running external commands requires --unsafe.")) rubber.util.abort_rubber_syntax_error () # Produce the source from its dependency rules, if needed. if src_node.make () == ERROR: msg.error (_("Producing the main LaTeX file failed: '%s'") \ % src) rubber.util.abort_generic_error () else: src = path from rubber.converters.latex import LaTeXDep self.env.final = self.env.main = LaTeXDep (self.env, src, self.jobname) return src
def illegal_option (self, opt): msg.error (_("error: illegal option %s") % opt) rubber.util.abort_rubber_syntax_error ()
def execute (self, prog, env={}, pwd=None, out=None, kpse=0): """ Silently execute an external program. The `prog' argument is the list of arguments for the program, `prog[0]' is the program name. The `env' argument is a dictionary with definitions that should be added to the environment when running the program. The standard output is passed line by line to the `out' function (or discarded by default). If the optional argument `kpse' is true, the error output is parsed and messages from Kpathsea are processed (to indicate e.g. font compilation), otherwise the error output is kept untouched. """ msg.info(_("executing: %s") % " ".join(prog)) if pwd: msg.log(_(" in directory %s") % pwd) if env != {}: msg.log(_(" with environment: %r") % env) progname = prog_available(prog[0]) if not progname: msg.error(_("%s not found") % prog[0]) return 1 penv = os.environ.copy() for (key,val) in env.items(): penv[key] = val if kpse: stderr = subprocess.PIPE else: stderr = None process = Popen(prog, executable = progname, env = penv, cwd = pwd, stdin = devnull(), stdout = subprocess.PIPE, stderr = stderr) if kpse: def parse_kpse (): for line in process.stderr.readlines(): line = line.rstrip() match = re_kpse.match(line) if not match: continue cmd = match.group("cmd") if self.kpse_msg.has_key(cmd): msg.progress(match.expand(self.kpse_msg[cmd])) else: msg.progress(_("kpathsea running %s") % cmd) t = threading.Thread(target=parse_kpse) t.start() #thread.start_new_thread(parse_kpse, ()) if out is not None: for line in process.stdout.readlines(): out(line) else: process.stdout.readlines() ret = process.wait() msg.log(_("process %d (%s) returned %d") % (process.pid, prog[0],ret)) return ret
def run (self): if self.date is not None: return True # FIXME msg.error(_("%r does not exist") % self.products[0]) return False
def main (self, cmdline): """ Run Rubber for the specified command line. This processes each specified source in order (for making or cleaning). If an error happens while making one of the documents, the whole process stops. The method returns the program's exit code. """ args = self.parse_opts (cmdline) initial_dir = os.getcwd() msg.cwd = os.path.join(initial_dir, "") if self.place == ".": self.place = initial_dir if self.place is not None: msg.path = self.place self.place = os.path.abspath(self.place) msg.log (_("This is Rubber version %s.") % rubber_version) for srcname in args: src = os.path.join(initial_dir, srcname) # Go to the appropriate directory try: if self.place != ".": if self.place is None: msg.path = os.path.dirname(src) os.chdir(os.path.dirname(src)) else: os.chdir(self.place) except OSError as e: msg.error(_("Error changing to working directory: %s") % e.strerror) rubber.util.abort_generic_error () # prepare the source file. this may require a pre-processing # step, or dumping stdin. thus, the input filename may change. # in case of build mode, preprocessors will be run as part of # prepare_source. env = self.env = Environment () src = self.prepare_source (src) # safe mode is off during the prologue self.env.is_in_unsafe_mode_ = True if self.include_only is not None: env.main.includeonly (self.include_only) # at this point, the LaTeX source file must exist; if it is # the result of pre-processing, this has happened already. # the main LaTeX file is not found via find_file (unlike # most other resources) by design: paths etc may be set up # from within via rubber directives, so that wouldn't make a # whole lot of sense. if not os.path.exists (src): msg.error (_("LaTeX source file not found: '%s'") % src) rubber.util.abort_generic_error () saved_vars = env.main.vars env.main.vars = rubber.util.Variables (saved_vars, { "cwd": initial_dir }) for dir in self.path: env.main.do_path(dir) for cmd in self.prologue: cmd = rubber.util.parse_line (cmd, env.main.vars) env.main.command(cmd[0], cmd[1:], {'file': 'command line'}) env.main.vars = saved_vars # safe mode is enforced for anything that comes from the .tex file self.env.is_in_unsafe_mode_ = self.unsafe env.main.parse() saved_vars = env.main.vars env.main.vars = rubber.util.Variables (saved_vars, { "cwd": initial_dir }) for cmd in self.epilogue: cmd = rubber.util.parse_line (cmd, env.main.vars) env.main.command(cmd[0], cmd[1:], {'file': 'command line'}) env.main.vars = saved_vars if self.compress is not None: last_node = env.final filename = last_node.products[0] if self.compress == 'gzip': import gzip env.final = rubber.converters.compressor.Node ( env.depends, gzip.GzipFile, '.gz', filename) else: # self.compress == 'bzip2' import bz2 env.final = rubber.converters.compressor.Node ( env.depends, bz2.BZ2File, '.bz2', filename) self.process_source (env) exit (0)
def parse_opts (self, cmdline): """ Parse the command-line arguments. Returns the extra arguments (i.e. the files to operate on), or an empty list, if no extra arguments are present. """ # if no arguments at all are given, print a short version of the # help text and exit. if cmdline == []: self.short_help () try: opts, args = getopt( cmdline, "I:bc:de:fhklm:n:o:pqr:SsvW:z", ["bzip2", "cache", "clean", "command=", "epilogue=", "force", "gzip", "help", "inplace", "into=", "jobname=", "keep", "landscape", "maxerr=", "module=", "only=", "post=", "pdf", "ps", "quiet", "read=", "readopts=", "src-specials", "shell-escape", "synctex", "unsafe", "short", "texpath=", "verbose", "version", "boxes", "check", "deps", "errors", "refs", "rules", "warnings", "warn="]) except GetoptError as e: msg.error (_("getopt error: %s") % str (e)) rubber.util.abort_rubber_syntax_error () extra = [] using_dvips = False for (opt,arg) in opts: # obsolete options if opt == "--cache": # unimplemented option (harmless) self.ignored_option (opt) elif opt in ("--readopts", "-l", "--landscape" ): # undocumented option which is no longer supported self.illegal_option (opt) # info elif opt in ("-h", "--help"): self.help () exit (0) elif opt == "--version": sys.stdout.write ("Rubber version: %s\n" % \ rubber_version) exit (0) # mode of operation elif opt == "--clean": self.ignored_option (opt) elif opt in ("-k", "--keep"): if self.rubber_mode == "pipe": self.keep_temp = True else: # does not make any sense except in pipe mode self.illegal_option (opt) # compression etc. which affects which products exist elif opt in ("-b", "--bzip2", "-z", "--gzip"): algo = "bzip2" if opt in ("-b", "--bzip2") else "gzip" if self.compress is not None and self.compress != algo: self.ignored_option (opt) else: self.compress = algo elif opt in ("-c", "--command"): self.prologue.append(arg) elif opt in ("-e", "--epilogue"): self.epilogue.append(arg) elif opt in ("-f", "--force"): self.force = True elif opt == "--inplace": self.place = None elif opt == "--into": self.place = arg elif opt == "--jobname": self.jobname = arg elif opt in ("-n", "--maxerr"): self.max_errors = int(arg) elif opt in ("-m", "--module"): self.prologue.append("module " + string.replace(arg, ":", " ", 1)) elif opt == "--only": self.include_only = arg.split(",") elif opt in ("-o", "--post"): if self.rubber_mode == "info": self.illegal_option (opt) self.epilogue.append("module " + string.replace(arg, ":", " ", 1)) elif opt in ("-d", "--pdf"): if using_dvips: self.epilogue.append("module ps2pdf") else: self.prologue.append("module pdftex") elif opt in ("-p", "--ps"): self.epilogue.append("module dvips") using_dvips = True elif opt in ("-q", "--quiet"): msg.level = msg.level - 1 # we continue to accept --shell-escape for now elif opt in ("--unsafe", "--shell-escape"): self.unsafe = True elif opt in ("-r" ,"--read"): self.prologue.append("read " + arg) elif opt in ("-S", "--src-specials"): self.prologue.append("set src-specials yes") elif opt in ("-s", "--short"): msg.short = 1 elif opt in ("--synctex"): self.prologue.append("synctex") elif opt in ("-I", "--texpath"): self.path.append(arg) elif opt in ("-v", "--verbose"): msg.level = msg.level + 1 elif opt in ("-W", "--warn"): self.warn = 1 if arg == "all": self.warn_boxes = 1 self.warn_misc = 1 self.warn_refs = 1 if arg == "boxes": self.warn_boxes = 1 elif arg == "misc": self.warn_misc = 1 elif arg == "refs": self.warn_refs = 1 elif opt in ("--boxes", "--check", "--deps", "--errors", "--refs", "--rules", "--warnings"): if self.rubber_mode != "info": self.illegal_option (opt) if self.info_action is not None: msg.error (_("error: cannot have both '--%s' and '%s'") \ % (self.info_action, opt)) rubber.util.abort_rubber_syntax_error () self.info_action = opt[2:] elif arg == "": extra.append(opt) else: extra.extend([arg, opt]) ret = extra + args if self.jobname is not None and len (ret) > 1: msg.error (_("error: cannot give jobname and have more than one input file")) rubber.util.abort_rubber_syntax_error () return ret
def run(self): if self.date is not None: return True else: msg.error(_("%r does not exist") % self.products[0], pkg="leaf") return False
def illegal_option(self, opt): msg.error(_("error: illegal option %s") % opt) rubber.util.abort_rubber_syntax_error()
def hook_bibliography (self, loc, bibs): msg.error(_("incompatible with \\bibliography"), pkg="bibtopic") rubber.util.abort_generic_error ()
def do_tool (self, tool): if tool not in ("makeindex", "xindy"): msg.error(_("unknown indexing tool '%s'") % tool) self.cmd [0] = tool
def execute(self, prog, env={}, pwd=None, out=None, kpse=0): """ Silently execute an external program. The `prog' argument is the list of arguments for the program, `prog[0]' is the program name. The `env' argument is a dictionary with definitions that should be added to the environment when running the program. The standard output is passed line by line to the `out' function (or discarded by default). If the optional argument `kpse' is true, the error output is parsed and messages from Kpathsea are processed (to indicate e.g. font compilation), otherwise the error output is kept untouched. """ msg.info(_("executing: %s") % " ".join(prog)) if pwd: msg.log(_(" in directory %s") % pwd) if env != {}: msg.log(_(" with environment: %r") % env) progname = prog_available(prog[0]) if not progname: msg.error(_("%s not found") % prog[0]) return 1 penv = os.environ.copy() for (key, val) in env.items(): penv[key] = val if kpse: stderr = subprocess.PIPE else: stderr = None process = Popen(prog, executable=progname, env=penv, cwd=pwd, stdin=devnull(), stdout=subprocess.PIPE, stderr=stderr) if kpse: def parse_kpse(): for line in process.stderr.readlines(): line = line.rstrip() match = re_kpse.match(line) if not match: continue cmd = match.group("cmd") if self.kpse_msg.has_key(cmd): msg.progress(match.expand(self.kpse_msg[cmd])) else: msg.progress(_("kpathsea running %s") % cmd) t = threading.Thread(target=parse_kpse) t.start() #thread.start_new_thread(parse_kpse, ()) if out is not None: for line in process.stdout.readlines(): out(line) else: process.stdout.readlines() ret = process.wait() msg.log(_("process %d (%s) returned %d") % (process.pid, prog[0], ret)) return ret
def main (self, cmdline): """ Run Rubber for the specified command line. This processes each specified source in order (for making or cleaning). If an error happens while making one of the documents, the whole process stops. The method returns the program's exit code. """ self.jobname = None self.prologue = [] self.epilogue = [] self.clean = 0 self.force = 0 self.unsafe = False self.warn = 0 self.warn_boxes = 0 self.warn_misc = 0 self.warn_refs = 0 self.place = "." args = self.parse_opts(cmdline) initial_dir = os.getcwd() msg.cwd = os.path.join(initial_dir, "") if self.place != "." and self.place is not None: msg.path = self.place self.place = os.path.abspath(self.place) msg.log(_("This is Rubber version %s.") % version) for srcname in args: src = os.path.abspath(os.path.join(initial_dir, srcname)) # Go to the appropriate directory try: if self.place != ".": if self.place is None: msg.path = os.path.dirname(src) os.chdir(os.path.dirname(src)) src = os.path.basename(src) else: os.chdir(self.place) except OSError as e: msg.error(_("Error changing to working directory: %s") % e.strerror) return 1 # Check the source and prepare it for processing env = Environment() if env.set_source(src, jobname=self.jobname): return 1 self.jobname = None env.is_in_unsafe_mode_ = self.unsafe if self.include_only is not None: env.main.includeonly(self.include_only) if self.clean: if env.main.products == []: msg.warn(_("there is no LaTeX source for %s") % srcname) continue else: env.make_source() saved_vars = env.main.vars env.main.vars = Variables(saved_vars, { "cwd": initial_dir }) for dir in self.path: env.main.do_path(dir) for cmd in self.prologue: cmd = parse_line(cmd, env.main.vars) env.main.command(cmd[0], cmd[1:], {'file': 'command line'}) env.main.vars = saved_vars env.main.parse() saved_vars = env.main.vars env.main.vars = Variables(saved_vars, { "cwd": initial_dir }) for cmd in self.epilogue: cmd = parse_line(cmd, env.main.vars) env.main.command(cmd[0], cmd[1:], {'file': 'command line'}) env.main.vars = saved_vars if self.compress is not None: last_node = env.final filename = last_node.products[0] if self.compress == 'gzip': from rubber.converters.gz import GzipDep env.final = GzipDep(env.depends, filename + '.gz', filename) elif self.compress == 'bzip2': from rubber.converters.bzip2 import Bzip2Dep env.final = Bzip2Dep(env.depends, filename + '.bz2', filename) # Compile the document if self.clean: env.final.clean() continue if self.force: ret = env.main.make(True) if ret != ERROR and env.final is not env.main: ret = env.final.make() else: # This is a hack for the call to get_errors() below # to work when compiling failed when using -f. env.final.failed_dep = env.main.failed_dep else: ret = env.final.make(self.force) if ret == ERROR: msg.info(_("There were errors compiling %s.") % srcname) number = self.max_errors for err in env.final.failed().get_errors(): if number == 0: msg.info(_("More errors.")) break msg.display(**err) number -= 1 return 1 if ret == UNCHANGED: msg(1, _("nothing to be done for %s") % srcname) if self.warn: log = env.main.log if log.read(env.main.target + ".log"): msg.error(_("cannot read the log file")) return 1 msg.display_all(log.parse(boxes=self.warn_boxes, refs=self.warn_refs, warnings=self.warn_misc)) return 0
def parse_opts(self, cmdline): """ Parse the command-line arguments. Returns the extra arguments (i.e. the files to operate on), or an empty list, if no extra arguments are present. """ # if no arguments at all are given, print a short version of the # help text and exit. if cmdline == []: self.short_help() try: opts, args = getopt(cmdline, "I:bc:de:fhklm:n:o:pqr:SsvW:z", [ "bzip2", "cache", "clean", "command=", "epilogue=", "force", "gzip", "help", "inplace", "into=", "jobname=", "keep", "landscape", "maxerr=", "module=", "only=", "post=", "pdf", "ps", "quiet", "read=", "readopts=", "src-specials", "shell-escape", "synctex", "unsafe", "short", "texpath=", "verbose", "version", "boxes", "check", "deps", "errors", "refs", "rules", "warnings", "warn=" ]) except GetoptError as e: msg.error(_("getopt error: %s") % str(e)) rubber.util.abort_rubber_syntax_error() extra = [] using_dvips = False for (opt, arg) in opts: # obsolete options if opt == "--cache": # unimplemented option (harmless) self.ignored_option(opt) elif opt == "--readopts": # undocumented option which is no longer supported self.illegal_option(opt) # info elif opt in ("-h", "--help"): self.help() exit(0) elif opt == "--version": sys.stdout.write ("Rubber version: %s\n" % \ rubber_version) exit(0) # mode of operation elif opt == "--clean": self.ignored_option(opt) elif opt in ("-k", "--keep"): if self.rubber_mode == "pipe": self.keep_temp = True else: # does not make any sense except in pipe mode self.illegal_option(opt) # compression etc. which affects which products exist elif opt in ("-b", "--bzip2", "-z", "--gzip"): algo = "bzip2" if opt in ("-b", "--bzip2") else "gzip" if self.compress is not None and self.compress != algo: self.ignored_option(opt) else: self.compress = algo elif opt in ("-c", "--command"): self.prologue.append(arg) elif opt in ("-e", "--epilogue"): self.epilogue.append(arg) elif opt in ("-f", "--force"): self.force = True elif opt == "--inplace": self.place = None elif opt == "--into": self.place = arg elif opt == "--jobname": self.jobname = arg elif opt in ("-l", "--landscape"): self.prologue.append("paper landscape") elif opt in ("-n", "--maxerr"): self.max_errors = int(arg) elif opt in ("-m", "--module"): self.prologue.append("module " + string.replace(arg, ":", " ", 1)) elif opt == "--only": self.include_only = arg.split(",") elif opt in ("-o", "--post"): if self.rubber_mode == "info": self.illegal_option(opt) self.epilogue.append("module " + string.replace(arg, ":", " ", 1)) elif opt in ("-d", "--pdf"): if using_dvips: self.epilogue.append("module ps2pdf") else: self.prologue.append("module pdftex") elif opt in ("-p", "--ps"): self.epilogue.append("module dvips") using_dvips = True elif opt in ("-q", "--quiet"): msg.level = msg.level - 1 # we continue to accept --shell-escape for now elif opt in ("--unsafe", "--shell-escape"): self.unsafe = True elif opt in ("-r", "--read"): self.prologue.append("read " + arg) elif opt in ("-S", "--src-specials"): self.prologue.append("set src-specials yes") elif opt in ("-s", "--short"): msg.short = 1 elif opt in ("--synctex"): self.prologue.append("synctex") elif opt in ("-I", "--texpath"): self.path.append(arg) elif opt in ("-v", "--verbose"): msg.level = msg.level + 1 elif opt in ("-W", "--warn"): self.warn = 1 if arg == "all": self.warn_boxes = 1 self.warn_misc = 1 self.warn_refs = 1 if arg == "boxes": self.warn_boxes = 1 elif arg == "misc": self.warn_misc = 1 elif arg == "refs": self.warn_refs = 1 elif opt in ("--boxes", "--check", "--deps", "--errors", "--refs", "--rules", "--warnings"): if self.rubber_mode != "info": self.illegal_option(opt) if self.info_action is not None: msg.error (_("error: cannot have both '--%s' and '%s'") \ % (self.info_action, opt)) rubber.util.abort_rubber_syntax_error() self.info_action = opt[2:] elif arg == "": extra.append(opt) else: extra.extend([arg, opt]) ret = extra + args if self.jobname is not None and len(ret) > 1: msg.error( _("error: cannot give jobname and have more than one input file" )) rubber.util.abort_rubber_syntax_error() return ret
def main(self, cmdline): """ Run Rubber for the specified command line. This processes each specified source in order (for making or cleaning). If an error happens while making one of the documents, the whole process stops. The method returns the program's exit code. """ args = self.parse_opts(cmdline) initial_dir = os.getcwd() msg.cwd = os.path.join(initial_dir, "") if self.place == ".": self.place = initial_dir if self.place is not None: msg.path = self.place self.place = os.path.abspath(self.place) global rubber msg.log(_("This is Rubber version %s.") % rubber_version) for srcname in args: src = os.path.join(initial_dir, srcname) # Go to the appropriate directory try: if self.place != ".": if self.place is None: msg.path = os.path.dirname(src) os.chdir(os.path.dirname(src)) else: os.chdir(self.place) except OSError as e: msg.error( _("Error changing to working directory: %s") % e.strerror) rubber.util.abort_generic_error() # prepare the source file. this may require a pre-processing # step, or dumping stdin. thus, the input filename may change. # in case of build mode, preprocessors will be run as part of # prepare_source. env = self.env = Environment() self.env.is_in_unsafe_mode_ = self.unsafe src = self.prepare_source(src) if self.include_only is not None: env.main.includeonly(self.include_only) # at this point, the LaTeX source file must exist; if it is # the result of pre-processing, this has happened already. # the main LaTeX file is not found via find_file (unlike # most other resources) by design: paths etc may be set up # from within via rubber directives, so that wouldn't make a # whole lot of sense. if not os.path.exists(src): msg.error(_("LaTeX source file not found: '%s'") % src) rubber.util.abort_generic_error() saved_vars = env.main.vars env.main.vars = rubber.util.Variables(saved_vars, {"cwd": initial_dir}) for dir in self.path: env.main.do_path(dir) for cmd in self.prologue: cmd = rubber.util.parse_line(cmd, env.main.vars) env.main.command(cmd[0], cmd[1:], {'file': 'command line'}) env.main.vars = saved_vars env.main.parse() saved_vars = env.main.vars env.main.vars = rubber.util.Variables(saved_vars, {"cwd": initial_dir}) for cmd in self.epilogue: cmd = rubber.util.parse_line(cmd, env.main.vars) env.main.command(cmd[0], cmd[1:], {'file': 'command line'}) env.main.vars = saved_vars if self.compress is not None: last_node = env.final filename = last_node.products[0] if self.compress == 'gzip': import gzip env.final = rubber.converters.compressor.Node( env.depends, gzip.GzipFile, '.gz', filename) else: # self.compress == 'bzip2' import bz2 env.final = rubber.converters.compressor.Node( env.depends, bz2.BZ2File, '.bz2', filename) self.process_source(env) exit(0)
def run(self): if self.date is not None: return True # FIXME msg.error(_("%r does not exist") % self.products[0]) return False