Re: Passing a parameter to Scheme

2022-10-29 Thread Thomas Morley
Am Sa., 29. Okt. 2022 um 12:32 Uhr schrieb Paul Hodges :
>
> 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 
> To: lilypond-user 
> 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 

Re: Passing a parameter to Scheme

2022-10-29 Thread Aaron Hill

On 2022-10-29 2:50 am, Paul Hodges wrote:

%%

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.


Review the documentation on defining and using music functions:

[1]: 
https://lilypond.org/doc/v2.23/Documentation/extending/music-functions


You could end up with something like this:


speak =
#(define-music-function
  (position)
  (number?)

  (define (stencil-proc 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"))
  (- position)

  #{ \once \override Stem.stencil = #stencil-proc #})

{
  \speak 1.6 g'4
  \speak 2.2 b'8 8
  \speak 2.8 a'2
}



-- Aaron Hill



Re: Passing a parameter to Scheme

2022-10-29 Thread Paul Hodges
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  
 To:   lilypond-user  
 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

Passing a parameter to Scheme

2022-10-29 Thread Paul Hodges
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