Hi, 2018-04-02 6:32 GMT+02:00 brob2684 <bennrobert...@hotmail.com>: > Hi Harm, > > I hadn't really thought about no key signature as being an issue, but I can > certainly see how it can cause confusion. > > I think you are correct in suggesting "no key signature present" would be > the appropriate output, although I'll admit I'm unlikely to ever come across > such a case in my use of lilypond.
Well, even your first musical example has no (initial) KeySignature ;) >>> melody = \relative c'' { >>> \time 4/4 >>> c1 \key d \major d \key e \major e \key f \major f >>> } For the arbitrary reuse of a variable, this variable needs to be defined at toplevel. It's possible to update such a toplevel-variable by using an engraver, though if you clear that variable in the engraver the value(s)/entries are only available _in_ the score where the engraver works. For multiple scores in the same file this means: if you don't clear it then the values will accumulate (or override themselves). Additionally the engraver updates it too late to have direct access to the new values for other toplevel-markups. So I decided to let the key-sig-names accumulate in a toplevel-list, numbering them. Also, I wrote a markup-command where you need to select the correct entry by using a number. A markup-command is processed late enough. Code attached, note the comments. HTH, Harm
\version "2.19.81" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%% After: %%%% %%%% http://lsr.di.unimi.it/LSR/Item?id=856 %%%% see also lists.gnu.org/archive/html/lilypond-user/2013-12/msg00828.html %%%% by Paul Morris %% tonic-num: number of the tonic note 0-6, C=0, B=6 %% acc-type: the accidental sign type, 1/2=sharp, -1/2=flat %% acc-count: the number and type of accidentals in the key signature %% values are: -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 %% (negative = flats, positive = sharps) %% tonic-acc: #f if the tonic note is not sharp or flat, otherwise a pair %% maj-num: number of the tonic note 0-6, if the key sig were major %% mode-num: number of the mode 0-6 %% txt-size: size of key name text %% mult: for correct resizing when the staff is resized %% This list will be filled by the engraver and %% 'replace-key-sig-name'-markup-command accesses it #(define key-signature-list '()) #(define update-key-signature-list ;; Update `key-signature-list' by a pair containing a number and `entry' ;; The numbers increase. (lambda (entry) (set! key-signature-list (cons (cons (1+ (length key-signature-list)) entry) key-signature-list)))) #(define (initial-moment? ctx) "Is current-moment the @code{ZERO-MOMENT} or before?" (not (ly:moment<? ZERO-MOMENT (ly:context-current-moment ctx)))) #(define Store_initial_key_engraver ;; This engraver stores initial key-signatures in `key-signature-list'. ;; If no key-signature is present some text will be taken. ;; Because `key-signature-list' is a toplevel-definition all initial ;; key-signatures of all scores of a file will get an entry there. ;; To distuingish them they are numbered. (lambda (context) (let ((initial-key #f)) (make-engraver ;; If no initial key-signature is present let `initial-key' unchanged. ;; An entry in `key-signature-list' will then be done during th ;; `finalize'-step. ;; Otherwise `key-signature-list' will be updated in `acknowledgers'. (listeners ((key-change-event engraver ev) (if (initial-moment? context) (set! initial-key #t)))) (acknowledgers ((key-signature-interface engraver grob source-engraver) ;; If key cancellation then do nothing (TODO needed?). ;; If we are at the very beginning, update `key-signature-list' (if (and (initial-moment? context) (not (eq? 'KeyCancellation (grob::name grob)))) (let* ((tonic-pitch (ly:context-property context 'tonic)) (tonic-num (ly:pitch-notename tonic-pitch)) (acc-list (ly:grob-property grob 'alteration-alist)) (acc-type (if (null? acc-list) 0 (cdr (list-ref acc-list 0)))) (acc-count (* (length acc-list) (if (< acc-type 0) -1 1))) (maj-num (case acc-count ((0) 0) ((1) 4) ((2) 1) ((3) 5) ((4) 2) ((5) 6) ((6) 3) ((7) 0) ((-1) 3) ((-2) 6) ((-3) 2) ((-4) 5) ((-5) 1) ((-6) 4) ((-7) 0))) (mode-num (modulo (- tonic-num maj-num) 7)) ;; Select the tonic-name (key-letter (case tonic-num ((0) "C" ) ((1) "D" ) ((2) "E" ) ((3) "F" ) ((4) "G" ) ((5) "A" ) ((6) "B" ))) (mult (magstep (ly:grob-property grob 'font-size 0.0))) ;; format accidentals for text (txt-sharp #{ \markup { \translate #(cons (* mult -0.3) (* mult 0.8)) \magnify #(* mult 0.9) \sharp } #}) (txt-flat #{ \markup { \translate #(cons (* mult -0.2) (* mult 0.4)) \magnify #(* mult 0.9) \flat } #}) ;; select the final accidental (tonic-acc (if (pair? (assq tonic-num acc-list)) (if (= acc-type 0.5) txt-sharp txt-flat) "")) ;; select the scale-name (key-mode (case mode-num ((0) "Major") ((1) "Dorian") ((2) "Phrygian") ((3) "Lydian") ((4) "Mixolydian") ((5) "Minor") ((6) "Locrian")))) (update-key-signature-list (list key-letter tonic-acc key-mode)))))) ;; If not initial KeySignature is set, do an entry here. ((finalize engraver) (if (not initial-key) (update-key-signature-list (list "no"))) (set! initial-key #f)))))) %% We need to go for a markup-command, `key-signature-list' is updated too late %% to acces it more directly. #(define-markup-command (replace-key-sig-name layout props which arg) (index? markup?) #:category font " Replaces \"key-signature-name\" in @var{arg} by an entry from @code{key-signature-list}, the relevant entry needs to be specified by @var{which}" (interpret-markup layout props (if (string=? (markup->string arg) "key-signature-name") (make-line-markup (assoc-get which key-signature-list (list "??"))) arg))) \layout { \context { \Staff \consists \Store_initial_key_engraver } } %%%%%%%%%%%%%%%%%%%%%%%%% %% EXAMPLES %%%%%%%%%%%%%%%%%%%%%%%%% txt = \markuplist { Some text later that states that the above piece starts in key-signature-name key } lazySpacer = \markup \column { \vspace #1 \draw-hline } \new Staff \relative f'' { \key cis \minor c1 d \key b \minor a1 } \markup \replace-key-sig-name #1 \txt \lazySpacer \new Staff \relative f'' { \key gis \minor c1 d \key d \major a1 } \markup \replace-key-sig-name #2 \txt \lazySpacer \new Staff \relative f'' { c1 d a1 } \markup \replace-key-sig-name #3 \txt \lazySpacer \new Staff \relative f'' { \key c \major c1 d a1 } \markup \replace-key-sig-name #4 \txt \lazySpacer \new Staff \relative f'' { \key as \major c1 d \key d \major a1 } \markup \replace-key-sig-name #5 \txt \lazySpacer
_______________________________________________ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user