X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=buildscripts%2Fmf-to-table.py;h=f3b9c2e661fd6cee2810624bd91b17fc0bc7b5a0;hb=1a16035eb63fca3df67718042a446e6546507ce9;hp=4722fea6cd90ebd30abe716843521238b38ff836;hpb=07d4d05df6479d58c3c5152c07d7c86b94ee98b4;p=lilypond.git diff --git a/buildscripts/mf-to-table.py b/buildscripts/mf-to-table.py index 4722fea6cd..f3b9c2e661 100644 --- a/buildscripts/mf-to-table.py +++ b/buildscripts/mf-to-table.py @@ -4,7 +4,7 @@ # # source file of the GNU LilyPond music typesetter # -# (c) 1997 Han-Wen Nienhuys +# (c) 1997--2004 Han-Wen Nienhuys import os import sys @@ -13,39 +13,11 @@ 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 = open (fn).read () str = re.sub ('\n', '', str) str = re.sub ('[\t ]+', ' ', str) @@ -65,181 +37,276 @@ def read_log_file (fn): 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) +class Char_metric: + def __init__ (self): + pass + + +def tfm_checksum (fn): + sys.stderr.write ("Reading checksum from `%s'\n" % fn) + s = open (fn).read () + s = s[ 12 * 2 : ] + cs_bytes = s[:4] + + shift = 24 + cs = 0 + for b in cs_bytes: + cs = cs + (long (ord (b)) << shift) + shift = shift - 8 + + return cs + +## ugh. What's font_family supposed to be? It's not an afm thing. +font_family = 'feta' +def parse_logfile (fn): + (autolines, deps) = read_log_file (fn) + charmetrics = [] + global_info = {} + group = '' + + for l in autolines: + tags = string.split(l, '@:') + if tags[0] == 'group': + group = tags[1] + elif tags[0] == 'puorg': + group = '' + elif tags[0] == 'char': + name = tags[9] + if group: + name = group + '-' + name + m = { + 'description': tags[1], + 'name': name, + 'tex': tags[10], + 'code': string.atoi (tags[2]), + 'breapth':string.atof (tags[3]), + 'width': string.atof (tags[4]), + 'depth':string.atof (tags[5]), + 'height':string.atof (tags[6]), + 'wx': string.atof (tags[7]), + 'wy':string.atof (tags[8]), + } + charmetrics.append (m) + elif tags[0] == 'font': + global font_family + font_family = (tags[3]) + # To omit 'GNU' (foundry) from font name proper: + # name = tags[2:] + #urg + if 0: #testing + tags.append ('Regular') + + + encoding = re.sub (' ','-', tags[5]) + tags = tags[:-1] + name = tags[1:] + global_info['DesignSize'] = string.atof (tags[4]) + global_info['FontName'] = string.join (name,'-') + global_info['FullName'] = string.join (name,' ') + global_info['FamilyName'] = string.join (name[1:-1], + '-') + if 1: + global_info['Weight'] = tags[4] + else: #testing + global_info['Weight'] = tags[-1] + + global_info['FontBBox'] = '0 0 1000 1000' + global_info['Ascender'] = '0' + global_info['Descender'] = '0' + global_info['EncodingScheme'] = encoding - 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) + return (global_info, charmetrics, deps) + +def write_afm_char_metric(file, charmetric): + + f = 1000; + tup = (charmetric['code'], + charmetric['name'], + -charmetric['breapth'] *f, + -charmetric['depth']*f, + charmetric['width']*f, + charmetric['height']*f, + charmetric['wx'] * f, + charmetric['wy'] * f) + file.write ('C %d ; N %s ; B %d %d %d %d ; W %d %d ;\n'% tup) + +def write_afm_header (file): + file.write ("StartFontMetrics 2.0\n") + file.write ("Comment Automatically generated by mf-to-table.py\n") + +def write_afm_metric (file, global_info, charmetrics): + for (k,v) in global_info.items(): + file.write ("%s %s\n" % (k,v)) + file.write ('StartCharMetrics %d\n' % len(charmetrics )) + for m in charmetrics: + write_afm_char_metric (file,m) + file.write ('EndCharMetrics\n') + file.write ('EndFontMetrics\n') + + +def write_tex_defs (file, global_info, charmetrics): + ##nm = global_info['FontFamily'] + nm = font_family + for m in charmetrics: + file.write (r'''\gdef\%s%s{\char%d}%%%s''' % (nm, m['tex'], m['code'],'\n')) + file.write ('\\endinput\n') + +def write_ps_encoding (name, file, global_info, charmetrics): + encs = ['.notdef'] * 256 + for m in charmetrics: + encs[m['code']] = m['tex'] + + file.write ('/%s [\n' % name) + for m in range(0,256): + file.write (' /%s %% %d\n' % (encs[m], m)) + file.write ('] def\n') -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) +def write_fontlist (file, global_info, charmetrics): + ##nm = global_info['FontFamily'] + nm = font_family + per_line = 3 + file.write (r""" +%% LilyPond file to list all font symbols and the corresponding names +%% Automatically generated by mf-to-table.py +\score{ \new Lyrics \lyrics { \time %d/8 +""" % (2*per_line+1)) + + count = 0 + for m in charmetrics: + + count += 1 + +## \musicglyph and \markup require "_" to be escaped differently: + + + scm_string = re.sub('_', r'_', m['name']) + tex_string = re.sub ('_', r'\\_' , m['name']) + +## prevent TeX from interpreting "--" as long dash: + tex_string=re.sub('--','-{}-', tex_string) + + file.write (' \\markup { \\raise #0.75 \\vcenter \\musicglyph #"%s" " %s" } 4 \n' % (scm_string, tex_string)) + + if (count % 3) ==0: + file.write ('\skip 8 \\break\n') + file.write (r""" +} + \paper{ + interscoreline = 1.0 + indent = 0.0 \cm + \context { + \Lyrics + \override SeparationItem #'padding = #2 + minimumVerticalExtent = ##f + } + \context { + \Score + \remove "Bar_number_engraver" + } + } + } +""") + +def write_deps (file, deps, targets): - 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; + for t in targets: + t = re.sub ( '^\\./', '', t) + file.write ('%s '% t) + file.write (": ") + for d in deps: + file.write ('%s ' % d) + file.write ('\n') -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 + sys.stdout.write(r"""Usage: mf-to-table [OPTIONS] LOGFILEs +Generate feta metrics table from preparated feta log. + Options: - -a, --afm=FILE .afm file + -a, --afm=FILE specify .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""" + -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: +(options, files) = getopt.getopt( + sys.argv[1:], 'a:d:hl:o:p:t:', + ['enc=', 'afm=', 'outdir=', 'dep=', 'tex=', 'ly=', 'debug', 'help', 'package=']) + + +enc_nm = '' +texfile_nm = '' +depfile_nm = '' +afmfile_nm = '' +lyfile_nm = '' +outdir_prefix = '.' + +for opt in options: o = opt[0] a = opt[1] if o == '--dep' or o == '-d': - depfile_nm = a + depfile_nm = a elif o == '--outdir' or o == '-o': - outdir_prefix = a + outdir_prefix = a elif o == '--tex' or o == '-t': - texfile_nm = a + texfile_nm = a + elif o == '--enc': + enc_nm = a + elif o == '--ly' or o == '-l': + lyfile_nm = a elif o== '--help' or o == '-h': - help() + help() elif o=='--afm' or o == '-a': - afmfile_nm = a + afmfile_nm = a elif o == '--debug': - debug_b = 1 + debug_b = 1 elif o == '-p' or o == '--package': - topdir = a + topdir = a else: - print o - raise getopt.error + print o + raise getopt.error + +base = re.sub ('.tex$', '', texfile_nm) + +for filenm in files: + (g, m, deps) = parse_logfile (filenm) + cs = tfm_checksum (re.sub ('.log$', '.tfm', filenm)) + afm = open (afmfile_nm, 'w') + + write_afm_header (afm) + afm.write ("Comment TfmCheckSum %d\n" % cs) + afm.write ("Comment DesignSize %.2f\n" % g['DesignSize']) + + del g['DesignSize'] + + write_afm_metric (afm, g, m) + + write_tex_defs (open (texfile_nm, 'w'), g, m) + enc_name = 'FetaEncoding' + if re.search ('parmesan', filenm) : + enc_name = 'ParmesanEncoding' + elif re.search ('feta-brace', filenm) : + enc_name = 'FetaBraceEncoding' + + write_ps_encoding (enc_name, open (enc_nm, 'w'), g, m) + + if depfile_nm: + write_deps (open (depfile_nm, 'wb'), deps, + [base + '.dvi', base + '.pfa', base + '.pfb', + texfile_nm, afmfile_nm]) + if lyfile_nm: + write_fontlist (open (lyfile_nm, 'w'), g, m) - 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()