]> git.donarmstrong.com Git - lilypond.git/blob - buildscripts/mf-to-table.py
release: 1.2.4
[lilypond.git] / buildscripts / mf-to-table.py
1 #!@PYTHON@
2
3 # mf-to-table.py -- convert spacing info in  MF logs .afm and .tex
4
5 # source file of the GNU LilyPond music typesetter
6
7 # (c) 1997 Han-Wen Nienhuys <hanwen@cs.uu.nl>
8
9 import os
10 import sys
11 import getopt
12 import string
13 import re
14 import time
15
16 (options, files) = getopt.getopt(
17     sys.argv[1:], 'a:d:hl:o:p:t:', 
18     ['afm=', 'outdir=', 'dep=',  'tex=', 'debug', 'help', 'package='])
19
20 for opt in options:
21     o = opt[0]
22     a = opt[1]
23     if o == '-p' or o == '--package':
24         topdir = a
25
26 def gulp_file(f):
27         try:
28                 i = open(f)
29                 i.seek (0, 2)
30                 n = i.tell ()
31                 i.seek (0,0)
32         except:
33                 print 'can\'t open file: ' + f + '\n'
34                 return ''
35         s = i.read (n)
36         if len (s) <= 0:
37                 print 'gulped empty file: ' + f + '\n'
38         i.close ()
39         return s
40
41 version = '0.9'
42
43 postfixes = ['log', 'dvi', '2602gf', 'tfm']
44
45 print re
46
47 def read_log_file (fn):
48         str = gulp_file (fn)
49         str = re.sub ('\n', '', str)    
50         str = re.sub ('[\t ]+', ' ', str) 
51
52         deps = []
53         autolines = []
54         def include_func (match, d = deps):
55                 d.append (match.group (1))
56                 return ''
57
58         def auto_func (match, a = autolines):
59                 a.append (match.group (1))
60                 return ''
61
62         str = re.sub ('\(([a-zA-Z_0-9-]+\.mf)', include_func, str)
63         str = re.sub ('@{(.*?)@}', auto_func, str)
64
65         return (autolines, deps)
66
67
68 class Afm_file:
69     def print_dimen(self, f):
70         f = f * 1000 / self.fontsize
71     
72         dimstr = '%.2f' % f
73
74         # try to mask rounding errors
75         if (dimstr == '-0.00'):
76                 dimstr = '0.00'
77         self.write( dimstr  +' ');
78
79     def def_symbol (self, code, lily_id, tex_id, xdim, ydim):
80         xdim = map (string.atof, xdim)
81         ydim = map (string.atof, ydim)
82         
83         wid = xdim[0] + xdim[1]
84         self.write ('C %s ; ' % code)
85         self.write ('WX ')
86         self.print_dimen (wid)
87
88         self.write (' ; N %s-%s ; B ' % (self.groupname, lily_id))
89
90         self.print_dimen(-xdim [0])
91         self.print_dimen(-ydim [0])
92         self.print_dimen(xdim [1])
93         self.print_dimen(ydim [1])
94
95         self.write (' ;\n');
96     def write (self, str):
97         self.file.write (str)
98     def __init__ (self, fn):
99         self.file = open (fn,'w')
100     def start (self,nm):
101         self.write ('Start%s\n' % nm)
102     def end (self,nm):
103         self.write ('End%s\n' % nm)
104
105         
106         
107 class Log_reader:
108     """Read logs, destill info, and put into output files"""
109     def output_label(self, line):
110
111         if not line:
112             return;
113
114         tags = string.split(line, '@:')
115         label = tags[0]
116         name = tags[1]
117         afm = self.afmfile
118
119         if tags[0] == 'font':
120             self.texfile.write("% name\n")
121
122             afm.write ('FontName %s\n' % name)
123             afm.start ('FontMetrics')
124             afm.start ('CharMetrics')       
125             afm.fontsize = string.atof(tags[2])
126         elif label == "group":
127             self.texfile.write("% " + name + "\n")
128             afm.groupname = name
129         elif label == "puorg":
130             self.texfile.write("\n")
131         elif label == "tnof":
132             afm.end ('CharMetrics')
133             afm.end('FontMetrics');
134         elif label == "char":
135             code = tags[2]
136             id = tags [7]
137             texstr = tags [8]
138             xdim = tags[3:5]
139             ydim = tags[5:7]
140             
141             self.texfile.write("\\def\\feta%s{\\char%s}\n" % (texstr, code))
142             afm.def_symbol (code, id, texstr, xdim, ydim)
143         else:
144             raise 'unknown label: ' + label
145
146     def writedeps (self, deps):
147         if not len (deps):
148             sys.stderr.write  ('Huh, no main target??')
149             return
150         filename = deps[0]
151         split = os.path.splitext(filename)      
152         basename=split[0];
153
154         targets =  map (lambda x,y = basename, z = self.outdir: z + '/' + y + '.' + x, postfixes)
155         depstring = reduce(lambda x,y: x + ' ' + y, deps) 
156         dependencies = map (lambda x, y=depstring: x + ': ' + y, targets)
157         for x in dependencies: 
158             self.depfile.write (x + '\n')
159         
160     def do_file(self,filenm):
161         self.texfile.write ('\n% input from ' + filenm + '\n')
162         (autolines, deps) = read_log_file (filenm)
163
164         for a in autolines:
165             self.output_label(a)
166         
167         self.writedeps (deps)
168
169     def __init__(self,  texfile_nm, depfile_nm, afmfile_nm):        
170         self.texfile = open(texfile_nm, 'w')
171         self.depfile = open (depfile_nm, 'w')
172         self.afmfile = Afm_file (afmfile_nm)
173         headerstr = '%% Creator: %s\n%% Automatically generated on\n%% Do not edit' % \
174                    (program_id() )
175
176         self.texfile.write(headerstr)
177         self.depfile.write ('# automatically generated by %s\n' % program_id ())
178
179     def close(self):
180         self.texfile.close()
181         self.depfile.close ()
182
183     def __del__(self):
184         self.close()
185
186 def today_str():
187     return time.asctime(time.localtime(time.time()))
188         
189 def program_id():
190     return 'mf-to-table.py version ' + version;
191
192 def identify():
193     sys.stdout.write(program_id() + '\n')
194     
195 def help():
196     sys.stdout.write(r"""Usage: mf-to-table [options] LOGFILEs
197 Generate feta metrics table from preparated feta log\n
198 Options:
199   -a, --afm=FILE         .afm file
200   -d, --dep=FILE         print dependency info to FILE
201   -h, --help             print this help
202   -l, --ly=FILE          name output table
203   -o, --outdir=DIR       prefix for dependency info
204   -p, --package=DIR      specify package
205   -t, --tex=FILE         name output tex chardefs"""
206 )
207     sys.exit (0)
208
209
210 def main():
211     identify()
212
213     texfile_nm = '';
214     depfile_nm = ''
215     afmfile_nm = ''
216     outdir_prefix = '.'
217     for opt in options:
218         o = opt[0]
219         a = opt[1]
220         if o == '--dep' or o == '-d':
221             depfile_nm = a
222         elif o == '--outdir' or o == '-o':
223             outdir_prefix = a
224         elif o == '--tex' or o == '-t':
225             texfile_nm = a
226         elif o== '--help' or o == '-h':
227             help()
228         elif o=='--afm' or o == '-a':
229             afmfile_nm = a
230         elif o == '--debug':
231             debug_b = 1
232         elif o == '-p' or o == '--package':
233             topdir = a
234         else:
235             print o
236             raise getopt.error
237
238     log_reader = Log_reader( texfile_nm, depfile_nm, afmfile_nm)
239     log_reader.outdir = outdir_prefix
240     for filenm in files:
241         log_reader.do_file(filenm)
242     log_reader.close()
243
244
245 main()