-
-
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
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 | |
# Author: Timo Korthals <[email protected]> | |
# 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') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hint: Line 39 should be
filename=filename+'.tex'
(the dot is missing)