lilypond-user
[Top][All Lists]
Advanced

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

Re: Extending Lilypond


From: Rip mus
Subject: Re: Extending Lilypond
Date: Sat, 31 Dec 2022 16:43:52 +0100
User-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Thunderbird/102.6.1

Dear Jean,

as I've already said before, I'm grateful for all your efforts and your correction reply is yet another example: thank you! I made all the corrections and in fact the new grob has made some progress (attached)! I apologize for the naivety regarding the interfaces: I definitely misunderstood!

May I ask if you have any advice to better understand how all the "pieces" that make up Lilypond work?I don't know exactly where I intend to get with this study, but I think it will be really useful for me.

Thank you and happy new year to everyone!

Rip_mus

Il 31/12/2022 00:21, Jean Abou Samra ha scritto:
Le 30/12/2022 à 13:27, Rip _Mus a écrit :
Hello everyone,
for three days I have been immersed in the documentation written by Mr. Samra, on how to define a new grob, a new event and a new engraver that takes care of engraving the new grob, following a specific command.


Nice to hear :-)


Attached is the first result of my studies, available to everyone. Clearly the built grob is completely useless, but it helped me to make some attempts and understand the logic. I hope it could be a script that shows the various stages of defining new components, rather than modifying some existing ones. At present it needs a revision, so: to the more experienced, I would ask for an evaluation of what has been done (i'm not a programmer!), above all given the non-functioning of some overrides, which modify the properties of certain interfaces which are however included in the grob definition.


You seem to be expecting that adding some interfaces to the grob's
meta.interfaces list makes the grob support the properties declared by
the interfaces. It would be too easy if it worked like that :-) An
interface is not a magic wand that makes your grob support properties.
Rather, it serves to *document*, for human users (via the Internals
Reference manual), and for other parts of LilyPond's code (via
acknowledgers in engravers and the grob::has-interface function),
that your grob supports certain properties and behaviors. Most
often, the interface provides some callbacks that can be used
to actually give these behaviors to the grob. If you want your grob
to support the padding property, you need to give it a Y-offset callback
that reads this property, and side-position-interface provides
exactly such a one: side-position-interface::y-aligned-side .
Likewise, self-alignment-interface provides
ly:self-alignment-interface::aligned-on-x-parent (and some
variants) which you should put into X-offset so that PippoText
supports self-alignment-X and parent-alignment-X.

If you set Y-offset to ly:side-position-interface:y-aligned-side,
you will see that it outputs programming errors.  The reason is that
you read Y-offset in process-music in the engraver, which triggers
all the positioning logic, which reads X-extent and Y-extent while
they're still empty at that point. Did you leave the y-offset variable
by accident, since it's unused?

In general, it's a better idea to make something computed by
a callback than to ly:grob-set-property! it. In this case,
you can remove all this part of the code in the engraver

              (t (ly:grob-property grob 'text))
              (stil (grob-interpret-markup grob t))
              (x-extent (ly:stencil-extent stil X))
              (y-extent (ly:stencil-extent stil Y))
              (y-offset (ly:grob-property grob 'Y-offset))
...
            (ly:grob-set-property! grob 'X-extent x-extent)
            (ly:grob-set-property! grob 'Y-extent y-extent)

and instead use in the grob definition

  (X-extent . ,ly:grob::stencil-width)
  (Y-extent . ,ly:grob::stencil-height)

Those two functions are equivalent to

(define (ly:grob::stencil-width grob)
  (let ((stencil (ly:grob-property grob 'stencil)))
    (if (stencil? stencil)
        (ly:stencil-extent stencil X)
        empty-interval)))

(define (ly:grob::stencil-height grob)
  (let ((stencil (ly:grob-property grob 'stencil)))
    (if (stencil? stencil)
        (ly:stencil-extent stencil Y)
        empty-interval)))

Actually, you can even leave out that part of the grob
definition entirely, because using ly:grob::stencil-width
and ly:grob::stencil-height is the default.

Lastly, your function pippo-stencil

#(define (pippo-stencil grob) (grob-interpret-markup grob (ly:grob-property grob 'text)))

is the same as ly:text-interface::print.


HTH,
Jean

Attachment: extending_v2.ly
Description: Text Data


reply via email to

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