%by: ArnoldTheresius % update for cooperation with poly-mark-engraver or multi-mark-engraver % see LSR No. 976 for the poly-mark-engraver % \include "poly-mark-engraver.ly" % The compatibility test with the poly-mark-engraver below % is commented out, too! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % START of my personal include file 'double-mark.ly' %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #(define-public (string-or-markup-or-boolean? e) (or (string? e) (markup? e) (boolean? e))) #(define (music-property-description symbol type? description) (if (not (equal? #f (object-property symbol 'music-doc))) (ly:error (_ "symbol ~S redefined") symbol)) (set-object-property! symbol 'music-type? type?) (set-object-property! symbol 'music-doc description) symbol) #(for-each (lambda (x) (apply music-property-description x)) `((left-label ,string-or-markup-or-boolean? "set the left part of a RehearsalMark") (right-label ,string-or-markup-or-boolean? "set the right part of a RehearsalMark") )) #(define (double-rehearsalmark-stencil grob) (let* ((grobs-event (ly:grob-property grob 'cause '())) (left-label (ly:event-property grobs-event 'left-label)) (right-label (ly:event-property grobs-event 'right-label)) (gap (ly:grob-property grob 'gap 1.4))) (if (not (or (null? left-label) (null? right-label))) (case (ly:item-break-dir grob) ((-1) (if (boolean? left-label) empty-stencil (grob-interpret-markup grob (make-right-align-markup left-label)))) ((1) (if (boolean? right-label) empty-stencil (grob-interpret-markup grob (make-left-align-markup right-label)))) (else (if (boolean? left-label) (grob-interpret-markup grob (if left-label (make-center-align-markup right-label) (make-left-align-markup right-label))) (if (boolean? right-label) (grob-interpret-markup grob (if right-label (make-center-align-markup left-label) (make-right-align-markup left-label))) (ly:stencil-add (ly:stencil-translate (grob-interpret-markup grob (make-right-align-markup left-label)) (cons (* -0.5 gap) 0.0)) (ly:stencil-translate (grob-interpret-markup grob (make-left-align-markup right-label)) (cons (* 0.5 gap) 0.0))))))) (begin (ly:warning "\"doubleMark stencil\" did not find \"doubleMark texts\".") (ly:warning "fallback to using \"ly:text-interface::print\".") (ly:text-interface::print grob))))) doubleMark = #(define-music-function (left-string right-string) (string-or-markup-or-boolean? string-or-markup-or-boolean?) (if (and (boolean? left-string) (boolean? right-string)) (ly:warning "~a \\doubleMark - at least one string or markup required" (*location*))) (make-music 'SequentialMusic 'elements (list (make-music 'ContextSpeccedMusic 'context-type 'Score 'element (make-music 'OverrideProperty 'symbol 'RehearsalMark 'grob-value double-rehearsalmark-stencil 'grob-property-path (list 'stencil) 'pop-first #t 'once #t)) (make-music 'ContextSpeccedMusic 'context-type 'Score 'element (make-music 'OverrideProperty 'symbol 'RehearsalMark 'grob-value #f 'grob-property-path (list 'self-alignment-X) 'pop-first #t 'once #t)) (make-music 'ContextSpeccedMusic 'context-type 'Score 'element (make-music 'OverrideProperty 'symbol 'RehearsalMark 'grob-value `#(,(not (boolean? left-string)) #t ,(not (boolean? right-string))) 'grob-property-path (list 'break-visibility) 'pop-first #t 'once #t)) (make-music 'RehearsalMarkEvent 'label #f 'left-label left-string 'right-label right-string 'origin (*location*))))) % only for use with the poly-mark-engraver, based on a % copy of 'mark' from music-functions.ly, then extended: doublePolyMark = #(define-music-function (key left-string right-string) (((lambda (x) (or (symbol? x) (and (pair? x) (symbol? (car x))))) #f) (string-or-markup-or-boolean? #f) (string-or-markup-or-boolean? #f)) "Make the music for the \\doublePolyMark command." (let* ((set (and (integer? label) (context-spec-music (make-property-set 'rehearsalMark label) 'Score))) (ev (make-music 'RehearsalMarkEvent 'left-label left-string 'right-label right-string 'origin (*location*))) (entry-key (if (symbol? key) key (if (and (list? key) (symbol? (car key))) (car key) #f))) (add-opts (if (pair? key) (cdr key) '()))) (if (symbol? entry-key) (ly:music-set-property! ev 'key entry-key)) (ly:music-set-property! ev 'additional-options (acons 'stencil double-rehearsalmark-stencil (acons 'self-alignment-X #f (acons 'break-visibility `#(,(not (boolean? left-string)) #t ,(not (boolean? right-string))) add-opts)))) (if set (make-sequential-music (list set ev)) (begin (set! (ly:music-property ev 'label) #f) ev)))) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % END of my personal include file 'double-mark.ly' %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% { c''1 % make the coda sign begin-of-line-invisible % center it, except at the end of line, there let it be right adjusted \doubleMark \markup { \musicglyph "scripts.coda" } ##t c'' % line breaking RehearsalMark % will be joined with a space of the size 'gap' of no line break occurs \doubleMark \markup { \with-color #blue { "D.C. al " \raise #1.0 \musicglyph "scripts.coda" "e poi" } } \markup { \with-color #blue "CODA" } \break c'' % make the "Fine" begin-of-line-invisible and right adjusted \doubleMark "Fine" ##f c'' \doubleMark "CODA da capo al Fine" ##f \bar "|." } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % using \doublePolyMark, % only possible if the poly-mark-engraver is loaded % therefore it's commented out here! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %{ c''1 % make the coda sign begin-of-line-invisible % center it, except at the end of line, there let it be right adjusted \polyMark #'CenterDown \markup \box \fontsize #-3 \column { "another" "polyMark" } \doubleMark \markup { \musicglyph "scripts.coda" } ##t c'' % line breaking RehearsalMark % will be joined with a space of the size 'gap' of no line break occurs \mark \markup \box \fontsize #-3 \column { "another" "mark" } \doublePolyMark #'anySymbol \markup { \with-color #blue { "D.C. al " \raise #1.0 \musicglyph "scripts.coda" "e poi" } } \markup { \with-color #blue "CODA" } \break c'' % make the "Fine" begin-of-line-invisible and right adjusted \mark \markup \box \fontsize #-3 \column { "another" "mark" } \doublePolyMark #'CenterDown "Fine" ##f c'' \doublePolyMark #'CenterDown "CODA da capo al Fine" ##f \bar "|." %} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Some more functions for tweaking a broken RehearsakMark %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% direction set-mark-y-dir = #(define-music-function (ls)(list?) " Sets 'direction of RehearsalMark. Depending on their break-dir. @var{ls} is supposed to be an alist with entries like ( . ) A full list is not needed. An empty list is possible, too, will default to all items UP. Example: `( (,left . ,DOWN) (,center . ,DOWN) (,right . ,UP) ) Ofcourse this is the same as: '((-1 . -1)(0 . -1)(1 . 1)) " #{ \override Score.RehearsalMark.before-line-breaking = #(lambda (grob) (let* ((get-break-dir (ly:item-break-dir grob)) (left-y-dir (or (assoc-get left ls) 1)) (right-y-dir (or (assoc-get right ls) 1)) (center-y-dir (or (assoc-get center ls) 1))) (ly:grob-set-property! grob 'direction (case get-break-dir ((-1) left-y-dir) ((1) right-y-dir) ((0) center-y-dir) ;; better be paranoiac (else 1))))) #}) \relative c' { \set-mark-y-dir #`( (,left . ,DOWN) (,center . ,DOWN) (,right . ,UP) ) c4 d e f g a b c b a g f e d c b \bar "||" \once \override Score.RehearsalMark.self-alignment-X = #RIGHT \doubleMark \markup \fontsize #-3 \italic { D.C. al Coda } \markup { \musicglyph "scripts.coda" } \break \key d \major d' e fis g a b cis d\mark "XY" cis b a g fis e d cis \bar "|." } %% padding set-broken-mark-padding = #(define-music-function (ls)(list?) " Sets 'padding of RehearsalMark. Depending on their break-dir. @var{ls} is supposed to be an alist with entries like ( . ) A full list is not needed. An empty list is possible, too, will default to all items having @code{padding} 0. Example: `( (,left . 1) (,center . 2) (,right . 3) ) Ofcourse this is the same as: '((-1 . 1)(0 . 2)(1 . 3)) " #{ \override Score.RehearsalMark.padding = #(lambda (grob) (let* ((get-break-dir (ly:item-break-dir grob)) (y-off #f) (left-y-off (assoc-get left ls)) (right-y-off (assoc-get right ls)) (center-y-off (assoc-get center ls))) (case get-break-dir ((-1) left-y-off) ((1) right-y-off) ((0) center-y-off) ;; better be paranoiac (else 0)))) #}) \paper { tagline = ##f } \relative c' { \set-mark-y-dir #`( (,left . ,DOWN) (,center . ,DOWN) ) \set-broken-mark-padding #`( (,right . 3)) c4 d e f g a b c b a g f e d c b \bar "||" \once \override Score.RehearsalMark.self-alignment-X = #RIGHT \doubleMark \markup \fontsize #-3 \italic { D.C. al Coda } \markup { \musicglyph "scripts.coda" } \break \key d \major d' e fis g a b cis d cis b a g fis e d cis \bar "|." }