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_vocal": "TEMPLATE_Settings_Vocal.ily",
162 "snippet_part_score": "TEMPLATE_Snippet_PartScore.ily",
164 "score_full": "TEMPLATE_Score_FullScore.ly",
165 "score_instrument": "TEMPLATE_Score_Instrument.ly",
166 "score_vocal": "TEMPLATE_Score_VocalVoice.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_Vocal.ily", templates
["settings_vocal"] % replacements
);
242 del replacements
["includefiles"]
245 ######################################################################
246 # Creating movement files
247 ######################################################################
249 def generate_movement_files (settings
, templates
, replacements
):
250 movements
= settings
.get ("parts", []);
251 instruments
= settings
.get ("instruments", []);
252 lyrics
= settings
.get ("lyrics", []);
253 if (movements
== {}):
254 print ("No parts defined in settings file...");
256 if (instruments
== []):
257 print ("No instruments defined in settings file...");
263 name
= m
.get ("name", "TODO")
264 filename_ext
= m
.get ("filename", name
)
265 replacements
["movement"] = name
266 replacements
["movementname"] = m
.get ("piece", name
)
267 replacements
["movementtacet"] = m
.get ("piecetacet", replacements
["movementname"] + " tacet")
270 replacements
["movement"] = m
271 replacements
["movementname"] = m
272 replacements
["movementtacet"] = (m
+ " tacet")
274 print ("Type of movement entry %s is not a dict or a string" % m
)
278 for i
in instruments
:
279 replacements
["instrument"] = i
280 defs
+= (templates
["snippet_def_music"] % replacements
);
282 defs
+= (templates
["snippet_def_lyrics"] % replacements
);
283 del replacements
["instrument"]
284 replacements
["movementinstrumentdefinitions"] = defs
285 fn
= basename
+ "_Music_" + filename_ext
+ ".ily"
286 write_file (output_dir
+ fn
, templates
["movement"] % replacements
);
287 src_files
.append (fn
)
288 del replacements
["movement"]
289 del replacements
["movementname"]
290 del replacements
["movementtacet"]
293 ######################################################################
294 # Creating instrumental score files
295 ######################################################################
297 def generate_instrument_files (settings
, templates
, replacements
):
298 movements
= settings
.get ("parts", []);
299 instruments
= settings
.get ("instruments", []);
300 lyrics
= settings
.get ("lyrics", []);
302 for i
in instruments
:
303 replacements
["instrument"] = i
307 replacements
["movement"] = m
.get ("name", "TODO")
308 replacements
["movementname"] = m
.get ("piece", replacements
["movement"])
310 replacements
["movement"] = m
311 replacements
["movementname"] = m
312 defs
+= (templates
["snippet_part_score"] % replacements
);
313 del replacements
["movement"]
314 del replacements
["movementname"]
315 replacements
["partlist"] = defs
317 template
= "score_vocal"
319 template
= "score_instrument"
320 fn
= output_dir
+ basename
+ "_Instrument_" + i
+ ".ly"
321 write_file (fn
, templates
[template
] % replacements
);
322 score_files
.append (fn
)
323 del replacements
["instrument"]
326 ######################################################################
327 # Creating score files
328 ######################################################################
332 "ParticellScore": "Particell",
335 def generate_score_files (settings
, templates
, replacements
):
336 movements
= settings
.get ("parts",[]);
337 scores
= settings
.get ("scores", []);
341 replacements
["score"] = score_names
.get (sn
, sn
)
342 replacements
["instrument"] = replacements
["score"]
346 replacements
["movement"] = m
.get ("name", "TODO")
347 replacements
["movementname"] = m
.get ("piece", replacements
["movement"])
349 replacements
["movement"] = m
350 replacements
["movementname"] = m
351 defs
+= (templates
["snippet_part_score"] % replacements
);
352 del replacements
["movement"]
353 del replacements
["movementname"]
354 replacements
["partlist"] = defs
355 filename
= output_dir
+ basename
+ "_Score_" + i
+ ".ly";
357 filename
= output_dir
+ basename
+ "_Score.ly"
358 write_file (filename
, templates
["score_full"] % replacements
);
359 score_files
.append (filename
)
360 del replacements
["score"]
361 del replacements
["instrument"]
364 ######################################################################
365 # Creating LaTeX files
366 ######################################################################
368 def write_tex_file (fn
, contents
):
369 write_file (output_dir
+ "/"+ fn
, contents
);
370 tex_files
.append (fn
)
372 def generate_tex_files (settings
, templates
, replacements
):
373 write_tex_file ("TeX_" + basename
+ "_Settings.itex", templates
["itex_settings"] % replacements
);
374 write_tex_file ("TeX_" + basename
+ "_Include_Coverpage.itex", templates
["itex_coverpage"] % replacements
);
375 write_tex_file ("TeX_" + basename
+ "_Include_Backpage.itex", templates
["itex_backpage"] % replacements
);
376 write_tex_file ("TeX_" + basename
+ "_Include_About.itex", templates
["itex_about"] % replacements
);
377 write_tex_file ("TeX_" + basename
+ "_Include_Leben.itex", templates
["itex_leben"] % replacements
);
378 write_tex_file ("TeX_" + basename
+ "_Include_Todo.itex", templates
["itex_todo"] % replacements
);
379 write_tex_file ("TeX_" + basename
+ "_Include_Preface_Long.itex", templates
["itex_preface_long"] % replacements
);
380 write_tex_file ("TeX_" + basename
+ "_Include_Preface_Short.itex", templates
["itex_preface_short"] % replacements
);
384 for m
in settings
.get ("parts",[]):
386 replacements
["movement"] = m
.get ("name", "TODO")
387 replacements
["movementname"] = m
.get ("piece", replacements
["movement"])
389 replacements
["movement"] = m
390 replacements
["movementname"] = m
391 txt
+= (templates
["itex_snippet_textmovement"] % replacements
);
392 kb
+= (templates
["itex_snippet_kritbericht"] % replacements
);
393 del replacements
["movement"]
394 del replacements
["movementname"]
395 replacements
["movementtexts"] = txt
396 replacements
["kritbericht_movements"] = kb
397 write_tex_file ("TeX_" + basename
+ "_Include_Text.itex", templates
["itex_text"] % replacements
);
398 write_tex_file ("TeX_" + basename
+ "_Include_KritBericht.itex", templates
["itex_kritbericht"] % replacements
);
399 del replacements
["movementtexts"]
400 del replacements
["kritbericht_movements"]
402 ### Contents and Material:
404 for i
in settings
.get ("scores", []):
405 replacements
["type"] = i
+ "Score";
406 lst
+= templates
["itex_snippet_material"] % replacements
407 replacements
["type"] = "Instruments"
408 lst
+= templates
["itex_snippet_material"] % replacements
409 for i
in settings
.get ("instruments", []):
410 replacements
["type"] = i
;
411 lst
+= templates
["itex_snippet_material"] % replacements
412 del replacements
["type"]
413 replacements
["material_list"] = lst
;
414 write_tex_file ("TeX_" + basename
+ "_Include_ContentsMaterial.itex", templates
["itex_contents"] % replacements
);
415 del replacements
["material_list"]
418 for s
in settings
.get ("scores", []):
419 replacements
["scoretype"] = s
;
420 write_tex_file ("TeX_" + basename
+ "_Score_" + s
+ ".tex", templates
["tex_score"] % replacements
);
421 del replacements
["scoretype"];
423 ### Orchestra material
424 replacements
["scoretype"] = "InstrumentalParts"
426 for i
in settings
.get ("instruments", []):
427 replacements
["instrument"] = i
428 lst
+= templates
["itex_snippet_instrument"] % replacements
;
429 del replacements
["instrument"]
430 replacements
["instrumentscores"] = lst
;
431 write_tex_file ("TeX_" + basename
+ "_Score_Instruments.tex", templates
["tex_instruments"] % replacements
);
432 del replacements
["instrumentscores"];
436 ######################################################################
437 # Creating Make files
438 ######################################################################
440 def generate_make_files (settings
, templates
, replacements
):
441 movements
= settings
.get ("parts", {});
443 replacements
["instruments"] = string
.join (settings
.get ("instruments", []));
444 replacements
["scores"] = string
.join (settings
.get ("scores", []))## + " Instruments";
445 replacements
["srcfiles"] = string
.join (src_files
);
447 write_file (output_dir
+ "Makefile", templates
["Makefile"] % replacements
);
449 del replacements
["instruments"]
450 del replacements
["scores"]
451 del replacements
["srcfiles"]
455 ######################################################################
456 # Link the orchestrallily package
457 ######################################################################
459 def generate_oly_link (settings
, templates
, replacements
):
460 print ("Creating symlink %s to %s" % ("orchestrallily/", script_path
))
462 os
.symlink ("../"+script_path
, output_dir
+"orchestrallily")
466 ######################################################################
468 ######################################################################
470 settings
= load_settings (settings_file
);
471 templates
= load_templates (settings
);
472 replacements
= init_replacements (settings
);
474 generate_movement_files (settings
, templates
, replacements
);
475 generate_settings_files (settings
, templates
, replacements
);
476 generate_instrument_files (settings
, templates
, replacements
);
477 generate_score_files (settings
, templates
, replacements
);
478 generate_tex_files (settings
, templates
, replacements
);
479 generate_make_files (settings
, templates
, replacements
);
480 generate_oly_link (settings
, templates
, replacements
);