\version "2.25.10"

\header {
  tagline = ##f
}

\layout {
  \context {
    \Staff
    \accepts ExtraClefStaff
  }
  \context {
    \name ExtraClefStaff
    \type Engraver_group
    \alias Staff
    \accepts Voice
    \consists Clef_engraver
    \override Clef.font-size = #-4
    %% The break-align-symbol stacks the extra clef to the right of
    %% the normal clef
    \override Clef.break-align-symbol = #'cue-clef
    %% This break-visibility repeats the extra clef every bar.  Should
    %% this be the actual default?  Or should the default just be
    %% the normal #begin-of-line-visible ?
    \override Clef.break-visibility = #end-of-line-invisible
    %% different size for first clef in line is uncalled for
    firstClef = ##f
  }
}

\midi {
  \context {
    \Staff
    \accepts ExtraClefStaff
  }
  \context {
    \name ExtraClefStaff
    \type Performer_group
    \alias Staff
    \accepts Voice
  }
}

extraClef =
#(define-music-function (offset clef-type) ((number?) string?)
  #{ \new ExtraClefStaff = "extraclef" { }
     \change Staff = "extraclef"
     #(if offset #{ \override Staff.Clef.Y-offset = #offset #})
     \clef #clef-type
     #})

all-clef-properties =
#(map (lambda (x) (ly:music-property x 'symbol))
  (extract-named-music (make-clef-set "treble_(8)") 'PropertySet))

extraClefEnd =
#(context-spec-music
  (make-apply-context
   (lambda (ctx)
     ;; Should be a given in context-spec-music
     (if (eq? (ly:context-name ctx) 'ExtraClefStaff)
	 (begin
	   ;; revert clef-specific settings in case some clef is still
	   ;; issued before the context dies: in that case it should
	   ;; correspond to the supervening Staff clef.
	   (for-each (lambda (p) (ly:context-unset-property ctx p))
		     all-clef-properties)
  	   ;; All children of the ExtraClefStaff are reseated to its
	   ;; parent context, removing it from the hierarchy
	   (let ((switch (ly:make-stream-event
			  (ly:make-event-class 'ChangeParent)
			  `((context . ,(ly:context-parent ctx))))))
	     (for-each
	      (lambda (x)
		(ly:broadcast (ly:context-event-source x) switch))
	      (ly:context-children ctx))))
	 (ly:programming-error "Not in ExtraClefStaff"))))
  'ExtraClefStaff)


\score {
    \new Staff = "lower" {
        \key d \minor
        \numericTimeSignature
        \time 3/4
        \clef bass
        \relative c' {
          \voices 1,""
            <<
                {
                    s2. r4 r8. \clef treble
                    \tuplet 3/2 16 { g'32 (a bes }
                    c8.) c16--
                    c16-- bes g a
                    g8. 
                    \omit TupletBracket
                    \tuplet 3/2 16 { f32 (g a }
                    bes8.) bes16
                  } \\
                {
                  d,,,8.-- d16-- d2--~ 2.~
                  \extraClef #-3 "bass"
                  \voiceTwo
                  2.~ \break 2.~2.
                  \oneVoice
		  \extraClefEnd
		  c''2.
                }
            >>
        }
    }
}
If made built-in, it would affect several files and introduce a new
default context type.

I don't think it covers multiple simultanous main clefs (like sometimes
seen in compact mensural notation).  I am not sure that there'd be a
sensible common interface including this use case.

-- 
David Kastrup

Reply via email to