]> git.donarmstrong.com Git - lilypond.git/commitdiff
Clef support for cue notes
authorReinhold Kainhofer <reinhold@kainhofer.com>
Tue, 28 Sep 2010 13:03:20 +0000 (15:03 +0200)
committerReinhold Kainhofer <reinhold@kainhofer.com>
Wed, 29 Dec 2010 01:06:34 +0000 (02:06 +0100)
-) Added \cueDuringWithClef, which allows to specify a clef for
   the cue notes. At the end of the cue section, the clef is
   automatically reset to the containing voice's clef.
-) Cue clefs are implemented as CueClef and CueEndClef grobs,
   created by a dedicated Cue_clef_engraver, which reads
   some cueClef* context properties.
-) After a line break, a cue clef does NOT override the global clef
   of the containing voice, but prints (in smaller size) after
   the containing clef.

14 files changed:
Documentation/changes.tely
input/regression/cue-clef-begin-of-score.ly [new file with mode: 0644]
input/regression/cue-clef-new-line.ly [new file with mode: 0644]
input/regression/cue-clef-octavation.ly [new file with mode: 0644]
input/regression/cue-clef.ly [new file with mode: 0644]
lily/cue-clef-engraver.cc [new file with mode: 0644]
lily/pitch-scheme.cc
ly/engraver-init.ly
ly/music-functions-init.ly
scm/define-context-properties.scm
scm/define-grobs.scm
scm/define-music-properties.scm
scm/music-functions.scm
scm/parser-clef.scm

index ddc6c575ce8bc34c3a5e15f3db86f99f8f032b9e..29882e3eafbf825e9d414c8955d6f7cfc56a080d 100644 (file)
@@ -66,6 +66,34 @@ which scares away people.
 
 @end ignore
 
+@item
+By using @code{\cueDuringWithClef}, cue notes can now also have their own
+clef, which is correctly reset at the end of the cue notes.  At the begin
+of each line, the standard clef is still displayed, but the cue clef is
+shown after the time/key signature in smaller size.
+@lilypond
+vI = \relative c'' { \clef "treble" \repeat unfold 40 g4 }
+\addQuote vIQuote { \vI }
+
+Solo = \relative c {
+  \clef "bass"
+  \cueDuringWithClef #"vIQuote" #DOWN #"treble" { R1 } |
+  c4 \cueDuringWithClef #"vIQuote" #DOWN #"treble" {
+    r4 r2 |
+    r4
+  } c4 c2 |
+  \cueDuringWithClef #"vIQuote" #DOWN "soprano" { R1*2 \break R1 } |
+  c1
+}
+
+\score {
+  <<
+    \new Staff \new Voice \Solo
+  >>
+}
+@end lilypond
+
+
 @item
 Note names can be selected with a new
 @code{@bs{}language "italiano"} command, which
