~ubuntu-branches/ubuntu/precise/lilypond/precise

« back to all changes in this revision

Viewing changes to buildscripts/mf-to-table.py

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Bushnell, BSG
  • Date: 2006-12-19 10:18:12 UTC
  • mfrom: (3.1.4 feisty)
  • Revision ID: james.westby@ubuntu.com-20061219101812-7awtjkp0i393wxty
Tags: 2.8.7-3
scripts/midi2ly.py: When setting DATADIR, find Lilypond python files
in the @TOPLEVEL_VERSION@ directory, not 'current'.  Patch thanks to
Chris Lamb (chris@chris-lamb.co.uk).  (Closes: #400550)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#!@PYTHON@
2
2
 
3
 
# mf-to-table.py -- convert spacing info in  MF logs .afm and .tex
4
 
 
3
# mf-to-table.py -- convert spacing info in MF logs . and .tex
 
4
#
5
5
# source file of the GNU LilyPond music typesetter
6
 
7
 
# (c) 1997--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
 
6
#
 
7
# (c) 1997--2006 Han-Wen Nienhuys <hanwen@cs.uu.nl>
8
8
 
9
9
import os
10
10
import sys
13
13
import re
14
14
import time
15
15
 
16
 
 
17
 
postfixes = ['log', 'dvi', '2602gf', 'tfm']
18
 
 
19
16
def read_log_file (fn):
20
17
        str = open (fn).read ()
21
 
        str = re.sub ('\n', '', str)    
22
 
        str = re.sub ('[\t ]+', ' ', str) 
 
18
        str = re.sub ('\n', '', str)
 
19
        str = re.sub ('[\t ]+', ' ', str)
23
20
 
24
21
        deps = []
25
22
        autolines = []
37
34
        return (autolines, deps)
38
35
 
39
36
 
40
 
 
41
37
class Char_metric:
42
38
        def __init__ (self):
43
39
                pass
44
40
 
45
 
 
46
 
def tfm_checksum (fn):
47
 
        sys.stderr.write ("Reading checksum from `%s'\n" % fn) 
48
 
        s = open (fn).read ()
49
 
        s = s[ 12 * 2 : ]
50
 
        cs_bytes = s[:4]
51
 
 
52
 
        shift = 24
53
 
        cs = 0
54
 
        for b in cs_bytes:
55
 
                cs = cs  + (long (ord (b)) << shift)
56
 
                shift = shift - 8
57
 
 
58
 
        return cs
59
 
 
60
 
## ugh.  What's font_family supposed to be?  It's not an afm thing.
61
41
font_family = 'feta'
 
42
 
62
43
def parse_logfile (fn):
63
44
        (autolines, deps) = read_log_file (fn)
64
45
        charmetrics = []
65
 
        global_info = {}
 
46
        
 
47
        global_info = {
 
48
                'filename' : os.path.splitext (os.path.basename (fn))[0]
 
49
                }
66
50
        group = ''
67
51
 
68
52
        for l in autolines:
69
 
                tags = string.split(l, '@:')
 
53
                tags = string.split (l, '@:')
70
54
                if tags[0] == 'group':
71
55
                        group = tags[1]
 
56
                elif tags[0] == 'puorg':
 
57
                        group = ''
72
58
                elif tags[0] == 'char':
 
59
                        name = tags[9]
 
60
 
 
61
                        name = re.sub ('-', 'M', name)
 
62
                        if group:
 
63
                                name = group + '.' + name
73
64
                        m = {
74
 
                                'description':  tags[1],
75
 
                                'name': group + '-' + tags[9],
76
 
                                'tex': tags[10],
 
65
                                'description': tags[1],
 
66
                                'name': name,
77
67
                                'code': string.atoi (tags[2]),
78
 
                                'breapth':string.atof (tags[3]),
 
68
                                'breapth': string.atof (tags[3]),
79
69
                                'width': string.atof (tags[4]),
80
 
                                'depth':string.atof (tags[5]),
81
 
                                'height':string.atof (tags[6]),
 
70
                                'depth': string.atof (tags[5]),
 
71
                                'height': string.atof (tags[6]),
82
72
                                'wx': string.atof (tags[7]),
83
 
                                'wy':string.atof (tags[8]),
84
 
                                }
 
73
                                'wy': string.atof (tags[8]),
 
74
                        }
