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