4 # mf-to-table.py -- convert spacing info in MF logs .ly and .tex
6 # source file of the GNU LilyPond music typesetter
8 # (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
23 lilypath
= os
.environ
['LILYPOND_SOURCEDIR'] + '/'
26 lilypath
= os
.environ
['top_srcdir'] + '/'
28 print 'Please set LILYPOND_SOURCEDIR to the toplevel source, eg LILYPOND_SOURCEDIR=/home/foobar/lilypond-1.2.3/'
30 lilypath
= lilypath
+ '/bin/'
31 sys
.path
.append(lilypath
)
35 begin_autometric_re
= regex
.compile('@{')
36 end_autometric_re
= regex
.compile('@}')
37 include_re
= regex
.compile ('(\([a-zA-Z_0-9-]+\.mf\)')
38 autometric_re
= regex
.compile('@{\(.*\)@}')
40 postfixes
= ['log', 'dvi', '2602gf', 'tfm']
42 class Feta_file(File
):
43 """Read Feta metrics from a metafont log-file."""
45 def include_scan (self
, line
):
46 include_pos
= include_re
.search (line
)
47 while include_pos
<> -1:
48 self
.dependencies
.append (include_re
.group (1))
50 line
= line
[include_pos
+ 1:]
51 include_pos
= include_re
.search (line
)
53 def read_autometricline(self
):
55 while end_autometric_re
.search(line
) == -1 and not self
.eof():
56 suf
= File
.readline(self
)
57 self
.include_scan (suf
)
58 if begin_autometric_re
.search(line
) == -1:
60 line
= line
+ regsub
.sub('\n','', suf
)
67 """return what is enclosed in one @{ @} pair"""
69 while autometric_re
.search(line
) == -1 and not self
.eof():
70 line
= self
.read_autometricline()
75 return autometric_re
.group(1);
76 def __init__(self
, nm
):
77 File
.__init
__(self
, nm
)
78 self
.dependencies
= []
79 def do_file(infile_nm
):
83 # FIXME: should parse output for {} to do indenting.
85 class Indentable_file(File
):
86 """Output file with support for indentation"""
87 def __init__(self
,nm
, mode
):
88 File
.__init
__(self
,nm
,mode
)
89 self
.current_indent_
= 0
90 self
.delta_indent_
= 4
91 def writeline (self
, str):
94 File
.write(self
, '\n')
95 File
.write(self
, ' '* self
.current_indent_
)
98 self
.current_indent_
= self
.delta_indent_
+ self
.current_indent_
;
100 self
.current_indent_
= self
.current_indent_
- self
.delta_indent_
;
101 if self
.current_indent_
< 0:
104 def write(self
, str):
105 lines
= split(str, '\n')
109 self
.writeline (lines
[-1])
111 class Ly_file(Indentable_file
):
112 """extra provisions for mozarella quirks"""
113 def print_lit(self
, str):
114 self
.write('\"%s\"\t' % str)
116 def print_f_dimen(self
, f
):
119 # try to mask rounding errors
120 if (dimstr
== '-0.00'):
122 self
.write( dimstr
+'\\pt\t');
124 def print_dimen(self
, str):
125 self
.print_f_dimen(atof(str))
127 def neg_print_dimen(self
, str):
128 self
.print_f_dimen(-atof(str));
130 def def_symbol(self
, lily_id
, tex_id
, dims
):
131 self
.print_lit(lily_id
)
132 self
.print_lit('\\\\' + tex_id
)
134 self
.neg_print_dimen(dims
[0])
135 self
.print_dimen(dims
[1])
136 self
.neg_print_dimen(dims
[2])
137 self
.print_dimen(dims
[3])
142 """Read logs, destill info, and put into output files"""
143 def output_label(self
, line
):
147 tags
= split(line
, '@:')
151 if tags
[0] == 'font':
153 ly
.write("% name=\\symboltables {\n")
154 self
.texfile
.write("% name\n")
155 elif label
== "group":
158 ly
.write(' = \\table {\n')
159 self
.texfile
.write("% " + name
+ "\n")
160 elif label
== "puorg":
163 self
.texfile
.write("\n")
164 elif label
== "tnof":
166 ly
.write("% } % $name\n")
167 elif label
== "char":
172 ly
.def_symbol(id, texstr
, tags
[3:7])
174 self
.texfile
.write("\\fetdef\\%s{%s}\n" % (texstr
, code
))
176 raise 'unknown label: ' + label
178 def writedeps (self
, deps
):
180 sys
.stderr
.write ('Huh, no main target??')
183 split
= os
.path
.splitext(filename
)
186 targets
= map (lambda x
,y
= basename
, z
= self
.outdir
: z
+ '/' + y
+ '.' + x
, postfixes
)
187 depstring
= reduce(lambda x
,y
: x
+ ' ' + y
, deps
)
188 dependencies
= map (lambda x
, y
=depstring
: x
+ ': ' + y
, targets
)
189 for x
in dependencies
:
190 self
.depfile
.write (x
+ '\n')
192 def do_file(self
,filenm
):
193 self
.lyfile
.write ('\n% input from ' + filenm
+ '\n')
194 self
.texfile
.write ('\n% input from ' + filenm
+ '\n')
195 feta
= Feta_file(filenm
)
196 while not feta
.eof():
197 line
= feta
.readline()
198 self
.output_label(line
)
201 self
.writedeps (feta
.dependencies
)
203 def __init__(self
, lyfile_nm
, texfile_nm
, depfile_nm
):
204 self
.lyfile
= Ly_file(lyfile_nm
, 'w')
205 self
.texfile
= Indentable_file(texfile_nm
, 'w')
206 self
.depfile
= File (depfile_nm
, 'w')
208 headerstr
= '%% Creator: %s\n%% Automatically generated on\n%% Do not edit' % \
211 self
.lyfile
.write(headerstr
)
212 self
.texfile
.write(headerstr
)
213 self
.depfile
.write ('# automatically generated by %s\n' % program_id ())
218 self
.depfile
.close ()
224 return time
.asctime(time
.localtime(time
.time()))
227 return 'mf-to-table.py version ' + version
;
230 sys
.stdout
.write(program_id() + '\n')
233 sys
.stdout
.write("Usage: mf-to-table [options] LOGFILEs\n"
234 + "Generate mozarella metrics table from preparated feta log\n\n"
236 + " -h, --help print this help\n"
237 + " -l, --ly=FILE name output table\n"
238 + " -d, --dep=FILE print dependency info to FILE\n"
239 + " -o, --outdir=DIR prefix for dependency info\n"
240 + " -t, --tex=FILE name output tex chardefs\n")
246 (options
, files
) = getopt
.getopt(
247 sys
.argv
[1:], 'ho:l:t:d:', ['outdir=', 'dep=', 'ly=', 'tex=', 'debug', 'help'])
249 lyfile_nm
= texfile_nm
= '';
255 if o
== '--dep' or o
== '-d':
257 elif o
== '--outdir' or o
== '-o':
259 elif o
== '--ly' or o
== '-l':
261 elif o
== '--tex' or o
== '-t':
263 elif o
== '--help' or o
== '-h':
271 log_reader
= Log_reader(lyfile_nm
, texfile_nm
, depfile_nm
)
272 log_reader
.outdir
= outdir_prefix
274 log_reader
.do_file(filenm
)