]> git.donarmstrong.com Git - lilypond.git/blob - buildscripts/mf-to-table.py
3a07516048a45aa919b01b58f3ed2a763efe9441
[lilypond.git] / buildscripts / mf-to-table.py
1 #!@PYTHON@
2
3 # mf-to-table.py -- convert spacing info in MF logs . 
4 #
5 # source file of the GNU LilyPond music typesetter
6 #
7 # (c) 1997--2007 Han-Wen Nienhuys <hanwen@cs.uu.nl>
8
9 import os
10 import sys
11 import getopt
12 import re
13 import time
14
15 def read_log_file (fn):
16     str = open (fn).read ()
17     str = re.sub ('\n', '', str)
18     str = re.sub ('[\t ]+', ' ', str)
19
20     deps = []
21     autolines = []
22     def include_func (match, d = deps):
23         d.append (match.group (1))
24         return ''
25
26     def auto_func (match, a = autolines):
27         a.append (match.group (1))
28         return ''
29
30     str = re.sub ('\\(([/a-z.A-Z_0-9-]+\\.mf)', include_func, str)
31     str = re.sub ('@{(.*?)@}', auto_func, str)
32
33     return (autolines, deps)
34
35
36 class Char_metric:
37     def __init__ (self):
38         pass
39
40 font_family = 'feta'
41
42 def parse_logfile (fn):
43     autolines, deps = read_log_file (fn)
44     charmetrics = []
45     
46     global_info = {
47         'filename' : os.path.splitext (os.path.basename (fn))[0]
48         }
49     group = ''
50
51     for l in autolines:
52         tags = l.split ('@:')
53         if tags[0] == 'group':
54             group = tags[1]
55         elif tags[0] == 'puorg':
56             group = ''
57         elif tags[0] == 'char':
58             name = tags[9]
59
60             if group:
61                 name = group + '.' + name
62             m = {
63                 'description': tags[1],
64                 'name': name,
65                 'code': int (tags[2]),
66                 'breapth': float (tags[3]),
67                 'width': float (tags[4]),
68                 'depth': float (tags[5]),
69                 'height': float (tags[6]),
70                 'wx': float (tags[7]),
71                 'wy': float (tags[8]),
72             }
73             charmetrics.append (m)
74         elif tags[0] == 'font':
75             global font_family
76             font_family = (tags[3])
77             # To omit 'GNU' (foundry) from font name proper:
78             # name = tags[2:]
79             #urg
80             if 0: # testing
81                 tags.append ('Regular')
82
83             encoding = re.sub (' ','-', tags[5])
84             tags = tags[:-1]
85             name = tags[1:]
86             global_info['design_size'] = float (tags[4])
87             global_info['FontName'] = '-'.join (name)
88             global_info['FullName'] = ' '.join (name)
89             global_info['FamilyName'] = '-'.join (name[1:-1])
90             if 1:
91                 global_info['Weight'] = tags[4]
92             else: # testing
93                 global_info['Weight'] = tags[-1]
94
95             global_info['FontBBox'] = '0 0 1000 1000'
96             global_info['Ascender'] = '0'
97             global_info['Descender'] = '0'
98             global_info['EncodingScheme'] = encoding
99
100         elif tags[0] == 'parameter':
101             global_info[tags[1]] = tags[2];
102             
103     return (global_info, charmetrics, deps)
104
105
106
107 def character_lisp_table (global_info, charmetrics):
108
109     def conv_char_metric (charmetric):
110         f = 1.0
111         s = """(%s .
112 ((bbox . (%f %f %f %f))
113 (subfont . "%s")
114 (subfont-index . %d)
115 (attachment . (%f . %f))))
116 """ %(charmetric['name'],
117    -charmetric['breapth'] * f,
118    -charmetric['depth'] * f,
119    charmetric['width'] * f,
120    charmetric['height'] * f,
121    global_info['filename'],
122    charmetric['code'],
123    charmetric['wx'],
124    charmetric['wy'])
125
126         return s
127
128     s = ''
129     for c in charmetrics:
130         s += conv_char_metric (c)
131
132     return s
133
134
135 def global_lisp_table (global_info):
136     str = ''
137
138     keys = ['staffsize', 'stafflinethickness', 'staff_space',
139         'linethickness', 'black_notehead_width', 'ledgerlinethickness',
140         'design_size', 
141         'blot_diameter'
142         ]
143     for k in keys:
144         if global_info.has_key (k):
145             str = str + "(%s . %s)\n" % (k,global_info[k])
146
147     return str
148
149     
150 def ps_encoding (name, global_info, charmetrics):
151     encs = ['.notdef'] * 256
152     for m in charmetrics:
153         encs[m['code']] = m['name']
154
155
156     s =  ('/%s [\n' % name)
157     for m in range (0, 256):
158         s += ('  /%s %% %d\n' % (encs[m], m))
159     s +=  ('] def\n')
160     return s
161
162 def get_deps (deps, targets):
163     s = ''
164     for t in targets:
165         t = re.sub ( '^\\./', '', t)
166         s += ('%s '% t)
167     s += (": ")
168     for d in deps:
169         s += ('%s ' % d)
170     s += ('\n')
171     return s
172
173 def help ():
174     sys.stdout.write(r"""Usage: mf-to-table [OPTIONS] LOGFILEs
175
176 Generate feta metrics table from preparated feta log.
177
178 Options:
179  -d, --dep=FILE         print dependency info to FILE
180  -h, --help             print this help
181  -l, --ly=FILE          name output table
182  -o, --outdir=DIR       prefix for dependency info
183  -p, --package=DIR      specify package
184
185  """)
186     sys.exit (0)
187
188
189 (options, files) = \
190  getopt.getopt (sys.argv[1:],
191         'a:d:ho:p:t:',
192         ['enc=',  'outdir=', 'dep=', 'lisp=',
193          'global-lisp=',
194          'debug', 'help', 'package='])
195
196 global_lisp_nm = ''
197 char_lisp_nm = ''
198 enc_nm = ''
199 depfile_nm = ''
200 lyfile_nm = ''
201 outdir_prefix = '.'
202
203 for opt in options:
204     o = opt[0]
205     a = opt[1]
206     if o == '--dep' or o == '-d':
207         depfile_nm = a
208     elif o == '--outdir' or o == '-o':
209         outdir_prefix = a
210     elif o == '--lisp': 
211         char_lisp_nm = a
212     elif o == '--global-lisp': 
213         global_lisp_nm = a
214     elif o == '--enc':
215         enc_nm = a
216     elif o== '--help' or o == '-h':
217         help()
218     elif o == '--debug':
219         debug_b = 1
220     else:
221         print o
222         raise getopt.error
223
224 base = os.path.splitext (lyfile_nm)[0]
225
226 for filenm in files:
227     (g, m, deps) = parse_logfile (filenm)
228
229     enc_name = 'FetaEncoding'
230     if re.search ('parmesan', filenm):
231         enc_name = 'ParmesanEncoding'
232     elif re.search ('feta-brace', filenm):
233         enc_name = 'FetaBraceEncoding'
234     elif re.search ('feta-alphabet', filenm):
235         enc_name = 'FetaAlphabetEncoding';
236
237     open (enc_nm, 'w').write (ps_encoding (enc_name, g, m))
238     open (char_lisp_nm, 'w').write (character_lisp_table (g, m))
239     open (global_lisp_nm, 'w').write (global_lisp_table (g))
240     if depfile_nm:
241         open (depfile_nm, 'wb').write (get_deps (deps,
242                                                  [base + '.log', base + '.dvi', base + '.pfa',
243                                                   depfile_nm,
244                                                   base + '.pfb']))