]> git.donarmstrong.com Git - lilypond.git/blob - bin/mf-to-table.py
release: 0.1.48
[lilypond.git] / bin / mf-to-table.py
1 #!@PYTHON@
2
3
4 # mf-to-table.py -- convert spacing info in  MF logs .ly and .tex
5
6 # source file of the GNU LilyPond music typesetter
7
8 # (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
9
10
11 import getopt
12 from string import *
13 import regex
14 import regsub
15 import os
16 import sys
17 import time
18 from flower import *
19
20 begin_autometric_re = regex.compile('@{')
21 end_autometric_re = regex.compile('@}')
22 autometric_re = regex.compile('@{\(.*\)@}')
23 version = '0.5'
24
25 class Feta_file(File):
26     """Read Feta metrics from a metafont log-file."""
27     def read_autometricline(self):
28         line = ''
29         while end_autometric_re.search(line) == -1 and not self.eof():
30             suf = File.readline(self)
31             if begin_autometric_re.search(line) == -1:
32                 line = ''
33             line = line + regsub.sub('\n','', suf)
34
35         if self.eof():
36            return ''
37
38         return line;
39     def readline(self):
40         """return what is enclosed in one @{ @} pair"""
41         line = '';
42         while autometric_re.search(line) == -1 and not self.eof():
43             line = self.read_autometricline()
44
45         if self.eof():
46             return '';
47
48         return autometric_re.group(1);
49     def __init__(self, nm):
50         File.__init__(self, nm)
51     def do_file(infile_nm):
52         infile = readline();
53
54 #
55 # FIXME: should parse output for {} to do indenting.
56 #
57 class Indentable_file(File):
58     """Output file with support for indentation"""
59     def __init__(self,nm, mode):
60         File.__init__(self,nm,mode)
61         self.current_indent_ = 0
62         self.delta_indent_ = 4
63     def writeline (self, str):
64         File.write(self, str)
65     def writeeol(self):
66         File.write(self, '\n')
67         File.write(self, ' '* self.current_indent_)
68
69     def indent(self):
70         self.current_indent_ = self.delta_indent_ + self.current_indent_;
71     def dedent(self):
72         self.current_indent_ = self.current_indent_ - self.delta_indent_;
73         if self.current_indent_ < 0:
74             raise 'Nesting!'
75
76     def write(self, str):
77         lines = split(str, '\n')
78         for l in lines[:-1]:
79             self.writeline(l)
80             self.writeeol()
81         self.writeline (lines[-1])
82
83 class Ly_file(Indentable_file):
84     """extra provisions for mozarella quirks"""
85     def print_lit(self, str):
86         self.write('\"%s\"\t' % str)
87
88     def print_f_dimen(self, f):
89         dimstr = '%.2f' % f
90
91         # try to mask rounding errors
92         if (dimstr == '-0.00'):
93                 dimstr = '0.00'
94         self.write( dimstr  +'\\pt\t');
95
96     def print_dimen(self, str):
97         self.print_f_dimen(atof(str))
98     
99     def neg_print_dimen(self, str):
100         self.print_f_dimen(-atof(str));
101         
102     def def_symbol(self, lily_id, tex_id, dims):
103         self.print_lit(lily_id)
104         self.print_lit('\\\\' + tex_id)
105
106         self.neg_print_dimen(dims [0])
107         self.print_dimen(dims [1])
108         self.neg_print_dimen(dims [2])
109         self.print_dimen(dims [3])
110         self.write('\n')
111         
112         
113 class Log_reader:
114     """Read logs, destill info, and put into output files"""
115     def output_label(self, line):
116
117         if not line:
118             return;
119         tags = split(line, '@:')
120         label = tags[0]
121         name = tags[1]
122         ly = self.lyfile        
123         if tags[0] == 'font':
124             ly.indent()
125             ly.write("% name=\\symboltables {\n")
126             self.texfile.write("% name\n")
127         elif label == "group":
128             ly.indent()
129             ly.print_lit(name)
130             ly.write(' = \\table {\n')
131             self.texfile.write("% " + name + "\n")
132         elif label == "puorg":
133             ly.dedent()
134             ly.write("}\n")
135             self.texfile.write("\n")
136         elif label == "tnof":
137             ly.dedent()
138             ly.write("%  } % $name\n")
139         elif label == "char":
140             code = tags[2]
141             id = tags [7]
142             texstr = tags [8]
143             
144             ly.def_symbol(id, texstr, tags[3:7])
145             
146             self.texfile.write("\\fetdef\\%s{%s}\n" % (texstr, code))
147         else:
148             raise 'unknown label: ' + label
149
150
151     def do_file(self,filenm):
152         self.lyfile.write('\n% input from ' + filenm + '\n')
153         self.texfile.write('\n% input from ' + filenm + '\n')
154         feta = Feta_file(filenm)
155         while not feta.eof():
156             line = feta.readline()
157             self.output_label(line)
158         feta.close()
159
160     def __init__(self, lyfile_nm, texfile_nm):      
161         self.lyfile = Ly_file(lyfile_nm, 'w')
162         self.texfile = Indentable_file(texfile_nm, 'w')
163
164
165         headerstr = '%% Creator: %s\n%% Automatically generated on\n%% Do not edit' % \
166                    (program_id() )
167
168         self.lyfile.write(headerstr)
169         self.texfile.write(headerstr)
170
171     def close(self):
172         self.lyfile.close()
173         self.texfile.close()
174
175     def __del__(self):
176         self.close()
177
178 def today_str():
179     return time.asctime(time.localtime(time.time()))
180         
181 def program_id():
182     return 'mf-to-table.py version ' + version;
183
184 def identify():
185     sys.stdout.write(program_id() + '\n')
186     
187 def help():
188     sys.stdout.write("Usage: mf-to-table [options] LOGFILEs\n"
189                  + "Generate mozarella metrics table from preparated feta log\n\n"
190                  + "Options:\n"
191                  + "  -h, --help             print this help\n"
192                  + "  -l, --ly=FILE          name output table\n"
193                  + "  -t, --tex=FILE         name output tex chardefs\n")
194
195
196 def main():
197     identify()
198     (options, files) = getopt.getopt(
199         sys.argv[1:], 'hl:t:', ['ly=', 'tex=', 'debug', 'help'])
200
201     lyfile_nm = texfile_nm = '';
202     for opt in options:
203         o = opt[0]
204         a = opt[1]
205         if o == '--ly' or o == '-l':
206             lyfile_nm = a
207         elif o == '--tex' or o == '-t':
208             texfile_nm = a
209         elif o== '--help' or o == '-h':
210             help()
211         elif o == '--debug':
212             debug_b = 1
213         else:
214             raise getopt.error
215
216     log_reader = Log_reader(lyfile_nm, texfile_nm)
217     for filenm in files:
218         log_reader.do_file(filenm)
219     log_reader.close()
220
221
222 main()