2 # -*- coding: utf-8 -*-
13 program_name
= 'generate_oly_score'
14 settings_file
= 'oly_structure.def'
16 script_path
= os
.path
.dirname(__file__
)
24 ######################################################################
26 ######################################################################
28 help_text
= r
"""Usage: %(program_name)s [OPTIONS]... [DEF-FILE]
29 Create a complete file structure for a score using OrchestralLily.
30 If no definitions file it given, the file oly_structure.def is used
33 -h, --help print this help
34 -o, --output=NAME write tely doc to NAME (default: read from settings or current directory)
38 sys
.stdout
.write ( text
)
41 (options
, files
) = getopt
.getopt (sys
.argv
[1:], 'ho:',
47 if o
== '-h' or o
== '--help':
48 help (help_text
% vars ())
49 #elif o == '-s' or o == '--settings':
51 elif o
== '-o' or o
== '--output':
54 raise Exception ('unknown option: ' + o
)
57 settings_file
= files
[0]
60 ######################################################################
62 ######################################################################
64 def load_settings (file_name
):
65 global output_dir
, basename
;
67 in_f
= open (file_name
)
70 settings_expr
= eval(s
);
72 print ("Unable to load settings file '%s'. Exiting..." % file_name
)
74 except SyntaxError as ex
:
76 print ("Unable to interpret settings file '%s', it's syntax is invalid. Exiting..." % file_name
);
79 basename
= settings_expr
.get ("basename", "Score")
81 output_dir
= settings_expr
.get ("output_dir", output_dir
) + "/";
85 ######################################################################
87 ######################################################################
89 def write_file (file_name
, contents
):
91 if os
.path
.exists (file_name
):
94 dir = os
.path
.dirname (fn
);
95 if not os
.path
.exists (dir):
99 out_f
= open (fn
, "w")
100 s
= out_f
.write(contents
)
103 print ("Unable to write to output file '%s'. Exiting..." % fn
)
106 # If the file already existed, check if the new file is identical.
107 if (fn
!= file_name
):
108 patchfile
= os
.path
.join (dir, "patches", os
.path
.basename(file_name
) + ".patch")
109 if os
.path
.exists (patchfile
):
110 #print ("Trying to apply patch %s" % patchfile)
112 #retcode = subprocess.call(["patch ", fn, patchfile], shell=True)
113 retcode
= subprocess
.call("patch -Ns \""+ fn
+ "\" \"" + patchfile
+ "\"", shell
=True)
115 print >>sys
.stderr
, "Unable to apply patch to file \"", fn
, "\"."
117 #print >>sys.stderr, "Child returned", retcode
119 print >>sys
.stderr
, "Execution failed:", e
121 #print ("Unable to find patch %s" % patchfile)
123 if filecmp
.cmp (fn
, file_name
):
126 print ("A file %s already existed, created new file %s." % (os
.path
.basename(file_name
), os
.path
.basename(fn
)))
130 ######################################################################
132 ######################################################################
134 def init_replacements (settings
):
135 rep
= settings
.copy ();
137 del rep
["instruments"];
144 ######################################################################
146 ######################################################################
149 "Makefile": "Makefile",
151 "movement": "TEMPLATE_Include_Movement.ily",
152 "snippet_def_lyrics": "TEMPLATE_Snippet_DefinitionLyrics.ily",
153 "snippet_def_music": "TEMPLATE_Snippet_DefinitionMusic.ily",
154 "snippet_def_include": "TEMPLATE_Snippet_DefinitionInclude.ily",
156 "settings": "TEMPLATE_Settings.ily",
157 "settings_global": "TEMPLATE_Settings_Global.ily",
158 "settings_fullscore": "TEMPLATE_Settings_FullScore.ily",
159 "settings_instrument": "TEMPLATE_Settings_Instrument.ily",
160 "settings_vocalvoice": "TEMPLATE_Settings_VocalVoice.ily",
161 "settings_vocalscore": "TEMPLATE_Settings_VocalScore.ily",
163 "snippet_part_score": "TEMPLATE_Snippet_PartScore.ily",
165 "score_full": "TEMPLATE_Score_FullScore.ly",
166 "score_instrument": "TEMPLATE_Score_Instrument.ly",
168 "itex_settings": "TEXTEMPLATE_Settings.itex",
169 "itex_about": "TEXTEMPLATE_Include_About.itex",
170 "itex_contents": "TEXTEMPLATE_Include_ContentsMaterial.itex",
171 "itex_leben": "TEXTEMPLATE_Include_Leben.itex",
172 "itex_text": "TEXTEMPLATE_Include_Text.itex",
174 "itex_todo": "TEXTEMPLATE_Include_Todo.itex",
175 "itex_preface_long": "TEXTEMPLATE_Include_Preface_Long.itex",
176 "itex_preface_short": "TEXTEMPLATE_Include_Preface_Short.itex",
178 "itex_coverpage": "TEXTEMPLATE_Include_Coverpage.itex",
179 "itex_backpage": "TEXTEMPLATE_Include_Backpage.itex",
181 "itex_kritbericht": "TEXTEMPLATE_Include_KritBericht.itex",
182 "tex_score": "TEXTEMPLATE_Score.tex",
183 "tex_instruments": "TEXTEMPLATE_Score_Instruments.tex",
185 "itex_snippet_textmovement": "TEXTEMPLATE_Snippet_TextMovement.itex",
186 "itex_snippet_kritbericht": "TEXTEMPLATE_Snippet_KritBericht_Movement.itex",
187 "itex_snippet_material": "TEXTEMPLATE_Snippet_Material_Score.itex",
188 "itex_snippet_instrument": "TEXTEMPLATE_Snippet_Instrument.itex",
191 def load_file (file_name
):
194 in_f
= open (file_name
, "rb")
198 print ("Unable to load file %s" % file_name
);
201 def load_templates (settings
):
203 template_path
= script_path
+ "/Templates/";
205 for id in template_names
:
206 filename
= template_names
[id]
207 s
= load_file (template_path
+ filename
);
211 print ("Unable to load template file %s (id %s).\n" % (filename
, id));
215 ######################################################################
216 # Creating settings files
217 ######################################################################
219 def write_settings_file (fn
, contents
):
220 write_file (fn
, contents
);
221 settings_files
.append (fn
)
223 def generate_settings_files (settings
, templates
, replacements
):
226 replacements
["filename"] = m
227 inc
+= (templates
["snippet_def_include"] % replacements
)
228 del replacements
["filename"];
229 replacements
["includefiles"] = inc
231 write_settings_file (output_dir
+ basename
+ "_Settings.ily", templates
["settings"] % replacements
);
232 write_file (output_dir
+ basename
+ "_Settings_Global.ily", templates
["settings_global"] % replacements
);
234 if (settings
.get("scores", [])):
235 write_settings_file (output_dir
+ basename
+ "_Settings_FullScore.ily", templates
["settings_fullscore"] % replacements
);
236 if (settings
.get("instruments", [])):
237 write_settings_file (output_dir
+ basename
+ "_Settings_Instrument.ily", templates
["settings_instrument"] % replacements
);
239 print ("WARNING: No instruments: %s" % settings
.get("instruments", []));
240 if (settings
.get("lyrics", [])):
241 write_settings_file (output_dir
+ basename
+ "_Settings_VocalVoice.ily", templates
["settings_vocalvoice"] % replacements
);
242 write_settings_file (output_dir
+ basename
+ "_Settings_VocalScore.ily", templates
["settings_vocalscore"] % replacements
);
243 del replacements
["includefiles"]
246 ######################################################################
247 # Creating movement files
248 ######################################################################
250 def generate_movement_files (settings
, templates
, replacements
):
251 movements
= settings
.get ("parts", []);
252 instruments
= settings
.get ("instruments", []);
253 lyrics
= settings
.get ("lyrics", []);
254 if (movements
== {}):
255 print ("No parts defined in settings file...");
257 if (instruments
== []):
258 print ("No instruments defined in settings file...");
264 name
= m
.get ("name", "TODO")
265 filename_ext
= m
.get ("filename", name
)
266 replacements
["movement"] = name
267 replacements
["movementname"] = m
.get ("piece", name
)
268 replacements
["movementtacet"] = m
.get ("piecetacet", replacements
["movementname"] + " tacet")
271 replacements
["movement"] = m
272 replacements
["movementname"] = m
273 replacements
["movementtacet"] = (m
+ " tacet")
275 print ("Type of movement entry %s is not a dict or a string" % m
)
279 for i
in instruments
:
280 replacements
["instrument"] = i
281 defs
+= (templates
["snippet_def_music"] % replacements
);
283 defs
+= (templates
["snippet_def_lyrics"] % replacements
);
284 del replacements
["instrument"]
285 replacements
["movementinstrumentdefinitions"] = defs
286 fn
= basename
+ "_Music_" + filename_ext
+ ".ily"
287 write_file (output_dir
+ fn
, templates
["movement"] % replacements
);
288 src_files
.append (fn
)
289 del replacements
["movement"]
290 del replacements
["movementname"]
291 del replacements
["movementtacet"]
294 ######################################################################
295 # Creating instrumental score files
296 ######################################################################
298 def generate_instrument_files (settings
, templates
, replacements
):
299 movements
= settings
.get ("parts", []);
300 instruments
= settings
.get ("instruments", []);
301 lyrics
= settings
.get ("lyrics", []);
303 for i
in instruments
:
304 replacements
["instrument"] = i
308 replacements
["movement"] = m
.get ("name", "TODO")
309 replacements
["movementname"] = m
.get ("piece", replacements
["movement"])
311 replacements
["movement"] = m
312 replacements
["movementname"] = m
313 defs
+= (templates
["snippet_part_score"] % replacements
);
314 del replacements
["movement"]
315 del replacements
["movementname"]
316 replacements
["partlist"] = defs
318 settings
= "VocalVoice"
320 settings
= "Instrument"
321 replacements
["settings"] = settings
322 fn
= output_dir
+ basename
+ "_Instrument_" + i
+ ".ly"
323 write_file (fn
, templates
["score_instrument"] % replacements
);
324 score_files
.append (fn
)
325 del replacements
["instrument"]
326 del replacements
["settings"]
328 ######################################################################
329 # Creating score files
330 ######################################################################
334 "ParticellScore": "Particell",
337 "ChoralScore": "VocalScore",
338 "LongScore": "FullScore",
339 "OriginalScore": "FullScore",
340 "Particell": "FullScore"
343 def generate_score_files (settings
, templates
, replacements
):
344 movements
= settings
.get ("parts",[]);
345 scores
= settings
.get ("scores", []);
349 fullsn
= score_names
.get (sn
, sn
);
350 replacements
["score"] = fullsn
351 replacements
["settings"] = score_settings
.get (fullsn
,fullsn
)
352 replacements
["instrument"] = replacements
["score"]
356 replacements
["movement"] = m
.get ("name", "TODO")
357 replacements
["movementname"] = m
.get ("piece", replacements
["movement"])
359 replacements
["movement"] = m
360 replacements
["movementname"] = m
361 defs
+= (templates
["snippet_part_score"] % replacements
);
362 del replacements
["movement"]
363 del replacements
["movementname"]
364 replacements
["partlist"] = defs
365 filename
= output_dir
+ basename
+ "_Score_" + i
+ ".ly";
367 filename
= output_dir
+ basename
+ "_Score.ly"
368 write_file (filename
, templates
["score_full"] % replacements
);
369 score_files
.append (filename
)
370 del replacements
["score"]
371 del replacements
["instrument"]
374 ######################################################################
375 # Creating LaTeX files
376 ######################################################################
378 def write_tex_file (fn
, contents
):
379 write_file (output_dir
+ "/"+ fn
, contents
);
380 tex_files
.append (fn
)
382 def generate_tex_files (settings
, templates
, replacements
):
383 write_tex_file ("TeX_" + basename
+ "_Settings.itex", templates
["itex_settings"] % replacements
);
384 write_tex_file ("TeX_" + basename
+ "_Include_Coverpage.itex", templates
["itex_coverpage"] % replacements
);
385 write_tex_file ("TeX_" + basename
+ "_Include_Backpage.itex", templates
["itex_backpage"] % replacements
);
386 write_tex_file ("TeX_" + basename
+ "_Include_About.itex", templates
["itex_about"] % replacements
);
387 write_tex_file ("TeX_" + basename
+ "_Include_Leben.itex", templates
["itex_leben"] % replacements
);
388 write_tex_file ("TeX_" + basename
+ "_Include_Todo.itex", templates
["itex_todo"] % replacements
);
389 write_tex_file ("TeX_" + basename
+ "_Include_Preface_Long.itex", templates
["itex_preface_long"] % replacements
);
390 write_tex_file ("TeX_" + basename
+ "_Include_Preface_Short.itex", templates
["itex_preface_short"] % replacements
);
394 for m
in settings
.get ("parts",[]):
396 replacements
["movement"] = m
.get ("name", "TODO")
397 replacements
["movementname"] = m
.get ("piece", replacements
["movement"])
399 replacements
["movement"] = m
400 replacements
["movementname"] = m
401 txt
+= (templates
["itex_snippet_textmovement"] % replacements
);
402 kb
+= (templates
["itex_snippet_kritbericht"] % replacements
);
403 del replacements
["movement"]
404 del replacements
["movementname"]
405 replacements
["movementtexts"] = txt
406 replacements
["kritbericht_movements"] = kb
407 write_tex_file ("TeX_" + basename
+ "_Include_Text.itex", templates
["itex_text"] % replacements
);
408 write_tex_file ("TeX_" + basename
+ "_Include_KritBericht.itex", templates
["itex_kritbericht"] % replacements
);
409 del replacements
["movementtexts"]
410 del replacements
["kritbericht_movements"]
412 ### Contents and Material:
414 for i
in settings
.get ("scores", []):
415 replacements
["type"] = i
+ "Score";
416 lst
+= templates
["itex_snippet_material"] % replacements
417 replacements
["type"] = "Instruments"
418 lst
+= templates
["itex_snippet_material"] % replacements
419 for i
in settings
.get ("instruments", []):
420 replacements
["type"] = i
;
421 lst
+= templates
["itex_snippet_material"] % replacements
422 del replacements
["type"]
423 replacements
["material_list"] = lst
;
424 write_tex_file ("TeX_" + basename
+ "_Include_ContentsMaterial.itex", templates
["itex_contents"] % replacements
);
425 del replacements
["material_list"]
428 for s
in settings
.get ("scores", []):
429 replacements
["scoretype"] = s
;
430 write_tex_file ("TeX_" + basename
+ "_Score_" + s
+ ".tex", templates
["tex_score"] % replacements
);
431 del replacements
["scoretype"];
433 ### Orchestra material
434 replacements
["scoretype"] = "InstrumentalParts"
436 for i
in settings
.get ("instruments", []):
437 replacements
["instrument"] = i
438 lst
+= templates
["itex_snippet_instrument"] % replacements
;
439 del replacements
["instrument"]
440 replacements
["instrumentscores"] = lst
;
441 write_tex_file ("TeX_" + basename
+ "_Score_Instruments.tex", templates
["tex_instruments"] % replacements
);
442 del replacements
["instrumentscores"];
446 ######################################################################
447 # Creating Make files
448 ######################################################################
450 def generate_make_files (settings
, templates
, replacements
):
451 movements
= settings
.get ("parts", {});
453 replacements
["instruments"] = string
.join (settings
.get ("instruments", []));
454 replacements
["scores"] = string
.join (settings
.get ("scores", []))## + " Instruments";
455 replacements
["srcfiles"] = string
.join (src_files
);
457 write_file (output_dir
+ "Makefile", templates
["Makefile"] % replacements
);
459 del replacements
["instruments"]
460 del replacements
["scores"]
461 del replacements
["srcfiles"]
465 ######################################################################
466 # Link the orchestrallily package
467 ######################################################################
469 def generate_oly_link (settings
, templates
, replacements
):
470 print ("Creating symlink %s to %s" % ("orchestrallily/", script_path
))
472 os
.symlink ("../"+script_path
, output_dir
+"orchestrallily")
476 ######################################################################
478 ######################################################################
480 settings
= load_settings (settings_file
);
481 templates
= load_templates (settings
);
482 replacements
= init_replacements (settings
);
484 generate_movement_files (settings
, templates
, replacements
);
485 generate_settings_files (settings
, templates
, replacements
);
486 generate_instrument_files (settings
, templates
, replacements
);
487 generate_score_files (settings
, templates
, replacements
);
488 generate_tex_files (settings
, templates
, replacements
);
489 generate_make_files (settings
, templates
, replacements
);
490 generate_oly_link (settings
, templates
, replacements
);