\version "2.20.0" % custom engraver by Kevin Barry #(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))) % definition of shift-right-at-line-begin #(define (shift-right-at-line-begin g) "Shift an item to the right, but only at the start of the line." (if (and (ly:item? g) (equal? (ly:item-break-dir g) RIGHT)) (ly:grob-translate-axis! g 3.5 X))) 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 \compoundMeter #'((3 8) (1 16) (1 16) (1 16)) s4. s16 s16 s16 \time 4/4 s1 } \paper { top-margin = #15 bottom-margin = #15 left-margin = #15 right-margin = #15 system-system-spacing = #`((basic-distance . 10) (minimum-distance . 6) (padding . 2) ) } \markup \column \fontsize #4 { "Approach #1" "(http://lsr.di.unimi.it/LSR/Snippet?id=272)" } \score { \layout { \context { \Score \override MetronomeMark.break-align-symbols = #'(staff-bar time-signature) } \context { \Staff \override MultiMeasureRest.spacing-pair = #'(break-alignment . staff-bar) \override Clef.font-size = #5 \remove "Time_signature_engraver" } \context { \Score } } << \new Dynamics \with { \consists "Time_signature_engraver" \consists "Axis_group_engraver" \override TimeSignature.font-size = #8 \override TimeSignature.break-align-symbol = ##f \override TimeSignature.X-offset = #ly:self-alignment-interface::x-aligned-on-self \override TimeSignature.self-alignment-X = #LEFT \override TimeSignature.after-line-breaking = #shift-right-at-line-begin \numericTimeSignature } { \timeSignatures } \new StaffGroup << \relative c' { \time 4/4 c4 ( ^"↑ Problem 1d" d4 e4 f4 ) | \time 3/8 a'4 ( g8 ) | \time 3/4 R2. ^\markup { \column { "← Problem 1a" "Problem 1c →" " " " " } } | \time 4/4 c1 | \time 2/4 a8 ^"↑ Problem 1b" g8 f8 e8 | \compoundMeter #'((3 8) (1 16) (1 16) (1 16)) a2 g16 | \time 4/4 c4 c c c | } \relative c' { \time 4/4 R1 | \time 3/8 R4. | \clef bass \time 3/4 a,2. \> \startTextSpan | \break \time 4/4 c2 e2 \! \stopTextSpan | \time 2/4 \acciaccatura f8 a8 g8 f8 e8 | \compoundMeter #'((3 8) (1 16) (1 16) (1 16)) a2 g16 | \time 4/4 c4 c c c | } >> >> } \pageBreak \markup \column \fontsize #4 { "Approach #2" "(\override TimeSignature.break-align-symbol = #'staff-bar)" } \score { \layout { \context { \Score \override MetronomeMark.break-align-symbols = #'(staff-bar time-signature) } \context { \Staff \override MultiMeasureRest.spacing-pair = #'(break-alignment . staff-bar) \override Clef.font-size = #5 \remove "Time_signature_engraver" } \context { \Score } } << \new Dynamics \with { \consists "Time_signature_engraver" \consists "Axis_group_engraver" \override TimeSignature.font-size = #8 \override TimeSignature.break-align-symbol = #'staff-bar \override TimeSignature.X-offset = #ly:self-alignment-interface::x-aligned-on-self \override TimeSignature.self-alignment-X = #LEFT \numericTimeSignature } { \timeSignatures } \new StaffGroup << \relative c' { \time 4/4 \textLengthOn c4 ( ^"← Problem 2b" \textLengthOff d4 e4 f4 ) | \time 3/8 a'4 ( g8 ) | \time 3/4 R2. | \time 4/4 \override Score.RehearsalMark.X-offset = #-1.5 \mark "↓ Problem 2d" c1 | \time 2/4 a8 ^"↑ Problem 2c" g8 f8 e8 | \compoundMeter #'((3 8) (1 16) (1 16) (1 16)) a2 g16 | \time 4/4 c4 c c c | } \relative c' { \time 4/4 R1 | \time 3/8 R4. | \clef bass \time 3/4 a,2. \> \startTextSpan | \break \time 4/4 c2 ^"↓ Problem 2a" _"↑" e2 \! \stopTextSpan | \time 2/4 \acciaccatura f8 a8 g8 f8 e8 | \compoundMeter #'((3 8) (1 16) (1 16) (1 16)) a2 g16 | \time 4/4 c4 c c c | } >> >> } \pageBreak \markup \column \fontsize #4 { "Approach #3" "(custom engraver by Kevin Barry)" } \score { \layout { \context { \Score \override MetronomeMark.break-align-symbols = #'(staff-bar time-signature) } \context { \Staff \override MultiMeasureRest.spacing-pair = #'(break-alignment . staff-bar) \override Clef.font-size = #5 \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.before-line-breaking = #remove-except-at-line-end \override TimeSignature.break-align-symbol = #'staff-bar \override TextScript.before-line-breaking = #remove-at-end %↓ The only solution to problem 2b but it causes collisions %\override TextScript.extra-spacing-width = #'(+inf.0 . -inf.0) \override TextScript.extra-spacing-width = #'(0 . 0.8) \override TextScript.direction = #UP \override TextScript.Y-offset = #0 \numericTimeSignature } { \timeSignatures } \new StaffGroup << \relative c' { \time 4/4 \textLengthOn c4 ( ^"← Problem 2b" \textLengthOff d4 e4 f4 ) | \time 3/8 a'4 ( g8 ) | \time 3/4 R2. | \time 4/4 \override Score.RehearsalMark.X-offset = #-1.5 \mark "↓ Problem 2d" 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 | } \relative c' { \time 4/4 R1 | \time 3/8 R4. | \clef bass \time 3/4 a,2. \> \startTextSpan | \break \time 4/4 c2 e2 \! \stopTextSpan | \time 2/4 \acciaccatura f8 a8 g8 f8 e8 | \compoundMeter #'((3 8) (1 16) (1 16) (1 16)) a2 g16 | \time 4/4 c4 c c c | } >> >> } \pageBreak