Skip to content

Instantly share code, notes, and snippets.

@tik0
Forked from restrepo/master2single.py
Last active March 31, 2020 08:37
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tik0/7a8beb82e4e01e91a7ff6146dac06055 to your computer and use it in GitHub Desktop.
Save tik0/7a8beb82e4e01e91a7ff6146dac06055 to your computer and use it in GitHub Desktop.
Convert a LaTeX master file into a flatten LaTeX with all the files included
#!/usr/bin/env python
# Author: Timo Korthals <tkorthals@cit-ec.uni-bielefeld.de>
# Template by https://gist.github.com/restrepo/4207109
# Function:
# Convert a master latex file
# into a single document by including hierarchically
# automatically all the LaTeX documents
# which are arguments of
# \include, \input, or \import
# ignoring any \includeonly
import sys
import re
import tempfile
import filecmp
from shutil import copyfile
def exitMsg():
sys.exit('USAGE: %s masterfile.tex flattenfile.tex [-v] [-c]\n'
' masterfile.tex : Input file\n'
' flattenfile.tex : Flattened file\n'
' -v : Verbose mode\n'
' -c : Remove all comments' %sys.argv[0])
return
def flatten(masterfile, flattenfile, verbose):
filetex=open(masterfile,'r')
texlist=filetex.readlines()
finaltex=open(flattenfile,'w')
for i in texlist:
if re.match('(\s)*\\\\input{',i)!=None or re.match('(\s)*\\\\include{',i)!=None or re.match('(\s)*\\\\import{',i)!=None:
if verbose==True:
print('Command: '+i[:-1])
# Remove trailing comments which might taint the following processing
command=i.split('%')[0]
filename=command.split('{')[-1].split('}')[0]
# Check for expansion
if filename[-3:]!='tex':
filename=filename+'tex'
# Check for root if command is '\import'
dirname='./'
if i.find(r'\import{')==0:
dirname=dirname+i.split('{')[-2].split('}')[0]+'/'
filename=dirname+filename
if verbose==True:
print('Import: '+filename)
includetex=open(filename,'r')
finaltex.write(includetex.read())
finaltex.write('\n')
elif i.find(r'\includeonly{')==0:
finaltex.write(i.replace(r'\includeonly{',r'%\includeonly{'))
else:
finaltex.write(i)
filetex.close()
finaltex.close()
return
# Check for files
if len(sys.argv)>=3:
masterfile=sys.argv[1]
flattenfile=sys.argv[2]
else:
exitMsg()
# Check for switches
verbose=False
comment=False
if len(sys.argv)>3:
for x in sys.argv[3:]:
if x=='-v':
verbose=True
elif x=='-c':
comment=True
else:
exitMsg()
# Start flattening
print('Start flattening')
fileIn=masterfile
fileOut=tempfile.NamedTemporaryFile().name
while True:
if verbose==True:
print('Process '+fileIn+' > '+fileOut)
flatten(fileIn, fileOut, verbose)
if filecmp.cmp(fileIn, fileOut)==True:
break
fileIn=fileOut
fileOut=tempfile.NamedTemporaryFile().name
# Remove all comments and produce final output file
if comment==True:
print('Remove comments')
filetex=open(fileOut,'r')
texlist=filetex.readlines()
finaltex=open(flattenfile,'w')
for i in texlist:
if re.match('(\s)*%',i)!=None: # match all lines which are just comments
continue
elif re.search('[^\\\\-]%',i)!=None: # match all comments after commands, but not '\%'
finaltex.write(i[0:re.search('[^\\\\-]%',i).start(0)+1]+'\n')
else:
finaltex.write(i)
filetex.close()
finaltex.close()
else:
copyfile(fileOut, flattenfile)
print(flattenfile+' produced')
@0x33C0
Copy link

0x33C0 commented Mar 31, 2020

Hint: Line 39 should be filename=filename+'.tex' (the dot is missing)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment