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