85
75
                        charmetrics.append (m)
86
76
                elif tags[0] == 'font':
87
77
                        global font_family
89
79
                        # To omit 'GNU' (foundry) from font name proper:
90
80
                        # name = tags[2:]
91
81
                        #urg
92
 
                        if 0: #testing
 
82
                        if 0: # testing
93
83
                                tags.append ('Regular')
 
84
 
 
85
                        encoding = re.sub (' ','-', tags[5])
 
86
                        tags = tags[:-1]
94
87
                        name = tags[1:]
95
 
                        global_info['FontName'] = string.join (name,'-')
 
88
                        global_info['design_size'] = string.atof (tags[4])
 
89
                        global_info['FontName'] = string.join (name, '-')
96
90
                        global_info['FullName'] = string.join (name,' ')
97
91
                        global_info['FamilyName'] = string.join (name[1:-1],
98
92
                                                                 '-')
99
93
                        if 1:
100
94
                                global_info['Weight'] = tags[4]
101
 
                        else: #testing
 
95
                        else: # testing
102
96
                                global_info['Weight'] = tags[-1]
 
97
 
103
98
                        global_info['FontBBox'] = '0 0 1000 1000'
104
99
                        global_info['Ascender'] = '0'
105
100
                        global_info['Descender'] = '0'
106
 
                        global_info['EncodingScheme'] = 'FontSpecific'
107
 
        
 
101
                        global_info['EncodingScheme'] = encoding
 
102
 
 
103
                elif tags[0] == 'parameter':
 
104
                        global_info[tags[1]] = tags[2];
 
105
                        
108
106
        return (global_info, charmetrics, deps)
109
107
 
110
108
 
111
 
def write_afm_char_metric(file, charmetric):
112
 
 
113
 
        f = 1000;
114
 
        tup = (charmetric['code'],
115
 
                charmetric['name'],
116
 
                -charmetric['breapth'] *f,
117
 
                -charmetric['depth']*f,
118
 
                charmetric['width']*f,
119
 
                charmetric['height']*f,
120
 
               charmetric['wx'] * f,
121
 
               charmetric['wy'] * f)
122
 
        
123
 
        file.write ('C %d ; N %s ; B %d %d %d %d ; W %d %d ;\n'% tup)
124
 
 
125
 
def write_afm_header (file):
126
 
        file.write ("StartFontMetrics 2.0\n")
127
 
        file.write ("Comment Automatically generated by mf-to-table.py\n")
128
 
 
129
 
def write_afm_metric (file, global_info, charmetrics):
130
 
        for (k,v) in global_info.items():
131
 
                file.write ("%s %s\n" % (k,v))
132
 
        file.write ('StartCharMetrics %d\n' % len(charmetrics ))
133
 
        for m in charmetrics:
134
 
                write_afm_char_metric (file,m)
135
 
        file.write ('EndCharMetrics\n')
136
 
        file.write ('EndFontMetrics\n')
137
 
 
138
109
 
139
110
def write_tex_defs (file, global_info, charmetrics):
140
 
        ##nm = global_info['FontFamily']
141
111
        nm = font_family
142
112
        for m in charmetrics:
143
 
                file.write (r'''\gdef\%s%s{\char%d}%%%s''' % (nm, m['tex'], m['code'],'\n'))
 
113
                
 
114
                texname = re.sub ('[_.]', 'X',  m['name'])
 
115
                def digit_to_letter (match):
 
116
                        return chr (ord (match.group(1)) - ord ('0') + ord ('A'))
 
117
                texname = re.sub ('([0-9])', digit_to_letter, texname)
 
118
                file.write (r'''\gdef\%s%s{\char%d}%%%s''' % \
 
119
                            (nm, texname, m['code'],'\n'))
144
120
        file.write ('\\endinput\n')
145
121
 
 
122
 
 
123
def write_character_lisp_table (file, global_info, charmetrics):
 
124
 
 
125
        def conv_char_metric (charmetric):
 
126
                f = 1.0
 
