def _build_latex_cmd(fname, template_dir, use_shell_escape=False): """Builds LaTeX command and environment to process a given paper.""" bname = os.path.basename(fname).split('.')[0] tname = '{0}.tex'.format(bname) template = get_template(fname) if not template: raise IOError('{0} does not appear to have lines necessary to load a template.'.format(fname)) template_loc = scriptorium.find_template(template, template_dir) if not template_loc: raise IOError('{0} template not installed in {1}'.format(template, template_dir)) template_loc = os.path.abspath(os.path.join(template_loc, '..')) #Need to set up environment here new_env = dict(os.environ) for ii in ['TEXINPUTS', 'BIBINPUTS', 'BSTINPUTS']: old_inputs = new_env.get(ii) old_inputs = old_inputs + ':' if old_inputs else '' inputs = './:{0}:{1}'.format(template_loc + '/.//', old_inputs) new_env[ii] = inputs pdf_cmd = [scriptorium.CONFIG['LATEX_CMD'], '-halt-on-error', '-interaction=nonstopmode', tname] if platform.system() == 'Windows': pdf_cmd.insert(-2, '-include-directory={0}'.format(template_loc)) if use_shell_escape: pdf_cmd.insert(1, '-shell-escape') return pdf_cmd, new_env
def template_cmd(args): """Prints out all installed templates.""" if args.update: rev = args.update[1] if len(args.update) > 1 else None scriptorium.update_template(args.update[0], args.template_dir, rev) if args.list: templates = scriptorium.all_templates(args.template_dir) print('\n'.join(templates)) if args.readme: template = scriptorium.find_template(args.readme, args.template_dir) template_readme = os.path.join(template, 'README.md') if template and os.path.exists(template_readme): with open(template_readme, 'r') as readme: print(readme.read()) if args.install: scriptorium.install_template(args.install, args.template_dir) if args.variables: variables = scriptorium.list_variables(args.variables, args.template_dir) print('\n'.join(variables)) if args.manifest: manifest = scriptorium.get_manifest(args.manifest, args.template_dir) for kk, vv in manifest.items(): print("{0} -> {1}".format(vv, kk))
def create(paper_dir, template, force=False, use_git=True, config=None): """Create folder with paper skeleton. Returns a list of unpopulated variables if successfully created. """ config = {kk.upper():vv for kk, vv in config.items()} if os.path.exists(paper_dir) and not force: raise IOError('{0} exists'.format(paper_dir)) template_dir = scriptorium.find_template(template, scriptorium.CONFIG['TEMPLATE_DIR']) os.makedirs(paper_dir) if use_git and not os.path.exists(os.path.join(paper_dir, '.gitignore')): shutil.copyfile(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data', 'gitignore'), os.path.join(paper_dir, '.gitignore')) files = scriptorium.get_manifest(template) texts = {} for ofile, ifile in files.items(): ifile = os.path.join(template_dir, ifile) try: with open(ifile, 'r') as ifp: texts[ofile] = ifp.read() except IOError: texts[ofile] = '' unset_vars = _expand_variables(template, texts, config) for ofile, text in texts.items(): with open(os.path.join(paper_dir, ofile), 'w') as ofp: ofp.write(text) return unset_vars
def template_update(self, mess, args): """Updates the template to the latest version.""" self._check_requirements() template_dir = scriptorium.find_template(args) if not template_dir or not self._is_repo(template_dir): return "{0} is not a valid template.".format(args) if self._update_repo(template_dir, user=mess.frm.username): return "{0} has been updated to the latest version.".format(args)
def template_info(self, mess, args): """Get information about the status of the requested template.""" self._check_requirements() template_dir = scriptorium.find_template(args) if not self._is_repo(template_dir): return {'name': args, 'branch': "None", 'status': 'Not installed'} status = 'clean' if self._is_repo_clean(template_dir) else 'dirty' return {'name': args, 'branch': self._get_branch_name(template_dir), 'status': status}
def testTemplates(self): """Test that template has been installed""" self.assertEqual(TestScriptorium.template_dir, scriptorium.CONFIG['TEMPLATE_DIR']) self.assertTrue( os.path.exists( os.path.join(TestScriptorium.template_dir, 'simple_templates'))) ex_tdir = os.path.join(scriptorium.CONFIG['TEMPLATE_DIR'], 'simple_templates', 'report') self.assertEqual(scriptorium.find_template('report'), ex_tdir)
def create(paper_dir, template, force=False, use_git=True, config=None): """Create folder with paper skeleton. Returns a list of unpopulated variables if successfully created. """ if os.path.exists(paper_dir) and not force: raise IOError("{0} exists".format(paper_dir)) template_dir = scriptorium.find_template(template, scriptorium.TEMPLATE_DIR) os.makedirs(paper_dir) if use_git and not os.path.exists(os.path.join(paper_dir, ".gitignore")): shutil.copyfile( os.path.join(os.path.dirname(os.path.realpath(__file__)), "data", "gitignore"), os.path.join(paper_dir, ".gitignore"), ) files = {"paper.mmd": "frontmatter.mmd", "metadata.tex": "metadata.tex"} texts = {} for ofile, ifile in files.items(): ifile = os.path.join(template_dir, ifile) try: with open(ifile, "Ur") as ifp: texts[ofile] = ifp.read() except IOError: texts[ofile] = "" # Inject template as macro argument config["TEMPLATE"] = template # One line regex thanks to http://stackoverflow.com/a/6117124/59184 for ofile, text in texts.items(): texts[ofile] = re.sub("|".join([r"\${0}".format(ii) for ii in config]), lambda m: config[m.group(0)[1:]], text) # Regex to find variable names var_re = re.compile(r"\$[A-Z0-9_\.\-]+") unset_vars = set() for ofile, text in texts.items(): unset_vars |= set([ii.group(0) for ii in var_re.finditer(text)]) with open(os.path.join(paper_dir, ofile), "w") as ofp: ofp.write(text) return unset_vars
def template_cmd(args): """Prints out all installed templates.""" if args.update: rev = args.update[1] if len(args.update) > 1 else None scriptorium.update_template(args.update[0], args.template_dir, rev) if args.list: templates = scriptorium.all_templates(args.template_dir) print('\n'.join(templates)) if args.readme: template = scriptorium.find_template(args.readme, args.template_dir) template_readme = os.path.join(template, 'README.md') if template and os.path.exists(template_readme): with open(template_readme, 'r') as readme: print(readme.read()) if args.install: scriptorium.install_template(args.install, args.template_dir) if args.variables: variables = scriptorium.list_variables(args.variables, args.template_dir) print('\n'.join(variables))
def to_pdf(paper_dir, template_dir=None, use_shell_escape=False, flatten=False): """Build paper in the given directory, returning the PDF filename if successful.""" template_dir = template_dir or scriptorium.TEMPLATE_DIR paper_dir = os.path.abspath(paper_dir) if os.path.isdir(paper_dir): fname = paper_root(paper_dir) elif os.path.isfile(paper_dir): fname = paper_dir paper_dir = os.path.dirname(paper_dir) else: raise IOError("{0} is not a valid directory".format(paper_dir)) old_cwd = os.getcwd() if old_cwd != paper_dir: os.chdir(paper_dir) if not fname: raise IOError("{0} has no obvious root.".format(paper_dir)) # Convert all auxillary MMD files to LaTeX for mmd in _list_files(paper_dir): bname = os.path.basename(mmd).split(".")[0] tname = "{0}.tex".format(bname) with open(mmd, "Ur") as mmd_fp, open(tname, "w") as tex_fp: txt = pymmd.convert(mmd_fp.read(), fmt=pymmd.LATEX, dname=mmd) tex_fp.write(txt) bname = os.path.basename(fname).split(".")[0] tname = "{0}.tex".format(bname) template = get_template(fname) if not template: raise IOError("{0} does not appear to have lines necessary to load a template.".format(fname)) template_loc = scriptorium.find_template(template, template_dir) if not template_loc: raise IOError("{0} template not installed in {1}".format(template, template_dir)) template_loc = os.path.abspath(os.path.join(template_loc, "..")) # Need to set up environment here new_env = dict(os.environ) old_inputs = new_env.get("TEXINPUTS") texinputs = "./:{0}:{1}".format(template_loc + "/.//", old_inputs + ":" if old_inputs else "") new_env["TEXINPUTS"] = texinputs if flatten: with tempfile.NamedTemporaryFile() as tmp: subprocess.check_call(["latexpand", "-o", tmp.name, tname], env=new_env) shutil.copyfile(tmp.name, tname) pdf_cmd = ["pdflatex", "-halt-on-error", "-interaction=nonstopmode", tname] if platform.system() == "Windows": pdf_cmd.insert(-2, "-include-directory={0}".format(template_loc)) if use_shell_escape: pdf_cmd.insert(1, "-shell-escape") try: subprocess.check_output(pdf_cmd, env=new_env, universal_newlines=True).encode("utf-8") except subprocess.CalledProcessError as exc: raise IOError(exc.output) try: auxname = "{0}.aux".format(bname) # Check if bibtex is defined in the frontmatter bibtex_re = re.compile(r"^bibtex:", re.MULTILINE) with open(fname, "Ur") as paper_fp: if bibtex_re.search(paper_fp.read()): biber_re = re.compile(r"\\bibdata", re.MULTILINE) full = open(auxname, "Ur").read() if biber_re.search(full): subprocess.check_output(["bibtex", auxname], universal_newlines=True) else: subprocess.check_output(["biber", bname], universal_newlines=True) subprocess.check_output(pdf_cmd, env=new_env, universal_newlines=True) subprocess.check_output(pdf_cmd, env=new_env, universal_newlines=True) except subprocess.CalledProcessError as exc: raise IOError(exc.output) # Revert working directory if os.getcwd() != old_cwd: os.chdir(old_cwd) return os.path.join(paper_dir, "{0}.pdf".format(bname))