Skip to content

Instantly share code, notes, and snippets.

@alcides
Created July 4, 2023 20:34
Show Gist options
  • Save alcides/04c741468a38987ea8478f3e37b97bf6 to your computer and use it in GitHub Desktop.
Save alcides/04c741468a38987ea8478f3e37b97bf6 to your computer and use it in GitHub Desktop.
Script to (recursively) literally include all \input or \include, and put all files in the root folder (for submission in journals with an awful UI system)
"""
This script flattens the structure of this project in the output folder.
"""
import os
import re
import sys
import shutil
from datetime import date
from pathlib import Path
today = str(date.today())
OUTPUT_FOLDER = f"submission_{today}"
output_f = Path(OUTPUT_FOLDER)
if output_f.exists():
shutil.rmtree(output_f)
output_f.mkdir(exist_ok=True)
def replace_contents(fname:str, reps):
with open(fname, "rt") as f:
data = f.read()
for k in reps:
data = data.replace(k, reps[k])
with open(fname, "wt") as f:
f.write(data)
f.close()
def flatten(main_name:str):
""" Taken and adapted from https://github.com/rekka/latex-flatten/blob/master/latex-flatten.py """
with open(main_name,'r') as main:
out = []
for line in main.readlines():
s = re.split('%', line, 2)
tex = s[0]
if len(s) > 1:
comment = '%' + s[1]
else:
comment = ''
chunks = re.split(r'\\(?:input|include)\{[^}]+\}', tex)
if len(chunks) > 1:
for (c, t) in zip(chunks, re.finditer(r'\\(input|include)\{([^}]+)\}', tex)):
cmd_name = t.group(1)
include_name = t.group(2)
if '.' not in include_name: include_name = include_name + '.tex'
if c.strip(): output.write(c + '\n')
out.append('% BEGIN \\' + cmd_name + '{' + include_name + '}\n')
include = flatten(include_name)
out.append(include)
out.append('% END \\' + cmd_name + '{' + include_name + '}\n')
tail = chunks[-1] + comment
if tail.strip(): output.write(tail)
else:
out.append(line)
return "".join(out)
replacements = {}
for p in output_f.parent.rglob("*"):
if p.is_dir():
continue
if str(p)[0] == "." or "/." in str(p):
continue
if str(p).startswith(OUTPUT_FOLDER):
continue
if str(p) == "main.tex":
newmain = flatten(p)
with open(output_f / "main.tex", "w") as f:
f.write(newmain)
if p.name.endswith(".tex"):
continue
needs_move = os.path.sep in str(p)
print(str(p))
if needs_move:
newname = str(p).replace(os.path.sep, "_")
shutil.copy(p, output_f / newname)
replacements[str(p)] = newname
else:
shutil.copy(p, output_f)
for p in output_f.rglob("main.tex"):
data = replace_contents(p, replacements)
os.system(f"cd {OUTPUT_FOLDER}; pdflatex main.tex; bibtex main; pdflatex main.tex; bibtex main; pdflatex main.tex; rm main.acn; main.aux; rm main.bbl; rm main.glo; rm main.ist;rm main.log ;rm main.out")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment