]> git.donarmstrong.com Git - lilypond.git/blob - scripts/mudela-book.py
release: 1.0.8
[lilypond.git] / scripts / mudela-book.py
1
2 # python version of mudela-book.  WIP.
3
4 #  TODO: center option
5
6 # log:
7
8 # 0.3:
9 #   rewrite in Python.
10
11 import os
12 import string
13 import regex
14 import getopt
15 import sys
16 import regsub
17
18 outdir = 'out/'
19 program_version = '0.3'
20
21
22
23
24 def file_exist_b(name):
25     try: 
26         f = open(name)
27     except IOError:
28         return 0
29     f.close ()
30     return 1
31
32 class CompileStatus:
33         pass
34
35 def file_mtime (name):
36     return os.stat (name)[8] #mod time
37
38 def compile (command, infile, outfile):
39         indate = file_mtime (infile)
40         try:
41                 outdate = file_mtime (outfile)
42                 recompile = indate > outdate
43
44         except os.error:
45                 recompile = 1
46
47         if recompile:
48                 sys.stderr.write ('invoking `%s\'\n' % command)
49                 
50                 status = os.system (command)
51                 if status:
52                         raise CompileStatus
53
54
55 class Mudela_output:
56         def __init__ (self):
57                 self.basename = ''
58                 self.fragment = 0
59                 self.size = 16
60                 
61         def open (self, basename):
62                 self.basename = basename
63                 self.temp_file = "%s/%s" %(outdir, 'mudela-temp.ly')
64                 self.file = open (self.temp_file, 'w')
65                 self.file.write ('\\include \"paper%d.ly\"\n' % self.size)
66                 if self.size == 16:
67                         s = 'sixteen'
68                 else:
69                         s = 'twenty'
70
71                 self.file.write ('default_paper = \\paper { \\paper_%s\n linewidth = -15.\\cm; }\n' % s)
72                 
73                 if self.fragment:
74                         self.file.write ('\\score { \\melodic { ')
75
76         def write (self,s):
77                 self.file.write (s)
78
79         def close (self):
80                 if self.fragment:
81                         self.file.write (
82                                 '}\n \\paper { linewidth = -1.0\\cm;\n' +
83                                 'castingalgorithm = \\Wordwrap; } }\n')
84
85
86                 self.file.close ()
87
88                 inf=self.basename + '.ly'
89                 outf = self.basename + '.tex'           
90                 if not file_exist_b (inf):
91                         status = 1
92                 else:
93 #                       print 'invoking %s' %('diff %s %s' % (self.temp_file, inf))
94                         status = os.system ('diff -q %s %s' % (self.temp_file, inf))
95 #                       print 'status %d' % status
96
97                 if status:
98                         os.rename (self.temp_file, inf)
99
100                 compile ('lilypond  -o %s %s'%  (self.basename, inf), inf, outf)
101 #                       os.rename (self.basename + '.tex', outdir  +)
102                 
103         
104
105 class Tex_output:
106         def __init__ (self, name):
107                 self.output_fn = '%s/%s' % (outdir, name)
108                 self.mudela = 0
109                 self.file = open (self.output_fn , 'w')
110                 self.verbatim = 0               
111         def open_mudela (self, basename):
112                 self.mudela_basename =basename
113                 if self.verbatim:
114                         self.file.write ('\\begin{verbatim}\n')
115                 self.mudela = 1
116
117         def write (self, s):
118                 self.file.write (s)
119                         
120         def write_mudela (self, s):
121                 if self.verbatim:
122                         self.file.write (s)
123                         
124         def close_mudela (self):
125                 if self.verbatim:
126                         self.file.write ('\\end{verbatim}\n')
127                         self.verbatim = 0
128                 
129                 self.file.write (
130                     '\\preMudelaExample\\input %s\n\postMudelaExample' %(self.mudela_basename))
131                 self.mudela = 0
132
133
134
135
136
137 begin_mudela_re = regex.compile ('^ *\\\\begin{mudela}')
138 begin_mudela_opts_re = regex.compile ('^ *\\\\begin{mudela}\[\(.*\)\]')
139 end_mudela_re = regex.compile ('^ *\\\\end{mudela}')
140 section_re = regex.compile ('\\\\section')
141 chapter_re = regex.compile ('\\\\chapter')
142 input_re = regex.compile ('^\\\\input[ \t\n]+\\(.*\\)$')
143
144 class Tex_input:
145         def __init__ (self,name):
146                 if regex.search ('\\.[^/\\\\]+',name) == -1:
147                         name = name + '.tex'
148                 print 'opening %s' % name
149                 self.filename = name
150                 self.infile = open (name)
151                 
152         def get_lines (self):
153                 lines = self.infile.readlines ()
154                 (retlines, retdeps) = ([],[self.filename])
155                 for line in lines:
156                         if input_re.search (line) <> -1:
157                                 t = Tex_input (input_re.group (1))
158                                 ls =t.get_lines ()
159                                 retlines = retlines + ls[0]
160                                 retdeps = retdeps + ls[1]
161                         else:
162                                 retlines.append (line)
163
164                 return (retlines, retdeps)
165
166 class Main_tex_input(Tex_input):
167         def __init__ (self, name, outname):
168                 
169                 Tex_input.__init__ (self, name) # ugh
170
171                 self.outname = outname
172                 self.chapter = 0
173                 self.section = 0
174                 self.fine_count =0
175                 self.mudtex = Tex_output (self.outname)
176                 self.mudela = None
177                 self.deps = []
178         def set_sections (self, l):
179                 if section_re.search (l) <> -1:
180                         self.section = self.section + 1
181                 if chapter_re.search (l) <> -1:
182                         self.section = 0
183                         self.chapter = self.chapter + 1
184
185                         
186         def gulp_mudela (self):
187                 pass
188
189         def gen_basename (self):
190                 return '%s/%s-%d.%d.%d' % (outdir, self.outname,self.chapter,self.section,self.fine_count)
191
192         def do_it(self):
193                 (lines, self.deps) = self.get_lines ()
194                 for line in lines:
195                         if begin_mudela_re.search (line) <> -1:
196                                 if begin_mudela_opts_re.search (line) <> -1:
197                                         opts = begin_mudela_opts_re.group (1)
198                                 else:
199                                         opts = ''
200                                 optlist = string.split (opts, ',')
201                                 self.mudela = Mudela_output ()
202                                 if 'fragment' in optlist:
203                                         self.mudela.fragment = 1
204                                 if '16pt' in optlist:
205                                         self.mudela.size = 16
206                                 if '20pt' in optlist:
207                                         self.mudela.size = 20
208                                 
209                                 if 'verbatim' in optlist:
210                                         self.mudtex.verbatim = 1
211
212                                 b = self.gen_basename ()
213                                 self.mudtex.open_mudela (b)
214                                 self.mudela.open (b)
215
216
217                                 continue
218                         elif end_mudela_re.search (line) <> -1:
219                                 self.mudela.close ()
220                                 self.mudtex.close_mudela ()
221                                 self.mudela = None
222                                 self.fine_count = self.fine_count + 1
223                                 continue
224                             
225                         if self.mudela:
226                                 self.mudela.write (line)
227                                 self.mudtex.write_mudela (line)
228                         else:
229                                 self.mudtex.write (line)
230                         self.set_sections(line)
231                 del self.mudtex
232                 
233
234 def help():
235     sys.stdout.write("Usage: mudela-book [options] FILE\n"
236                  + "Generate hybrid LaTeX input from Latex + mudela"
237                  + "Options:\n"
238                  + "  -h, --help             print this help\n"
239                  + "  -d, --outdir=DIR       prefix directory\n" 
240                  + "  -o, --outname=FILE     prefix for filenames\n"
241                      )
242     sys.exit (0)
243
244
245
246 sys.stderr.write ('This is %s version %s\n' % ('mudela-book', program_version))
247
248 outname = ''
249 (options, files) = getopt.getopt(
250         sys.argv[1:], 'hd:o:', [ 'outdir=', 'outname=', 'help', 'dependencies'])
251
252 do_deps = 0
253 for opt in options:
254         o = opt[0]
255         a = opt[1]
256         if o == '--outname' or o == '-o':
257                 outname = a
258         if o == '--outdir' or o == '-d':
259                 outdir = a
260         if o == '--help' or o == '-h':
261                 help ()
262         if o == '--dependencies':
263                 do_deps = 1
264
265 def write_deps (fn, out,  deps):
266         out_fn = outdir + '/' + fn
267         print '\`writing \`%s\'\n\'' % out_fn
268         
269         f = open (out_fn, 'w')
270         f.write ('%s: %s\n'% (outdir + '/' + out + '.dvi',
271                               reduce (lambda x,y: x + ' '+ y, deps)))
272         f.close ()
273
274
275 for f in files:
276         my_outname = outname
277         if not my_outname:
278                 my_outname = regsub.sub ('\\(.*\\)\\.doc', '\\1', f)
279
280         my_depname = my_outname + '.dep'
281
282         inp = Main_tex_input (f, my_outname)
283         inp.do_it ()
284
285         if do_deps:
286                 write_deps (my_depname, my_outname, inp.deps)
287
288