Hi Chen,

I think this is a situation where you can't have it both ways - I
can't think of any automatic way for the TimeSignature to only occupy
that space when it "needs" to. Bar widths are not directly modifiable
and setting the extra-spacing-width is always going to push things
around (as it happens, that is exactly what \textLengthOn does - it
sets values for extra-spacing-width and -height - and that's all it
does).

Given how unusual this particular circumstance is I think the best
thing would be to use overrides every time it happens so that the
extra-spacing-width is only set when it needs to be (and if it happens
frequently, then write a function that wraps \compoundMeter and use it
as necessary). If you have circumstances where you simultaneously need
to stretch the bars and have overlapping text/signatures with
textLengthOn, then in that case I'd say you may just have to resort to
overriding whatever offsets you need to to position everything where
you want.

I've attached your example with the overrides I mean added in.

Kevin

On Thu, 23 Apr 2020 at 16:56, Chen Leo <leo04c...@outlook.com> wrote:
>
> Hi Kevin,
>
> After I made some adjustments to my score, I was still able to find a problem 
> which only happens on rare occasions. That is, the bar widths don't expand 
> according to the time signatures' width when time signatures exceed the bar 
> lines (see attachment).
>
> Later I found out that this problem is caused by the extra-spacing-width 
> property. Being set to #'(+inf.0 . -inf.0) by default, the time signatures' 
> lengths are not aware by the bar widths. I tried to set extra-spacing-width 
> to #'(0 . 0.8) (Time signature objects' default value), this solves the 
> problem, however, the problem about the markup text being pushed to the left 
> when using \textLengthOn occurs again.
>
> I think some possible solutions for this problem would be either to make text 
> scripts from other staves unaware of the time signature text scripts or to 
> expand bar widths when the text scripts' widths are exceeding them.
>
> Thanks,
> Leo
\version "2.19.0"