127
                s = """(%s .
 
128
((bbox . (%f %f %f %f))
 
129
 (subfont . "%s")
 
130
 (subfont-index . %d)
 
131
 (attachment . (%f . %f))))
 
132
""" %(charmetric['name'],
 
133
      -charmetric['breapth'] * f,
 
134
      -charmetric['depth'] * f,
 
135
      charmetric['width'] * f,
 
136
      charmetric['height'] * f,
 
137
      global_info['filename'],
 
138
      charmetric['code'],
 
139
      charmetric['wx'],
 
140
      charmetric['wy'])
 
141
 
 
142
                return s
 
143
 
 
144
        for c in charmetrics:
 
145
                file.write (conv_char_metric (c))
 
146
 
 
147
 
 
148
def write_global_lisp_table (file, global_info):
 
149
        str = ''
 
150
 
 
151
        keys = ['staffsize', 'stafflinethickness', 'staff_space',
 
152
                'linethickness', 'black_notehead_width', 'ledgerlinethickness',
 
153
                'design_size', 
 
154
                'blot_diameter'
 
155
                ]
 
156
        for k in keys:
 
157
                if global_info.has_key (k):
 
158
                        str = str + "(%s . %s)\n" % (k,global_info[k])
 
159
 
 
160
        file.write (str)
 
161
 
 
162
        
146
163
def write_ps_encoding (name, file, global_info, charmetrics):
147
164
        encs = ['.notdef'] * 256
148
165
        for m in charmetrics:
149
 
                encs[m['code']] = m['tex']
 
166
                encs[m['code']] = m['name']
150
167
 
151
168
        file.write ('/%s [\n' % name)
152
 
        for m in range(0,256):
 
169
        for m in range (0, 256):
153
170
                file.write ('  /%s %% %d\n' % (encs[m], m))
154
171
        file.write ('] def\n')
155
 
        
156
 
def write_fontlist (file, global_info, charmetrics):
157
 
        ##nm = global_info['FontFamily']
158
 
        nm = font_family
159
 
        per_line = 3
160
 
        file.write (r"""
161
 
%% LilyPond file to list all font symbols and the corresponding names
162
 
%% Automatically generated by mf-to-table.py
163
 
\score{ \lyrics \new Lyrics { \time %d/8
164
 
""" % (2*per_line+1))
165
 
 
166
 
        count = 0
167
 
        for m in charmetrics:
168
 
 
169
 
                count += 1
170
 
                
171
 
## \musicglyph and \markup require "_" to be escaped differently:
172
 
                
173
 
 
174
 
                scm_string = re.sub('_', r'_', m['name'])
175
 
                tex_string = re.sub ('_', r'\\_' , m['name'])
176
 
                
177
 
## prevent TeX from interpreting "--" as long dash:
178
 
                tex_string=re.sub('--','-{}-', tex_string)
179
 
 
180
 
                file.write ('  \\markup { \\raise #0.75 \\vcenter \\musicglyph #"%s" " %s" } 4 \n' % (scm_string, tex_string))
181
 
 
182
 
                if (count % 3) ==0:
183
 
                        file.write ('\skip 8  \\break\n')
184
 
        file.write (r"""
185
 
}
186
 
  \paper{
187
 
    interscoreline = 1.0
188
 
    indent = 0.0 \cm
189
 
    \context {
190
 
      \LyricsContext
191
 
      \override SeparationItem #'padding = #2
192
 
      minimumVerticalExtent = ##f
193
 
    }
194
 
    \context {
195
 
        \ScoreContext
196
 
        \remove "Bar_number_engraver"
197
 
        }
198
 
        }
199
 
        }
200
 
""")
 
172
 
201
173
 
202
174
def write_deps (file, deps, targets):
203
 
        
204
 
        
205
175
        for t in targets:
206
176
                t = re.sub ( '^\\./', '', t)
207
177
                file.write ('%s '% t)
210
180
                file.write ('%s ' % d)
211
181
        file.write ('\n')
212
182
 
213
 