diff --git a/input/regression/cue-clef-begin-of-score.ly b/input/regression/cue-clef-begin-of-score.ly
new file mode 100644 (file)
index 0000000..9c3d695
--- /dev/null
@@ -0,0 +1,20 @@
+\version "2.13.45"
+
+\header {
+  texidoc = "Clefs for cue notes at the start of a score should print the
+standard clef plus a small cue clef after the time/key signature."
+}
+
+vI = \relative c'' { \clef "treble" \repeat unfold 40 g4 }
+\addQuote vIQuote { \vI }
+
+Solo = \relative c'' {
+  \clef "bass"
+  \cueDuringWithClef #"vIQuote" #DOWN #"treble" { r2 } d,,4 d4 |
+}
+
+\score {
+  <<
+    \new Staff \new Voice \Solo
+  >>
+}
diff --git a/input/regression/cue-clef-new-line.ly b/input/regression/cue-clef-new-line.ly
new file mode 100644 (file)
index 0000000..56f2e93
--- /dev/null
@@ -0,0 +1,30 @@
+\version "2.13.45"
+
+\header {
+  texidoc = "Clefs for cue notes and line breaks.  If the cue notes start in a
+new line, the cue clef should not be printed at the end of the previous line.
+Similarly, an end clef for cue notes ending at a line break should only be
+printed at the end of the line.
+
+Cue notes going over a line break should print the standard clef on the new
+line plus an additional cue clef after the time/key signature."
+}
+
+vI = \relative c'' { \clef "treble" \repeat unfold 40 g4 }
+\addQuote vIQuote { \vI }
+
+Solo = \relative c {
+  \clef "bass"
+  c1 | \break
+  \cueDuringWithClef #"vIQuote" #UP #"tenor" { R1 } | \break
+  c1 |
+  \cueDuringWithClef #"vIQuote" #UP #"tenor" { R1 | \break
+    R1 } |
+  c1
+}
+
+\score {
+  <<
+    \new Staff \new Voice \Solo
+  >>
+}
diff --git a/input/regression/cue-clef-octavation.ly b/input/regression/cue-clef-octavation.ly
new file mode 100644 (file)
index 0000000..cbe1010
--- /dev/null
@@ -0,0 +1,26 @@
+\version "2.13.45"
+
+\header {
+  texidoc = "Octavation for clefs for cue notes."
+}
+
+vI = \relative c'' { \clef "treble" \repeat unfold 40 g4 }
+\addQuote vIQuote { \vI }
+
+Solo = \relative c' {
+  \clef "treble_8" c1 |
+  \cueDuringWithClef #"vIQuote" #UP #"bass^8" { R1 } |
+  c1 | \break
+  c c
+  \clef "bass^8" c1 |
+  \cueDuringWithClef #"vIQuote" #UP #"treble_8" { R1 R1 } |
+  c
+  \cueDuringWithClef #"vIQuote" #UP #"treble_8" { R1 \break R } |
+  c
+}
+
+\score {
+  <<
+    \new Staff \new Voice \Solo
+  >>
+}
diff --git a/input/regression/cue-clef.ly b/input/regression/cue-clef.ly
new file mode 100644 (file)
index 0000000..c29759c
--- /dev/null
@@ -0,0 +1,25 @@
+\version "2.13.45"
+
+\header {
+  texidoc = "Clefs for cue notes: Print a cue clef at the begin of the cue
+notes and a cancelling clef after the cue notes."
+}
+
+vI = \relative c'' { \clef "treble" \repeat unfold 16 g4 }
+\addQuote vIQuote { \vI }
+
+Solo = \relative c {
+  \clef "bass"
+  c4 \cueDuringWithClef #"vIQuote" #DOWN #"treble" {
+    r4 r2 |
+    r4
+  } c4 c2 |
+  \cueDuringWithClef #"vIQuote" #DOWN "soprano" { R1*2 } |
+  c1
+}
+
+\score {
+  <<
+    \new Staff \new Voice \Solo
+  >>
+}
diff --git a/lily/cue-clef-engraver.cc b/lily/cue-clef-engraver.cc
new file mode 100644 (file)
index 0000000..be4ddf4
--- /dev/null
@@ -0,0 +1,241 @@
+/*
+  This file is part of LilyPond, the GNU music typesetter.
+
+  Copyright (C) 1997--2010 Han-Wen Nienhuys <hanwen@xs4all.nl>
+                           Mats Bengtsson <matsb@s3.kth.se>
+  Copyright (C) 2010 Reinhold Kainhofer <reinhold@kainhofer.com>
+
+  LilyPond is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  LilyPond is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <cctype>
+using namespace std;
+
+#include "item.hh"
+#include "context.hh"
+#include "bar-line.hh"
+#include "staff-symbol-referencer.hh"
+#include "engraver.hh"
+#include "direction.hh"
+#include "side-position-interface.hh"
+#include "warn.hh"
+#include "international.hh"
+
+#include "translator.icc"
+
+class Cue_clef_engraver : public Engraver
+{
+public:
+  TRANSLATOR_DECLARATIONS (Cue_clef_engraver);
+
+protected:
+  void stop_translation_timestep ();
+  void process_music ();
+  DECLARE_ACKNOWLEDGER (bar_line);
+
+  virtual void derived_mark () const;
+private:
+  Item *clef_;
+  Item *octavate_;
+
+  SCM prev_glyph_;
+  SCM prev_cpos_;
+  SCM prev_octavation_;
+  void create_clef ();
+  void create_end_clef ();
+  void set_glyph ();
+  void inspect_clef_properties ();
+  void create_octavate_eight (SCM oct);
+};
+
+void
+Cue_clef_engraver::derived_mark () const
+{
+  scm_gc_mark (prev_octavation_);
+  scm_gc_mark (prev_cpos_);
+  scm_gc_mark (prev_glyph_);
+}
+
+Cue_clef_engraver::Cue_clef_engraver ()
+{
+  clef_ = 0;
+  octavate_ = 0;
+
+  prev_octavation_ = prev_cpos_ = prev_glyph_ = SCM_EOL;
+}
+
+void
+Cue_clef_engraver::set_glyph ()
+{
+  SCM glyph_sym = ly_symbol2scm ("glyph");
+  SCM basic = ly_symbol2scm ("CueClef");
+  execute_pushpop_property (context (), basic, glyph_sym, SCM_UNDEFINED);
+  execute_pushpop_property (context (), basic, glyph_sym, get_property ("cueClefGlyph"));
+
+  basic = ly_symbol2scm ("CueEndClef");
+  execute_pushpop_property (context (), basic, glyph_sym, SCM_UNDEFINED);
+  execute_pushpop_property (context (), basic, glyph_sym, get_property ("clefGlyph"));
+}
+
+/**
+   Generate a clef at the start of a measure. (when you see a Bar,
+   ie. a breakpoint)
+*/
+void
+Cue_clef_engraver::acknowledge_bar_line (Grob_info info)
+{
+  Item *item = info.item ();
+  if (item && scm_is_string (get_property ("cueClefGlyph")))
+    create_clef ();
+}
+
+void
+Cue_clef_engraver::create_octavate_eight (SCM oct)
+{
+  if (scm_is_number (oct) && scm_to_int (oct))
+    {
+      Item *g = make_item ("OctavateEight", SCM_EOL);
+
+      int abs_oct = scm_to_int (oct);
+      int dir = sign (abs_oct);
+      abs_oct = abs (abs_oct) + 1;
+
+      SCM txt = scm_number_to_string (scm_from_int (abs_oct),
+                                     scm_from_int (10));
+
+      g->set_property ("text",
+                      scm_list_n (ly_lily_module_constant ("vcenter-markup"),
+                                  txt, SCM_UNDEFINED));
+      Side_position_interface::add_support (g, clef_);
+
+      g->set_parent (clef_, Y_AXIS);
+      g->set_parent (clef_, X_AXIS);
+      g->set_property ("direction", scm_from_int (dir));
+
+      // Inherit the break-visibility from the clef!
+      SCM vis = clef_->get_property ("break-visibility");
+      if (vis && g)
+       g->set_property ("break-visibility", vis);
+
+      octavate_ = g;
+    }
+}
+
+void
+Cue_clef_engraver::create_clef ()
+{
+  if (!clef_)
+    {
+      Item *c = make_item ("CueClef", SCM_EOL);
+
+      clef_ = c;
+      SCM cpos = get_property ("cueClefPosition");
+      if (scm_is_number (cpos))
+       clef_->set_property ("staff-position", cpos);
+
+      create_octavate_eight (get_property ("cueClefOctavation"));
+    }
+}
+
+void
+Cue_clef_engraver::create_end_clef ()
+{
+  if (!clef_)
+    {
+      clef_ = make_item ("CueEndClef", SCM_EOL);
+      SCM cpos = get_property ("clefPosition");
+      if (scm_is_number (cpos))
+       clef_->set_property ("staff-position", cpos);
+
+      create_octavate_eight (get_property ("clefOctavation"));
+    }
+}
+
+void
+Cue_clef_engraver::process_music ()
+{
+  inspect_clef_properties ();
+}
+
+void
+Cue_clef_engraver::inspect_clef_properties ()
+{
+  SCM glyph = get_property ("cueClefGlyph");
+  SCM clefpos = get_property ("cueClefPosition");
+  SCM octavation = get_property ("cueClefOctavation");
+
+  if (scm_equal_p (glyph, prev_glyph_) == SCM_BOOL_F
+      || scm_equal_p (clefpos, prev_cpos_) == SCM_BOOL_F
+      || scm_equal_p (octavation, prev_octavation_) == SCM_BOOL_F
+      || to_boolean (force_clef))
+    {
+      set_glyph ();
+      if (scm_is_string (glyph))
+       {
+         create_clef ();
+         if (clef_)
+           clef_->set_property ("non-default", SCM_BOOL_T);
+       }
+      else
+        create_end_clef ();
+
+      prev_cpos_ = clefpos;
+      prev_glyph_ = glyph;
+      prev_octavation_ = octavation;
+    }
+
+}
+
+void
+Cue_clef_engraver::stop_translation_timestep ()
+{
+  if (clef_)
+    {
+      SCM vis = 0;
+      if (to_boolean (clef_->get_property ("non-default")))
+       vis = get_property ("explicitCueClefVisibility");
+
+      if (vis)
+       {
+         clef_->set_property ("break-visibility", vis);
+         if (octavate_)
+           octavate_->set_property ("break-visibility", vis);
+       }
+
+      clef_ = 0;
+      octavate_ = 0;
+    }
+}
+
+ADD_ACKNOWLEDGER (Cue_clef_engraver, bar_line);
+ADD_TRANSLATOR (Cue_clef_engraver,
+               /* doc */
+               "Determine and set reference point for pitches in cued voices.",
+
+               /* create */
+               "CueClef "
+               "CueEndClef "
+               "OctavateEight ",
+
+               /* read */
+               "cueClefGlyph "
+               "cueClefOctavation "
+               "cueClefPosition "
+               "explicitCueClefVisibility "
+               "middleCCuePosition "
+               "clefOctavation ",
+
+               /* write */
+               ""
+               );
index be499050c128f1b8435d768f90b8defaca6b8cb2..58e31a3b93414f86c16091fd2cc5264623167b4c 100644 (file)
@@ -168,6 +168,10 @@ LY_DEFINE (ly_set_middle_C_x, "ly:set-middle-C!",
   Context *c = unsmob_context (context);
   int clef_pos = robust_scm2int (c->get_property ("middleCClefPosition"), 0);
   int offset = robust_scm2int (c->get_property ("middleCOffset"), 0);
+  /* middleCCuePosition overrides the clef! */
+  SCM cue_pos = c->get_property ("middleCCuePosition");
+  if (scm_is_number (cue_pos))
+    clef_pos = robust_scm2int (cue_pos, 0);
 
   c->set_property (ly_symbol2scm ("middleCPosition"), scm_from_int (clef_pos + offset));
   return SCM_UNDEFINED;
index d102d7c5d4e3e489e69f913d2966b26c36b0f3f0..f5c4eab9b2708ccf239174e32179ea14f31f4ab1 100644 (file)
@@ -75,6 +75,7 @@
   \consists "Figured_bass_engraver"
   \consists "Figured_bass_position_engraver"
   \consists "Script_row_engraver"
+  \consists "Cue_clef_engraver"
 
   localKeySignature = #'()
   createSpacing = ##t
@@ -553,6 +554,7 @@ automatically when an output definition (a @code{\score} or
   automaticBars = ##t
 
   explicitClefVisibility = #all-visible
+  explicitCueClefVisibility = #end-of-line-invisible
   explicitKeySignatureVisibility = #all-visible
   implicitTimeSignatureVisibility = #end-of-line-invisible
 
index 9d66ee72ed03a5a1568d9ae6ee30b766422645ce..b591344ed588ba5ee93fcebd0f471a71adf72273 100644 (file)
@@ -214,6 +214,15 @@ clef =
    (_i "Set the current clef to @var{type}.")
    (make-clef-set type))
 
+cueClef =
+#(define-music-function (parser location type) (string?)
+  (_i "Set the current cue clef to @var{type}.")
+  (make-cue-clef-set type))
+cueClefUnset =
+#(define-music-function (parser location) ()
+  (_i "Unset the current cue clef.")
+  (make-cue-clef-unset))
+
 cueDuring =
 #(define-music-function
    (parser location what dir main-music) (string? ly:dir? ly:music?)
