2 # -*- coding: utf-8 -*-
13 program_name
= 'generate_oly_score'
14 settings_file
= 'oly_structure.def'
16 script_path
= os
.path
.dirname(__file__
)
23 ######################################################################
25 ######################################################################
27 help_text
= r
"""Usage: %(program_name)s [OPTIONS]... [DEF-FILE]
28 Create a complete file structure for a score using OrchestralLily.
29 If no definitions file it given, the file oly_structure.def is used
32 -h, --help print this help
33 -o, --output=NAME write tely doc to NAME (default: read from settings or current directory)
37 sys
.stdout
.write ( text
)
40 (options
, files
) = getopt
.getopt (sys
.argv
[1:], 'ho:',
46 if o
== '-h' or o
== '--help':
47 help (help_text
% vars ())
48 #elif o == '-s' or o == '--settings':
50 elif o
== '-o' or o
== '--output':
53 raise Exception ('unknown option: ' + o
)
56 settings_file
= files
[0]
59 ######################################################################
61 ######################################################################
63 def load_settings (file_name
):
66 in_f
= open (file_name
)
69 settings_expr
= eval(s
);
71 print ("Unable to load settings file '%s'. Exiting..." % file_name
)
73 except SyntaxError as ex
:
75 print ("Unable to interpret settings file '%s', it's syntax is invalid. Exiting..." % file_name
);
79 output_dir
= settings_expr
.get ("output_dir", output_dir
) + "/";
83 ######################################################################
85 ######################################################################
87 def write_file (file_name
, contents
):
89 if os
.path
.exists (file_name
):
92 dir = os
.path
.dirname (fn
);
93 if not os
.path
.exists (dir):
97 out_f
= open (fn
, "w")
98 s
= out_f
.write(contents
)
101 print ("Unable to write to output file '%s'. Exiting..." % fn
)
104 # If the file already existed, check if the new file is identical.
105 if (fn
!= file_name
):
106 patchfile
= os
.path
.join (dir, "patches", os
.path
.basename(file_name
) + ".patch")
107 if os
.path
.exists (patchfile
):
108 #print ("Trying to apply patch %s" % patchfile)
110 #retcode = subprocess.call(["patch ", fn, patchfile], shell=True)
111 retcode
= subprocess
.call("patch -Ns \""+ fn
+ "\" \"" + patchfile
+ "\"", shell
=True)
113 print >>sys
.stderr
, "Unable to apply patch to file \"", fn
, "\"."
115 #print >>sys.stderr, "Child returned", retcode
117 print >>sys
.stderr
, "Execution failed:", e
119 #print ("Unable to find patch %s" % patchfile)
121 if filecmp
.cmp (fn
, file_name
):
124 print ("A file %s already existed, created new file %s." % (os
.path
.basename(file_name
), os
.path
.basename(fn
)))
128 ######################################################################
130 ######################################################################
132 def init_replacements (settings
):
133 rep
= settings
.copy ();
134 if not rep
["basename"]:
135 rep
["basename"] = "Score";
136 if not rep
["tex_basename"]:
137 rep
["tex_basename"] = rep
["basename"];
139 del rep
["instruments"];
148 ######################################################################
150 ######################################################################
153 "Makefile": "Makefile",
155 "movement": "TEMPLATE_Include_Movement.ily",
156 "snippet_def_lyrics": "TEMPLATE_Snippet_DefinitionLyrics.ily",
157 "snippet_def_music": "TEMPLATE_Snippet_DefinitionMusic.ily",
158 "snippet_def_include": "TEMPLATE_Snippet_DefinitionInclude.ily",
160 "settings": "TEMPLATE_Settings.ily",
161 "settings_global": "TEMPLATE_Settings_Global.ily",
162 "settings_fullscore": "TEMPLATE_Settings_FullScore.ily",
163 "settings_instrument": "TEMPLATE_Settings_Instrument.ily",
164 "settings_vocalvoice": "TEMPLATE_Settings_VocalVoice.ily",
165 "settings_vocalscore": "TEMPLATE_Settings_VocalScore.ily",
167 "snippet_part_score": "TEMPLATE_Snippet_PartScore.ily",
169 "score_full": "TEMPLATE_Score_FullScore.ly",
170 "score_instrument": "TEMPLATE_Score_Instrument.ly",
172 "itex_settings": "TEXTEMPLATE_Settings.itex",
173 "itex_about": "TEXTEMPLATE_Include_About.itex",
174 "itex_contents": "TEXTEMPLATE_Include_ContentsMaterial.itex",
175 "itex_leben": "TEXTEMPLATE_Include_Leben.itex",
176 "itex_text": "TEXTEMPLATE_Include_Text.itex",
178 "itex_todo": "TEXTEMPLATE_Include_Todo.itex",
179 "itex_preface_long": "TEXTEMPLATE_Include_Preface_Long.itex",
180 "itex_preface_short": "TEXTEMPLATE_Include_Preface_Short.itex",
182 "itex_coverpage": "TEXTEMPLATE_Include_Coverpage.itex",
183 "itex_backpage": "TEXTEMPLATE_Include_Backpage.itex",
185 "itex_kritbericht": "TEXTEMPLATE_Include_KritBericht.itex",
186 "tex_score": "TEXTEMPLATE_Score.tex",
187 "tex_instruments": "TEXTEMPLATE_Score_Instruments.tex",
189 "itex_snippet_textmovement": "TEXTEMPLATE_Snippet_TextMovement.itex",
190 "itex_snippet_kritbericht": "TEXTEMPLATE_Snippet_KritBericht_Movement.itex",
191 "itex_snippet_material": "TEXTEMPLATE_Snippet_Material_Score.itex",
192 "itex_snippet_instrument": "TEXTEMPLATE_Snippet_Instrument.itex",
195 def load_file (file_name
):
198 in_f
= open (file_name
, "rb")
202 print ("Unable to load file %s" % file_name
);
205 def load_templates (settings
):
207 template_path
= script_path
+ "/Templates/";
209 for id in template_names
:
210 filename
= template_names
[id]
211 s
= load_file (template_path
+ filename
);
215 print ("Unable to load template file %s (id %s).\n" % (filename
, id));
219 ######################################################################
220 # Creating settings files
221 ######################################################################
223 def write_settings_file (fn
, contents
):
224 write_file (fn
, contents
);
225 settings_files
.append (fn
)
227 def generate_settings_files (settings
, templates
, replacements
):
230 replacements
["filename"] = m
231 inc
+= (templates
["snippet_def_include"] % replacements
)
232 del replacements
["filename"];
233 replacements
["includefiles"] = inc
235 basename
= replacements
["basename"];
236 write_settings_file (output_dir
+ basename
+ "_Settings.ily", templates
["settings"] % replacements
);
237 write_file (output_dir
+ basename
+ "_Settings_Global.ily", templates
["settings_global"] % replacements
);
239 if (settings
.get("scores", [])):
240 write_settings_file (output_dir
+ basename
+ "_Settings_FullScore.ily", templates
["settings_fullscore"] % replacements
);
241 if (settings
.get("instruments", [])):
242 write_settings_file (output_dir
+ basename
+ "_Settings_Instrument.ily", templates
["settings_instrument"] % replacements
);
244 print ("WARNING: No instruments: %s" % settings
.get("instruments", []));
245 if (settings
.get("lyrics", [])):
246 write_settings_file (output_dir
+ basename
+ "_Settings_VocalVoice.ily", templates
["settings_vocalvoice"] % replacements
);
247 write_settings_file (output_dir
+ basename
+ "_Settings_VocalScore.ily", templates
["settings_vocalscore"] % replacements
);
248 del replacements
["includefiles"]
251 ######################################################################
252 # Creating movement files
253 ######################################################################
255 def generate_movement_files (settings
, templates
, replacements
):
256 movements
= settings
.get ("parts", []);
257 instruments
= settings
.get ("instruments", []);
258 lyrics
= settings
.get ("lyrics", []);
259 if (movements
== {}):
260 print ("No parts defined in settings file...");
262 if (instruments
== []):
263 print ("No instruments defined in settings file...");
269 name
= m
.get ("name", "TODO")
270 filename_ext
= m
.get ("filename", name
)
271 replacements
["movement"] = name
272 replacements
["movementname"] = m
.get ("piece", name
)
273 replacements
["movementtacet"] = m
.get ("piecetacet", replacements
["movementname"] + " tacet")
276 replacements
["movement"] = m
277 replacements
["movementname"] = m
278 replacements
["movementtacet"] = (m
+ " tacet")
280 print ("Type of movement entry %s is not a dict or a string" % m
)
284 for i
in instruments
:
285 replacements
["instrument"] = i
286 defs
+= (templates
["snippet_def_music"] % replacements
);
288 defs
+= (templates
["snippet_def_lyrics"] % replacements
);
289 del replacements
["instrument"]
290 replacements
["movementinstrumentdefinitions"] = defs
291 fn
= replacements
["basename"] + "_Music_" + filename_ext
+ ".ily"
292 write_file (output_dir
+ fn
, templates
["movement"] % replacements
);
293 src_files
.append (fn
)
294 del replacements
["movement"]
295 del replacements
["movementname"]
296 del replacements
["movementtacet"]
299 ######################################################################
300 # Creating instrumental score files
301 ######################################################################
303 def generate_instrument_files (settings
, templates
, replacements
):
304 movements
= settings
.get ("parts", []);
305 instruments
= settings
.get ("instruments", []);
306 lyrics
= settings
.get ("lyrics", []);
308 for i
in instruments
:
309 replacements
["instrument"] = i
313 replacements
["movement"] = m
.get ("name", "TODO")
314 replacements
["movementname"] = m
.get ("piece", replacements
["movement"])
316 replacements
["movement"] = m
317 replacements
["movementname"] = m
318 defs
+= (templates
["snippet_part_score"] % replacements
);
319 del replacements
["movement"]
320 del replacements
["movementname"]
321 replacements
["partlist"] = defs
323 settings
= "VocalVoice"
325 settings
= "Instrument"
326 replacements
["settings"] = settings
327 fn
= output_dir
+ replacements
["basename"] + "_Instrument_" + i
+ ".ly"
328 write_file (fn
, templates
["score_instrument"] % replacements
);
329 score_files
.append (fn
)
330 del replacements
["instrument"]
331 del replacements
["settings"]
333 ######################################################################
334 # Creating score files
335 ######################################################################
339 "ParticellScore": "Particell",
342 "OrganScore": "VocalScore",
343 "ChoralScore": "VocalScore",
344 "LongScore": "FullScore",
345 "OriginalScore": "FullScore",
346 "Particell": "FullScore"
348 scores_cues
= ["ChoralScore", "VocalScore"];
350 def generate_score_files (settings
, templates
, replacements
):
351 movements
= settings
.get ("parts",[]);
352 scores
= settings
.get ("scores", []);
356 fullsn
= score_names
.get (sn
, sn
);
357 if fullsn
in scores_cues
:
358 replacements
["cues"] = "";
360 replacements
["cues"] = "NoCues";
361 replacements
["score"] = fullsn
362 replacements
["settings"] = score_settings
.get (fullsn
,fullsn
)
363 replacements
["instrument"] = replacements
["score"]
367 replacements
["movement"] = m
.get ("name", "TODO")
368 replacements
["movementname"] = m
.get ("piece", replacements
["movement"])
370 replacements
["movement"] = m
371 replacements
["movementname"] = m
372 defs
+= (templates
["snippet_part_score"] % replacements
);
373 del replacements
["movement"]
374 del replacements
["movementname"]
375 replacements
["partlist"] = defs
376 filename
= output_dir
+ replacements
["basename"] + "_Score_" + i
+ ".ly";
378 filename
= output_dir
+ replacements
["basename"] + "_Score.ly"
379 write_file (filename
, templates
["score_full"] % replacements
);
380 score_files
.append (filename
)
381 del replacements
["score"]
382 del replacements
["instrument"]
384 replacements
["cues"] = "";
387 ######################################################################
388 # Creating LaTeX files
389 ######################################################################
391 def write_tex_file (fn
, contents
):
392 write_file (output_dir
+ "/"+ fn
, contents
);
393 tex_files
.append (fn
)
395 def generate_tex_files (settings
, templates
, replacements
):
396 basename
= replacements
["tex_basename"]
397 write_tex_file ("TeX_" + basename
+ "_Settings.itex", templates
["itex_settings"] % replacements
);
398 write_tex_file ("TeX_" + basename
+ "_Include_Coverpage.itex", templates
["itex_coverpage"] % replacements
);
399 write_tex_file ("TeX_" + basename
+ "_Include_Backpage.itex", templates
["itex_backpage"] % replacements
);
400 write_tex_file ("TeX_" + basename
+ "_Include_About.itex", templates
["itex_about"] % replacements
);
401 write_tex_file ("TeX_" + basename
+ "_Include_Leben.itex", templates
["itex_leben"] % replacements
);
402 write_tex_file ("TeX_" + basename
+ "_Include_Todo.itex", templates
["itex_todo"] % replacements
);
403 write_tex_file ("TeX_" + basename
+ "_Include_Preface_Long.itex", templates
["itex_preface_long"] % replacements
);
404 write_tex_file ("TeX_" + basename
+ "_Include_Preface_Short.itex", templates
["itex_preface_short"] % replacements
);
408 for m
in settings
.get ("parts",[]):
410 replacements
["movement"] = m
.get ("name", "TODO")
411 replacements
["movementname"] = m
.get ("piece", replacements
["movement"])
413 replacements
["movement"] = m
414 replacements
["movementname"] = m
415 txt
+= (templates
["itex_snippet_textmovement"] % replacements
);
416 kb
+= (templates
["itex_snippet_kritbericht"] % replacements
);
417 del replacements
["movement"]
418 del replacements
["movementname"]
419 replacements
["movementtexts"] = txt
420 replacements
["kritbericht_movements"] = kb
421 write_tex_file ("TeX_" + basename
+ "_Include_Text.itex", templates
["itex_text"] % replacements
);
422 write_tex_file ("TeX_" + basename
+ "_Include_KritBericht.itex", templates
["itex_kritbericht"] % replacements
);
423 del replacements
["movementtexts"]
424 del replacements
["kritbericht_movements"]
426 ### Contents and Material:
428 for i
in settings
.get ("scores", []):
429 replacements
["type"] = i
+ "Score";
430 lst
+= templates
["itex_snippet_material"] % replacements
431 replacements
["type"] = "Instruments"
432 lst
+= templates
["itex_snippet_material"] % replacements
433 for i
in settings
.get ("instruments", []):
434 replacements
["type"] = i
;
435 lst
+= templates
["itex_snippet_material"] % replacements
436 del replacements
["type"]
437 replacements
["material_list"] = lst
;
438 write_tex_file ("TeX_" + basename
+ "_Include_ContentsMaterial.itex", templates
["itex_contents"] % replacements
);
439 del replacements
["material_list"]
442 for s
in settings
.get ("scores", []):
443 replacements
["scoretype"] = s
;
444 write_tex_file ("TeX_" + basename
+ "_Score_" + s
+ ".tex", templates
["tex_score"] % replacements
);
445 del replacements
["scoretype"];
447 ### Orchestra material
448 replacements
["scoretype"] = "InstrumentalParts"
450 for i
in settings
.get ("instruments", []):
451 replacements
["instrument"] = i
452 lst
+= templates
["itex_snippet_instrument"] % replacements
;
453 del replacements
["instrument"]
454 replacements
["instrumentscores"] = lst
;
455 write_tex_file ("TeX_" + basename
+ "_Score_Instruments.tex", templates
["tex_instruments"] % replacements
);
456 del replacements
["instrumentscores"];
460 ######################################################################
461 # Creating Make files
462 ######################################################################
464 def generate_make_files (settings
, templates
, replacements
):
465 movements
= settings
.get ("parts", {});
467 replacements
["instruments"] = string
.join (settings
.get ("instruments", []));
468 replacements
["scores"] = string
.join (settings
.get ("scores", []))## + " Instruments";
469 replacements
["srcfiles"] = string
.join (src_files
);
471 write_file (output_dir
+ "Makefile", templates
["Makefile"] % replacements
);
473 del replacements
["instruments"]
474 del replacements
["scores"]
475 del replacements
["srcfiles"]
479 ######################################################################
480 # Link the orchestrallily package
481 ######################################################################
483 def generate_oly_link (settings
, templates
, replacements
):
484 print ("Creating symlink %s to %s" % ("orchestrallily/", script_path
))
486 os
.symlink ("../"+script_path
, output_dir
+"orchestrallily")
490 ######################################################################
492 ######################################################################
494 settings
= load_settings (settings_file
);
495 templates
= load_templates (settings
);
496 replacements
= init_replacements (settings
);
498 generate_movement_files (settings
, templates
, replacements
);
499 generate_settings_files (settings
, templates
, replacements
);
500 generate_instrument_files (settings
, templates
, replacements
);
501 generate_score_files (settings
, templates
, replacements
);
502 generate_tex_files (settings
, templates
, replacements
);
503 generate_make_files (settings
, templates
, replacements
);
504 generate_oly_link (settings
, templates
, replacements
);