#! /usr/bin/env python

import re
import os
import os.path
import shutil

# Simple utility program - run in a folder of latex creates a sub folder called 'flat' that contains the latex file and its dependants in a flat directory structure. Makes lots of assumptions, so you need to be sure that it fits yours. Basically exists because IJCV pissed me off with their fucking backwards submission system.



def parse_tex(fn_in, fn_out):
  """Given an input tex file writes to a new tex file a version where all directory paths have been flattened."""
  print 'Parsing file %s'%fn_in
  
  path_commands = ['\\includegraphics', '\\numimage']
  skip_commands = ['\\newcommand']
  
  # Open the input and output files...
  fin = open(fn_in, 'r')
  if os.path.isfile(fn_out): raise Exception('File already exists')
  fout = open(fn_out, 'w')
  
  # Read in the input, split it on every { and } so we have a list of strings that constitute the file, where every { and } is a seperate string...
  pattern = re.compile('([\{\}])')
  parts = pattern.split(fin.read())
  
  # Go through and find every \includegraphics, then flatten the path between the { and } immediatly following it...
  while len(parts)!=0:
    part = parts.pop(0)
    fout.write(part)
    
    if True in map(lambda p: p in part, path_commands):
      if parts.pop(0)!='{': raise Exception('Start of graphics path does not exist.' + part)
      fout.write('{')
      
      path = parts.pop(0)
      path = '_'.join(path.split('/'))
      fout.write(path)
      
      if parts.pop(0)!='}': raise Exception('End of graphics path does not exist.' + part)
      fout.write('}')
    
    if True in map(lambda p: p in part, skip_commands):
      if parts.pop(0)!='{': raise Exception('Start of skip does not exist.' + part)
      fout.write('{')
      
      fout.write(parts.pop(0))
      
      if parts.pop(0)!='}': raise Exception('End of skip does not exist.' + part)
      fout.write('}')
  
  # Close the files...
  fin.close()
  fout.close()



def parse_directory(path, output_path, prefix = None):
  """Given a directory processes it, moving files as needed and making changes required"""
  
  accept = re.compile('.*\.(pdf|tex|bib|bst|clo|cls|png)$')
  
  for child in os.listdir(path):
    full = os.path.join(path, child)
    if child=='flat' or child=='ijcv': continue
    
    prefix_name = '%s_%s'%(prefix,child) if prefix!=None else child
    
    if os.path.isdir(full):
      parse_directory(full, output_path, prefix_name)
    elif os.path.isfile(full):
      if accept.match(child):
        if child.endswith('.tex'):
          parse_tex(full, os.path.join(output_path, prefix_name))
        else:
          out_path = os.path.join(output_path, prefix_name)
          if os.path.exists(out_path): raise Exception('Copy to path already exists')
          shutil.copyfile(full, out_path)


os.makedirs('flat')
parse_directory('.', 'flat')
