From 5b03334eaf11104855ef5fd3e18a7c00cd0fcea2 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Fri, 26 Nov 2004 11:53:54 +0000 Subject: [PATCH] * lily/context-specced-music-iterator.cc (construct_children): interpret special context id $uniqueContextId * lily/context.cc (create_unique_context): new method. Move creation of unique (\new) contexts into interpreting phase. This makes * scm/define-music-properties.scm (all-music-properties): add quoted-voice-direction * ly/music-functions-init.ly: killCues function. * scm/music-functions.scm (cue-substitute): move creation of voice contexts further to the back. --- ChangeLog | 23 +++++++++ input/regression/quote-cue-during.ly | 67 +++++++++++++++----------- lily/context-specced-music-iterator.cc | 10 ++-- lily/context.cc | 51 +++++++++++++++++++- lily/include/context.hh | 2 + lily/parser.yy | 26 +++++----- ly/music-functions-init.ly | 57 +++++++++------------- scm/define-music-properties.scm | 1 + scm/define-music-types.scm | 2 +- scm/music-functions.scm | 39 +++++++++++++-- 10 files changed, 199 insertions(+), 79 deletions(-) diff --git a/ChangeLog b/ChangeLog index b4f950990b..33e6d4ad22 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2004-11-26 Han-Wen Nienhuys + + * lily/context-specced-music-iterator.cc (construct_children): + interpret special context id $uniqueContextId + + * lily/context.cc (create_unique_context): new method. Move + creation of unique (\new) contexts into interpreting phase. This + makes + + foo= \new Staff .. + << \foo \foo >> + + produce 2 staves. + + + * scm/define-music-properties.scm (all-music-properties): add + quoted-voice-direction + + * ly/music-functions-init.ly: killCues function. + + * scm/music-functions.scm (cue-substitute): move creation of voice + contexts further to the back. + 2004-11-25 Werner Lemberg * tex/GNUmakefile ($(outdir)/latin1.enc): Replace `/minus' with diff --git a/input/regression/quote-cue-during.ly b/input/regression/quote-cue-during.ly index 1bf62b7f6f..36ea22f6c7 100644 --- a/input/regression/quote-cue-during.ly +++ b/input/regression/quote-cue-during.ly @@ -1,40 +1,53 @@ -\header { texidoc = " The @code{cueDuring} form of quotation will set -stem directions on both quoted and main voice, and deliver the quoted -voice in the @code{cue} @code{Voice}." +\header { -} + + texidoc = " The @code{cueDuring} form of quotation will set stem +directions on both quoted and main voice, and deliver the quoted voice +in the @code{cue} @code{Voice}. The music function @code{\killCues} +can be remove all cue notes." + + } \version "2.5.0" \layout { - raggedright = ##t + raggedright = ##t } quoteMe = \relative c' { fis4 r16 a8.-> b4-\ff c4 } \addquote quoteMe \quoteMe + original = \relative c'' { c8 d s2 es8 gis8 } +cueStaff = \relative c'' << + % setup cue note layout. + \context Voice = cue { + \set fontSize = #-4 + \override Stem #'lengths = #'(2.5 2.5 3.0 3.0) + \skip 1 + } + + \set Staff.quotedEventTypes = #'(note-event articulation-event) + \original + { s4 \cueDuring #"quoteMe" #1 { r2 } } +>> + << - \new Staff { - \set Staff.instrument = "quoteMe" - \quoteMe - } - \new Staff { - \set Staff.instrument = "orig" - \original - } - \new Staff \relative c'' << - - % setup cue note layout. - \context Voice = cue { - \set fontSize = #-4 - \override Stem #'lengths = #'(2.5 2.5 3.0 3.0) - \skip 1 - } - - \set Staff.instrument = "orig+quote" - \set Staff.quotedEventTypes = #'(note-event articulation-event) - \original - { s4 \cueDuring #"quoteMe" #1 { r2. } } - >> + \new Staff { + \set Staff.instrument = "quoteMe" + \quoteMe + } + \new Staff { + \set Staff.instrument = "orig" + \original + } + \new Staff { + \set Staff.instrument = "orig+quote" + \cueStaff + } + \new Staff { + \set Staff.instrument = "killCues" + \killCues \cueStaff + + } >> diff --git a/lily/context-specced-music-iterator.cc b/lily/context-specced-music-iterator.cc index c5d917a330..a4df122a44 100644 --- a/lily/context-specced-music-iterator.cc +++ b/lily/context-specced-music-iterator.cc @@ -29,11 +29,15 @@ Context_specced_music_iterator::construct_children () c_id = ly_scm2string (ci); SCM ops = get_music ()->get_property ("property-operations"); - Context * a - = get_outlet ()->find_create_context (ct, c_id, ops); + Context * a = 0; + + if (c_id == "$uniqueContextId") + a = get_outlet ()->create_unique_context (ct, ops); + else + a = get_outlet ()->find_create_context (ct, c_id, ops); if (a - && to_boolean (get_music ()->get_property ("descend-only")) + && to_boolean (get_music ()->get_property ("descend-only")) && !is_child_context (get_outlet (), a)) a = 0; diff --git a/lily/context.cc b/lily/context.cc index effb574d1c..fc9e780ae3 100644 --- a/lily/context.cc +++ b/lily/context.cc @@ -103,6 +103,54 @@ Context::Context (Object_key const* key) scm_gc_unprotect_object (key_->self_scm ()); } +Context* +Context::create_unique_context (SCM n, SCM operations) +{ + /* + Don't create multiple score contexts. + */ + if (dynamic_cast (this) + && dynamic_cast (this)->get_score_context ()) + return get_score_context ()->create_unique_context (n, operations); + + /* + TODO: use accepts_list_. + */ + Link_array path + = unsmob_context_def (definition_)->path_to_acceptable_context (n, get_output_def ()); + + if (path.size ()) + { + Context * current = this; + + // start at 1. The first one (index 0) will be us. + for (int i=0; i < path.size (); i++) + { + SCM ops = (i == path.size () -1) ? operations : SCM_EOL; + + current = current->create_context (path[i], + "", + ops); + } + + return current; + } + + /* + Don't go up to Global_context, because global goes down to + Score_context + */ + Context *ret = 0; + if (daddy_context_ && !dynamic_cast (daddy_context_)) + ret = daddy_context_->create_unique_context (n, operations); + else + { + warning (_f ("Cannot find or create new `%s'", + ly_symbol2string (n).to_str0 ())); + ret =0; + } + return ret; +} Context * @@ -121,7 +169,6 @@ Context::find_create_context (SCM n, String id, SCM operations) if (n == ly_symbol2scm ("Bottom")) { Context* tg = get_default_interpreter (); - tg->id_string_ = id; return tg; } @@ -189,6 +236,8 @@ Context::create_context (Context_def * cdef, return new_group; } + + Object_key const* Context::get_context_key (String type, String id) { diff --git a/lily/include/context.hh b/lily/include/context.hh index 8c2901e372..060fe9c22f 100644 --- a/lily/include/context.hh +++ b/lily/include/context.hh @@ -89,6 +89,8 @@ public: Context *find_create_context (SCM context_name, String id, SCM ops); + Context *create_unique_context (SCM context_name, + SCM ops); Link_array path_to_acceptable_context (SCM alias, Output_def*) const; diff --git a/lily/parser.yy b/lily/parser.yy index f42cd76f05..d3f044b034 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -54,7 +54,8 @@ TODO: Music *property_op_to_music (SCM op); Music *context_spec_music (SCM type, SCM id, Music *m, SCM ops); -SCM get_next_unique_context (); +SCM get_next_unique_context_id (); +SCM get_next_unique_lyrics_context_id (); #define YYERROR_VERBOSE 1 @@ -1131,7 +1132,7 @@ Prefix_composite_music: $$ = context_spec_music ($2, SCM_UNDEFINED, $4, $3); } | NEWCONTEXT simple_string optional_context_mod Music { - $$ = context_spec_music ($2, get_next_unique_context (), $4, + $$ = context_spec_music ($2, get_next_unique_context_id (), $4, $3); } @@ -1181,7 +1182,7 @@ Prefix_composite_music: THIS->lexer_->pop_state (); } | mode_changing_head_with_context optional_context_mod Grouped_music_list { - $$ = context_spec_music ($1, get_next_unique_context (), + $$ = context_spec_music ($1, get_next_unique_context_id (), $3, $2); if ($1 == ly_symbol2scm ("ChordNames")) { @@ -1299,7 +1300,7 @@ re_rhythmed_music: SCM name = get_first_context_id (scm_makfrom0str ("Voice"), voice); if (!scm_is_string (name)) { - name = get_next_unique_context (); + name = get_next_unique_lyrics_context_id (); voice = context_spec_music (scm_makfrom0str ("Voice"), name, voice, SCM_EOL); @@ -1314,7 +1315,7 @@ re_rhythmed_music: Music *music = unsmob_music (scm_car (s)); Music *com = make_lyric_combine_music (name, music); Music *csm = context_spec_music (context, - get_next_unique_context (), com, SCM_EOL); + get_next_unique_context_id (), com, SCM_EOL); lst = scm_cons (csm->self_scm (), lst); } all->set_property ("elements", scm_cons (voice->self_scm (), @@ -2713,15 +2714,18 @@ context_spec_music (SCM type, SCM id, Music *m, SCM ops) return csm; } -/* -FIXME: this should be postponed until the music hits \Score -*/ SCM -get_next_unique_context () +get_next_unique_context_id () +{ + return scm_makfrom0str ("$uniqueContextId"); +} + + +SCM +get_next_unique_lyrics_context_id () { static int new_context_count; - char s[1024]; + char s[128]; snprintf (s, 1024, "uniqueContext%d", new_context_count++); return scm_makfrom0str (s); } - diff --git a/ly/music-functions-init.ly b/ly/music-functions-init.ly index 526f397ccb..cf2a2745de 100644 --- a/ly/music-functions-init.ly +++ b/ly/music-functions-init.ly @@ -77,41 +77,18 @@ keepWithTag = %% doing %% def-music-function in a .scm causes crash. -cueDuring = # -(def-music-function +cueDuring = +#(def-music-function (location what dir main-music) (string? ly:dir? ly:music?) - (let* - ((quote-music - (make-music 'QuoteMusic - 'quoted-context-type 'Voice - 'quoted-context-id "cue" - 'quoted-music-name what - 'origin location)) - (main-voice (if (= 1 dir) 2 1)) - (cue-voice (if (= 1 dir) 1 2)) - (return-value quote-music) - ) - - (if (not (= dir 0)) - (begin - (set! return-value - (make-sequential-music - (list - (context-spec-music (make-voice-props-set cue-voice) 'Voice "cue") - quote-music - (context-spec-music (make-voice-props-revert) 'Voice "cue")) - )) - - (set! main-music - (make-sequential-music - (list - (make-voice-props-set main-voice) - main-music - (make-voice-props-revert))) - ))) - (set! (ly:music-property quote-music 'element) main-music) - return-value)) + (make-music 'QuoteMusic + 'element main-music + 'quoted-context-type 'Voice + 'quoted-context-id "cue" + 'quoted-music-name what + 'quoted-voice-direction dir + 'origin location)) + quoteDuring = # (def-music-function @@ -123,6 +100,20 @@ quoteDuring = # 'origin location)) + + +killCues = +#(def-music-function + (location music) + (ly:music?) + (music-map + (lambda (mus) + (if (string? (ly:music-property mus 'quoted-music-name)) + (ly:music-property mus 'element) + mus)) music)) + + + %{ TODO: diff --git a/scm/define-music-properties.scm b/scm/define-music-properties.scm index 195b86c8ee..c3c6eadac5 100644 --- a/scm/define-music-properties.scm +++ b/scm/define-music-properties.scm @@ -86,6 +86,7 @@ For chord inversions, this is negative.") (predicate ,procedure? "the predicate of a \\outputproperty.") (quoted-events ,vector? "A vector of with moment/event-list entries.") (quoted-music-name ,string? "The name of the voice to quote.") + (quoted-voice-direction ,ly:dir? "Should the quoted voice be up-stem or down-stem?") (quoted-context-type ,symbol? "The name of the context to direct quotes to, eg., @code{Voice}.") (quoted-context-id ,string? "The id of the context to direct quotes to, eg., @code{cue}.") diff --git a/scm/define-music-types.scm b/scm/define-music-types.scm index d0acbc4425..9dfcc33de1 100644 --- a/scm/define-music-types.scm +++ b/scm/define-music-types.scm @@ -401,7 +401,7 @@ goes down).") (QuoteMusic . ( (description . "Quote preprocessed snippets of music. ") - (internal-class-name . "Music_wrapper") ;; so we get Event::get_length (). + (internal-class-name . "Music_wrapper") (iterator-ctor . ,Quote_iterator::constructor) (types . (general-music)) )) diff --git a/scm/music-functions.scm b/scm/music-functions.scm index c402c23034..d47de57077 100644 --- a/scm/music-functions.scm +++ b/scm/music-functions.scm @@ -576,15 +576,47 @@ Syntax: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(define-public (cue-substitute quote-music) + (if (vector? (ly:music-property quote-music 'quoted-events)) + (let* + ((dir (ly:music-property quote-music 'quoted-voice-direction)) + (main-voice (if (eq? 1 dir) 2 1)) + (cue-voice (if (eq? 1 dir) 1 2)) + (main-music (ly:music-property quote-music 'element)) + (return-value quote-music) + ) + + (if (or (eq? 1 dir) (eq? -1 dir)) + + ;; if we have stem dirs, change both quoted and main music + ;; to have opposite stems. + (begin + (set! return-value + (make-sequential-music + (list + (context-spec-music (make-voice-props-set cue-voice) 'Voice "cue") + quote-music + (context-spec-music (make-voice-props-revert) 'Voice "cue")) + )) + (set! main-music + (make-sequential-music + (list + (make-voice-props-set main-voice) + main-music + (make-voice-props-revert))) + ) + (set! (ly:music-property quote-music 'element) main-music))) + + return-value) + quote-music)) + (define-public ((quote-substitute quote-tab) music) (let* ((quoted-name (ly:music-property music 'quoted-music-name)) (quoted-vector (if (string? quoted-name) (hash-ref quote-tab quoted-name #f) #f - )) - - ) + ))) (if (string? quoted-name) (if (vector? quoted-vector) @@ -624,6 +656,7 @@ Syntax: (lambda (music parser) (voicify-music music)) (lambda (x parser) (music-map glue-mm-rest-texts x)) (lambda (x parser) (music-map music-check-error x)) + (lambda (x parser) (music-map cue-substitute x)) (lambda (music parser) (music-map (quote-substitute (ly:parser-lookup parser 'musicQuotes)) music)) -- 2.39.2