[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Passing a parameter to Scheme
From: |
Thomas Morley |
Subject: |
Re: Passing a parameter to Scheme |
Date: |
Sat, 29 Oct 2022 13:28:43 +0200 |
Am Sa., 29. Okt. 2022 um 12:32 Uhr schrieb Paul Hodges <pwh@cassland.org>:
>
> On further thought, I suspect that I can't aim at "\speak #-3.8 c" because
> #-3.8 isn't a music expression so LilyPond won't let me. I guess I'll need
> to use a \tweak or \set on the parameter variable instead. But that leaves
> me even further from knowing how to write it, largely because my brain's
> model of computing (honed over 55 years) is entirely based on procedural
> languages with nested scopes (Algol, C) or Assembly language with everything
> global. I simply don't know how scopes and namespaces work in Scheme, and
> thus how to define that parameter in a way that I can access it to tweak.
>
> Paul
>
>
> From: Paul Hodges <pwh@cassland.org>
> To: lilypond-user <lilypond-user@gnu.org>
> Sent: 29/10/2022 10:50
> Subject: Passing a parameter to Scheme
>
> I am trying to make my first steps in actually modifying some Scheme. I am
> using a procedure taken from the snippets repository to add a cross to a stem
> (e.g. to indicate sprechgesang):
>
> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
> speak = {
> \once \override Stem.stencil =
> #(lambda (grob)
> (let* ((x-parent (ly:grob-parent grob X))
> (is-rest? (ly:grob? (ly:grob-object x-parent 'rest))))
> (if is-rest?
> empty-stencil
> (ly:stencil-combine-at-edge
> (ly:stem::print grob)
> Y
> (- (ly:grob-property grob 'direction))
> (grob-interpret-markup grob
> (markup #:center-align #:fontsize -2
> #:musicglyph
> "noteheads.s2cross"))
> -2.3))))
> }
> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
>
> This works fine, writing "\speak c4" for instance.
>
> However, I'd like to be able to parameterise the position of the cross which
> is hard-coded as -2.3, so that I can write "\speak #-3.8 c" for instance.
> I've tried a couple of ways to write it, but I can't find one that works. I
> suppose that I will need something like "lambda (grob posn)" to define the
> parameter for use at the end, but I can't see how to get the value of posn
> from the LilyPond source into the Scheme procedure.
>
> Help?
>
> Thanks,
> Paul
Hi Paul,
please always give the link to the LSR snippet:
https://lsr.di.unimi.it/LSR/Item?id=374
and some example code of your use case.
That said...
I'd always use `grob-transformer', if the original value of a grob is
taken and modified (here Stem.stencil with (ly:stem::print grob)).
This procedure was not available back when the snippet was coded, though.
Making for:
\version "2.23.14"
speakOff = \revert Stem.stencil
speakOnI =
\override Stem.stencil =
#(grob-transformer 'stencil
(lambda (grob orig)
(let* ((x-parent (ly:grob-parent grob X))
(is-rest? (ly:grob-object x-parent 'rest #f)))
(if is-rest?
orig
(ly:stencil-combine-at-edge
orig
Y
(- (ly:grob-property grob 'direction))
(grob-interpret-markup
grob
(markup #:center-align #:fontsize -2
#:musicglyph "noteheads.s2cross"))
-2.3)))))
\score {
\new Staff {
\relative c'' {
a8 b a c
\speakOnI
g f r g
b r d e
\speakOff
c a g f
}
}
}
This does not solve your question, but we can start from it.
(1) Most common would be to code a music-function.
I think it's explained in the Extending Manual.
Making for:
speakOff = \revert Stem.stencil
speakOnII =
#(define-music-function (y-pad)(number?)
#{
\override Stem.stencil =
#(grob-transformer 'stencil
(lambda (grob orig)
(let* ((x-parent (ly:grob-parent grob X))
(is-rest? (ly:grob-object x-parent 'rest #f))) ;; no
need to chaeck for ly:grob?
(if is-rest?
orig
(ly:stencil-combine-at-edge
orig
Y
(- (ly:grob-property grob 'direction))
(grob-interpret-markup
grob
(markup #:center-align #:fontsize -2
#:musicglyph "noteheads.s2cross"))
y-pad)))))
#})
\score {
\new Staff {
\relative c'' {
a8 b a c
\speakOnII #-2.3
g f r g
b r d e
\speakOff
c a g f
}
}
}
(2) Read a custom details,sub-property:
speakOff = \revert Stem.stencil
speakOnIII =
\override Stem.stencil =
#(grob-transformer 'stencil
(lambda (grob orig)
(let* ((x-parent (ly:grob-parent grob X))
(is-rest? (ly:grob-object x-parent 'rest #f)))
(if is-rest?
orig
(let* ((details (ly:grob-property grob 'details))
(my-y-move (assoc-get 'my-y-move details -2.3)))
(ly:stencil-combine-at-edge
orig
Y
(- (ly:grob-property grob 'direction))
(grob-interpret-markup
grob
(markup #:center-align #:fontsize -2
#:musicglyph "noteheads.s2cross"))
my-y-move))))))
\score {
\new Staff {
\relative c'' {
a8 b a c
\speakOnIII
g f r g
\once \override Stem.details.my-y-move = #-1.5
b r8 d e
\speakOff
c a g f
}
}
}
You may want to rename my-y-move :)
Though, you will see that the cross will collide with flags and beams
of short note values.
Probably one could dive deeper into Stem.details to create an
automagically method.
Maybe another thread?
Cheers,
Harm