lilypond-user
[Top][All Lists]
Advanced

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

Re: Apply a music-function script to all elements of a list


From: David Nalesnik
Subject: Re: Apply a music-function script to all elements of a list
Date: Wed, 10 May 2017 11:06:21 -0500

On Wed, May 10, 2017 at 10:18 AM, David Nalesnik
<address@hidden> wrote:
> Hi,
>
> On Wed, May 10, 2017 at 9:31 AM, David Nalesnik
> <address@hidden> wrote:
>>
>>
>> On Wed, May 10, 2017 at 9:23 AM, daviau ewen <address@hidden> wrote:
>>>
>>> Is that okay ?
>>> http://lilypond.1069038.n5.nabble.com/file/n203059/incdiato82.ly
>>>>
>>>>
>>
>> Yes, thank you.
>>
>
> Your original:
>
> % ici on défini les points qu'on fait sur le piano
> #(define (make-dot-list l1)
>    (if (null? l1)
>        empty-stencil
>        (ly:stencil-add
>           (make-dot (ly:pitch-notename (car l1)))
>
>           )))
>
> OK, your function is intended to return a list of dots, but you only
> call make-dot on the first element of the list.
>
> You need to apply make-dot to every element of your pitch list, and
> then combine these into a stencil.  To combine stencils, I use reduce:
> (Documentation here:
> https://www.gnu.org/software/guile/docs/docs-1.8/guile-ref/SRFI_002d1-Fold-and-Map.html#index-append_002dmap-3619).
> I found reduce and fold somewhat difficult to grasp at first, but they
> definitely repay study.
>
> My rewrite:
>
> #(define (make-dot-list l1)
>    (reduce
>     ly:stencil-add
>     empty-stencil
>     (map
>      (lambda (dl) (make-dot (ly:pitch-notename dl)))
>      l1)))
>
> %%%%%%%%%%%%%
>
> Your original:
>
> #(define-markup-command (complete layout props the-chord)
>    (ly:music?)
>
>      (ly:stencil-scale
>       ( ly:stencil-add
>         (engrave-back)
>         (make-dot-list (map (lambda (m) (ly:music-property m 'pitch))
>                           (extract-named-music the-chord 'NoteEvent)))
>          )
>       1
>       1))
>
> Here, the error messages are instructive.  The function ly:stencil-add
> expects its arguments to be individual stencils, but you are providing
> it with *lists* of stencils (the result of calling engrave-back and
> make-dot-list--the latter corrected as I show above, of course!)
>
> The solution once again is to first create a list of stencils, then
> combine them using reduce:
>
> #(define-markup-command (complete layout props the-chord)
>    (ly:music?)
>    (ly:stencil-scale
>     (reduce
>      ly:stencil-add
>      empty-stencil
>      (cons
>       (make-dot-list (map (lambda (m) (ly:music-property m 'pitch))
>                        (extract-named-music the-chord 'NoteEvent)))
>       (engrave-back)))
>     1 1))
>
> %%%%%%
>

Actually, maybe this makes more sense (for the two functions), since
make-dot-list ought to, well, return a list instead of a combined
stencil.  I've just quoted the two functions I adapted:

#(define (make-dot-list l1)
   (map
    (lambda (dl) (make-dot (ly:pitch-notename dl)))
    l1))

#(define-markup-command (complete layout props the-chord)
   (ly:music?)
   (ly:stencil-scale
    (reduce
     ly:stencil-add
     empty-stencil
     (append
      (make-dot-list (map (lambda (m) (ly:music-property m 'pitch))
                       (extract-named-music the-chord 'NoteEvent)))
      (engrave-back)))
    1 1))

-David



reply via email to

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