[Top][All Lists]

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

ly:grob-basic-properties confusion (bug?)

From: Mark Polesky
Subject: ly:grob-basic-properties confusion (bug?)
Date: Thu, 9 Apr 2009 00:06:14 -0700 (PDT)

I was trying to see if I could access a grob's stencil from within a 
callback without actually knowing what the grob is. I know it sounds
pointless, but there's a good reason. Anyway, my approach was:

1) get the grob's immutable properties with ly:grob-basic-properties.
2) from that alist, access the 'stencil property (which I assumed would
    be a #<primitive-procedure>) using ly:assoc-get.
3) call the retrieved function with grob to return its stencil.

Just to be clear, the expected result of the following code was 
*nothing*. Just trying to set a stencil to itself:

\relative c'' {
  \override Staff.Clef #'stencil =
    #(lambda (grob)
      (let ((f (ly:assoc-get 'stencil (ly:grob-basic-properties grob))))
       (f grob)))

Well, that didn't work (LP nearly froze), so I debugged with display:

\relative c'' {
  \override Staff.Clef #'stencil =
    #(lambda (grob)
      (let ((f (ly:assoc-get 'stencil (ly:grob-basic-properties grob))))
       (display f)
       (ly:clef::print grob)))

Of course this works. But interestingly (display f) returns:

#<procedure #f (grob)>#<procedure #f (grob)>
No idea what's going on. I looked at ly_assoc_get in,
but I wouldn't know a C++ bug if it flew in my eye. So then I tried:

#(use-modules (ice-9 pretty-print))

\relative c'' {
  \override Staff.Clef #'stencil =
    #(lambda (grob)
      (let ((basic-props (ly:grob-basic-properties grob)))
       (pretty-print basic-props)
       (ly:clef::print grob)))

Here the alist is displayed twice, but even stranger (to me), there are 
two entries for stencil...

((glyph . "clefs.G")
 (stencil . #<procedure #f (grob)>)
 (stencil . #<primitive-procedure ly:clef::print>)

All of the other grobs I tested had the same issue. So when I retrieve
'stencil with ly:assoc-get, it gets the first one, but obviously I want
the ly:<grob>::print one.

What's going on? And how can I safely get the entry I mean to get? If 
you're curious, I'm exploring macros that look something like this: 
modifyGrob =
     (parser location context-str grob-str)
     (string? string?)
        \override $context-str . $grob-str #'stencil =
          #(lambda (grob)
            (define (modify-the-stencil stil) ...)
            (let* ((basic-props (ly:grob-basic-properties grob))
                   (stil-proc   (ly:assoc-get 'stencil basic-props))
                   (this-stil   (stil-proc grob)))
              (modify-the-stencil this-stil)))

\relative c'' {
  \modifyGrob "Staff" "Clef"

Of course, if there's a better approach for this sort of thing, please
let me know.

Thanks so much. I'm happy to be a part of LilyPond, one way or another.
- Mark


reply via email to

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