summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReinhold Kainhofer <reinhold@kainhofer.com>2010-09-28 15:03:20 +0200
committerReinhold Kainhofer <reinhold@kainhofer.com>2010-12-29 02:06:34 +0100
commit29640aafbf7ad7b2191813c4c16d282f15a127fd (patch)
treef27e2558c456b46a6f367d97e98880cb99d3979d
parent9551796a06445e9570d5481a73aff11f1d259568 (diff)
Clef support for cue notes
-) 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.
-rw-r--r--Documentation/changes.tely28
-rw-r--r--input/regression/cue-clef-begin-of-score.ly20
-rw-r--r--input/regression/cue-clef-new-line.ly30
-rw-r--r--input/regression/cue-clef-octavation.ly26
-rw-r--r--input/regression/cue-clef.ly25
-rw-r--r--lily/cue-clef-engraver.cc241
-rw-r--r--lily/pitch-scheme.cc4
-rw-r--r--ly/engraver-init.ly2
-rw-r--r--ly/music-functions-init.ly25
-rw-r--r--scm/define-context-properties.scm11
-rw-r--r--scm/define-grobs.scm81
-rw-r--r--scm/define-music-properties.scm1
-rw-r--r--scm/music-functions.scm10
-rw-r--r--scm/parser-clef.scm59
14 files changed, 553 insertions, 10 deletions
diff --git a/Documentation/changes.tely b/Documentation/changes.tely
index ddc6c575ce..29882e3eaf 100644
--- a/Documentation/changes.tely
+++ b/Documentation/changes.tely
@@ -67,6 +67,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
can be used in safe mode. The old
diff --git a/input/regression/cue-clef-begin-of-score.ly b/input/regression/cue-clef-begin-of-score.ly
new file mode 100644
index 0000000000..9c3d69538b
--- /dev/null
+++ b/input/regression/cue-clef-begin-of-score.ly
@@ -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
index 0000000000..56f2e9311b
--- /dev/null
+++ b/input/regression/cue-clef-new-line.ly
@@ -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
index 0000000000..cbe101024c
--- /dev/null
+++ b/input/regression/cue-clef-octavation.ly
@@ -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
index 0000000000..c29759ca2d
--- /dev/null
+++ b/input/regression/cue-clef.ly
@@ -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
index 0000000000..be4ddf44f7
--- /dev/null
+++ b/lily/cue-clef-engraver.cc
@@ -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 */
+ ""
+ );
diff --git a/lily/pitch-scheme.cc b/lily/pitch-scheme.cc
index be499050c1..58e31a3b93 100644
--- a/lily/pitch-scheme.cc
+++ b/lily/pitch-scheme.cc
@@ -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;
diff --git a/ly/engraver-init.ly b/ly/engraver-init.ly
index d102d7c5d4..f5c4eab9b2 100644
--- a/ly/engraver-init.ly
+++ b/ly/engraver-init.ly
@@ -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
diff --git a/ly/music-functions-init.ly b/ly/music-functions-init.ly
index 9d66ee72ed..b591344ed5 100644
--- a/ly/music-functions-init.ly
+++ b/ly/music-functions-init.ly
@@ -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))
diff --git a/scm/define-context-properties.scm b/scm/define-context-properties.scm
index d4cfe13766..795701ac74 100644
--- a/scm/define-context-properties.scm
+++ b/scm/define-context-properties.scm
@@ -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.")
diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm
index d47633d48d..95df5c37d1 100644
--- a/scm/define-grobs.scm
+++ b/scm/define-grobs.scm
@@ -102,7 +102,9 @@
(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))
@@ -415,9 +417,11 @@
(break-align-orders . ;; end of line
#((
left-edge
+ cue-end-clef
ambitus
breathing-sign
clef
+ cue-clef
staff-bar
key-cancellation
key-signature
@@ -427,9 +431,11 @@
;; unbroken
(
left-edge
+ cue-end-clef
ambitus
breathing-sign
clef
+ cue-clef
staff-bar
key-cancellation
key-signature
@@ -446,6 +452,7 @@
key-signature
staff-bar
time-signature
+ cue-clef
custos)))
(non-musical . #t)
(positioning-done . ,ly:break-alignment-interface::calc-positioning-done)
@@ -467,6 +474,8 @@
(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)
@@ -499,7 +508,7 @@
(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))
@@ -556,6 +565,61 @@
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)
@@ -940,6 +1004,7 @@
(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)
@@ -962,6 +1027,7 @@
(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)
@@ -1014,16 +1080,18 @@
(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)
@@ -2087,6 +2155,7 @@
(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))))
diff --git a/scm/define-music-properties.scm b/scm/define-music-properties.scm
index 23faf5644a..577b9d2925 100644
--- a/scm/define-music-properties.scm
+++ b/scm/define-music-properties.scm
@@ -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}.")
diff --git a/scm/music-functions.scm b/scm/music-functions.scm
index 688900411f..1f8b593318 100644
--- a/scm/music-functions.scm
+++ b/scm/music-functions.scm
@@ -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
diff --git a/scm/parser-clef.scm b/scm/parser-clef.scm
index 757a1876de..f6e0fb9b0b 100644
--- a/scm/parser-clef.scm
+++ b/scm/parser-clef.scm
@@ -143,6 +143,65 @@
(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"