-
-
Save leouieda/35251a6bffcb3460adc5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
from __future__ import division, print_function | |
""" | |
This script generates a file to use for building authorea papers, and then runs | |
latex on them. | |
Requires python >= 2.6 (3.x should work, too) | |
The key assumptions are: | |
* ``layout.md`` exists in the article (I think it always does in Authorea) | |
* ``preamble.tex``, ``header.tex``, ``title.tex``, and | |
``bibliobgraphy/biblio.bib`` exist (I think these are created normally in a | |
new Authorea article) | |
* ``posttitle.tex`` exists. This one you'll have to create, containing | |
everything you want after the title but before the beginning of the document. | |
""" | |
import os | |
import subprocess | |
#lots of dobule-{}'s are here because we use it as a formatting template below | |
MAIN_TEMPLATE = r""" | |
{preamblein} | |
{headerin} | |
\begin{{document}} | |
{titlecontent} | |
{sectioninputs} | |
\bibliography{{{bibloc}}}{{}} | |
\end{{document}} | |
""" | |
FIGURE_TEMPLATE=r""" | |
\begin{figure}[h!] | |
\begin{center} | |
\includegraphics[width=1\columnwidth]{<figfn>} | |
<caption> | |
\end{center} | |
\end{figure} | |
""".replace('{', '{{').replace('}', '}}').replace('<', '{').replace('>', '}') | |
def get_input_string(filename, localdir): | |
if filename.endswith('.tex'): | |
filename = filename[:-4] | |
return r'\input{' + os.path.join(os.path.abspath(localdir), filename) + '}' | |
def get_figure_string(filename, localdir): | |
figdir, figfn = os.path.split(filename) | |
figdir = os.path.join(localdir, figdir) | |
print('rep', figfn) | |
figfnbase = os.path.splitext(figfn)[0] | |
figfn = os.path.join(figdir, figfn) | |
pdffn = os.path.join(figdir, figfnbase + '.pdf') | |
epsfn = os.path.join(figdir, figfnbase + '.eps') | |
if not os.path.exists(pdffn): | |
pdffn = None | |
if not os.path.exists(epsfn): | |
epsfn = None | |
if pdffn or epsfn: | |
figfn = os.path.join(figdir, figfnbase) | |
figfn = os.path.abspath(figfn) | |
capfn = os.path.join(figdir, 'caption.tex') | |
if os.path.exists(capfn): | |
caption = r'\caption{ \protect\input{' + os.path.abspath(capfn) + '}}' | |
else: | |
caption = '' | |
return FIGURE_TEMPLATE.format(**locals()) | |
def build_authorea_latex(localdir, builddir, latex_exec, bibtex_exec, outname, | |
usetitle, dobibtex, npostbibcalls, openwith): | |
if not os.path.exists(builddir): | |
os.mkdir(builddir) | |
if not os.path.isdir(builddir): | |
raise IOError('Requested build directory {0} is a file, not a ' | |
'directory'.format(builddir)) | |
# generate the main tex file as a string | |
preamblein = get_input_string('preamble', localdir) | |
headerin = get_input_string('header', localdir) | |
bibloc = os.path.join(os.path.abspath(localdir), 'bibliography', 'biblio') | |
titlecontent = [] | |
if usetitle: | |
titlecontent.append(r'\title{' + get_input_string('title', localdir) + '}') | |
if os.path.exists(os.path.join(os.path.abspath(localdir), 'posttitle.tex')): | |
titlecontent.append(get_input_string('posttitle', localdir)) | |
titlecontent = '\n'.join(titlecontent) | |
sectioninputs = [] | |
with open(os.path.join(localdir, 'layout.md')) as f: | |
for l in f: | |
ls = l.strip() | |
if ls == '': | |
pass | |
elif ls.startswith('figures'): | |
sectioninputs.append(get_figure_string(ls, localdir)) | |
else: | |
sectioninputs.append(get_input_string(ls, localdir)) | |
sectioninputs = '\n'.join(sectioninputs) | |
maintexstr = MAIN_TEMPLATE.format(**locals()) | |
#now save that string out as a file | |
outname = outname if outname.endswith('.tex') else (outname + '.tex') | |
outtexpath = os.path.join(builddir, outname) | |
with open(outtexpath, 'w') as f: | |
f.write(maintexstr) | |
if outname.endswith('.tex'): | |
outname = outname[:-4] | |
#now actually run latex/bibtex | |
args = [latex_exec, outname + '.tex'] | |
print('\n\RUNNING THIS COMMAND: "{0}"\n'.format(' '.join([latex_exec, outname + '.tex']))) | |
subprocess.check_call(args, cwd=builddir) | |
if dobibtex: | |
args = [bibtex_exec, outname] | |
print('\n\RUNNING THIS COMMAND: "{0}"\n'.format(' '.join([latex_exec, outname + '.tex']))) | |
subprocess.check_call(args, cwd=builddir) | |
for _ in range(npostbibcalls): | |
args = [latex_exec, outname + '.tex'] | |
print('\n\RUNNING THIS COMMAND: "{0}"\n'.format(' '.join([latex_exec, outname + '.tex']))) | |
subprocess.check_call(args, cwd=builddir) | |
#launch the result if necessary | |
resultfn = outtexpath[:-4] + ('.pdf' if 'pdf' in latex_exec else '.dvi') | |
if openwith: | |
args = openwith.split(' ') | |
args.append(resultfn) | |
print('\nLaunching as:' + str(args), '\n') | |
subprocess.check_call(args) | |
else: | |
msg = '\nBuild completed. You can see the result in "{0}": "{1}"' | |
print(msg.format(builddir, resultfn), '\n') | |
if __name__ == '__main__': | |
import argparse | |
parser = argparse.ArgumentParser(description='Local builder for authorea papers.') | |
parser.add_argument('localdir', nargs='?', default='.', | |
help='The directory to actually search for the authorea' | |
' files in. Default to the current directory.') | |
parser.add_argument('--build-dir', '-d', default='authorea_build', | |
help='the directory to build the paper in') | |
parser.add_argument('--latex', '-l', default='pdflatex', | |
help='The executable to use for the latex build step.') | |
parser.add_argument('--bibtex', '-b', default='bibtex', | |
help='The executable to use for the bibtex build step.') | |
parser.add_argument('--filename', '-f', default='authorea_paper', | |
help='The name to use for the output tex file.') | |
parser.add_argument('--no-bibtex', action='store_false', dest='usebibtex', | |
help='Provide this to not run bibtex.') | |
parser.add_argument('--no-title', action='store_false', dest='usetitle', | |
help='Provide this to skip the title command.') | |
parser.add_argument('--n-runs-after-bibtex', '-n', type=int, default=3, | |
help='The number of times to call latex after bibtex.') | |
parser.add_argument('--open-with', '-o', default=None, | |
help='An executable to launch the output file with. ' | |
'Default is to not do anything with it.') | |
args = parser.parse_args() | |
build_authorea_latex(args.localdir, args.build_dir, args.latex, args.bibtex, | |
args.filename, args.usetitle, args.usebibtex, | |
args.n_runs_after_bibtex, args.open_with) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment