]> git.donarmstrong.com Git - lilypond.git/blob - scripts/mudela-book.py
release: 1.0.17
[lilypond.git] / scripts / mudela-book.py
1 #!@PYTHON@
2
3 #  TODO: center option
4
5 # log:
6
7 # 0.3:
8 #   rewrite in Python.
9
10 import os
11 import string
12 import re
13 import getopt
14 import sys
15
16 outdir = 'out/'
17 program_version = '0.3'
18
19
20
21
22 def file_exist_b(name):
23     try: 
24         f = open(name)
25     except IOError:
26         return 0
27     f.close ()
28     return 1
29
30 class CompileStatus:
31         pass
32
33 def file_mtime (name):
34     return os.stat (name)[8] #mod time
35
36 def compile (command, infile, outfile):
37         indate = file_mtime (infile)
38         try:
39                 outdate = file_mtime (outfile)
40                 recompile = indate > outdate
41
42         except os.error:
43                 recompile = 1
44
45         if recompile:
46                 sys.stderr.write ('invoking `%s\'\n' % command)
47                 
48                 status = os.system (command)
49                 if status:
50                         raise CompileStatus
51
52
53 class Mudela_output:
54         def __init__ (self):
55                 self.basename = ''
56                 self.fragment = 0
57                 self.size = 16
58                 
59         def open (self, basename):
60                 self.basename = basename
61                 self.temp_file = "%s/%s" %(outdir, 'mudela-temp.ly')
62                 self.file = open (self.temp_file, 'w')
63                 self.file.write ('\\include \"paper%d.ly\"\n' % self.size)
64                 if self.size == 16:
65                         s = 'sixteen'
66                 else:
67                         s = 'twenty'
68
69                 self.file.write ('default_paper = \\paper { \\paper_%s\n linewidth = -15.\\cm; }\n' % s)
70                 
71                 if self.fragment:
72                         self.file.write ('\\score { \\notes { ')
73
74         def write (self,s):
75                 self.file.write (s)
76
77         def close (self):
78                 if self.fragment:
79                         self.file.write (
80                                 '}\n \\paper { linewidth = -1.0\\cm;\n' +
81                                 'castingalgorithm = \\Wordwrap; } }\n')
82
83
84                 self.file.close ()
85
86                 inf=self.basename + '.ly'
87                 outf = self.basename + '.tex'           
88                 if not file_exist_b (inf):
89                         status = 1
90                 else:
91 #                       print 'invoking %s' %('diff %s %s' % (self.temp_file, inf))
92                         status = os.system ('diff -q %s %s' % (self.temp_file, inf))
93 #                       print 'status %d' % status
94
95                 if status:
96                         os.rename (self.temp_file, inf)
97
98                 compile ('lilypond  -o %s %s'%  (self.basename, inf), inf, outf)
99 #                       os.rename (self.basename + '.tex', outdir  +)
100                 
101         
102
103 class Tex_output:
104         def __init__ (self, name):
105                 self.output_fn = '%s/%s' % (outdir, name)
106                 self.mudela = 0
107                 self.file = open (self.output_fn , 'w')
108                 self.verbatim = 0               
109         def open_mudela (self, basename):
110                 self.mudela_basename =basename
111                 if self.verbatim:
112                         self.file.write ('\\begin{verbatim}\n')
113                 self.mudela = 1
114
115         def write (self, s):
116                 self.file.write (s)
117                         
118         def write_mudela (self, s):
119                 if self.verbatim:
120                         self.file.write (s)
121                         
122         def close_mudela (self):
123                 if self.verbatim:
124                         self.file.write ('\\end{verbatim}\n')
125                         self.verbatim = 0
126                 
127                 self.file.write (
128                     '\\preMudelaExample\\input %s\n\postMudelaExample' %(self.mudela_basename))
129                 self.mudela = 0
130
131
132
133
134
135 begin_mudela_re = re.compile ('^ *\\\\begin{mudela}')
136 begin_mudela_opts_re = re.compile ('^ *\\\\begin{mudela}\[(.*)\]')
137 end_mudela_re = re.compile ('^ *\\\\end{mudela}')
138 section_re = re.compile ('\\\\section')
139 chapter_re = re.compile ('\\\\chapter')
140 input_re = re.compile ('^\\\\input[ \t\n]+(.*)$')
141
142 class Tex_input:
143         def __init__ (self,name):
144                 if not re.search ('\\.[^/\\\\]+',name):
145                         name = name + '.tex'
146                 print 'opening %s' % name
147                 self.filename = name
148                 self.infile = open (name)
149                 
150         def get_lines (self):
151                 lines = self.infile.readlines ()
152                 (retlines, retdeps) = ([],[self.filename])
153                 for line in lines:
154                         m = input_re.search (line)
155                         if m:
156                                 t = Tex_input (m.group (1))
157                                 ls =t.get_lines ()
158                                 retlines = retlines + ls[0]
159                                 retdeps = retdeps + ls[1]
160                         else:
161                                 retlines.append (line)
162
163                 return (retlines, retdeps)
164
165 class Main_tex_input(Tex_input):
166         def __init__ (self, name, outname):
167                 
168                 Tex_input.__init__ (self, name) # ugh
169
170                 self.outname = outname
171                 self.chapter = 0
172                 self.section = 0
173                 self.fine_count =0
174                 self.mudtex = Tex_output (self.outname)
175                 self.mudela = None
176                 self.deps = []
177         def set_sections (self, l):
178                 if section_re.search (l):
179                         self.section = self.section + 1
180                 if chapter_re.search (l):
181                         self.section = 0
182                         self.chapter = self.chapter + 1
183
184                         
185         def gulp_mudela (self):
186                 pass
187
188         def gen_basename (self):
189                 return '%s/%s-%d.%d.%d' % (outdir, self.outname,self.chapter,self.section,self.fine_count)
190
191         def do_it(self):
192                 (lines, self.deps) = self.get_lines ()
193                 for line in lines:
194                         if begin_mudela_re.search (line):
195                                 m =begin_mudela_opts_re.search (line) 
196                                 if m:
197                                         opts = m.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):
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