\version "2.19.59" %%% SNIPPET BEGINS #(define-markup-command (single-pad layout props axis-dir amount arg) (pair? number? markup?) #:category align " @cindex padding text horizontally Add padding @var{amount} to @var{arg} in the direction of @code{(car axis-dir)}, but only at the edge specified by @code{(cdr axis-dir)}. @lilypond[verbatim,quote] \\markup { \\box { \\single-pad #'(1 . -1) #2 XY \\single-pad #(cons Y UP) #2 XY \\single-pad #'(0 . -1) #2 XY \\single-pad #`(,X . ,RIGHT) #2 XY } } @end lilypond" (let* ((m (interpret-markup layout props arg)) (x (ly:stencil-extent m X)) (y (ly:stencil-extent m Y)) (new-x (cond ((and (= (car axis-dir) X) (= (cdr axis-dir) RIGHT)) (cons (car x) (+ amount (cdr x)))) ((and (= (car axis-dir) X) (= (cdr axis-dir) LEFT)) (cons (- (car x) amount) (cdr x))) (else x))) (new-y (cond ((and (= (car axis-dir) Y) (= (cdr axis-dir) UP)) (cons (car y) (+ amount (cdr y)))) ((and (= (car axis-dir) Y) (= (cdr axis-dir) DOWN)) (cons (- (car y) amount) (cdr y))) (else y)))) (ly:make-stencil (ly:stencil-expr m) new-x new-y))) %% markup-commands adding space to one predifined edge #(define-markup-command (pad-left layout props amount arg) (number? markup?) #:category align (interpret-markup layout props (make-single-pad-markup `(,X . ,LEFT) amount arg))) #(define-markup-command (pad-right layout props amount arg) (number? markup?) #:category align (interpret-markup layout props (make-single-pad-markup `(,X . ,RIGHT) amount arg))) #(define-markup-command (pad-up layout props amount arg) (number? markup?) #:category align (interpret-markup layout props (make-single-pad-markup `(,Y . ,UP) amount arg))) #(define-markup-command (pad-down layout props amount arg) (number? markup?) #:category align (interpret-markup layout props (make-single-pad-markup `(,Y . ,DOWN) amount arg))) %% Examples for pad-whatever markup-commands % \markup \column \box { % \pad-left #2 "pad-left" % \pad-right #2 "pad-right" % \pad-up #2 "pad-up" % \pad-down #2 "pad-down" % } %% markup-commands formatting a string like "8va" %% depending on the direction it will appear bottom or top aligned %% a little adjustable, space is added before the last two characters #(define-markup-command (format-ottava layout props arg)(markup?) #:properties ((arg-padding 0.25) (direction 1)) (ly:stencil-aligned-to (interpret-markup layout props (if (and (string? arg) (>= (string-length arg) 3)) (let* ((nmbr (list->string (drop-right (string->list arg) 2))) (up-down (list->string (take-right (string->list arg) 2))) (dir (if (= 1 direction) UP DOWN))) #{ \markup \override #`(word-space . ,arg-padding) \line { \general-align #Y #dir { $nmbr $up-down } } #} ) arg)) Y DOWN)) %% like format-ottava, but adding "(" and ")" around the argument %% those parentheses are per default 'roman, but overridable as well as th %% padding used after "(" and before ")" #(define-markup-command (format-parenthesized-ottava layout props arg)(markup?) #:properties ((par-padding '(0 . 0)) (par-font-shape 'roman) (arg-padding 0.25)) (interpret-markup layout props #{ \markup \concat { \pad-right #(car par-padding) \override #`(font-shape . ,par-font-shape) "(" \override #`(word-space . ,arg-padding) \format-ottava $arg \pad-left #(cdr par-padding) \override #`(font-shape . ,par-font-shape) ")" } #})) %% Two scheme-functions, which further formats their args using `format-ottava' %% and `format-parenthesized-ottava' %% Because we can't align the markup with the spanner-line `single-pad' is %% used to fake. Will add empty space though %% `translate' is used to move the markup in X-direction %% There may be need to change values for `single-pad', `translate' and %% `par-padding', though formatUnbrokenOttavaText = #(define-scheme-function (dir arg)(integer? markup?) #{ \markup %\box \translate #'(0.75 . 0) \single-pad #(if (= dir 1) '(1 . 1) '(1 . -1)) #(if (= dir 1) 1.45 1.6) \italic \format-ottava $arg #}) formatBrokenOttavaText = #(define-scheme-function (dir arg)(integer? markup?) #{ \markup %\box \translate #'(2.4 . 0) \single-pad #(if (= dir 1) '(1 . 1) '(1 . -1)) #(if (= dir 1) 1.8 1.3) \italic \format-ottava $arg #}) %% The final formatting function %% But why, for Gods sake, this messing with 'before-line-breaking is needed?? formatOttavaText = #(define-music-function (proc1 proc2)(procedure? procedure?) #{ \override Staff.OttavaBracket.before-line-breaking = #(lambda (grob) (let* ((txt (ly:grob-property grob 'text)) (dir (ly:grob-property grob 'direction))) (ly:grob-set-property! grob 'text (proc1 dir txt)) txt)) \override Staff.OttavaBracket.after-line-breaking = #(lambda (grob) (let* ((orig (ly:grob-original grob)) (siblings (if (ly:grob? orig) (ly:spanner-broken-into orig) '())) (text (ly:grob-property grob 'before-line-breaking)) (dir (ly:grob-property grob 'direction))) (if (> (length siblings) 1) (for-each (lambda (sib) (ly:grob-set-property! sib 'text (proc2 dir text))) (cdr siblings))))) #}) %%%% For direct use in a music-expression, integrating setting for \ottava %octavateMusic = %#(define-music-function (octave)(integer?) %#{ % \formatOttavaText % #(lambda (dir arg) (formatUnbrokenOttavaText dir arg)) % #(lambda (dir arg) (formatBrokenOttavaText dir arg)) % \ottava $octave %#}) % \version "2.19.59" #(set-global-staff-size 18) %#(ly:set-option 'debug-skylines #t) \paper { ragged-right = ##f short-indent = 15 } \layout { \context { \Staff %% vertical padding: \override OttavaBracket.padding = #1 \formatOttavaText #(lambda (dir arg) (formatUnbrokenOttavaText dir arg)) #(lambda (dir arg) (formatBrokenOttavaText dir arg)) } } { \ottava #1 c''4 4 4 4 4 4 \ottava #0 4 4 \break \ottava #2 c''4 4 4 4 4 4 \ottava #0 4 4 \break \ottava #-1 c4 4 4 4 4 4 \ottava #0 4 4 \break \ottava #-2 c'4 4 4 4 4 4 \ottava #0 4 4 \break } { \ottava #1 c''4 4 4 4 \break 4 4 \ottava #0 4 4 \break \ottava #2 c''4 4 4 4 \break 4 4 \ottava #0 4 4 \break \ottava #-1 c4 4 4 4 \break 4 4 \ottava #0 4 4 \break \ottava #-2 c'4 4 4 4 \break 4 4 \ottava #0 4 4 \break \pageBreak } { \ottava #1 c''4 4 4 4 \break \repeat volta 2 { 4 4 \ottava #0 4 4 \break } \ottava #2 c''4 4 4 4 \break \repeat volta 2 { 4 4 \ottava #0 4 4 \break } \ottava #-1 c4 4 4 4 \break \repeat volta 2 { 4 4 \ottava #0 4 4 \break } \ottava #-2 c'4 4 4 4 \break \repeat volta 2 { 4 4 \ottava #0 4 4 \break } } %%% SNIPPET ENDS