#(define (Time_signature_markup_engraver context)
   (let ((time-sig '())
         (time-sig-copy #f)
         (previous-was-grace #f)) ; to avoid printing twice at grace notes
     (make-engraver
      (acknowledgers
       ((time-signature-interface engraver grob source-engraver)
        (let* ((current-moment (ly:context-current-moment context))
               (grace-nom (ly:moment-grace-numerator current-moment)))
          (if (not (eqv? 0 grace-nom))
              (begin
               (set! previous-was-grace #t)
               (set! time-sig grob))
              (if (and (eqv? 0 grace-nom) previous-was-grace)
                  (begin
                   (set! previous-was-grace #f)
                   (set! time-sig '()))
                  (set! time-sig grob))))))
      ((process-acknowledged engraver)
       (and (not (null? time-sig))
            (let* ((time-sig-copy (ly:engraver-make-grob
                                   engraver
                                   'TextScript
                                   time-sig))
                   (copy-prop (lambda (prop)
                                (ly:grob-set-property!
                                 time-sig-copy
                                 prop
                                 (ly:grob-property time-sig prop))))
                   (timing-context (ly:context-find context 'Timing))
                   (timing-time-sig
                    (ly:context-grob-definition timing-context 'TimeSignature))
                   (timing-time-sig-stencil
                    (ly:assoc-get 'stencil timing-time-sig '()))
                   (prop-list '(fraction
                                style
                                font-size
                                extra-spacing-width
                                cause)))
              (map copy-prop prop-list)
              (ly:grob-set-property! time-sig-copy 'stencil
                timing-time-sig-stencil)
              (ly:grob-set-parent! time-sig-copy Y time-sig)
              (ly:grob-set-parent! time-sig-copy X time-sig)
              (set! time-sig '())
              )))
      ((stop-translation-timestep engraver)
       (set! time-sig-copy #f)))))

#(define (remove-except-at-line-end grob)
   (if (not (equal? (ly:item-break-dir grob) LEFT))
       (ly:grob-set-property! grob 'stencil #f)))

#(define (remove-at-end grob)
   (if (equal? (ly:item-break-dir grob) LEFT)
       (ly:grob-set-property! grob 'stencil #f)))

#(define (center-over-barline grob)
   (if (equal? (ly:item-break-dir grob) 0)
       (let* ((x-extent (ly:grob-property grob 'X-extent))
              (width (interval-length x-extent)))
         (ly:grob-set-property! grob 'X-offset (* -1 (/ width 2))))))

#(define (center-over-barline-and-remove-at-end grob)
   (begin
    (remove-at-end grob)
    (center-over-barline grob)))

#(define (left-align-at-end grob)
   (and (and (ly:item? grob)
             (equal? (ly:item-break-dir grob) LEFT))
        (ly:grob-set-property! grob 'self-alignment-X 1)))

timeSignatures = {
  \tempo 4 = 80
  \time 4/4 s1
  \time 3/8 s4.
  \time 3/4 s2.
  \time 4/4 s1
  \time 2/4 \acciaccatura s8 s2
  % if you do this often, put it in a function
  \override TimeSignature.extra-spacing-width = #'(0 . 0.8)
  \compoundMeter #'((3 8) (1 16) (1 16) (1 16))
  \revert TimeSignature.extra-spacing-width
  s4. s16 s16 s16
  \time 4/4 \acciaccatura s8 s1
}

\score {
  \layout {
    \context {
      \Score
      \override MetronomeMark.break-align-symbols = #'(staff-bar time-signature)
      \remove "Bar_number_engraver"
    }
    \context {
      \Staff
      \override MultiMeasureRest.spacing-pair = #'(break-alignment . staff-bar)
      \override TimeSignature.stencil = ##f
      %\remove "Time_signature_engraver"
    }
    \context {
      \Score
    }
  }
  <<
    {
      \new Dynamics \with {
        \consists "Time_signature_engraver"
        \consists \Time_signature_markup_engraver
        \override TimeSignature.font-size = #8
        \override TimeSignature.font-name = #"Roboto Bold"
        \override TimeSignature.before-line-breaking = #remove-except-at-line-end
        \override TimeSignature.break-align-symbol = #'staff-bar
        %\override TextScript.font-size = #8
        \override TextScript.font-name = #"Roboto Bold"
        \override TextScript.before-line-breaking = #remove-at-end
        %The example is a bit exaggerated, but it demonstrates the problem.
        %↓ use this command to make bar widths aware of the time signature markups' width.
        %\override TextScript.extra-spacing-width = #'(0 . 0.8)
        \override TimeSignature.extra-spacing-width = #'(+inf.0 . -inf.0)
        \override TextScript.direction = #UP
        \override TextScript.Y-offset = #0
        \numericTimeSignature
      }
      {
        \timeSignatures
      }
    }
    %{
    \new Dynamics \with {
      \consists "Time_signature_engraver"
      \override TimeSignature.font-size = #8
      \override TimeSignature.break-align-symbol = #'staff-bar
      \override TimeSignature.break-align-anchor = ##f
      \override TimeSignature.extra-spacing-width = #'(0 . 0)
      \numericTimeSignature
    }
    {
      \timeSignatures
    }
    %}
    
    \new StaffGroup \with {} <<
   
      \new Staff \with {
        \consists "Bar_number_engraver"
      }
      \relative c' {
        \textLengthOn
        \time 4/4
        c4 ( _\markup \column {
          "← Objects failed to appear"
          "below the time signature"
          "when using \\textLengthOn"
        }
        \textLengthOff
        d4 e4 f4 )
        \time 3/8
        a'4 ( g8 ) 
        \time 3/4
        R2. 
        \time 4/4
        c1
        
        \time 2/4
        a8 ^\markup \column {
          "← Time signature appear twice" 
          "when one staff has a grace note" 
          "as the first note in a bar"
        } g8 f8 e8
        
        \compoundMeter #'((3 8) (1 16) (1 16) (1 16))
        a2 g16
        
        \time 4/4
        c4 c c c
        
      }
   
      \new Staff \relative c' {
        \time 4/4
        R1
        \time 3/8
        R4.
        \clef bass
        \time 3/4
        a,2. \> \startTextSpan 
        \break
        \time 4/4
        c2 _\markup \column {
          "  "
          "↑"
          "Harpin stops below the time signature"
        }
        ^\markup \column {
          "TextSpanner stops below the time signature"
          "↓"
        }
        e2 \! \stopTextSpan
        \clef treble
        \time 2/4
        \acciaccatura f'8 a8
        g8 f8 e8
        \compoundMeter #'((3 8) (1 16) (1 16) (1 16))
        a2 g16
        \time 4/4
        \acciaccatura f'8
        c4 c c c
      }
    >>
    \new Staff \relative c' { 
      \clef bass 
      \time 4/4
      R1 
      \time 3/8
      R4. 
      \time 3/4
      R2. 
      \time 4/4
      c1
      \time 2/4
      a8 g8 f8 e8
      \compoundMeter #'((3 8) (1 16) (1 16) (1 16))
      a2 g16
      \time 4/4
      c4 c c c
    }
  >>
  
}

Reply via email to