Hi,

please have a look at the code below.
It is an attempt to implement an aligning spanner between certain
marks at score-level.
Here I use TextMark and a newly defined TextMarkSpanner-grob.

Currently the TextNarks are moved, which is nice. Though, it relies on
the highest element in the Staff, regardles if it's under the spanner
or not.
It should only rely on the elements covered by said spanner.

Furthermore, skylines are not working for the moved TextMarks.
Consequently -dcrop does not work as wished.

What am I missing or doing wrongly?

Disclaimer:
This is stripped down code only meant for demonstration. Although, the
given example compiles, don't use it for serious work.

Thanks,
  Harm

\version "2.25.11"

#(define (add-grob-definition grob-entry)
   (set! all-grob-descriptions
         (cons
          ((@@ (lily) completize-grob-entry) grob-entry)
          all-grob-descriptions)))

#(define-event-class 'text-mark-line-spanner-interface 'span-event)

#(define text-mark-spanner-types
   '((TextMarkSpanEvent
      . ((description . "DOCME")
         (types . (text-mark-span-event span-event event))))))

#(set!
  text-mark-spanner-types
  (map (lambda (x)
         (set-object-property! (car x)
                               'music-description
                               (cdr (assq 'description (cdr x))))
         (let ((lst (cdr x)))
           (set! lst (assoc-set! lst 'name (car x)))
           (set! lst (assq-remove! lst 'description))
           (hashq-set! music-name-to-property-table (car x) lst)
           (cons (car x) lst)))
       text-mark-spanner-types))

#(set! music-descriptions
       (sort (append text-mark-spanner-types music-descriptions) alist<?))

#(add-grob-definition
 `(TextMarkSpanner
     . (
        (after-line-breaking
          . ,ly:side-position-interface::move-to-extremal-staff)
        (axes . (,Y))
        (cross-staff . ,ly:side-position-interface::calc-cross-staff)
        (direction . ,UP)
        (outside-staff-priority . 1250)
        (padding . 0)
        (side-axis . ,Y)
        (vertical-skylines
          . ,grob::always-vertical-skylines-from-element-stencils)
        (X-extent . ,ly:axis-group-interface::width)
        (Y-extent . ,axis-group-interface::height)
        (Y-offset . ,side-position-interface::y-aligned-side)
        (meta . ((class . Spanner)
                 (object-callbacks
                   . ((pure-Y-common
                        . ,ly:axis-group-interface::calc-pure-y-common)
                      (pure-relevant-grobs
                        . ,ly:axis-group-interface::calc-pure-relevant-grobs)))
                 (interfaces . (axis-group-interface
                                text-mark-interface
                                outside-staff-interface
                                side-position-interface))
                 (description . "DOCME"))))))

#(define (Text_mark_align_engraver context)
  (let ((text-mark-spanner #f))
   (make-engraver
     (acknowledgers
       ((text-mark-interface this-engraver grob source-engraver)
        (let ((color (ly:grob-property grob 'color)))
          (when (and (equal? color red) text-mark-spanner)
            (ly:spanner-set-bound!
              text-mark-spanner
              RIGHT
              (ly:context-property context 'currentCommandColumn))
            (ly:grob-set-parent! grob Y text-mark-spanner)
            (set! text-mark-spanner #f))
          (when (and (equal? color green) (not text-mark-spanner))
            (set! text-mark-spanner
                  (ly:engraver-make-grob this-engraver 'TextMarkSpanner '()))
            (ly:grob-set-parent! grob Y text-mark-spanner)
            (ly:spanner-set-bound!
              text-mark-spanner
              LEFT
              (ly:context-property context 'currentCommandColumn)))))))))

\layout {
  \context {
    \Global
    \grobdescriptions #all-grob-descriptions
  }
  \context {
    \Score
    \override TextMark.Y-offset = ##f
    \consists #Text_mark_align_engraver
  }
}

#(ly:set-option 'debug-skylines #t)
\paper { ragged-right = ##f }

{
  b'1
  \once \override Score.TextMark.color = #green
  \textMark "foo"
  b'
  b'
  \once \override Score.TextMark.color = #red
  \textMark "bar"
  b'

  \once \override Score.TextMark.color = #green
  \textMark "foo"
  b'
  b'''-1\5 ->
  \once \override Score.TextMark.color = #red
  \textMark "bar"
  b'
}

Reply via email to