lilypond-user
[Top][All Lists]
Advanced

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

Re: [Spam] RE: Clef change placement


From: Jacques Menu
Subject: Re: [Spam] RE: Clef change placement
Date: Tue, 4 Feb 2020 09:18:40 +0100

Thanks Aaron, great example!

JM

> Le 4 févr. 2020 à 06:05, Aaron Hill <address@hidden> a écrit :
> 
> On 2020-02-03 1:54 pm, Rutger Hofman wrote:
>> I would also welcome this feature. How difficult is it to write a
>> [Scheme] engraver?
> 
> The mechanics of defining and using a Scheme engraver are relatively simple:
> 
> %%%%
> \version "2.19.83"
> 
> Custom_engraver = #(lambda (context)
>  ;; The let block can define variables to track
>  ;; the state of an instance of the engraver.
>  (let ((some-condition? #f)
>        (some-counter 0)
>        (some-list '()))
> 
>    ;; An engraver is an association list (alist) with
>    ;; specific symbols mapping to procedures or alists
>    ;; of their own.  The make-engraver utility macro
>    ;; can simplify defining the alist for an engraver.
>    (make-engraver
> 
>      ;; Procedures for one-time setup and cleanup.
>      ((initialize engraver)
>        (format #t "\n initialize: ~a" engraver))
>      ((finalize engraver)
>        (format #t "\n finalize: ~a" engraver))
> 
>      ;; Procedures for each processing stage in the music.
>      ((start-translation-timestep engraver)
>        (format #t "\n  start-translation-timestep: ~a ~a" engraver
>          (ly:context-now context)))
>      ((stop-translation-timestep engraver)
>        (format #t "\n  stop-translation-timestep: ~a ~a" engraver
>          (ly:context-now context)))
>      ((process-music engraver)
>        (format #t "\n   process-music: ~a" engraver))
>      ((process-acknowledged engraver)
>        (format #t "\n   process-acknowledged: ~a" engraver))
> 
>      ;; Procedures for handling events.
>      (listeners
>        ((time-signature-event engraver event)
>          (format #t "\n   time-signature-event: ~a ~a" engraver
>            (ly:event-property event 'origin)))
>        ((note-event engraver event)
>          (format #t "\n   note-event: ~a ~a" engraver
>            (ly:event-property event 'origin))))
> 
>      ;; Procedures for handling grobs.
>      (acknowledgers
>        ((note-head-interface engraver grob source-engraver)
>          (format #t "\n    note-head-interface: ~a ~a ~a"
>            engraver grob source-engraver))
>        ((accidental-interface engraver grob source-engraver)
>          (format #t "\n    accidental-interface: ~a ~a ~a"
>            engraver grob source-engraver)))
>      (end-acknowledgers
>        ((beam-interface engraver grob source-engraver)
>          (format #t "\n    beam-interface (end): ~a ~a ~a"
>            engraver grob source-engraver))
>        ((slur-interface engraver grob source-engraver)
>          (format #t "\n    slur-interface (end): ~a ~a ~a"
>            engraver grob source-engraver)))
>    )))
> 
> \new Staff \with { \consists \Custom_engraver }
> \fixed c' { \time 3/4 a8 b( cis'2) }
> %%%%
> 
> The above snippet shows examples of all possible handlers.  In practice, an 
> engraver would define only the procedures, listeners, and acknowledgers that 
> are relevant.
> 
> While most of the engravers in LilyPond are implemented in C++, there are a 
> few to be found in scheme-engravers.scm.  However, the C++ engravers can 
> still be useful for figuring out how things should work in an engraver, 
> providing you have rudimentary knowledge of the language.  Many of the C++ 
> functions are exported to or have equivalents in Scheme; so an interesting 
> learning exercise would be to take one of the simpler C++ engravers and 
> reimplement it within Scheme.
> 
> 
> -- Aaron Hill
> 




reply via email to

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