Bracketed or parenthesized alternative KeySignature
Sometimes bracketed or parenthesized KeySignatures indicate an alternative key.
The here proposed alternativeKey-function tries to do so.
It takes three arguments: the tonic-pitch of the original key, the tonic-pitch of the alternative key and the scale. An optional argument is provided as well. It determines whether to use brackets or parentheses, possible settings are 'bracketified (default) or 'parenthesized. Other settings will issue a warning and the alternative KeySignature will be printed without any brackets or parentheses.
Limitations
- works only for minor and major, other scales are not supported
- it's not possible to use a different scale for the alternative key
\version "2.24.0"
\paper { tagline = ##f }
#(define (key-alt-key-stencil p-1 p-2 scale-def bracket-style)
(lambda (grob)
(let* ((staff-space (ly:staff-symbol-staff-space grob))
(th (ly:staff-symbol-line-thickness grob))
(default-stil (ly:key-signature-interface::print grob))
;; a-minor and c-major don't have a visible KeySignature
;; TODO: add support for other scales: ionian, locrian etc
(no-visible-key?
(lambda (p)
(or (and (= (ly:pitch-notename p) 5)
(= (ly:pitch-alteration p) 0)
(eq? scale-def minor))
(and (= (ly:pitch-notename p) 0)
(= (ly:pitch-alteration p) 0)
(eq? scale-def major)))))
(stil-to-add
(if (no-visible-key? p-2)
#f
(grob-interpret-markup grob
#{
\markup
\score {
%% updaters remark:
%% 2.22. warns for a loney KeySignature, thus we insert s1*1/100000.
%% Otherwise an assertion error happens.
{ \key $p-2 $scale-def s1*1/100000 }
\layout {
\omit Staff.TimeSignature
\omit Staff.Clef
\override Staff.StaffSymbol.line-count = #0
indent = 0
}
}
#}))))
(if stil-to-add
(let* ((stil-to-add-x-ext (ly:stencil-extent stil-to-add X))
(stil-to-add-y-ext (ly:stencil-extent stil-to-add Y))
(new-key-sig-stil
(ly:make-stencil
(ly:stencil-expr stil-to-add)
;; left bracket is too far away, trimmed a little
(cons
(+ (car stil-to-add-x-ext) (* 0.7 staff-space))
(cdr stil-to-add-x-ext))
;; adjusting the top and bottom ending of the bracket
(cons
(+ (car stil-to-add-y-ext) (* 0.2 staff-space))
(- (cdr stil-to-add-y-ext) (* 0.5 staff-space)))))
(bracketified-stil
(cond ((eq? bracket-style 'bracketified)
(apply bracketify-stencil
(list
;; stil
new-key-sig-stil
;; axis
Y
;; thick
th
;; protrusion
(* 2.5 th)
;; padding
th)))
((eq? bracket-style 'parenthesized)
(apply parenthesize-stencil
(list
;; stencil
new-key-sig-stil
;; half-thickness
th
;; width
(* 0.5 staff-space)
;; angularity
(* 2.5 th)
;; padding
th)))
(else
(ly:warning "Unknown bracket-style: ~a, ignoring"
bracket-style)
new-key-sig-stil))))
(if (no-visible-key? p-1)
bracketified-stil
(ly:stencil-combine-at-edge
default-stil
X
RIGHT
bracketified-stil
staff-space)))
default-stil))))
alternativeKey =
#(define-music-function (style p1 p2 scale)
((symbol? 'bracketified) ly:pitch? ly:pitch? number-pair-list?)
#{
\override Staff.KeySignature.stencil =
#(key-alt-key-stencil p1 p2 scale style)
\key $p1 $scale
#})
%%%%%%%%%%%%%%
% EXAMPLES
%%%%%%%%%%%%%%
%%{
\relative c' {
\alternativeKey c f \major
c1
\alternativeKey b c \major
c
\alternativeKey e ees \major
c
\alternativeKey a aes \major
c
\alternativeKey #'parenthesized d des \major
c
\alternativeKey g ges \major
c
\alternativeKey c ces \major
c
\alternativeKey ges g \major
c
\alternativeKey des d \major
c
\alternativeKey aes a \major
c
\alternativeKey ees e \major
c
\alternativeKey bes b \major
c
\alternativeKey f fis \major
c
\alternativeKey ces cis \minor
c
}