lilypond-user
[Top][All Lists]
Advanced

[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



reply via email to

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