Snippets

Created by Atri Bhattacharya last modified
#!/usr/bin/python3
# vim: set ai et ts=4 sw=4 tw=80:

import sys
from pathlib import Path
import re
import os
from os import path
import tarfile as tar
import shutil
import argparse
import subprocess

### PARSE INPUT ARGUMENTS AND ADDITIONAL OPTIONS ###
parser = argparse.ArgumentParser(description="Build a tarball "
                                 "including all source files needed to "
                                 "compile your TeX file.")

parser.add_argument("fname", type=str,
                    help='Input file name (.tex or .fls) (mandatory)')

parser.add_argument("-b", "--bib",
                    help="find and add bib file to tarball ",
                    action="store_true")

parser.add_argument("-f", "--files",
                    type=str, default=[],
                    help='Comma separated list of additional files to tar'
                         ' (locations relative to main TeX source)')

parser.add_argument("-o", "--output",
                    type=str, default=None,
                    help='Name of output tar.gz file (w/o the .tar.gz part)')

parser.add_argument("-v", "--verbose",
                    help='Display file names added to tarball',
                    action="store_true")

parser.add_argument("-x", "--excl",
                    type=str, default=[],
                    help='Comma separated list of files to exclude from tarball'
                         ' (locations relative to main TeX source)')

args = parser.parse_args()
####################################################

fname    = args.fname
name     = fname.rsplit('.', 1)[0]
ext      = fname.rsplit('.', 1)[-1]
addfiles = args.files.split(',') if len(args.files) > 0 else []
excl     = args.excl.split(',') if len(args.excl) > 0 else []

# print(name)
# print(ext)

if not Path(fname).exists():
    print('Error: File not found - {:s}'.format(fname))
    sys.exit(-1)


if ext == 'tex':
#    Generate flx file from tex file by running latexmk
    if not shutil.which('latexmk'):
        raise Exception("latexmk not found in your path; "
                        "needed for generating fls from tex.")

    subprocess.call(['latexmk', '-pdf', '-cd', name])
    flsfile = Path(name + '.fls')
elif ext == 'fls':
    flsfile = Path(fname)
else:
    raise Exception("Invalid file extension. .tex or .fls file accepted.")

cwd = os.getcwd()
tarname = args.output if args.output else flsfile.stem

if not flsfile.exists():
    print('Error: File not found - {:s}'.format(flsfile.name))
    sys.exit(-2)
elif flsfile.suffix != '.fls':
    sys.exit(-3)
 
#for f in addfiles:
#    print(Path(f).resolve())

# Get dir of fls file
wdir = flsfile.resolve().parent
os.chdir(wdir)
# print(wdir)

# Match only lines beginning with INPUT
patt = re.compile('^INPUT')

# Auxilliary file extensions to ignore
auxfiles = ['.aux', '.toc', '.out', '.fls', '.fdb_latexmk', '.log', '.blg']

deps = []
with open(flsfile.name) as f:
    for line in f:
        if patt.match(line):
            p = Path(line.split()[-1])
            if not p.is_absolute():
                if (p.as_posix() not in deps) and (p.as_posix() not in excl):
                    if (p.suffix not in auxfiles):
                        deps.append(p.as_posix())

if args.bib:
    bibre  = re.compile(r'^\\bibliography\{.*\}')
    bibstr = None
    texf   = Path(flsfile.name).with_suffix('.tex')
    with open(texf) as f:
        for line in f:
            #print(line)
            m = bibre.search(line)
            if m:
                bibstr = m.group()
                break
    
    if bibstr:
        bibstr  = re.sub(r'^\\bibliography\{', '', bibstr).rstrip('}')
        bibstr += '.bib' if bibstr.split('.')[-1] != '.bib' else ''
        bibf    = Path(bibstr)

# Always save the tarball in the calling directory
with tar.open(path.join(cwd, tarname + '.tar.gz'), mode='w:gz') as f:
    for xf in addfiles:
        if not Path(xf).exists():
            print('Warning: File {:s} marked for addition not found, '
                  'skipping...'.format(xf))
            continue
        if args.verbose:
            print(xf)
        f.add(xf)
    for dep in deps:
        if args.verbose:
            print(dep)
        f.add(dep)

    if args.bib:
        f.add(bibf)
        if args.verbose:
            print(bibf)

Comments (0)

HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.