Johan Vromans <jvromans <at> squirrel.nl> writes: > > Dan Eble <dan <at> faithful.be> writes: > > > These two functions should help. > > Thanks! I can use this. > > > You will either need to define your optional music to be empty when > > it is not required, as in this example, or provide a function to > > create empty music if it is not already defined. > > I would be very interested in the latter.
Johan, I have a framework for creating collections of many short pieces. The music for each piece is in its own file, along with metadata pertaining to the music. For example, composer = "William H. Monk" compositionDate = "1861" tune = "Eventide" meter = "10.10.10.10" Four voices are supported: sNotes, aNotes, tNotes, and bNotes. (If I were to start over, I would use aNotes, bNotes, cNotes, etc.) Shared notation (e.g. rehearsal marks) is defined in staffItems. The variable names are the same in every piece, and would normally conflict when included in the top-level file. I use some functions to work around that problem: \include "notes/tune/Eventide.ly" title = "Abide with Me" secRefBook = "Gospel Hymns" secRefPage = "317" \headerStore "AWM" \fourpartStore "AWM" \include "notes/tune/Diadem.ly" title = "All Hail the Power of Jesus' Name" secRefBook = "Apostolic Christian Hymnal" secRefPage = "320" \headerStore "AHTPOJN" \fourpartStore "AHTPOJN" Conceptually, headerStore and fourpartStore move the metadata variables and music variables into a named scope. Actually, they just rename the variables. In the example above, sNotes defined in Eventide.ly becomes AWMsNotes. (Notice that some header variables are defined outside the notes file. This is because they relate to the lyrics rather than the music, so they could differ in other contexts.) This does half the job. The variables for every song can live together in peace and harmony, waiting to be used in the \score blocks. But the staff definition files included from each \score block refer to the original names (e.g. sNotes), so two more functions are required. \score { << \fourpartLoad "AWM" \include "staff/satb_hymn.ly" >> \header { #(header-load "AWM") } \layout { } \midi { } } fourpartLoad and header-load remove the prefixes from the necessary variable names, so that satb_hymn.ly can simply use sNotes etc. (I tried defining a \headerLoad function for symmetry; as I recall, it would not parse.) How does all this connect to your situation? The functions make sure that all the variables which could be used are defined (possibly empty) in the top-level file, even if they had not been defined in the included files. So, without further ado, here are the functions. I store them in a file called namespace-functions.ly. I hope this will serve you well. % For the given symbols that are defined in the module, rename each by % prepending the prefix. #(define (module-add-symbol-prefix module symbols prefix) (for-each (lambda (genSym) (if (module-defined? module genSym) (let* ((var (module-variable module genSym)) (val (variable-ref var)) (specSym (string->symbol (string-append prefix (symbol->string genSym))))) (module-define! module specSym val) (module-remove! module genSym)))) symbols)) % For the given symbols with the prefix that are defined in the module, % rename each by removing the prefix. For those that are not defined, % define them with the default value. #(define (module-remove-symbol-prefix module symbols prefix defval) (for-each (lambda (genSym) (let* ((specSym (string->symbol (string-append prefix (symbol->string genSym))))) (if (module-defined? module specSym) (let* ((val (variable-ref (module-variable module specSym)))) (module-define! module genSym val) (module-remove! module specSym)) (module-define! module genSym defval)))) symbols)) #(define fourpart-vars '(sNotes aNotes tNotes bNotes staffItems)) fourpartLoad = #(define-music-function (parser location prefix) (string?) (module-remove-symbol-prefix (current-module) fourpart-vars prefix (make-void-skip-music)) (make-music 'SequentialMusic 'void #t) ) fourpartStore = #(define-music-function (parser location prefix) (string?) (module-add-symbol-prefix (current-module) fourpart-vars prefix) (make-music 'SequentialMusic 'void #t) ) #(define header-vars '(title subtitle subsubtitle poet poemDate translator translationDate musicPub musicPubDate composer compositionDate arranger arrangementDate opus tune meter secRefBook secRefPage)) headerStore = #(define-music-function (parser location prefix) (string?) (module-add-symbol-prefix (current-module) header-vars prefix) (make-music 'SequentialMusic 'void #t) ) #(define-public (header-load prefix) (module-remove-symbol-prefix (current-module) header-vars prefix #f)) -- Dan _______________________________________________ lilypond-user mailing list lilypond-user@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-user