From a1fa0e63b1bf2c61a9c19a33b7034989fb3fac05 Mon Sep 17 00:00:00 2001 From: Reinhold Kainhofer Date: Sat, 22 Aug 2009 00:47:41 +0200 Subject: [PATCH] Implement framework for post-fix text (de)cresc spanners (backend only) The main problem why \decr or \dim were prefix operators was that the new dynamic engraver was reading only the properties of the Engraver itself, so there was no way to create a CrescendoEvent and at the same time specify the hairpin/text behavior. This patch makes the New_dynamic_engraver also look at the properties of the (Dec|C)recendoEvent and prefer a setting from there. If the event does not have a property (which will be the case most of the time), the Engraver's settings are used (i.e. same behavior as now). With this change, e.g. \dim can be defined as dim = #(make-music 'DecrescendoEvent 'span-direction START 'span-type text 'span-text "dim.") and used as postfix like a4\dim without the need of any overrides before the affected note. This is just the backend commit, implementing processing of the event's properties. The definition of \cresc is still unchanged, leaving the old prefix notation in place, until we find good upgrade path. Also add regtests for text cresc spanners and add the regtest to the snippets. --- .../dynamics-custom-text-spanner-postfix.ly | 26 ++++++++++++++++++ .../new/dynamics-text-spanner-postfix.ly | 27 +++++++++++++++++++ .../dynamics-custom-text-spanner-postfix.ly | 26 ++++++++++++++++++ .../dynamics-text-spanner-postfix.ly | 27 +++++++++++++++++++ lily/new-dynamic-engraver.cc | 16 +++++++++-- scm/define-music-properties.scm | 4 ++- 6 files changed, 123 insertions(+), 3 deletions(-) create mode 100644 Documentation/snippets/new/dynamics-custom-text-spanner-postfix.ly create mode 100644 Documentation/snippets/new/dynamics-text-spanner-postfix.ly create mode 100644 input/regression/dynamics-custom-text-spanner-postfix.ly create mode 100644 input/regression/dynamics-text-spanner-postfix.ly diff --git a/Documentation/snippets/new/dynamics-custom-text-spanner-postfix.ly b/Documentation/snippets/new/dynamics-custom-text-spanner-postfix.ly new file mode 100644 index 0000000000..f3f26b0cf2 --- /dev/null +++ b/Documentation/snippets/new/dynamics-custom-text-spanner-postfix.ly @@ -0,0 +1,26 @@ +\version "2.13.4" + +\header { +texidoc = "Postfix functions for custom crescendo text spanners. The spanners +should start on the first note of the measure. One has to use -\mycresc, +otherwise the spanner start will rather be assigned to the next note." +} + +% Two functions for (de)crescendo spanners where you can explicitly give the +% spanner text. +mycresc = #(define-music-function (parser location mymarkup) (string?) + (make-music 'CrescendoEvent 'span-direction START + 'span-type 'text 'span-text mymarkup)) +mydecresc = #(define-music-function (parser location mymarkup) (string?) + (make-music 'DecrescendoEvent 'span-direction START + 'span-type 'text 'span-text mymarkup)) + +\relative c' { + c4-\mycresc "custom cresc" c4 c4 c4 | + c4 c4 c4 c4 | + c4-\mydecresc "custom decresc" c4 c4 c4 | + c4 c4\! c4 c4 +} + + + diff --git a/Documentation/snippets/new/dynamics-text-spanner-postfix.ly b/Documentation/snippets/new/dynamics-text-spanner-postfix.ly new file mode 100644 index 0000000000..2b1044c670 --- /dev/null +++ b/Documentation/snippets/new/dynamics-text-spanner-postfix.ly @@ -0,0 +1,27 @@ +\version "2.13.4" + +\header { +texidoc = "The \cresc, \dim and \decresc spanners can now be redefined as +postfix operators and produce one text spanner. Defining custom spanners is +also easy. Hairpin and text crescendi can be easily mixed. \< and \> produce +hairpins by default, \cresc etc. produce text spanners by default." +} + +% Some sample text dynamic spanners, to be used as postfix operators +crpoco = #(make-music 'CrescendoEvent 'span-direction START + 'span-type 'text 'span-text "cresc. poco a poco") +% Redefine the existing \cresc, \dim and \decresc commands to use postfix syntax +cresc = #(make-music 'CrescendoEvent 'span-direction START + 'span-type 'text 'span-text "cresc.") +dim = #(make-music 'DecrescendoEvent 'span-direction START + 'span-type 'text 'span-text "dim.") +decresc = #(make-music 'DecrescendoEvent 'span-direction START + 'span-type 'text 'span-text "decresc.") + +\relative c' { + c4\cresc d4 e4 f4 | + g4 a4\! b4\crpoco c4 | + c4 d4 e4 f4 | + g4 a4\! b4\< c4 | + g4\dim a4 b4\decresc c4\! +} diff --git a/input/regression/dynamics-custom-text-spanner-postfix.ly b/input/regression/dynamics-custom-text-spanner-postfix.ly new file mode 100644 index 0000000000..f3f26b0cf2 --- /dev/null +++ b/input/regression/dynamics-custom-text-spanner-postfix.ly @@ -0,0 +1,26 @@ +\version "2.13.4" + +\header { +texidoc = "Postfix functions for custom crescendo text spanners. The spanners +should start on the first note of the measure. One has to use -\mycresc, +otherwise the spanner start will rather be assigned to the next note." +} + +% Two functions for (de)crescendo spanners where you can explicitly give the +% spanner text. +mycresc = #(define-music-function (parser location mymarkup) (string?) + (make-music 'CrescendoEvent 'span-direction START + 'span-type 'text 'span-text mymarkup)) +mydecresc = #(define-music-function (parser location mymarkup) (string?) + (make-music 'DecrescendoEvent 'span-direction START + 'span-type 'text 'span-text mymarkup)) + +\relative c' { + c4-\mycresc "custom cresc" c4 c4 c4 | + c4 c4 c4 c4 | + c4-\mydecresc "custom decresc" c4 c4 c4 | + c4 c4\! c4 c4 +} + + + diff --git a/input/regression/dynamics-text-spanner-postfix.ly b/input/regression/dynamics-text-spanner-postfix.ly new file mode 100644 index 0000000000..2b1044c670 --- /dev/null +++ b/input/regression/dynamics-text-spanner-postfix.ly @@ -0,0 +1,27 @@ +\version "2.13.4" + +\header { +texidoc = "The \cresc, \dim and \decresc spanners can now be redefined as +postfix operators and produce one text spanner. Defining custom spanners is +also easy. Hairpin and text crescendi can be easily mixed. \< and \> produce +hairpins by default, \cresc etc. produce text spanners by default." +} + +% Some sample text dynamic spanners, to be used as postfix operators +crpoco = #(make-music 'CrescendoEvent 'span-direction START + 'span-type 'text 'span-text "cresc. poco a poco") +% Redefine the existing \cresc, \dim and \decresc commands to use postfix syntax +cresc = #(make-music 'CrescendoEvent 'span-direction START + 'span-type 'text 'span-text "cresc.") +dim = #(make-music 'DecrescendoEvent 'span-direction START + 'span-type 'text 'span-text "dim.") +decresc = #(make-music 'DecrescendoEvent 'span-direction START + 'span-type 'text 'span-text "decresc.") + +\relative c' { + c4\cresc d4 e4 f4 | + g4 a4\! b4\crpoco c4 | + c4 d4 e4 f4 | + g4 a4\! b4\< c4 | + g4\dim a4 b4\decresc c4\! +} diff --git a/lily/new-dynamic-engraver.cc b/lily/new-dynamic-engraver.cc index 8c8fce9800..54aa8a8c6d 100644 --- a/lily/new-dynamic-engraver.cc +++ b/lily/new-dynamic-engraver.cc @@ -33,6 +33,8 @@ protected: virtual void process_music (); virtual void stop_translation_timestep (); private: + SCM get_property_setting (Stream_event *evt, char const *evprop, char const *ctxprop); + Drul_array accepted_spanevents_drul_; Spanner *current_spanner_; Spanner *finished_spanner_; @@ -68,6 +70,14 @@ New_dynamic_engraver::listen_span_dynamic (Stream_event *ev) ASSIGN_EVENT_ONCE (accepted_spanevents_drul_[d], ev); } +SCM +New_dynamic_engraver::get_property_setting (Stream_event *evt, char const *evprop, char const *ctxprop) +{ + SCM spanner_type = evt->get_property (evprop); + if (spanner_type == SCM_EOL) + spanner_type = get_property (ctxprop); + return spanner_type; +} void New_dynamic_engraver::process_music () @@ -105,7 +115,8 @@ New_dynamic_engraver::process_music () return; } - SCM cresc_type = get_property ((start_type + "Spanner").c_str ()); + SCM cresc_type = get_property_setting (current_span_event_, "span-type", + (start_type + "Spanner").c_str ()); if (cresc_type == ly_symbol2scm ("text")) { @@ -113,7 +124,8 @@ New_dynamic_engraver::process_music () = make_spanner ("DynamicTextSpanner", accepted_spanevents_drul_[START]->self_scm ()); - SCM text = get_property ((start_type + "Text").c_str ()); + SCM text = get_property_setting (current_span_event_, "span-text", + (start_type + "Text").c_str ()); if (Text_interface::is_markup (text)) { current_spanner_->set_property ("text", text); diff --git a/scm/define-music-properties.scm b/scm/define-music-properties.scm index 3d11e06c1c..05f9e2b221 100644 --- a/scm/define-music-properties.scm +++ b/scm/define-music-properties.scm @@ -139,9 +139,11 @@ or down-stem?") (repeat-count ,integer? "Do a @code{\\repeat} how often?") (span-direction ,ly:dir? "Does this start or stop a spanner?") - (span-type ,string? "What kind of spanner should be created? + (span-type ,string? "What kind of spanner should be created? E.g. ligature +for ligatures, or text or hairpin for (de-)crescendi. TODO: Consider making type into symbol.") + (span-text ,string? "The displayed text for text spanners (e.g. cresc.)") (split-list ,list? "Splitting moments for part combiner.") (start-callback ,procedure? "Function to compute the negative length of starting grace notes. This property can only be defined as initializer -- 2.39.2