[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