Am Di., 23. Okt. 2018 um 08:28 Uhr schrieb Urs Liska <li...@openlilylib.org>:
>
> Hi,
>
> I want to use TextScript.staff-padding to produce markup elements that
> are aligned to their baseline. In order to prevent the texts from moving
> vertically to avoid collisions I used \textLengthOn (or its spelled-out
> variant):
>
> \version "2.19.82"
>
> test =
> #(define-event-function (text)(markup?)
>     #{
>       -\tweak extra-spacing-width #(cons -0.0 0.4)
>       -\tweak extra-spacing-height #(cons -inf.0 +inf.0)
>       -\tweak staff-padding 3
>       -\markup #text
>     #})
>
> \relative {
>    c''8 ^\test "foobar" d16 c
>    c8 ^\test "foobar" d16 ^\test "John Doe" c
> }
>
> However, this does not only push the next notes when there actually is
> some neighboring text (as in the second beat of the following example)
> but also when it wouldn't be needed (see atttached image):
>
> Uncommenting the extra-spacing... tweaks will result in the texts moving
> vertically which is not desired.
>
> Is there another approach to make the following note columns move - but
> only if there *is* something in the way?
>
> Thanks
> Urs

Hi Urs,

from your description it sounds you need sort of a spanner with
adjustable length.
Attached some coding hacking TextSpanner.
What do you think?

Cheers,
  Harm
\version "2.19.82"

%% after 'Adding extra fingering with scheme'
%% http://lsr.di.unimi.it/LSR/Item?id=83
endTextSpanners =
#(define-music-function (parser location music) (ly:music?)
   (let ((script #{ \stopTextSpan #})
         (do-it? #f)
         (last-seen #f))
   
     (define (append-script-at! my-music prop)
       (set! (ly:music-property my-music prop)
             (append (ly:music-property my-music prop)
                     (list (ly:music-deep-copy script))))
       my-music)
     (map-some-music
      (lambda (mus)
        (case (ly:music-property mus 'name)
          ((EventChord)
            (set! last-seen mus)
            (let* ((starts (extract-typed-music mus 'text-span-event)))
              (cond ((and (not do-it?) (pair? starts))
                     (set! do-it? #t)
                     mus)
                    ((and do-it? (pair? starts))
                     (append-script-at! mus 'elements))
                    (else mus))))
          ((NoteEvent RestEvent SkipEvent)
            (set! last-seen mus)
            (let* ((starts (extract-typed-music mus 'text-span-event)))
              (cond ((and (not do-it?) (pair? starts))
                     (set! do-it? #t)
                     mus)
                    ((and do-it? (pair? starts))
                     (append-script-at! mus 'articulations))
                    (else mus))))
          (else #f)))
      music)
      
      (case (ly:music-property last-seen 'name)
          ((EventChord)
           (append-script-at! last-seen 'elements))
          ((NoteEvent RestEvent SkipEvent)
           (append-script-at! last-seen 'articulations))
          (else #f))
      (set! do-it? #f)
      (set! last-seen #f)
      music))

#(define (minimum-length-from-stencil process-string?)
   ;; Set the minimum-length of a grob, which is supposed to be a TextSpanner,
   ;; to the length of the stencil of bound-details.left.text plus 0.1
   (lambda (grob)
     (let* ((bound-details (ly:grob-property grob 'bound-details))
            (lft (assoc-get 'left bound-details))
            (txt (assoc-get 'text lft))
            (txt-stil 
              (if (markup? txt) 
                  (grob-interpret-markup 
                    grob 
                    (if process-string?
                        (markup->string txt)
                        txt))
                  #f))
            (txt-x-ext (if txt-stil (ly:stencil-extent txt-stil X) #f))
            (txt-x-length 
              (if (and txt-x-ext (interval-sane? txt-x-ext))
                  (- (cdr txt-x-ext) (car txt-x-ext)) 
                  0)))
                  
   ;; debugging aid
   ; (newline)  
   ; (display-scheme-music
   ;   (list
   ;     (cons 'txt txt)
   ;     (cons 'txt-stil txt-stil)
   ;     (cons 'txt-x-ext txt-x-ext)
   ;     (cons 'txt-x-length txt-x-length)))
   (+ txt-x-length 0.1))))

testII =
#(define-event-function (zero-dimensions? txt)((boolean? #f) markup?)
  ;; Don't use manual \start/stopTextSpan while using this function.
  #{
  	-\tweak style #'none
  	-\tweak springs-and-rods #ly:spanner::set-spacing-rods
  	-\tweak minimum-length  #(minimum-length-from-stencil #f)
  	-\tweak minimum-length-after-break 0
  	-\tweak font-shape #'upright
    -\tweak bound-details.left.text     
      #(if zero-dimensions?
           (make-with-dimensions-markup empty-interval empty-interval txt) 
           txt)
    -\tweak bound-details.left-broken.text ##f
    \startTextSpan 
  #})
  
  
break = 
\break 
% {}
  
\score {
  \new Staff
  <<
    \relative {
       \time 2/4
       c''8 d16 c c8 d16 c
       c2
       \break
       c8 d16 c c8 d16 c
       c2
    }
    \new Voice
    \endTextSpanners 
    {
       s4\testII "foobar"  
       s8\testII "foobarq"  
       s8\testII  "John & Jane Doe"
       s2
       s4\testII "foobar"  
       s8\testII "foobarq" 
       s \testII ##t "John & Jane Doe"
       s2 
    }
  
  >>
  \layout {
    ragged-right = ##t
    \override TextSpanner.staff-padding = 2
    %\override TextSpanner.direction = -1
  }
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Test default TextSpanner with long left-text at line-break
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% \paper { ragged-right = ##t }
%% { 
%%   c'1-\tweak bound-details.left.text "John & Jane Doe" \startTextSpan
%%   \break
%%   d'\stopTextSpan
%% }
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Tests for \endTextSpanners 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% \endTextSpanners 
%%   { c'4-3\startTextSpan <c' e' g'>\startTextSpan r c'4 }
%% 
%% \endTextSpanners 
%% {
%%   c'4 4\startTextSpan 4 4
%%   \repeat volta 2 {
%%     4\startTextSpan 4 
%%     \tuplet 3/2 { 4\startTextSpan 4 <c' e'>4 }
%%   }
%% }

_______________________________________________
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to