def help():
214
 
    sys.stdout.write(r"""Usage: mf-to-table [OPTIONS] LOGFILEs
 
183
 
 
184
def help ():
 
185
        sys.stdout.write(r"""Usage: mf-to-table [OPTIONS] LOGFILEs
 
186
 
215
187
Generate feta metrics table from preparated feta log.
216
188
 
217
189
Options:
218
 
  -a, --afm=FILE         specify .afm file
219
190
  -d, --dep=FILE         print dependency info to FILE
220
191
  -h, --help             print this help
221
192
  -l, --ly=FILE          name output table
223
194
  -p, --package=DIR      specify package
224
195
  -t, --tex=FILE         name output tex chardefs
225
196
 
226
 
  """
227
 
)
228
 
    sys.exit (0)
229
 
 
230
 
 
231
 
 
232
 
(options, files) = getopt.getopt(
233
 
    sys.argv[1:], 'a:d:hl:o:p:t:', 
234
 
    ['enc=', 'afm=', 'outdir=', 'dep=',  'tex=', 'ly=', 'debug', 'help', 'package='])
235
 
 
236
 
 
 
197
  """)
 
198
        sys.exit (0)
 
199
 
 
200
 
 
201
(options, files) = \
 
202
  getopt.getopt (sys.argv[1:],
 
203
                 'a:d:ho:p:t:',
 
204
                 ['enc=',  'outdir=', 'dep=', 'lisp=',
 
205
                  'global-lisp=',
 
206
                  'tex=', 'debug', 'help', 'package='])
 
207
 
 
208
global_lisp_nm = ''
 
209
char_lisp_nm = ''
237
210
enc_nm = ''
238
211
texfile_nm = ''
239
212
depfile_nm = ''
240
 
afmfile_nm = ''
241
213
lyfile_nm = ''
242
214
outdir_prefix = '.'
243
215
 
250
222
                outdir_prefix = a
251
223
        elif o == '--tex' or o == '-t':
252
224
                texfile_nm = a
 
225
        elif o == '--lisp': 
 
226
                char_lisp_nm = a
 
227
        elif o == '--global-lisp': 
 
228
                global_lisp_nm = a
253
229
        elif o == '--enc':
254
230
                enc_nm = a
255
 
        elif o == '--ly' or o == '-':
256
 
                lyfile_nm = a
257
231
        elif o== '--help' or o == '-h':
258
232
                help()
259
 
        elif o=='--afm' or o == '-a':
260
 
                afmfile_nm = a
261
233
        elif o == '--debug':
262
234
                debug_b = 1
263
 
        elif o == '-p' or o == '--package':
264
 
                topdir = a
265
235
        else:
266
236
                print o
267
237
                raise getopt.error
269
239
base = re.sub ('.tex$', '', texfile_nm)
270
240
 
271
241
for filenm in files:
272
 
        (g,m, deps) =  parse_logfile (filenm)
273
 
        cs = tfm_checksum (re.sub ('.log$', '.tfm', filenm))
274
 
        afm = open (afmfile_nm, 'w')
 
242
        (g, m, deps) = parse_logfile (filenm)
275
243
 
276
 
        write_afm_header (afm)
277
 
        afm.write ("Comment TfmCheckSum %d\n" % cs)
278
 
        write_afm_metric (afm, g, m)
279
 
        
280
244
        write_tex_defs (open (texfile_nm, 'w'), g, m)
281
245
        enc_name = 'FetaEncoding'
282
 
        if re.search ('parmesan', filenm) :
 
246
        if re.search ('parmesan', filenm):
283
247
                enc_name = 'ParmesanEncoding'
284
 
        elif re.search ('feta-brace', filenm) :
 
248
        elif re.search ('feta-brace', filenm):
285
249
                enc_name = 'FetaBraceEncoding'
 
250
        elif re.search ('feta-alphabet', filenm):
 
251
                enc_name = 'FetaAlphabetEncoding';
286
252
 
287
 
                
288
253
        write_ps_encoding (enc_name, open (enc_nm, 'w'), g, m)
289
 
 
290
 
        write_deps (open (depfile_nm, 'wb'), deps, [base + '.dvi', base + '.pfa', base + '.pfb',  texfile_nm, afmfile_nm])
291
 
        if lyfile_nm != '':
292
 
                write_fontlist(open (lyfile_nm, 'w'), g, m)
293
 
 
294
 
 
295
 
 
 
254
        write_character_lisp_table (open (char_lisp_nm, 'w'), g, m)  
 
255
        write_global_lisp_table (open (global_lisp_nm, 'w'), g)  
 
256
        if depfile_nm:
 
257
                write_deps (open (depfile_nm, 'wb'), deps,
 
258
                            [base + '.log', base + '.dvi', base + '.pfa',
 
259
                             base + '.pfb', texfile_nm])