* input/regression/quote-cue-during.ly: new file.
* input/regression/quote-grace.ly: new file.
* lily/grace-engraver.cc: new file. Set properties for grobs based
on the grace-ness of now_moment().
* lily/new-quote-iterator.cc (construct_children): set
quote_outlet_ if no quoted-context-{id,type} specified.
2004-11-07 Han-Wen Nienhuys <hanwen@xs4all.nl>
+ * lily/new-quote-iterator.cc (quote_ok): new function.
+
+ * input/regression/quote-cue-during.ly: new file.
+
+ * input/regression/quote-grace.ly: new file.
+
* scm/define-context-properties.scm (Module): change definition of
graceSettings
--- /dev/null
+\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}."
+
+}
+\version "2.4.0"
+\layout {
+ raggedright = ##t
+}
+
+
+quoteMe = \relative c' { fis4 r16 a8.-> b4-\ff }
+
+\addquote quoteMe \quoteMe
+original = \relative c'' { c8 d s2 es8 gis8 }
+
+<<
+ \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. } }
+ >>
+>>
\header
{
- texidoc = "With @code{\\quoteDuring}, fragments of previously
-entered music may be quoted. @code{quotedEventTypes} will determines
-what things are quoted. In this example, a 16th rests is not quoted,
-since @code{rest-event} is not in @code{quotedEventTypes}."
+ texidoc = "With @code{\\cueDuring} and @code{\\quoteDuring},
+fragments of previously entered music may be
+quoted. @code{quotedEventTypes} will determines what things are
+quoted. In this example, a 16th rests is not quoted, since
+@code{rest-event} is not in @code{quotedEventTypes}."
}
\version "2.4.0"
\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 \quoteDuring #"quoteMe" #1 { r2. } }
+ { s4 \quoteDuring #"quoteMe" { s2. } }
>>
>>
--- /dev/null
+
+\header {
+
+ texidoc = "Quotes may contain grace notes. The grace note leading up
+ to an unquoted note is not quoted."
+
+}
+\paper { raggedright= ##t }
+
+\version "2.4.0"
+quoted = \relative c'' {
+ R1
+ \grace g16 f4 \grace a16 bes4 \grace b16 c4 c4
+}
+
+\addquote quoted \quoted
+
+
+<<
+ \new Staff {
+ \set Staff.instrument = "quoted"
+ \quoted
+ }
+ \new Staff \new Voice \relative c'' {
+ \set Staff.instrument = "quoted"
+ R1
+ \cueDuring #"quoted" #1 { \grace s16. r2 }
+ c2^"original"
+ }
+>>
--- /dev/null
+/*
+ grace-engraver.cc -- implement Grace_engraver
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 2004 Han-Wen Nienhuys <hanwen@xs4all.nl>
+
+*/
+
+#include "engraver.hh"
+#include "context.hh"
+#include "warn.hh"
+
+class Grace_engraver : public Engraver
+{
+protected:
+ virtual void start_translation_timestep ();
+ virtual void derived_mark ();
+
+ TRANSLATOR_DECLARATIONS (Grace_engraver);
+ Moment last_moment_;
+ SCM grace_settings_;
+public:
+};
+
+
+Grace_engraver::Grace_engraver()
+{
+ grace_settings_ = SCM_EOL;
+}
+
+void
+Grace_engraver::derived_mark ()
+{
+ scm_gc_mark (grace_settings_);
+}
+
+void
+Grace_engraver::start_translation_timestep ()
+{
+ Moment now = now_mom ();
+ if (last_moment_.grace_part_ && !now.grace_part_)
+ {
+ for (SCM s = grace_settings_; scm_is_pair (s); s = scm_cdr (s))
+ {
+ SCM context = scm_caar (s);
+ SCM entry = scm_cdar (s);
+ SCM grob = scm_cadr (entry);
+ SCM sym = scm_caddr (entry);
+
+ execute_pushpop_property (unsmob_context (context),
+ grob, sym, SCM_UNDEFINED);
+ }
+
+ grace_settings_ = SCM_EOL;
+ }
+ else if (!last_moment_.grace_part_ && now.grace_part_)
+ {
+ SCM settings = get_property ("graceSettings");
+
+ grace_settings_ = SCM_EOL;
+ for (SCM s = settings; scm_is_pair (s); s = scm_cdr (s))
+ {
+ SCM entry = scm_car (s);
+ SCM context_name = scm_car (entry);
+ SCM grob = scm_cadr (entry);
+ SCM sym = scm_caddr (entry);
+ SCM val = scm_cadddr (entry);
+
+ Context *c = context ();
+ while (c
+ && c->context_name_symbol () != context_name)
+ {
+ c = c->get_parent_context ();
+ }
+
+ if (c)
+ {
+ execute_pushpop_property (c,
+ grob, sym, val);
+ grace_settings_
+ = scm_cons (scm_cons (c->self_scm(), entry), grace_settings_);
+ }
+ else
+ {
+ programming_error ("Cannot find context");
+ scm_display (context_name, scm_current_error_port());
+ }
+ }
+ }
+
+ last_moment_ = now;
+}
+
+
+ENTER_DESCRIPTION (Grace_engraver,
+ /* descr */ "Set font size and other properties for grace notes.",
+ /* creats*/ "",
+ /* accepts */ "",
+ /* acks */ "",
+ /* reads */ "graceSettings",
+ /* write */ "");
/*
- grace-music.cc -- implement Grace_music
+ grace-music.cc -- implement Grace_music
- source file of the GNU LilyPond music typesetter
+ source file of the GNU LilyPond music typesetter
- (c) 1999--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+ (c) 1999--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
- */
+*/
#include "grace-music.hh"
#include "grace-iterator.hh"
Grace_music::Grace_music ()
{
set_property ("iterator-ctor",
- Grace_iterator::constructor_proc);
+ Grace_iterator::constructor_proc);
}
ADD_MUSIC (Grace_music);
Interpretation_context_handle quote_outlet_;
Moment start_moment_;
+ Moment stop_moment_;
SCM event_vector_;
int event_idx_;
int end_idx_ ;
SCM transposed_musics_;
DECLARE_SCHEME_CALLBACK (constructor, ());
-
+ bool quote_ok () const;
bool accept_music_type (Music*) const;
protected:
virtual void derived_mark () const;
quote_outlet_.set_context (get_outlet ());
}
- Moment now = get_outlet ()->now_mom ();
- Moment stop = now + get_music()->get_length ();
- start_moment_ = now;
event_vector_ = get_music ()->get_property ("quoted-events");
-
- if (ly_c_vector_p (event_vector_))
- {
- event_idx_ = binsearch_scm_vector (event_vector_, now.smobbed_copy (), &moment_less);
- end_idx_ = binsearch_scm_vector (event_vector_, stop.smobbed_copy (), &moment_less);
- }
- else
- {
- get_music ()->origin()->warning (_("No events found for \\quote"));
- }
+
+ /*
+ We have to delay initting event_idx_ , since we have to
+ take starting grace notes into account. Those may offset
+ event_idx_.
+ */
+ event_idx_ = -1;
}
{
return
Music_wrapper_iterator::ok()
- && ly_c_vector_p (event_vector_) && (event_idx_ <= end_idx_);
+ || quote_ok ();
+}
+
+bool
+New_quote_iterator::quote_ok () const
+{
+ return (event_idx_ >= 0
+ && ly_c_vector_p (event_vector_)
+ && event_idx_ <= end_idx_
+
+ /*
+ Don't quote the grace notes leading to an unquoted note.
+ */
+ && vector_moment (event_idx_).main_part_ < stop_moment_.main_part_
+ );
}
Moment
New_quote_iterator::pending_moment () const
{
- return
- Music_wrapper_iterator::pending_moment()
- <?
- vector_moment (event_idx_) - start_moment_;
+ Rational infty;
+ infty.set_infinite (1);
+ Moment m (infty);
+
+ if (Music_wrapper_iterator::ok())
+ m = m <? Music_wrapper_iterator::pending_moment();
+
+ /*
+ In case event_idx_ < 0, we're not initted yet, and the wrapped
+ music expression determines the starting moment.
+ */
+ if (quote_ok ())
+ m = m <? vector_moment (event_idx_) - start_moment_;
+
+ return m;
}
Moment
SCM entry = SCM_VECTOR_REF (event_vector_, idx);
return *unsmob_moment (scm_caar (entry));
}
-
void
New_quote_iterator::process (Moment m)
{
- Music_wrapper_iterator::process (m);
+ if (Music_wrapper_iterator::ok())
+ Music_wrapper_iterator::process (m);
+
+ if (event_idx_ < 0)
+ {
+ event_idx_ = binsearch_scm_vector (event_vector_,
+ get_outlet ()->now_mom ().smobbed_copy (),
+ &moment_less);
+ start_moment_ = get_outlet ()->now_mom () - music_start_mom();
+ stop_moment_ = start_moment_ + get_music()->get_length ();
+
+ end_idx_ = binsearch_scm_vector (event_vector_,
+ stop_moment_.smobbed_copy (),
+ &moment_less);
+ }
m += start_moment_;
while (event_idx_ <= end_idx_)
event_idx_++;
}
- if (event_idx_ <= end_idx_)
+ if (quote_ok ())
{
SCM entry = SCM_VECTOR_REF (event_vector_, event_idx_);
Pitch * quote_pitch = unsmob_pitch (scm_cdar (entry));
mus->origin ()->warning (_f ("In quotation: junking event %s", mus->name ()));
}
}
+
+ event_idx_ ++;
}
- event_idx_ ++;
}
IMPLEMENT_CTOR_CALLBACK (New_quote_iterator);
part-combine-listener))
(first-voice-handle (last-pair noticed)))
- ; (display (last-pair noticed))
+ ;; (display (last-pair noticed))
(if (pair? first-voice-handle)
(hash-set! tab name
;; cdr : skip name string
sequential-music-to-chord-exceptions
set-default-paper-size
set-part-combine-listener
- set-start-grace-properties
- set-stop-grace-properties
Accidental_interface::after_line_breaking
Accidental_interface::print