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