Hi Ming, I took another look at this and since there's only one key signature where the accidentals do not extend above the staff (F major / D minor) I just added extra padding for those keys. Now the key names always appear above the staff, regardless of the clef.
The
sizing of the accidental signs in the key names is better in this version as well.
\version "2.16.0"
% tonic-semi: semitone of tonic note, 0-11, 0=C, 2=D, etc
% psn: vertical staff position of the last accidental sign in key signature
% accsign: the accidental sign type, 1/2=sharp, -1/2=flat
% Knowing these 3 things is enough to identify the key and whether it is major/minor
% txt-size: size of key name text
% padd: padding between key signature and key name
% F Major and D Minor get extra padding to clear the staff
% It does not handle modal keys correctly (dorian, lydian, etc.)
#(define Custom_key_sig_engraver
(make-engraver
(acknowledgers
((key-signature-interface
engraver grob source-engraver)
(let* (
(context (ly:translator-context engraver))
(tonic-pitch (ly:context-property context 'tonic))
(tonic-semi (modulo (ly:pitch-semitones tonic-pitch) 12))
(acclist (ly:grob-property grob 'alteration-alist))
(accsign (if (null? acclist) 0 (cdr (list-ref acclist 0))))
(psn (if (null? acclist) 0 (car (list-ref acclist 0))))
(key-name #{ \markup {} #})
(txt-size .7)
(padd .5)
)
(cond
((= accsign 0) (cond
((= tonic-semi 0) (set! key-name #{ \markup {C Major} #}) (set! padd 3.2))
((= tonic-semi 9) (set! key-name #{ \markup {A Minor} #}) (set! padd 3.2))
(else (set! key-name #{\markup{}#}))
))
((= accsign 1/2)
(cond
((= psn 3) (cond
((= tonic-semi 7) (set! key-name #{ \markup {G Major} #}))
((= tonic-semi 4) (set! key-name #{ \markup {E Minor} #}))
(else (set! key-name #{\markup{}#}))
))
((= psn 0) (cond
((= tonic-semi 2) (set!
key-name #{ \markup {D Major} #}))
((= tonic-semi 11) (set! key-name #{ \markup {B Minor} #}))
(else (set! key-name #{\markup{}#}))
))
((= psn 4) (cond
((= tonic-semi 9) (set! key-name #{ \markup {A Major} #}))
((= tonic-semi 6) (set! key-name #{ \markup {F\raise #.8 \magnify #.8 {\sharp} Minor} #}))
(else (set! key-name #{\markup{}#}))
))
((= psn 1) (cond
((= tonic-semi 4) (set! key-name #{ \markup {E Major} #}))
((= tonic-semi 1) (set! key-name #{ \markup {C\raise #.8 \magnify #.8 {\sharp} Minor} #}))
(else (set! key-name #{\markup{}#}))
))
((= psn 5) (cond
((= tonic-semi 11) (set! key-name #{ \markup {B
Major} #}))
((= tonic-semi 8) (set! key-name #{ \markup {G\raise #.8 \magnify #.8 {\sharp} Minor} #}))
(else (set! key-name #{\markup{}#}))
))
((= psn 2) (cond
((= tonic-semi 6) (set! key-name #{ \markup {F\raise #.8 \magnify #.8 {\sharp} Major} #}))
((= tonic-semi 3) (set! key-name #{ \markup {D\raise #.8 \magnify #.8 {\sharp} Minor} #}))
(else (set!
key-name #{\markup{}#}))
))
((= psn 6) (cond
((= tonic-semi 1) (set! key-name #{ \markup {C\raise #.8 \magnify #.8 {\sharp} Major} #}))
((= tonic-semi 10) (set! key-name #{ \markup {A\raise #.8 \magnify #.8 {\sharp} Minor} #}))
(else (set! key-name #{\markup{}#}))
))
)
)
((= accsign -1/2)
(cond
((= psn 6) (cond
((= tonic-semi 5) (set! key-name #{ \markup {F Major} #}) (set! padd 1.4))
((= tonic-semi 2) (set! key-name #{ \markup {D Minor} #}) (set! padd 1.7))
(else (set! key-name #{\markup{}#}))
))
((= psn 2)
(cond
((= tonic-semi 10) (set! key-name #{ \markup {B\raise #.4 \magnify #.8 {\flat} Major} #}))
((= tonic-semi 7) (set! key-name #{ \markup {G Minor} #}))
(else (set! key-name #{\markup{}#}))
))
((= psn 5) (cond
((= tonic-semi 3) (set! key-name #{ \markup {E\raise #.4 \magnify #.8 {\flat} Major} #}))
((= tonic-semi 0) (set! key-name #{ \markup {C
Minor} #}))
(else (set! key-name #{\markup{}#}))
))
((= psn 1) (cond
((= tonic-semi 8) (set! key-name #{ \markup {A\raise #.4 \magnify #.8 {\flat} Major} #}))
((= tonic-semi 5) (set! key-name #{ \markup {F Minor} #}))
(else (set! key-name #{\markup{}#}))
))
((= psn 4)
(cond
((= tonic-semi 1) (set! key-name #{ \markup {D\raise #.4 \magnify #.8 {\flat} Major} #}))
((= tonic-semi 10) (set! key-name #{ \markup {B\raise #.4 \magnify #.8 {\flat} Minor} #}))
(else (set! key-name #{\markup{}#}))
))
((= psn 0) (cond
((= tonic-semi 6) (set! key-name #{ \markup {G\raise #.4 \magnify #.8 {\flat} Major} #}))
((= tonic-semi 3)
(set! key-name #{ \markup {E\raise #.4 \magnify #.8 {\flat} Minor} #}))
(else (set! key-name #{\markup{}#}))
))
((= psn 3) (cond
((= tonic-semi 11) (set! key-name #{ \markup {C\raise #.4 \magnify #.8 {\flat} Major} #}))
((= tonic-semi 8) (set! key-name #{ \markup {A\raise #.4 \magnify #.8 {\flat} Minor} #}))
(else (set! key-name #{\markup{}#}))
))
)
)
)
(ly:grob-set-property! grob 'stencil
(ly:stencil-combine-at-edge
(ly:key-signature-interface::print grob)
1 1
(ly:stencil-scale (grob-interpret-markup grob key-name)
txt-size txt-size)
padd ))
)))))
\layout {
\context {
\Staff
\consists \Custom_key_sig_engraver
}
}
\new Staff \relative c {
\clef bass
\key c \major
c1
\key a \minor
a1
\key g \major
g1
\key e \minor
e'1
\key d \major
d1
\key b \minor
b1
\key a \major
a1
\key fis \minor
fis'1
\key e \major
e1
\key cis \minor
cis1
\key b \major
b1
\key gis \minor
gis1
\key fis \major
fis'1
\key dis \minor
dis1
\key cis \major
cis1
\key ais \minor
ais1
\key f \major
f'1
\key d \minor
d1
\key bes \major
bes1
\key g \minor
g'1
\key ees \major
ees1
\key c \minor
c1
\key aes
\major
aes1
\key f \minor
f'1
\key des \major
des1
\key bes \minor
bes1
\key ges \major
ges'1
\key ees \minor
ees1
\key ces \major
ces1
\key aes \minor
aes1
}