[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Scheme engraver structure questions
From: |
Carl Sorensen |
Subject: |
Re: Scheme engraver structure questions |
Date: |
Tue, 27 Dec 2011 02:13:14 +0000 |
User-agent: |
Microsoft-MacOutlook/14.13.0.110805 |
On 12/26/11 12:50 PM, "David Kastrup" <address@hidden> wrote:
>Nicolas Sceaux <address@hidden> writes:
>
>> Le 9 févr. 2010 à 14:42, David Kastrup a écrit :
>>
>>> I find that syntax tiresome to read. It requires evaluation and thus
>>> does not have a close correspondence to print syntax.
>>>
>>> That's partly because of the way the Scheme engraver example has been
>>> written.
>>>
>>> I'd much prefer it to use backquote syntax, such as
>>
>> A real improvement would be to add syntax to define scheme engravers,
>> something like:
>>
>> #(define-engraver example-engraver)
>>
>> #(define-engraver-method example-engraver initialize (trans)
>> (display (list "initialize"
>> (ly:context-current-moment
>> (ly:translator-context trans)) "\n")))
>>
>> #(define-engraver-listener example-engraver rest-event (engraver event)
>> (let* ((x (ly:engraver-make-grob engraver 'TextScript event)))
>> (display (list "caught event" event "\ncreate:\n" x "\n"))
>> (ly:grob-set-property! x 'text "hi")))
>>
>> \layout {
>> \context {
>> \Voice \consists #example-engraver
>> }
>> }
>
>Actually, what about the following rather minimalistic approach?
>#(define-macro (make-engraver . translist)
> (define (make-lambdas translist)
> `(list
> ,@(map (lambda (x)
> (if (pair? (car x))
> `(cons ',(caar x) (lambda ,(cdar x) ,@(cdr x)))
> `(cons ',(car x) ,(make-lambdas (cdr x)))))
> translist)))
> (make-lambdas translist))
>
>\header {
>
> texidoc = "\\consists can take a scheme alist as arguments, which
> should be functions, which will be invoked as engraver functions."
>
>}
>
>\version "2.14.0"
>
>\layout {
> \context {
> \Voice
> \consists
> #(make-engraver
> ((initialize trans)
> (display (list "initialize"
> (ly:context-current-moment
> (ly:translator-context trans)) "\n")))
> ((start-translation-timestep trans)
> (display (list "start-trans"
> (ly:context-current-moment
> (ly:translator-context trans)) "\n")))
> (listeners
> ((rest-event engraver event)
> (let*
> ((x (ly:engraver-make-grob engraver 'TextScript event)))
> (display (list "caught event" event "\ncreate:\n" x "\n"))
> (ly:grob-set-property! x 'text "hi"))))
> (acknowledgers
> ((note-head-interface engraver grob source-engraver)
> (display (list "saw head: " grob " coming from " source-engraver))))
> (end-acknowledgers
> ((beam-interface engraver grob source-engraver)
> (display (list "saw end of beam: " grob " coming from "
>source-engraver))))
> ((process-music trans)
> (display (list "process-music"
> (ly:context-current-moment
> (ly:translator-context trans)) "\n")))
> ((process-acknowledged trans)
> (display (list "process-acknowledged"
> (ly:context-current-moment
> (ly:translator-context trans)) "\n")))
> ((stop-translation-timestep trans)
> (display (list "stop-trans"
> (ly:context-current-moment
> (ly:translator-context trans)) "\n")))
> ((finalize trans)
> (display (list "finalize"
> (ly:context-current-moment
> (ly:translator-context trans)) "\n"))))
> }}
>
>\relative c' {
> c8[ r c]
>}
Very nice! The only think that I think ought to be added would be some
way of storing a global status variable in the engraver, as they are
frequently used. The status variable should be persistent between calls
to the engraver, I think.
Thanks,
Carl