\version "2.14.2" #(set-global-staff-size 20) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Definitions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% rochadeAlpha = { \once\override Score.BreakAlignment #'break-align-orders = #'#( ;; end of line (left-edge ambitus clef staff-bar key-cancellation key-signature time-signature custos breathing-sign ) ;; middle of line (left-edge ambitus breathing-sign staff-bar ;!! clef key-cancellation key-signature time-signature ;staff-bar ;;! custos) ;; begin of line (left-edge ambitus breathing-sign clef key-cancellation key-signature time-signature staff-bar custos)) } rochadeBeta = { \once\override Score.BreakAlignment #'break-align-orders = #'#( ;; end of line (left-edge ambitus staff-bar clef key-cancellation key-signature time-signature custos breathing-sign ) ;; middle of line (left-edge ambitus breathing-sign staff-bar ;!! clef key-cancellation key-signature time-signature ;staff-bar ;;! custos) ;; begin of line (left-edge ambitus breathing-sign clef key-cancellation key-signature time-signature staff-bar custos)) } #(define time-signature-space-alist '( (first-note fixed-space . 2.0) (right-edge extra-space . 0.5) (breathing-sign minimum-space . 2.8) (staff-bar minimum-space . 2.5))) #(define key-cancellation-space-alist '( (time-signature extra-space . 1.25) (breathing-sign extra-space . 1) (staff-bar extra-space . 0.6) (key-signature extra-space . 0.5) (cue-clef extra-space . 0.5) (right-edge extra-space . 0.5) (first-note semi-fixed-space . 2.5))) #(define key-signature-space-alist '( (time-signature extra-space . 1.15) (breathing-sign extra-space . 1) (staff-bar extra-space . 1.1) (cue-clef extra-space . 0.5) (right-edge extra-space . 0.5) (first-note semi-fixed-space . 2.5))) #(define barline-space-alist '( (breathing-sign extra-space . 0.3) (time-signature extra-space . 0.75) (custos minimum-space . 2.0) (clef minimum-space . 1.0) (key-signature extra-space . 1.0) (key-cancellation extra-space . 0.75) (first-note fixed-space . 2) (next-note semi-fixed-space . 0.9) (right-edge extra-space . 0.0))) #(define (breathing-sign-space-alist arg) (list (cons 'right-edge (cons 'extra-space arg)) (cons 'time-signature (cons 'minimum-space 1.3)) (cons 'clef (cons 'minimum-space 1.3)) (cons 'staff-bar (cons 'minimum-space 1.5)))) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % The function %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% space = #(define-music-function (parser location space music)(list? ly:music?) (let ( (space-left (car space)) (space-right (cadr space)) (space-down (caddr space)) ) #{ \overrideProperty #"Score.NonMusicalPaperColumn" #'line-break-system-details #(list (cons 'X-offset $space-left) ) $music \once \override Score.TimeSignature #'space-alist = #time-signature-space-alist \once\override Score.KeyCancellation #'space-alist = #key-cancellation-space-alist \once\override Score.KeySignature #'space-alist = #key-signature-space-alist \once \override Score.BarLine #'space-alist = #barline-space-alist \once \override Score.BreathingSign #'space-alist = #(breathing-sign-space-alist $space-right) \override Voice.BreathingSign #'layer = #2 \once\override BreathingSign #'text = \markup \with-dimensions #'(0 . 0) #'(0 . 0) %\with-color #red %% better viewing: switch to red! \with-color #white \filled-box #(cons -0.3 $space-right) #(cons $space-down 0.5) #0 \breathe \break \rochadeAlpha %\rochadeBeta %% different order at line-end! \once \override Score.Clef #'(space-alist key-cancellation) = #'(extra-space . 0.6) \override Score.BarLine #'layer = #3 \override Score.SpanBar #'layer = #3 #})) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Tweaks %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Tweaking Slur, PhrasingSlur and Tie % http://old.nabble.com/file/p32185810/shapeSlur_rev1.ly #(define ((alter-slur-curve offsets) grob) (let ((coords (ly:slur::calc-control-points grob))) (define (add-offsets coords offsets) (if (null? coords) '() (cons (cons (+ (caar coords) (car offsets)) (+ (cdar coords) (cadr offsets))) (add-offsets (cdr coords) (cddr offsets))))) (if (null? offsets) coords (add-offsets coords offsets)))) #(define ((shape-slur offsets) grob) (let* ((orig (ly:grob-original grob)) (siblings (if (ly:grob? orig) (ly:spanner-broken-into orig) '() )) (total-found (length siblings))) (if (>= total-found 2) (let loop ((n 0)) (if (eq? (list-ref siblings n) grob) ((alter-slur-curve (list-ref offsets n)) grob) (if (< n total-found) (loop (1+ n)) ((alter-slur-curve '()) grob)))) ((alter-slur-curve offsets) grob)))) % Changed definition to shape ties #(define ((alter-tie-curve offsets) grob) (let ((coords (ly:tie::calc-control-points grob))) (define (add-offsets coords offsets) (if (null? coords) '() (cons (cons (+ (caar coords) (car offsets)) (+ (cdar coords) (cadr offsets))) (add-offsets (cdr coords) (cddr offsets))))) (if (null? offsets) coords (add-offsets coords offsets)))) #(define ((shape-tie offsets) grob) (let* ((orig (ly:grob-original grob)) (siblings (if (ly:grob? orig) (ly:spanner-broken-into orig) '() )) (total-found (length siblings))) (if (>= total-found 2) (let loop ((n 0)) (if (eq? (list-ref siblings n) grob) ((alter-tie-curve (list-ref offsets n)) grob) (if (< n total-found) (loop (1+ n)) ((alter-tie-curve '()) grob)))) ((alter-tie-curve offsets) grob)))) shapePhrasingSlur = #(define-music-function (parser location offsets)(list?) #{ \once \override PhrasingSlur #'control-points = #(shape-slur $offsets) #}) shapeSlur = #(define-music-function (parser location offsets)(list?) #{ \once \override Slur #'control-points = #(shape-slur $offsets) #}) shapeTie = #(define-music-function (parser location offsets)(list?) #{ \once \override Tie #'control-points = #(shape-tie $offsets) #}) % Tweaking Hairpins % Thanks to Mike Solomon and David Nalesnik % http://old.nabble.com/shorten-a-broken-hairpin-at-a-linebreak--td32343028.html #(define (has-interface? grob interface) (member interface (assoc-get 'interfaces (ly:grob-property grob 'meta)))) #(define (find-system grob) (if (has-interface? grob 'system-interface) grob (find-system (ly:grob-parent grob X)))) #(define (last-bar grob) ;; return the X-coordinate of the last barline on a line (let* ((sys (find-system grob)) (array (ly:grob-object sys 'all-elements)) (grob-name (lambda (x) (assq-ref (ly:grob-property x 'meta) 'name))) (lst (filter (lambda (x) (eq? 'BarLine (grob-name x))) (ly:grob-array->list array))) (bar-coords (sort (map (lambda (x) (ly:grob-relative-coordinate x sys X)) lst) >))) (car bar-coords))) #(define (first-musical-column grobl) (if (not (eqv? #t (ly:grob-property (car grobl) 'non-musical))) (car grobl) (first-musical-column (cdr grobl)))) #(define (change-bound grob) (let* ((system (find-system grob)) (cols (ly:grob-array->list (ly:grob-object system 'columns))) (musical-column (first-musical-column (reverse cols)))) (ly:spanner-set-bound! grob RIGHT musical-column))) #(define (change-broken-hairpins grob) (let* ((st (ly:hairpin::print grob)) (orig (ly:grob-original grob)) (siblings (if (ly:grob? orig) (ly:spanner-broken-into orig) '())) (gd (ly:grob-property grob 'grow-direction)) (w (ly:stencil-extent st X)) (thick (* (ly:grob-property grob 'thickness) (ly:staff-symbol-line-thickness grob))) (h (ly:stencil-extent st Y)) (bar-pos (last-bar grob)) (hairpin-origin (ly:grob-relative-coordinate grob (find-system grob) X)) (add (- (interval-length (cons (cdr w) bar-pos)) 1.5)) (xr (- (+ add (cdr w)) hairpin-origin)) (ylu (if (eqv? gd LEFT) (cdr h) (if (and (equal? gd RIGHT)(>= (length siblings) 2) (eq? (car siblings) grob)) (interval-center h) (interval-center (cons (interval-center h)(cdr h))) ))) (yru (if (eqv? gd RIGHT) (cdr h) (interval-center (cons (interval-center h) (cdr h))) )) (yld (if (eqv? gd LEFT) (car h) (if (and (equal? gd RIGHT)(>= (length siblings) 2) (eq? (car siblings) grob)) (interval-center h) (interval-center (cons (car h)(interval-center h))) ))) (yrd (if (eqv? gd RIGHT) (car h) (interval-center (cons (car h)(interval-center h))) )) (new-stencil (ly:stencil-add (make-line-stencil thick (car w) ylu xr yru) (make-line-stencil thick (car w) yld xr yrd))) ) new-stencil )) #(define (internal-my-callback grob fn1 fn2) (let* ((orig (ly:grob-original grob)) (siblings (if (ly:grob? orig) (ly:spanner-broken-into orig) '()))) (if (and (>= (length siblings) 2) (not (eq? (car (reverse siblings)) grob))) (fn1 grob) (fn2 grob)))) #(define (my-broken-hairpin-callback grob) (internal-my-callback grob change-bound values) (internal-my-callback grob change-broken-hairpins ly:hairpin::print)) % Tweaking TextSpanner, TrillSpanner and DynamicTextSpanner #(define extent #f) trillSpanner = { \override Staff.TrillSpanner #'stencil = #ly:line-spanner::print \override Staff.TrillSpanner #'bound-details = #`((left . ((Y . 0) (attach-dir . ,CENTER) (padding . 0) (stencil-align-dir-y . ,CENTER) (text . ,(markup #:musicglyph "scripts.trill" #:hspace 1 )) )) (left-broken . ((Y . 0) (attach-dir . ,LEFT) (end-on-note . #t) (padding . -0.25) (stencil-align-dir-y . ,CENTER) (text . #f) )) (right . ((Y . 0) (padding . -2) (attach-dir . ,RIGHT) ;(text . ,(make-draw-line-markup (cons 0 -1.2))) )) (right-broken . ((Y . 0) (attach-dir . ,LEFT) (padding . -4) (text . #f) (stencil-align-dir-y . ,CENTER) )) ) \override Staff.TrillSpanner #'left-bound-info = #ly:line-spanner::calc-left-bound-info-and-text \override Staff.TrillSpanner #'right-bound-info = #ly:line-spanner::calc-right-bound-info %\override Voice.TrillSpanner #'(bound-details left text) = \markup \upright "XXXXXXXXXXX" \override TrillSpanner #'color = #green } textSpanner = { \override Staff.TextSpanner #'stencil = #ly:line-spanner::print \override Staff.TextSpanner #'bound-details = #`((left . ((Y . 0) (attach-dir . ,LEFT) (padding . 0) (stencil-align-dir-y . ,CENTER) (text . ,(markup #:bold #:italic "TextSpanner" #:hspace 0.5 )) )) (left-broken . ((Y . 0) (attach-dir . ,LEFT) (end-on-note . #t) (padding . 0.25) (stencil-align-dir-y . ,CENTER) (text . #f) )) (right . ((Y . 0) (padding . 0) (attach-dir . ,RIGHT) (text . ,(make-draw-line-markup (cons 0 -1.2))) )) (right-broken . ((Y . 0) (attach-dir . ,LEFT) (padding . -3.5) (text . #f) (stencil-align-dir-y . ,CENTER) )) ) \override Staff.TextSpanner #'left-bound-info = #ly:line-spanner::calc-left-bound-info-and-text \override Staff.TextSpanner #'right-bound-info = #ly:line-spanner::calc-right-bound-info \override Voice.TextSpanner #'style = #'line \override Voice.TextSpanner #'color = #blue } dynamicTextSpanner = { \override Staff.DynamicTextSpanner #'stencil = #ly:line-spanner::print \override Staff.DynamicTextSpanner #'bound-details = #`((left . ((Y . 0) (attach-dir . ,CENTER) (padding . 0) ;(stencil-align-dir-y . ,CENTER) (stencil-offset -0.75 . -0.5) ;(text . ,(markup #:bold #:italic "TrillSpanner ")) )) (left-broken . ((Y . 0) (attach-dir . ,RIGHT) (end-on-note . #t) (padding . -0.25) (stencil-align-dir-y . ,CENTER) (text . #f) )) (right . ((Y . 0) (padding . 0) (attach-dir . ,RIGHT) )) (right-broken . ((Y . 0) (attach-dir . ,LEFT) (padding . -3) (text . #f) (stencil-align-dir-y . ,CENTER) )) ) \override Staff.DynamicTextSpanner #'left-bound-info = #ly:line-spanner::calc-left-bound-info-and-text \override Staff.DynamicTextSpanner #'right-bound-info = #ly:line-spanner::calc-right-bound-info \override DynamicTextSpanner #'color = #'(1 0 1) \override DynamicTextSpanner #'style = #'dashed-line } % The only additional tweak needed using \space addStemSpace = \once \override Score.Stem #'X-extent = #'(0 . 0.9) %----------------------------- Test -------------------------------------------- \header { tagline = ##f } \paper { %line-width = 160 indent = 0 %short-indent = 0 %left-margin = 30 %right-margin = 20 } spaceLayout = { \space #'(18 36 -30) s1*4 \space #'(35 30 -30) s1*4 \space #'(8 16 -30) { s1 s1*3 } s1*4 } one = { \relative c { \clef treble \key bes\major \time 4/4 \override Hairpin #'stencil = #my-broken-hairpin-callback c'1\>^\markup \bold \italic "PhrasingSlur" \shapePhrasingSlur #'( (0 0 0 0 -16 0 -16 1) (1 0 1 0 -18 0 -18 0) (1 0 1 0 -24 0 -24 1) (1 0 1 0 0 0 0 0) ) d ^\(e f \once \override Score.RehearsalMark #'break-visibility = #'#(#t #f #f) \mark \default \bar ":|:" \break \clef alto \key d\major \time 8/8 c d e f \bar ":|:" \break \clef treble \key ges\major \time 4/4 \mark \default c d e f \bar ":|:" \break \clef alto \key cis\major \time 2/2 \mark \default c d\) e\! f \bar ":|" } } two = { \relative c { \key bes\major \override Hairpin #'color = #red d'4_\markup { \null \translate #'(-8 . -3.5) \bold \italic \with-color #red "Hairpin" } d \shapeSlur #'( (0 0 0 0 -10 -1 -10 -1) (5.5 -1 5.5 0 -11 -1 -11 -1) (5.5 -1 5.5 0 0 0 0 0) ) \override Hairpin #'stencil = #my-broken-hairpin-callback d\<^\markup \bold \italic "Slur" (d %2 d d d d %3 d d d d %4 d d d^\markup \bold \italic "Tie" \addStemSpace d4 ~ \key d\major \break %5 \repeat unfold 3 { d4 d d d } d d d \addStemSpace d4 \break \key ges\major \repeat unfold 3 { d d d d } d d d) \addStemSpace d4 \break \key cis\major \repeat unfold 3 { d d d d } d d\! d d } } twoII = { \relative c { s1*4 %c'1 c c c \repeat unfold 12 { s1 } } } three = { \clef bass \relative c { \textSpanner \trillSpanner \dynamicTextSpanner \crescTextCresc \key bes\major c4 c\startTextSpan c\< c %2 \repeat unfold 2 { c c c c } %4 c c c c \key d\major \repeat unfold 3 { c4 c c c } c c c \addStemSpace c \key ges\major \repeat unfold 3 { c c c c } c\startTrillSpan c c c \key cis\major \repeat unfold 3 { c c c c } c c\stopTrillSpan c\stopTextSpan c\! } } \paper { ragged-last-bottom = ##f } \score { \new PianoStaff << \new Staff << \new Voice \spaceLayout %% to see default spacing: comment out! \new Voice \one >> \new Staff \new Voice \two %\new Staff \new Voice \twoII %% Staff with empty Voice ! \new Staff \new Voice \three >> \layout { \context { \Score \override NonMusicalPaperColumn #'line-break-permission = ##f \override NonMusicalPaperColumn #'page-break-permission = ##f \override VerticalAxisGroup #'remove-first = ##t \override TextSpanner #'layer = #-3 \override TrillSpanner #'layer = #-3 \override SpanBar #'layer = #3 \override BarLine #'layer = #3 } \context { \Staff \RemoveEmptyStaves } \context { \PianoStaff \remove "Keep_alive_together_engraver" } } }