Initial clef change: Difference between revisions
mNo edit summary |
Add "See also" Tags: Reverted Visual edit |
||
| Line 1: | Line 1: | ||
This snippet handles initial clef changes with a custom engraver. This engraver checks whether there is a difference between the initial clef (as given by <code>\with { \clef ... }</code> and the clef at the first timestep. If any difference is encountered a new clef (spaced like a cue clef) is created, while the original clef and any key signatures are modified to look like the initial clef values. | This snippet handles initial clef changes with a custom engraver. This engraver checks whether there is a difference between the initial clef (as given by <code>\with { \clef ... }</code> and the clef at the first timestep. If any difference is encountered a new clef (spaced like a cue clef) is created, while the original clef and any key signatures are modified to look like the initial clef values. See also [[Clef change at the beginning of a piece]] and [[Clef change at the beginning of a piece (alternative)]]. | ||
< | <span></span> | ||
%%% This engraver records the initial clef properties (e.g. what is set by \with { \clef ... }) | \version "2.24" | ||
%%% If in the first timestep these changed, engrave the original clef, and change formatting and break | |||
%%% alignment of the actual clef to mimic a clef change clef. Duplicates some procedure from clef engraver | %%% This engraver records the initial clef properties (e.g. what is set by \with { \clef ... }) | ||
%%% and could easily be integrated. | %%% If in the first timestep these changed, engrave the original clef, and change formatting and break | ||
#(define (initial-clef-change-engraver context) | %%% alignment of the actual clef to mimic a clef change clef. Duplicates some procedure from clef engraver | ||
%%% and could easily be integrated. | |||
<nowiki>#</nowiki>(define (initial-clef-change-engraver context) | |||
<nowiki> </nowiki> (let ((initial-clef-properties #f) (cclef #f) (keysigs '())) | |||
<nowiki> </nowiki> ; macro for checking if any clef property has changed | |||
<nowiki> </nowiki> (define (clef-changed) | |||
<nowiki> </nowiki> (> | |||
<nowiki> </nowiki> (length initial-clef-properties) | |||
<nowiki> </nowiki> (length | |||
<nowiki> </nowiki> (filter | |||
<nowiki> </nowiki> (lambda (x) (equal? (cdr x) (ly:context-property context (car x)))) | |||
<nowiki> </nowiki> initial-clef-properties)))) | |||
<nowiki> </nowiki> (make-engraver | |||
<nowiki> </nowiki> ; Record initials propertis | |||
<nowiki> </nowiki> ((initialize engraver) | |||
<nowiki> </nowiki> (set! | |||
<nowiki> </nowiki> initial-clef-properties | |||
<nowiki> </nowiki> `((clefGlyph . ,(ly:context-property context 'clefGlyph)) | |||
<nowiki> </nowiki> (clefPosition . ,(ly:context-property context 'clefPosition)) | |||
<nowiki> </nowiki> (middleCClefPosition . ,(ly:context-property context 'middleCClefPosition)) | |||
<nowiki> </nowiki> (clefTransposition . ,(ly:context-property context 'clefTransposition))))) | |||
<nowiki> </nowiki> ; Record the actual clef to adjust. Use details.muted to not acknowledge clef created by this engraver. | |||
<nowiki> </nowiki> (acknowledgers | |||
<nowiki> </nowiki> ((clef-interface engraver grob source-engraver) | |||
<nowiki> </nowiki> (if (not (assoc-get 'muted (ly:grob-property grob 'details) #f)) | |||
<nowiki> </nowiki> (set! cclef grob))) | |||
<nowiki> </nowiki> ((key-signature-interface engraver grob source-engraver) | |||
<nowiki> </nowiki> (set! keysigs (cons grob keysigs)))) | |||
<nowiki> </nowiki> ; Create a clef if necessary | |||
<nowiki> </nowiki> ((process-music engraver) | |||
<nowiki> </nowiki> (if (and initial-clef-properties (clef-changed)) | |||
<nowiki> </nowiki> (let ((clef (ly:engraver-make-grob engraver 'Clef '()))) | |||
<nowiki> </nowiki> (ly:grob-set-property! clef 'staff-position (assoc-get 'clefPosition initial-clef-properties)) | |||
<nowiki> </nowiki> (ly:grob-set-property! clef 'glyph (assoc-get 'clefGlyph initial-clef-properties)) | |||
<nowiki> </nowiki> (ly:grob-set-nested-property! clef '(details muted) #t) | |||
<nowiki> </nowiki> (if ((lambda (x) (and (number? x) (not (= 0 x)))) | |||
<nowiki> </nowiki> (assoc-get 'clefTransposition initial-clef-properties 0)) | |||
<nowiki> </nowiki> (let ((mod (ly:engraver-make-grob engraver 'ClefModifier '())) | |||
<nowiki> </nowiki> (formatter (ly:context-property context 'clefTranspositionFormatter)) | |||
<nowiki> </nowiki> (style (ly:context-property context 'clefTranspositionStyle)) | |||
<nowiki> </nowiki> (dir (sign (assoc-get 'clefTransposition initial-clef-properties 0))) | |||
<nowiki> </nowiki> (abs_trans (1+ (abs (assoc-get 'clefTransposition initial-clef-properties 0))))) | |||
<nowiki> </nowiki> (if (procedure? formatter) | |||
<nowiki> </nowiki> (ly:grob-set-property! mod 'text (formatter (number->string abs_trans) style))) | |||
<nowiki> </nowiki> (ly:grob-set-object! mod 'side-support-elements (ly:grob-list->grob-array (list clef))) | |||
<nowiki> </nowiki> (ly:grob-set-parent! mod X clef) | |||
<nowiki> </nowiki> (ly:grob-set-parent! mod Y clef) | |||
<nowiki> </nowiki> (ly:grob-set-property! mod 'direction dir)))))) | |||
<nowiki> </nowiki> ; Adjust the actual clef and key signatures | |||
<nowiki> </nowiki> ((process-acknowledged engraver) | |||
<nowiki> </nowiki> (if (and cclef initial-clef-properties (clef-changed)) | |||
<nowiki> </nowiki> (begin | |||
<nowiki> </nowiki> ; Key signatures need to be handled if they appear before the cue-clef | |||
<nowiki> </nowiki> ; This requires the break alignment information, so this only sets a | |||
<nowiki> </nowiki> ; hook which will be processed during `before-line-breaking` of the | |||
<nowiki> </nowiki> ; BreakAlignGroups | |||
<nowiki> </nowiki> (for-each | |||
<nowiki> </nowiki> (lambda (keysig) | |||
<nowiki> </nowiki> (let ((det (ly:grob-property keysig 'details)) | |||
<nowiki> </nowiki> (initial-clef-properties initial-clef-properties)) | |||
<nowiki> </nowiki> (ly:grob-set-property! | |||
<nowiki> </nowiki> keysig | |||
<nowiki> </nowiki> 'details | |||
<nowiki> </nowiki> (acons | |||
<nowiki> </nowiki> 'break-alignment-handler | |||
<nowiki> </nowiki> (lambda (grob break-alignment) | |||
<nowiki> </nowiki> (let ((start-of-line | |||
<nowiki> </nowiki> (vector-ref | |||
<nowiki> </nowiki> (ly:grob-property break-alignment 'break-align-orders) | |||
<nowiki> </nowiki> 2))) | |||
<nowiki> </nowiki> (if (member 'cue-clef (or (member 'key-signature start-of-line) '())) | |||
<nowiki> </nowiki> (ly:grob-set-property! | |||
<nowiki> </nowiki> grob 'c0-position | |||
<nowiki> </nowiki> (assoc-get 'middleCClefPosition initial-clef-properties))))) | |||
<nowiki> </nowiki> det)))) | |||
<nowiki> </nowiki> keysigs) | |||
<nowiki> </nowiki> (ly:grob-set-property! cclef 'non-default #t) | |||
<nowiki> </nowiki> (ly:grob-set-property! cclef 'break-align-symbol 'cue-clef) | |||
<nowiki> </nowiki> (if (not (eq? #t (ly:grob-property cclef 'full-size-change))) | |||
<nowiki> </nowiki> (ly:grob-set-property! cclef 'glyph-name | |||
<nowiki> </nowiki> (format #f "~a_change" (ly:grob-property cclef 'glyph))))))) | |||
<nowiki> </nowiki> ; Unset parameters | |||
<nowiki> </nowiki> ((stop-translation-timestep engraver) | |||
<nowiki> </nowiki> (set! initial-clef-properties #f) | |||
<nowiki> </nowiki> (set! clef #f) | |||
\layout { | <nowiki> </nowiki> (set! keysigs '()))))) | ||
\layout { | |||
<nowiki> </nowiki> \context { | |||
<nowiki> </nowiki> \Staff | |||
<nowiki> </nowiki> \consists #initial-clef-change-engraver | |||
<nowiki> </nowiki> } | |||
<nowiki> </nowiki> \context { | |||
<nowiki> </nowiki> \Score | |||
<nowiki> </nowiki> \override BreakAlignGroup.before-line-breaking = | |||
<nowiki> </nowiki> #(lambda (grob) | |||
<nowiki> </nowiki> (let ((grobs (ly:grob-object grob 'elements)) | |||
<nowiki> </nowiki> (break-alignment (ly:grob-parent grob X))) | |||
<nowiki> </nowiki> (if (not (null? grobs)) | |||
<nowiki> </nowiki> (set! grobs (ly:grob-array->list grobs))) | |||
<nowiki> </nowiki> (for-each | |||
<nowiki> </nowiki> (lambda (grob) | |||
<nowiki> </nowiki> (let* ((det (ly:grob-property grob 'details)) | |||
<nowiki> </nowiki> (handler (assoc-get 'break-alignment-handler det))) | |||
<nowiki> </nowiki> (if (procedure? handler) | |||
<nowiki> </nowiki> (handler grob break-alignment)))) | |||
} | <nowiki> </nowiki> grobs))) | ||
<nowiki> </nowiki> } | |||
\new Staff \with { \clef "bass^15" } { | } | ||
\new Staff \with { \clef "bass^15" } { | |||
<nowiki> </nowiki> \key bes\major | |||
<nowiki> </nowiki> \clef "treble_8" | |||
<nowiki> </nowiki> c'1 c'1 | |||
} | <nowiki> </nowiki> \clef bass | ||
<nowiki> </nowiki> c'1 | |||
\score { | } | ||
\score { | |||
<nowiki> </nowiki> \layout { | |||
<nowiki> </nowiki> \context { | |||
<nowiki> </nowiki> \Score | |||
<nowiki> </nowiki> \override BreakAlignment.break-align-orders = | |||
<nowiki> </nowiki> ##((staff-ellipsis | |||
<nowiki> </nowiki> left-edge | |||
<nowiki> </nowiki> cue-end-clef | |||
<nowiki> </nowiki> ambitus | |||
<nowiki> </nowiki> breathing-sign | |||
<nowiki> </nowiki> optional-material-end-bracket | |||
<nowiki> </nowiki> signum-repetitionis | |||
<nowiki> </nowiki> clef | |||
<nowiki> </nowiki> cue-clef | |||
<nowiki> </nowiki> staff-bar | |||
<nowiki> </nowiki> key-cancellation | |||
<nowiki> </nowiki> key-signature | |||
<nowiki> </nowiki> time-signature | |||
<nowiki> </nowiki> optional-material-start-bracket | |||
<nowiki> </nowiki> custos) | |||
<nowiki> </nowiki> (staff-ellipsis | |||
<nowiki> </nowiki> left-edge | |||
<nowiki> </nowiki> optional-material-end-bracket | |||
<nowiki> </nowiki> cue-end-clef | |||
<nowiki> </nowiki> ambitus | |||
<nowiki> </nowiki> breathing-sign | |||
<nowiki> </nowiki> signum-repetitionis | |||
<nowiki> </nowiki> clef | |||
<nowiki> </nowiki> cue-clef | |||
<nowiki> </nowiki> staff-bar | |||
<nowiki> </nowiki> key-cancellation | |||
<nowiki> </nowiki> key-signature | |||
<nowiki> </nowiki> time-signature | |||
<nowiki> </nowiki> optional-material-start-bracket | |||
<nowiki> </nowiki> custos) | |||
<nowiki> </nowiki> (staff-ellipsis | |||
<nowiki> </nowiki> left-edge | |||
<nowiki> </nowiki> optional-material-end-bracket | |||
<nowiki> </nowiki> ambitus | |||
<nowiki> </nowiki> breathing-sign | |||
<nowiki> </nowiki> signum-repetitionis | |||
<nowiki> </nowiki> clef | |||
<nowiki> </nowiki> cue-clef | |||
<nowiki> </nowiki> key-cancellation | |||
<nowiki> </nowiki> key-signature | |||
<nowiki> </nowiki> time-signature | |||
<nowiki> </nowiki> staff-bar | |||
<nowiki> </nowiki> optional-material-start-bracket | |||
<nowiki> </nowiki> custos)) | |||
<nowiki> </nowiki> } | |||
<nowiki> </nowiki> } | |||
<nowiki> </nowiki> \new Staff \with { \clef "bass^15" } { | |||
<nowiki> </nowiki> \key bes\major | |||
<nowiki> </nowiki> \clef "treble_8" | |||
<nowiki> </nowiki> c'1 c'1 | |||
<nowiki> </nowiki> \clef bass | |||
} | <nowiki> </nowiki> c'1 | ||
<nowiki> </nowiki> } | |||
% Basic usage: | } | ||
\score { | |||
% Basic usage: | |||
\score { | |||
<nowiki> </nowiki> << | |||
<nowiki> </nowiki> % Just the treble clef | |||
<nowiki> </nowiki> \new Staff { | |||
<nowiki> </nowiki> \key bes \major | |||
<nowiki> </nowiki> c<nowiki>''</nowiki>1 | |||
<nowiki> </nowiki> } | |||
<nowiki> </nowiki> | |||
<nowiki> </nowiki> % Just the bass clef | |||
<nowiki> </nowiki> \new Staff \with { \clef bass } { | |||
<nowiki> </nowiki> \key bes \major | |||
<nowiki> </nowiki> c1 | |||
<nowiki> </nowiki> } | |||
<nowiki> </nowiki> | |||
<nowiki> </nowiki> % Initial treble clef, then bass clef | |||
<nowiki> </nowiki> \new Staff { | |||
<nowiki> </nowiki> \key bes \major | |||
<nowiki> </nowiki> \clef bass | |||
<nowiki> </nowiki> c1 | |||
<nowiki> </nowiki> } | |||
<nowiki> </nowiki> | |||
<nowiki> </nowiki> % Initial bass clef, then treble clef | |||
<nowiki> </nowiki> \new Staff \with { \clef bass } { | |||
<nowiki> </nowiki> \key bes \major | |||
<nowiki> </nowiki> \clef treble | |||
<nowiki> </nowiki> c<nowiki>''</nowiki>1 | |||
<nowiki> </nowiki> } | |||
<nowiki> </nowiki> >> | |||
<nowiki> </nowiki> \layout { | |||
<nowiki> </nowiki> \context { | |||
<nowiki> </nowiki> \Staff | |||
<nowiki> </nowiki> \consists #initial-clef-change-engraver | |||
} | <nowiki> </nowiki> } | ||
</ | <nowiki> </nowiki> } | ||
} | |||
<span></span> | |||
[[Category:Contexts and engravers]] | [[Category:Contexts and engravers]] | ||