import os
import re

TRUE = True
FALSE = False

# user defined variables

DOCNAME = 'document'
Rprefix = './Rchunks'
figPrefix = './figures'
deleteComments = True

# copy each chunk with option eval=TRUE to a file in the 'Rprefix' directory
# and create 'rnw.aux' with the options all the chunks
# create variable 'varsOrigin' tracking the file where a variable was created

fname = "%s.rnw" % DOCNAME
f = open(fname, 'r')
lines = f.readlines()
f.close()

n = len(lines)
c1 = [i for i in range(n) if re.search(r'^\s*\%<<(.*)>>=.*', lines[i])]
c2 = [i for i in range(n) if re.search(r'\\end\{Sinput\}', lines[i])]

frnwaux = open('rnw.aux', 'w')

chunks = []
labels = []
figures = []
varsOrigin = {}

for i in range(len(c1)):
  # get chunk
  chunk = lines[(c1[i]+2):c2[i]]
  chunkOpts = re.sub(r'^\s*%<<(.*)>>=.*\n$', '\\1', lines[c1[i]])  
  chunkOpts = eval("dict(%s)" % chunkOpts)
  # get options and write line to auxiliar file rnw.aux
  label = chunkOpts['label'] if 'label' in chunkOpts else 'chunk__%s' % (i + 1)
  chunkEcho = chunkOpts.get('echo', True)
  chunkResults = chunkOpts.get('results', 'verbatim')
  chunkFig = chunkOpts.get('fig', False)
  frnwaux.write("%s %s %s\n" % (label, chunkEcho, chunkResults))
  # work with those chunks with 'eval=TRUE'  
  if chunkOpts.get('eval', True) == True:
    if deleteComments:
      chunk = [re.sub(r'#.*', '', e) for e in chunk]
    chunks.append(chunk)
    if chunkFig == TRUE:
      figures.append('%s.pdf' % label)
    label = '%s.R' % label
    labels.append(label)
    # copy chunk to file
    f = open(os.path.join(Rprefix, label), 'w')
    f.writelines(chunk)
    f.close()
    # get user defined object names
    dvars = [re.sub(r'^\s*(.*)<-.*\n{0,1}$', '\\1', e) for e in chunk if re.search('<-', e)]
    dvars = [re.sub(r'\s$', '', e) for e in dvars]
    # unique names
    dvars = list(set(dvars))
    if len(dvars) > 0:
      varsOrigin.update(dict(zip(dvars, [labels[-1]] * len(dvars))))

frnwaux.close()

# search dependencies
# omit the variables created in the current chunk
# since a code chunk file already depends on itself 

allvars = varsOrigin.keys()
dep = [[e] for e in labels]
for i, chunk in enumerate(chunks):
  chunk = ''.join(chunk)
  for v in allvars:
    if varsOrigin[v] != labels[i]:
      #if re.search(r'(\(\s*|=\s*|,\s*)%s\b' % v, chunk):
      if re.search(r'\b%s\b' % v, chunk):      
	dep[i].append(varsOrigin[v])

# write the Makefile

Rout = ['%sout ' % e for e in labels]
f = open('Makefile', 'w')
f.write('DOCNAME = %s\n' % DOCNAME)
f.write('Rdir = %s\n' % Rprefix)
f.write('figDir = %s\n' % figPrefix)
f.write('RFLAGS = --slave --no-timing --no-readline --restore --save\n')
f.write('Rout = $(addprefix $(Rdir)/, %s)\n' % ''.join(Rout))
f.write('Figs = $(addprefix $(figDir)/, %s)\n\n' % ''.join(figures))
f.write('%.Rout : %.R\n')
f.write('\tR CMD BATCH $(RFLAGS) $< $@\n\n')
f.write('%.pdf : %.eps\n')
f.write('\tepstopdf $<\n')
f.write('\nall : R latex\n\n')
f.write('R : $(Rout)\n')
f.write('\t@echo \"done make R\"\n\n')
for i in range(len(labels)):
  f.write('$(Rdir)/%s: $(addprefix $(Rdir)/, %s)\n' % (Rout[i], ' '.join(dep[i])))
f.write('\nlatex : $(DOCNAME).rnw $(Rout) $(Figs)\n')
f.write('\t@python write.py\n')
f.write('\t@pdflatex $(DOCNAME).tex\n')
f.write('\t@while (grep "Rerun to get cross-references right" $(DOCNAME).log); do ')
f.write('pdflatex $(DOCNAME).tex; ')
f.write('done \n')
f.write('\t@echo \"done make latex\"\n\n')
f.write('.PHONY : clean\n\n')
f.write('clean :\n\t@rm -f .RData $(Rout) $(DOCNAME).tex $(DOCNAME).pdf $(DOCNAME).log ')
f.write('$(figDir)/*.eps  $(figDir)/*.pdf $(DOCNAME).aux rnw.aux\n')
f.close()

print 'Done, file Makefile has been created.'
