Jump to content

Initial clef change: Difference between revisions

From LilyPond wiki
Add "See also"
Tags: Reverted Visual edit
No edit summary
 
(One intermediate revision by the same user not shown)
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. See also [[Clef change at the beginning of a piece]] and [[Clef change at the beginning of a piece (alternative)]].
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 the snippets [[Clef change at the beginning of a piece]] and [[Clef change at the beginning of a piece (alternative)]].


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


[[Category:Contexts and engravers]]
[[Category:Contexts and engravers]]

Latest revision as of 17:22, 8 April 2026

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 \with { \clef ... } 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 the snippets Clef change at the beginning of a piece and Clef change at the beginning of a piece (alternative).

\version "2.24"

%%% This engraver records the initial clef properties (e.g. what is set by \with { \clef ... })
%%% 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
%%% and could easily be integrated.
#(define (initial-clef-change-engraver context)
   (let ((initial-clef-properties #f) (cclef #f) (keysigs '()))
     ; macro for checking if any clef property has changed
     (define (clef-changed)
       (>
        (length initial-clef-properties)
        (length
         (filter
          (lambda (x) (equal? (cdr x) (ly:context-property context (car x))))
          initial-clef-properties))))
     (make-engraver
      ; Record initials propertis
      ((initialize engraver)
       (set!
        initial-clef-properties
        `((clefGlyph . ,(ly:context-property context 'clefGlyph))
          (clefPosition  . ,(ly:context-property context 'clefPosition))
          (middleCClefPosition . ,(ly:context-property context 'middleCClefPosition))
          (clefTransposition  . ,(ly:context-property context 'clefTransposition)))))
      ; Record the actual clef to adjust. Use details.muted to not acknowledge clef created by this engraver.
      (acknowledgers
       ((clef-interface engraver grob source-engraver)
        (if (not (assoc-get 'muted (ly:grob-property grob 'details) #f))
            (set! cclef grob)))
       ((key-signature-interface engraver grob source-engraver)
        (set! keysigs (cons grob keysigs))))
      ; Create a clef if necessary
      ((process-music engraver)
       (if (and initial-clef-properties (clef-changed))
           (let ((clef (ly:engraver-make-grob engraver 'Clef '())))
             (ly:grob-set-property! clef 'staff-position (assoc-get 'clefPosition initial-clef-properties))
             (ly:grob-set-property! clef 'glyph (assoc-get 'clefGlyph initial-clef-properties))
             (ly:grob-set-nested-property! clef '(details muted) #t)
             (if ((lambda (x) (and (number? x) (not (= 0 x))))
                  (assoc-get 'clefTransposition initial-clef-properties 0))
                 (let ((mod (ly:engraver-make-grob engraver 'ClefModifier '()))
                       (formatter (ly:context-property context 'clefTranspositionFormatter))
                       (style (ly:context-property context 'clefTranspositionStyle))
                       (dir (sign (assoc-get 'clefTransposition initial-clef-properties 0)))
                       (abs_trans (1+ (abs (assoc-get 'clefTransposition initial-clef-properties 0)))))
                   (if (procedure? formatter)
                       (ly:grob-set-property! mod 'text (formatter (number->string abs_trans) style)))
                   (ly:grob-set-object! mod 'side-support-elements (ly:grob-list->grob-array (list clef)))
                   (ly:grob-set-parent! mod X clef)
                   (ly:grob-set-parent! mod Y clef)
                   (ly:grob-set-property! mod 'direction dir))))))
      ; Adjust the actual clef and key signatures
      ((process-acknowledged engraver)
       (if (and cclef initial-clef-properties (clef-changed))
           (begin

            ; Key signatures need to be handled if they appear before the cue-clef
            ; This requires the break alignment information, so this only sets a
            ; hook which will be processed during `before-line-breaking` of the
            ; BreakAlignGroups
            (for-each
             (lambda (keysig)
               (let ((det (ly:grob-property keysig 'details))
                     (initial-clef-properties initial-clef-properties))
                 (ly:grob-set-property!
                  keysig
                  'details
                  (acons
                   'break-alignment-handler
                   (lambda (grob break-alignment)
                     (let ((start-of-line
                            (vector-ref
                             (ly:grob-property break-alignment 'break-align-orders)
                             2)))
                       (if (member 'cue-clef (or (member 'key-signature start-of-line) '()))
                           (ly:grob-set-property!
                            grob 'c0-position
                            (assoc-get 'middleCClefPosition initial-clef-properties)))))
                   det))))
             keysigs)

            (ly:grob-set-property! cclef 'non-default #t)
            (ly:grob-set-property! cclef 'break-align-symbol 'cue-clef)
            (if (not (eq? #t (ly:grob-property cclef 'full-size-change)))
                (ly:grob-set-property! cclef 'glyph-name
                                      (format #f "~a_change" (ly:grob-property cclef 'glyph)))))))
      ; Unset parameters
      ((stop-translation-timestep engraver)
       (set! initial-clef-properties #f)
       (set! clef #f)
       (set! keysigs '())))))

\layout {
  \context {
    \Staff
    \consists #initial-clef-change-engraver
  }
  \context {
    \Score
    \override BreakAlignGroup.before-line-breaking =
    #(lambda (grob)
       (let ((grobs (ly:grob-object grob 'elements))
             (break-alignment (ly:grob-parent grob X)))
         (if (not (null? grobs))
             (set! grobs (ly:grob-array->list grobs)))
         (for-each
          (lambda (grob)
            (let* ((det (ly:grob-property grob 'details))
                   (handler (assoc-get 'break-alignment-handler det)))
              (if (procedure? handler)
                  (handler grob break-alignment))))
          grobs)))
  }
}

\new Staff \with { \clef "bass^15" } {
  \key bes\major
  \clef "treble_8"
  c'1 c'1
  \clef bass
  c'1
}

\score {
  \layout {
    \context {
      \Score
      \override BreakAlignment.break-align-orders =
      ##((staff-ellipsis
          left-edge
          cue-end-clef
          ambitus
          breathing-sign
          optional-material-end-bracket
          signum-repetitionis
          clef
          cue-clef
          staff-bar
          key-cancellation
          key-signature
          time-signature
          optional-material-start-bracket
          custos)
         (staff-ellipsis
          left-edge
          optional-material-end-bracket
          cue-end-clef
          ambitus
          breathing-sign
          signum-repetitionis
          clef
          cue-clef
          staff-bar
          key-cancellation
          key-signature
          time-signature
          optional-material-start-bracket
          custos)
         (staff-ellipsis
          left-edge
          optional-material-end-bracket
          ambitus
          breathing-sign
          signum-repetitionis
          clef
          cue-clef
          key-cancellation
          key-signature
          time-signature
          staff-bar
          optional-material-start-bracket
          custos))
    }
  }
  \new Staff \with { \clef "bass^15" } {
    \key bes\major
    \clef "treble_8"
    c'1 c'1
    \clef bass
    c'1
  }
}

% Basic usage:
\score {
  <<
    % Just the treble clef
    \new Staff {
      \key bes \major
      c''1
    }
      
    % Just the bass clef
    \new Staff \with { \clef bass  } {
      \key bes \major
      c1
    }
    
    % Initial treble clef, then bass clef
    \new Staff {
      \key bes \major
      \clef bass 
      c1
    }
    
    % Initial bass clef, then treble clef
    \new Staff \with { \clef bass  } {
      \key bes \major
      \clef treble 
      c''1
    }
  >>

  \layout {
    \context {
      \Staff
      \consists #initial-clef-change-engraver
    }
  }
}