Jump to content

Initial clef change: Difference between revisions

From LilyPond wiki
Add "See also"
Tags: Reverted Visual edit
m Reverted edit by Ksnortum (talk) to last revision by Lemzwerg
Tag: Rollback
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.


<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]]

Revision as of 17:21, 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.

\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
    }
  }
}