#!/usr/local/bin/python3

import re
import sys
import os.path

max_recurse_depth = 10 # limit depth of nested \Input statements

re_comment   = re.compile (r"^\s*%")
re_file_name = re.compile (r"^\s*\\Input\{([_a-zA-Z0-9./-]+)\}") # use \Input to avoid confusion with \input

def make_str (num,digits):
    return '{number:0{width}d}'.format(number=num,width=digits)

def include_files (txt, file_name, recurse_depth):

   def grep (this_line, regex, the_group):
       result = regex.search (this_line)
       if result:
          found = True
          group = result.group (the_group)
       else:
          found = False
          group = "<none>"
       return group, found

   def not_comment (the_line):
      return not re_comment.search (the_line)

   def read_include_name (the_line):
      file_name, found = grep (the_line,re_file_name,1)
      return file_name, found

   recurse_depth = recurse_depth + 1

   if recurse_depth > max_recurse_depth:
      print ("> merge-tex.py: Recursion limit for \\Input{...} reached (max = "+str(max_recurse_depth)+"), exit")
      sys.exit(1)

   with open (file_name,'r') as src:

      for the_line in src:

         if not_comment (the_line):
            inc_file, found = read_include_name (the_line)
            if found:
               if not os.path.isfile (inc_file):
                  print ("> merge-tex.py: Include file " + inc_file + " not found, exit.\n")
                  sys.exit(1)
               if markup:
                  txt.write (comment + " beg" + make_str(recurse_depth,2) + ": " + inc_file + "\n")
                  recurse_depth = include_files (txt, inc_file, recurse_depth)
                  txt.write (comment + " end" + make_str(recurse_depth,2) + ": " + inc_file + "\n")
               else:
                  recurse_depth = include_files (txt, inc_file, recurse_depth)
            else:
               txt.write (the_line)
         else:
            txt.write (the_line)

   recurse_depth = recurse_depth - 1

   return recurse_depth

# -----------------------------------------------------------------------------
# the main code

comment = "%%"  # standard comment marker for LaTeX source

import argparse

parser = argparse.ArgumentParser(description="Merge a sequence of LaTeX files into a single LaTeX file")
parser.add_argument("-i", dest="input", metavar="foo.tex", help="source file", required=True)
parser.add_argument("-o", dest="output", metavar="bah.tex", help="output file", required=True)
parser.add_argument("-S", dest="silent", default="False", action='store_true', help="suppress markup lines for each \\Input{foo.tex}", required=False)

src_file_name = parser.parse_args().input
out_file_name = parser.parse_args().output

silent = parser.parse_args().silent

if silent == "False":
   markup = True
else:
   markup = False

if src_file_name == out_file_name:
   print ("> merge-tex.py: Indentical files names for input and output, exit.")
   sys.exit (1)

if not os.path.isfile (src_file_name):
   print ("> merge-tex.py: Source file " + src_file_name + " not found, exit.")
   sys.exit (1)

with open (out_file_name,"w") as txt:

   recurse_depth = 0

   if markup:

      txt.write (comment + " --------------------------------------------------------------\n")
      txt.write (comment + "  Do not edit this file, it was created by merge-tex.py using:\n")
      txt.write (comment + "  merge-tex.py -i " + src_file_name + " -o " + out_file_name + "\n")
      txt.write (comment + " --------------------------------------------------------------\n")

      txt.write (comment + " beg" + make_str(recurse_depth,2) + ": ./" + src_file_name + "\n")
      recurse_depth = include_files (txt, "./" + src_file_name, recurse_depth)
      txt.write (comment + " end" + make_str(recurse_depth,2) + ": ./" + src_file_name + "\n")

   else:
      recurse_depth = include_files (txt, "./" + src_file_name, recurse_depth)

if not recurse_depth == 0:
   print("> merge-tex.py: error during merger")
   print("> recursion depth should be zero, actual value: "+str(recurse_depth))
