lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: scheme code producing solid 8va line


From: Jean Abou Samra
Subject: Re: scheme code producing solid 8va line
Date: Fri, 17 Dec 2021 23:46:03 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.3.1

Hi Valentin,

Le 17/12/2021 à 23:23, Valentin Petzel a écrit :
Hello Molly,

The code I gave you first back then was missing a something which made it
behave badly. Harm proposed a corrected and streamlined version, and even more
compact:

#(define (my-callback grob)
   (let* ((orig (ly:grob-original grob))
          (siblings (ly:spanner-broken-into orig)))
     (if (and (> (length siblings) 1) (not (eq? grob (car siblings))))
         (ly:grob-set-property! grob 'text #f))))


Still, I would recommend against doing that
in after-line-breaking. Here is a case where
this method fails:

\version "2.22.1"

#(define (my-callback grob)
  (let* ((orig (ly:grob-original grob))
         (siblings (ly:spanner-broken-into orig)))
    (ly:message "~s" (ly:grob-object (ly:grob-system grob) 'all-elements))
    (if (and (> (length siblings) 1) (not (eq? grob (car siblings))))
        (ly:grob-set-property! grob 'text #f))))

\layout {
  \context {
    \Staff
    \override OttavaBracket.after-line-breaking = #my-callback
  }
}

{
  \repeat volta 2 {
    c'1
  }
  \alternative {
    {
      c'1
      \ottava 1
      c'1 \break
      c'1
    }
    { c'1 }
  }
}


after-line-breaking callbacks are triggered in a
certain order, and some of them look at other grobs
in ways that can trigger more callback on these
grobs. Here, I arranged for the VoltaBracket to
come first in the internal order of grobs in the
system so that its after-line-breaking go first.
Volta brackets have
ly:side-position-interface::move-to-extremal-staff
in after-line-breaking, which reads staves'
X extents in order to determine the furthest
staff the bracket overlaps with. This triggers
all X-extent callbacks of staff objects.
In the case of OttavaBracket, the extent is
stencil-based, so this causes the stencil callback
to be triggered before you set the text to #f.

Dependency on callback order is the usual
problem with side effects like after-line-breaking.
In general, unless there is a more or less good
reason (like ly:spanner::kill-zero-spanned-time),
it's best to factor everything in callbacks for
the relevant properties so that the calculations
come just in time and not too early or too late.
The method I posted above works... whooops, no
it doesn't at all, I wrote it too fast. Here is
a corrected version:

\version "2.22.1"

#(define (ottava-bracket::text-only-if-first grob)
     (if (not-first-broken-spanner? grob)
         (ly:grob-set-property! grob 'text #f))
     (ly:ottava-bracket::print grob))

\layout {
  \context {
    \Staff
    \override OttavaBracket.stencil = #ottava-bracket::text-only-if-first
  }
}

{
  \repeat volta 2 {
    c'1
  }
  \alternative {
    {
      c'1
      \ottava 1
      c'1 \break
      c'1
    }
    { c'1 }
  }
}


Best,
Jean



reply via email to

[Prev in Thread] Current Thread [Next in Thread]