+2004-11-26 Han-Wen Nienhuys <hanwen@xs4all.nl>
+
+ * 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 <wl@gnu.org>
* tex/GNUmakefile ($(outdir)/latin1.enc): Replace `/minus' with
-\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
+
+ }
>>
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;
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<Global_context*> (this)
+ && dynamic_cast<Global_context*> (this)->get_score_context ())
+ return get_score_context ()->create_unique_context (n, operations);
+
+ /*
+ TODO: use accepts_list_.
+ */
+ Link_array<Context_def> 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<Global_context*> (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 *
if (n == ly_symbol2scm ("Bottom"))
{
Context* tg = get_default_interpreter ();
- tg->id_string_ = id;
return tg;
}
return new_group;
}
+
+
Object_key const*
Context::get_context_key (String type, String id)
{
Context *find_create_context (SCM context_name,
String id, SCM ops);
+ Context *create_unique_context (SCM context_name,
+ SCM ops);
Link_array<Context> path_to_acceptable_context (SCM alias,
Output_def*) const;
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
$$ = 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);
}
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"))
{
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);
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 (),
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);
}
-
%% 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
'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:
(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}.")
(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))
))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(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)
(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))