#!@PYTHON@

# mf-to-table.py -- convert spacing info in  MF logs .afm and .tex
# 
# source file of the GNU LilyPond music typesetter
# 
# (c) 1997 Han-Wen Nienhuys <hanwen@cs.uu.nl>

import os
import sys
import getopt
import string
import re
import time

(options, files) = getopt.getopt(
    sys.argv[1:], 'a:d:hl:o:p:t:', 
    ['afm=', 'outdir=', 'dep=',  'tex=', 'debug', 'help', 'package='])

for opt in options:
    o = opt[0]
    a = opt[1]
    if o == '-p' or o == '--package':
	topdir = a

def gulp_file(f):
	try:
		i = open(f)
		i.seek (0, 2)
		n = i.tell ()
		i.seek (0,0)
	except:
		print 'can\'t open file: ' + f + '\n'
		return ''
	s = i.read (n)
	if len (s) <= 0:
		print 'gulped empty file: ' + f + '\n'
	i.close ()
	return s

version = '0.9'

postfixes = ['log', 'dvi', '2602gf', 'tfm']

print re

def read_log_file (fn):
	str = gulp_file (fn)
	str = re.sub ('\n', '', str) 	
	str = re.sub ('[\t ]+', ' ', str) 

	deps = []
	autolines = []
	def include_func (match, d = deps):
		d.append (match.group (1))
		return ''

	def auto_func (match, a = autolines):
		a.append (match.group (1))
		return ''

	str = re.sub ('\(([a-zA-Z_0-9-]+\.mf)', include_func, str)
	str = re.sub ('@{(.*?)@}', auto_func, str)

	return (autolines, deps)


class Afm_file:
    def print_dimen(self, f):
	f = f * 1000 / self.fontsize
    
	dimstr = '%.2f' % f

	# try to mask rounding errors
	if (dimstr == '-0.00'):
		dimstr = '0.00'
	self.write( dimstr  +' ');

    def def_symbol (self, code, lily_id, tex_id, xdim, ydim):
	xdim = map (string.atof, xdim)
	ydim = map (string.atof, ydim)
	
	wid = xdim[0] + xdim[1]
	self.write ('C %s ; ' % code)
	self.write ('WX ')
	self.print_dimen (wid)

	self.write (' ; N %s-%s ; B ' % (self.groupname, lily_id))

	self.print_dimen(-xdim [0])
	self.print_dimen(-ydim [0])
	self.print_dimen(xdim [1])
	self.print_dimen(ydim [1])

	self.write (' ;\n');
    def write (self, str):
	self.file.write (str)
    def __init__ (self, fn):
        self.file = open (fn,'w')
    def start (self,nm):
	self.write ('Start%s\n' % nm)
    def end (self,nm):
	self.write ('End%s\n' % nm)

	
	
class Log_reader:
    """Read logs, destill info, and put into output files"""
    def output_label(self, line):

	if not line:
	    return;

	tags = string.split(line, '@:')
	label = tags[0]
	name = tags[1]
	afm = self.afmfile

	if tags[0] == 'font':
	    self.texfile.write("% name\n")

	    afm.write ('FontName %s\n' % name)
	    afm.start ('FontMetrics')
	    afm.start ('CharMetrics')	    
	    afm.fontsize = string.atof(tags[2])
	elif label == "group":
	    self.texfile.write("% " + name + "\n")
	    afm.groupname = name
	elif label == "puorg":
	    self.texfile.write("\n")
	elif label == "tnof":
	    afm.end ('CharMetrics')
	    afm.end('FontMetrics');
	elif label == "char":
	    code = tags[2]
	    id = tags [7]
	    texstr = tags [8]
	    xdim = tags[3:5]
	    ydim = tags[5:7]
	    
	    self.texfile.write("\\def\\feta%s{\\char%s}\n" % (texstr, code))
	    afm.def_symbol (code, id, texstr, xdim, ydim)
	else:
	    raise 'unknown label: ' + label

    def writedeps (self, deps):
	if not len (deps):
	    sys.stderr.write  ('Huh, no main target??')
	    return
	filename = deps[0]
	split = os.path.splitext(filename)	
	basename=split[0];

	targets =  map (lambda x,y = basename, z = self.outdir: z + '/' + y + '.' + x, postfixes)
	depstring = reduce(lambda x,y: x + ' ' + y, deps) 
	dependencies = map (lambda x, y=depstring: x + ': ' + y, targets)
	for x in dependencies: 
	    self.depfile.write (x + '\n')
	
    def do_file(self,filenm):
	self.texfile.write ('\n% input from ' + filenm + '\n')
	(autolines, deps) = read_log_file (filenm)

	for a in autolines:
	    self.output_label(a)
	
	self.writedeps (deps)

    def __init__(self,  texfile_nm, depfile_nm, afmfile_nm):	    
	self.texfile = open(texfile_nm, 'w')
	self.depfile = open (depfile_nm, 'w')
	self.afmfile = Afm_file (afmfile_nm)
	headerstr = '%% Creator: %s\n%% Automatically generated on\n%% Do not edit' % \
		   (program_id() )

	self.texfile.write(headerstr)
	self.depfile.write ('# automatically generated by %s\n' % program_id ())

    def close(self):
	self.texfile.close()
	self.depfile.close ()

    def __del__(self):
	self.close()

def today_str():
    return time.asctime(time.localtime(time.time()))
	
def program_id():
    return 'mf-to-table.py version ' + version;

def identify():
    sys.stdout.write(program_id() + '\n')
    
def help():
    sys.stdout.write(r"""Usage: mf-to-table [options] LOGFILEs
Generate feta metrics table from preparated feta log\n
Options:
  -a, --afm=FILE         .afm file
  -d, --dep=FILE         print dependency info to FILE
  -h, --help             print this help
  -l, --ly=FILE          name output table
  -o, --outdir=DIR       prefix for dependency info
  -p, --package=DIR      specify package
  -t, --tex=FILE         name output tex chardefs"""
)
    sys.exit (0)


def main():
    identify()

    texfile_nm = '';
    depfile_nm = ''
    afmfile_nm = ''
    outdir_prefix = '.'
    for opt in options:
	o = opt[0]
	a = opt[1]
	if o == '--dep' or o == '-d':
	    depfile_nm = a
	elif o == '--outdir' or o == '-o':
	    outdir_prefix = a
	elif o == '--tex' or o == '-t':
	    texfile_nm = a
	elif o== '--help' or o == '-h':
	    help()
	elif o=='--afm' or o == '-a':
	    afmfile_nm = a
	elif o == '--debug':
	    debug_b = 1
	elif o == '-p' or o == '--package':
	    topdir = a
	else:
	    print o
	    raise getopt.error

    log_reader = Log_reader( texfile_nm, depfile_nm, afmfile_nm)
    log_reader.outdir = outdir_prefix
    for filenm in files:
	log_reader.do_file(filenm)
    log_reader.close()


main()
