lilypond-devel
[Top][All Lists]
Advanced

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

Re: Scheme engraver structure questions


From: David Kastrup
Subject: Re: Scheme engraver structure questions
Date: Tue, 27 Dec 2011 09:22:22 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.92 (gnu/linux)

Carl Sorensen <address@hidden> writes:

> On 12/26/11 12:50 PM, "David Kastrup" <address@hidden> wrote:
>>
>>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))
>
> 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.

What's to be added?  The following works as expected (including the
expected warnings...).

#(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 = "Scheme engravers may be instantiated, with
  instance-scoped slots, by defining a 1 argument procedure which
  shall return the engraver definition as an alist, with the private
  slots defined in a closure.  The argument procedure argument is the
  context where the engraver is instantiated."

}

\version "2.14.0"

\layout {
  \context {
    \Voice
    \consists
    #(let ((instance-counter 0))
       (lambda (context)
         (set! instance-counter (1+ instance-counter))
         (let ((instance-id instance-counter)
               (private-note-counter 0))
          (make-engraver
           (listeners
            ((note-event engraver event)
             (set! private-note-counter (1+ private-note-counter))
             (let ((text (ly:engraver-make-grob engraver 'TextScript event)))
              (ly:grob-set-property! text 'text
               (format #f "~a.~a" instance-id
                private-note-counter)))))))))
  }
}

<<
  \relative c'' { c4 d e f }
  \\ \relative c' { c4 d e f }
>>
-- 
David Kastrup

reply via email to

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