@@ -224,8 +233,20 @@ in a CueVoice oriented by @var{dir}.")
               'quoted-context-type 'Voice
               'quoted-context-id "cue"
               'quoted-music-name what
-              'quoted-voice-direction dir
-              'origin location))
+              'quoted-voice-direction dir))
+
+cueDuringWithClef =
+#(define-music-function
+   (parser location what dir clef main-music) (string? ly:dir? string? ly:music?)
+   (_i "Insert contents of quote @var{what} corresponding to @var{main-music},
+in a CueVoice oriented by @var{dir}.")
+   (make-music 'QuoteMusic
+              'element main-music
+              'quoted-context-type 'Voice
+              'quoted-context-id "cue"
+              'quoted-music-name what
+              'quoted-music-clef clef
+              'quoted-voice-direction dir))
 
 
 
index d4cfe137662e5aa457ce61afbcb6aab178b09ff5..795701ac7493663f5025b8b0374861fa52f45d89 100644 (file)
@@ -174,6 +174,12 @@ crescendi.  Available values are @samp{hairpin} and @samp{text}.  If unset,
 a hairpin crescendo is used.")
      (crescendoText ,markup? "The text to print at start of non-hairpin
 crescendo, i.e., @samp{cresc.}.")
+     (cueClefGlyph ,string? "Name of the symbol within the music font.")
+     (cueClefOctavation ,integer? "Add this much extra octavation.
+Values of 7 and -7 are common.")
+     (cueClefPosition ,number? "Where should the center of the clef
+symbol go, measured in half staff spaces from the center of the
+staff.")
      (currentBarNumber ,integer? "Contains the current barnumber.
 This property is incremented at every bar line.")
 
@@ -210,6 +216,8 @@ values.")
 
      (explicitClefVisibility ,vector? "@samp{break-visibility}
 function for clef changes.")
+     (explicitCueClefVisibility ,vector? "@samp{break-visibility}
+function for cue clef changes.")
      (explicitKeySignatureVisibility ,vector? "@samp{break-visibility}
 function for explicit key changes.  @samp{\\override} of the
 @code{break-visibility} property will set the visibility for normal
@@ -330,6 +338,9 @@ markup.  Called with four arguments: text, duration, count and context.")
      (middleCClefPosition ,number? "The position of the middle C,
 as determined only by the clef.  This can be calculated by looking at
 @code{clefPosition} and @code{clefGlyph}.")
+     (middleCCuePosition ,number? "The position of the middle C,
+as determined only by the clef of the cue notes.  This can be calculated by
+looking at @code{cueClefPosition} and @code{cueClefGlyph}.")
      (middleCOffset ,number? "The offset of
 middle C from the position given by @code{middleCClefPosition} This
 is used for ottava brackets.")
index d47633d48d17f817f725a4d9286395c2defa5a92..95df5c37d166257cd3bca9dd6bbe2c9f24fca7e0 100644 (file)
        (break-visibility . ,begin-of-line-visible)
        (non-musical . #t)
        (space-alist . (
+                       (cue-end-clef . (extra-space . 0.5))
                        (clef . (extra-space . 0.5))
+                       (cue-clef . (extra-space . 0.5))
                        (key-signature . (extra-space . 0.0))
                        (staff-bar . (extra-space . 0.0))
                        (time-signature . (extra-space . 0.0))
        (break-align-orders . ;; end of line
                            #((
                               left-edge
+                              cue-end-clef
                               ambitus
                               breathing-sign
                               clef
+                              cue-clef
                               staff-bar
                               key-cancellation
                               key-signature
                              ;; unbroken
                              (
                               left-edge
+                              cue-end-clef
                               ambitus
                               breathing-sign
                               clef
+                              cue-clef
                               staff-bar
                               key-cancellation
                               key-signature
                               key-signature
                               staff-bar
                               time-signature
+                              cue-clef
                               custos)))
        (non-musical . #t)
        (positioning-done . ,ly:break-alignment-interface::calc-positioning-done)
                        (time-signature . (minimum-space . 1.5))
                        (staff-bar . (minimum-space . 1.5))
                        (clef . (minimum-space . 2.0))
+                       (cue-clef . (minimum-space . 2.0))
+                       (cue-end-clef . (minimum-space . 2.0))
                        (first-note . (fixed-space . 1.0)) ;huh?
                        (right-edge . (extra-space . 0.1))))
        (stencil . ,ly:text-interface::print)
        (break-visibility . ,begin-of-line-visible)
        (glyph-name . ,ly:clef::calc-glyph-name)
        (non-musical . #t)
-       (space-alist . ((ambitus . (extra-space . 2.0))
+       (space-alist . ((cue-clef . (extra-space . 2.0))
                        (staff-bar . (extra-space . 0.7))
                        (key-cancellation . (minimum-space . 3.5))
                        (key-signature . (minimum-space . 3.5))
                                text-interface
                                text-script-interface))))))
 
+    (CueClef
+     . (
+       (avoid-slur . inside)
+       (break-align-anchor . ,ly:break-aligned-interface::calc-extent-aligned-anchor)
+       (break-align-symbol . cue-clef)
+       (break-visibility . ,begin-of-line-visible)
+       (font-size . -3)
+       (glyph-name . ,ly:clef::calc-glyph-name)
+       (non-musical . #t)
+       (full-size-change . #t)
+       (space-alist . ((staff-bar . (minimum-space . 2.7))
+                       (key-cancellation . (minimum-space . 3.5))
+                       (key-signature . (minimum-space . 3.5))
+                       (time-signature . (minimum-space . 4.2))
+                       (custos . (minimum-space . 0.0))
+                       (first-note . (minimum-fixed-space . 3.0))
+                       (next-note . (extra-space . 0.5))
+                       (right-edge . (extra-space . 0.5))))
+       (stencil . ,ly:clef::print)
+       (extra-spacing-height . (-0.5 . 0.5))
+       (Y-offset . ,ly:staff-symbol-referencer::callback)
+       (meta . ((class . Item)
+                (interfaces . (break-aligned-interface
+                               clef-interface
+                               font-interface
+                               staff-symbol-referencer-interface))))))
+
+    (CueEndClef
+     . (
+       (avoid-slur . inside)
+       (break-align-anchor . ,ly:break-aligned-interface::calc-extent-aligned-anchor)
+       (break-align-symbol . cue-end-clef)
+       (break-visibility . ,begin-of-line-invisible)
+       (font-size . -3)
+       (glyph-name . ,ly:clef::calc-glyph-name)
+       (non-musical . #t)
+       (full-size-change . #t)
+       (space-alist . ((clef . (extra-space . 0.7))
+                       (cue-clef . (extra-space . 0.7))
+                       (staff-bar . (extra-space . 0.7))
+                       (key-cancellation . (minimum-space . 3.5))
+                       (key-signature . (minimum-space . 3.5))
+                       (time-signature . (minimum-space . 4.2))
+                       (first-note . (minimum-fixed-space . 5.0))
+                       (next-note . (extra-space . 0.5))
+                       (right-edge . (extra-space . 0.5))))
+       (stencil . ,ly:clef::print)
+       (extra-spacing-height . (-0.5 . 0.5))
+       (Y-offset . ,ly:staff-symbol-referencer::callback)
+       (meta . ((class . Item)
+                (interfaces . (break-aligned-interface
+                               clef-interface
+                               font-interface
+                               staff-symbol-referencer-interface))))))
+
     (Custos
      . (
        (break-align-symbol . custos)
                        (time-signature . (extra-space . 1.25))
                        (staff-bar . (extra-space . 0.6))
                        (key-signature . (extra-space . 0.5))
+                       (cue-clef . (extra-space . 0.5))
                        (right-edge . (extra-space . 0.5))
                        (first-note . (fixed-space . 2.5))))
        (stencil . ,ly:key-signature-interface::print)
        (space-alist . (
                        (time-signature . (extra-space . 1.15))
                        (staff-bar . (extra-space . 1.1))
+                       (cue-clef . (extra-space . 0.5))
                        (right-edge . (extra-space . 0.5))
                        (first-note . (fixed-space . 2.5))))
        (stencil . ,ly:key-signature-interface::print)
        (break-visibility . ,center-invisible)
        (non-musical . #t)
        (space-alist . (
-                       (custos . (extra-space . 0.0))
                        (ambitus . (extra-space . 2.0))
-                       (time-signature . (extra-space . 1.0))
-                       (staff-bar . (extra-space . 0.0))
                        (breathing-sign . (minimum-space . 0.0))
+                       (cue-end-clef . (extra-space . 0.8))
                        (clef . (extra-space . 0.8))
+                       (cue-clef . (extra-space . 0.8))
+                       (staff-bar . (extra-space . 0.0))
+                       (key-cancellation . (extra-space . 0.0))
+                       (key-signature . (extra-space . 0.8))
+                       (time-signature . (extra-space . 1.0))
+                       (custos . (extra-space . 0.0))
                        (first-note . (fixed-space . 2.0))
                        (right-edge . (extra-space . 0.0))
-                       (key-signature . (extra-space . 0.8))
-                       (key-cancellation . (extra-space . 0.0))
                        ))
        (X-extent . (0 . 0))
        (meta . ((class . Item)
        (extra-spacing-height . (-1.0 . 1.0))
        (non-musical . #t)
        (space-alist . (
+                       (cue-clef . (extra-space . 1.5))
                        (first-note . (fixed-space . 2.0))
                        (right-edge . (extra-space . 0.5))
                        (staff-bar . (minimum-space . 2.0))))
index 23faf5644a7917e18b7b4a8454dba72b1b20aa40..577b9d2925ceafa29e5dcaf89355275d6600b711 100644 (file)
@@ -148,6 +148,7 @@ e.g., @code{cue}.")
 direct quotes to, e.g., @code{Voice}.")
      (quoted-events ,vector? "A vector of with @code{moment} and
 @code{event-list} entries.")
+     (quoted-music-clef ,string? "The clef of the voice to quote.")
      (quoted-music-name ,string? "The name of the voice to quote.")
      (quoted-transposition ,ly:pitch? "The pitch used for the quote,
 overriding @code{\\transposition}.")
index 688900411fa446304cb390465cdbb6aae86f418f..1f8b593318f1bb409d468c906d2fdfd938d8c53e 100644 (file)
@@ -782,6 +782,7 @@ Syntax:
 
   (if (vector? (ly:music-property quote-music 'quoted-events))
       (let* ((dir (ly:music-property quote-music 'quoted-voice-direction))
+            (clef (ly:music-property quote-music 'quoted-music-clef))
             (main-voice (if (eq? 1 dir) 1 0))
             (cue-voice (if (eq? 1 dir) 0 1))
             (main-music (ly:music-property quote-music 'element))
@@ -793,14 +794,19 @@ Syntax:
            ;; to have opposite stems.
            (begin
              (set! return-value
-
                    ;; cannot context-spec Quote-music, since context
                    ;; for the quotes is determined in the iterator.
                    (make-sequential-music
                     (list
+                     (if (null? clef)
+                         (make-music 'Music)
+                         (make-cue-clef-set clef))
                      (context-spec-music (make-voice-props-set cue-voice) 'CueVoice "cue")
                      quote-music
-                     (context-spec-music (make-voice-props-revert)  'CueVoice "cue"))))
+                     (context-spec-music (make-voice-props-revert) 'CueVoice "cue")
+                     (if (null? clef)
+                         (make-music 'Music)
+                         (make-cue-clef-unset)))))
              (set! main-music
                    (make-sequential-music
                     (list
index 757a1876defd38f44c724c9b84ef8daf07c4d0d8..f6e0fb9b0bcc1b146c309a2564f7d7c1c6e13fd3 100644 (file)
                       (sort (map car supported-clefs) string<?)))
          (make-music 'Music)))))
 
+(define-public (make-cue-clef-set clef-name)
+  "Generate the clef setting commands for a cue clef with name CLEF-NAME."
+  (define (make-prop-set props)
+    (let ((m (make-music 'PropertySet)))
+      (map (lambda (x) (set! (ly:music-property m (car x)) (cdr x))) props)
+      m))
+  (let ((e '())
+       (c0 0)
+       (oct 0)
+       (match (string-match "^(.*)([_^])([1-9][0-9]*)$" clef-name)))
+    (if match
+       (begin
+         (set! clef-name (match:substring match 1))
+         (set! oct
+               (* (if (equal? (match:substring match 2) "^") -1 1)
+                  (- (string->number (match:substring match 3)) 1)))))
+    (set! e (assoc-get clef-name supported-clefs))
+    (if e
+       (let* ((musics (map make-prop-set
+                           `(((symbol . cueClefGlyph) (value . ,(car e)))
+                             ((symbol . middleCCuePosition)
+                              (value . ,(+ oct
+                                           (cadr e)
+                                           (assoc-get (car e) c0-pitch-alist))))
+                             ((symbol . cueClefPosition) (value . ,(cadr e)))
+                             ((symbol . cueClefOctavation) (value . ,(- oct))))))
+              (recalc-mid-C (make-music 'ApplyContext))
+              (seq (make-music 'SequentialMusic
+                               'elements (append musics (list recalc-mid-C))))
+              (csp (make-music 'ContextSpeccedMusic)))
+         (set! (ly:music-property recalc-mid-C 'procedure) ly:set-middle-C!)
+         (context-spec-music seq 'Staff))
+       (begin
+         (ly:warning (_ "unknown clef type `~a'") clef-name)
+         (ly:warning (_ "supported clefs: ~a")
+                     (string-join
+                      (sort (map car supported-clefs) string<?)))
+         (make-music 'Music)))))
+
+
+(define-public (make-cue-clef-unset)
+  "Reset the clef settings for a cue clef."
+  (define (make-prop-unset props)
+    (let ((m (make-music 'PropertyUnset)))
+      (set! (ly:music-property m (car props)) (cdr props))
+      m))
+  (let* ((musics (map make-prop-unset
+                       `((symbol . cueClefGlyph)
+                         (symbol . middleCCuePosition)
+                         (symbol . cueClefPosition)
+                         (symbol . cueClefOctavation))))
+        (recalc-mid-C (make-music 'ApplyContext))
+        (seq (make-music 'SequentialMusic
+                         'elements (append musics (list recalc-mid-C))))
+        (csp (make-music 'ContextSpeccedMusic)))
+    (set! (ly:music-property recalc-mid-C 'procedure) ly:set-middle-C!)
+    (context-spec-music seq 'Staff)))
+
+
 ;; a function to add new clefs at runtime
 (define-public (add-new-clef clef-name clef-glyph clef-position octavation c0-position)
   "Append the entries for a clef symbol to supported clefs and c0-pitch-alist"