3 # mf-to-table.py -- convert spacing info in MF logs .afm and .tex
5 # source file of the GNU LilyPond music typesetter
7 # (c) 1997 Han-Wen Nienhuys <hanwen@cs.uu.nl>
18 (options
, files
) = getopt
.getopt(
19 sys
.argv
[1:], 'a:d:hl:o:p:t:',
20 ['afm=', 'outdir=', 'dep=', 'tex=', 'debug', 'help', 'package='])
25 if o
== '-p' or o
== '--package':
28 sys
.path
.append (topdir
+ '/stepmake/bin')
29 from packagepython
import *
30 package
= Package (topdir
)
31 packager
= Packager ()
33 from packagepython
import *
36 begin_autometric_re
= regex
.compile('@{')
37 end_autometric_re
= regex
.compile('@}')
38 include_re
= regex
.compile ('(\([a-zA-Z_0-9-]+\.mf\)')
39 autometric_re
= regex
.compile('@{\(.*\)@}')
41 postfixes
= ['log', 'dvi', '2602gf', 'tfm']
43 class Feta_file(File
):
44 """Read Feta metrics from a metafont log-file."""
46 def include_scan (self
, line
):
47 include_pos
= include_re
.search (line
)
48 while include_pos
<> -1:
49 self
.dependencies
.append (include_re
.group (1))
51 line
= line
[include_pos
+ 1:]
52 include_pos
= include_re
.search (line
)
54 def read_autometricline(self
):
56 while end_autometric_re
.search(line
) == -1 and not self
.eof():
57 suf
= File
.readline(self
)
58 self
.include_scan (suf
)
59 if begin_autometric_re
.search(line
) == -1:
61 line
= line
+ regsub
.sub('\n','', suf
)
62 line
= regsub
.sub('\r','', line
)
69 """return what is enclosed in one @{ @} pair"""
71 while autometric_re
.search(line
) == -1 and not self
.eof():
72 line
= self
.read_autometricline()
77 return autometric_re
.group(1);
78 def __init__(self
, nm
):
79 File
.__init
__(self
, nm
)
80 self
.dependencies
= []
81 def do_file(infile_nm
):
85 # FIXME: should parse output for {} to do indenting.
87 class Indentable_file(File
):
88 """Output file with support for indentation"""
89 def __init__(self
,nm
, mode
):
90 File
.__init
__(self
,nm
,mode
)
91 self
.current_indent_
= 0
92 self
.delta_indent_
= 4
93 def writeline (self
, str):
96 File
.write(self
, '\n')
97 File
.write(self
, ' '* self
.current_indent_
)
100 self
.current_indent_
= self
.delta_indent_
+ self
.current_indent_
;
102 self
.current_indent_
= self
.current_indent_
- self
.delta_indent_
;
103 if self
.current_indent_
< 0:
106 def write(self
, str):
107 lines
= split(str, '\n')
111 self
.writeline (lines
[-1])
113 class Afm_file (File
):
114 def print_f_dimen(self
, f
):
115 f
= f
* 1000 / self
.fontsize
119 # try to mask rounding errors
120 if (dimstr
== '-0.00'):
122 self
.write( dimstr
+' ');
124 def neg_print_dimen(self
, str):
125 self
.print_f_dimen(-atof(str))
126 def print_dimen(self
, str):
127 self
.print_f_dimen(atof(str))
128 def def_symbol (self
, code
, lily_id
, tex_id
, xdim
, ydim
):
129 self
.write ('C %s; N %s-%s; B ' % (code
, self
.groupname
, lily_id
))
131 self
.neg_print_dimen(xdim
[0])
132 self
.neg_print_dimen(ydim
[0])
133 self
.print_dimen(xdim
[1])
134 self
.print_dimen(ydim
[1])
139 self
.write ('Start%s\n' % nm
)
141 self
.write ('End%s\n' % nm
)
145 """Read logs, destill info, and put into output files"""
146 def output_label(self
, line
):
150 tags
= split(line
, '@:')
154 if tags
[0] == 'font':
155 self
.texfile
.write("% name\n")
157 afm
.write ('FontName %s\n' % name
)
158 afm
.start ('FontMetrics')
159 afm
.start ('CharMetrics')
160 afm
.fontsize
= atof(tags
[2])
161 elif label
== "group":
162 self
.texfile
.write("% " + name
+ "\n")
164 elif label
== "puorg":
165 self
.texfile
.write("\n")
166 elif label
== "tnof":
167 afm
.end ('CharMetrics')
168 afm
.end('FontMetrics');
169 elif label
== "char":
176 self
.texfile
.write("\\fetdef\\%s{%s}\n" % (texstr
, code
))
177 afm
.def_symbol (code
, id, texstr
, xdim
, ydim
)
179 raise 'unknown label: ' + label
181 def writedeps (self
, deps
):
183 sys
.stderr
.write ('Huh, no main target??')
186 split
= os
.path
.splitext(filename
)
189 targets
= map (lambda x
,y
= basename
, z
= self
.outdir
: z
+ '/' + y
+ '.' + x
, postfixes
)
190 depstring
= reduce(lambda x
,y
: x
+ ' ' + y
, deps
)
191 dependencies
= map (lambda x
, y
=depstring
: x
+ ': ' + y
, targets
)
192 for x
in dependencies
:
193 self
.depfile
.write (x
+ '\n')
195 def do_file(self
,filenm
):
196 self
.texfile
.write ('\n% input from ' + filenm
+ '\n')
197 feta
= Feta_file(filenm
)
198 while not feta
.eof():
199 line
= feta
.readline()
200 self
.output_label(line
)
203 self
.writedeps (feta
.dependencies
)
205 def __init__(self
, texfile_nm
, depfile_nm
, afmfile_nm
):
206 self
.texfile
= Indentable_file(texfile_nm
, 'w')
207 self
.depfile
= File (depfile_nm
, 'w')
208 self
.afmfile
= Afm_file (afmfile_nm
, 'w')
209 headerstr
= '%% Creator: %s\n%% Automatically generated on\n%% Do not edit' % \
212 self
.texfile
.write(headerstr
)
213 self
.depfile
.write ('# automatically generated by %s\n' % program_id ())
217 self
.depfile
.close ()
223 return time
.asctime(time
.localtime(time
.time()))
226 return 'mf-to-table.py version ' + version
;
229 sys
.stdout
.write(program_id() + '\n')
232 sys
.stdout
.write("Usage: mf-to-table [options] LOGFILEs\n"
233 + "Generate mozarella metrics table from preparated feta log\n\n"
235 + " -a, --afm=FILE .afm file\n"
236 + " -d, --dep=FILE print dependency info to FILE\n"
237 + " -h, --help print this help\n"
238 + " -l, --ly=FILE name output table\n"
239 + " -o, --outdir=DIR prefix for dependency info\n"
240 + " -p, --package=DIR specify package\n"
241 + " -t, --tex=FILE name output tex chardefs\n"
256 if o
== '--dep' or o
== '-d':
258 elif o
== '--outdir' or o
== '-o':
260 elif o
== '--tex' or o
== '-t':
262 elif o
== '--help' or o
== '-h':
264 elif o
=='--afm' or o
== '-a':
268 elif o
== '-p' or o
== '--package':
274 log_reader
= Log_reader( texfile_nm
, depfile_nm
, afmfile_nm
)
275 log_reader
.outdir
= outdir_prefix
277 log_reader
.do_file(filenm
)