lilypond-user
[Top][All Lists]
Advanced

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

Re: Put the property of a grob in the output-attributes list


From: Stefano Troncaro
Subject: Re: Put the property of a grob in the output-attributes list
Date: Tue, 24 Dec 2019 13:47:37 -0300

Hi Paolo,

I've worked a bit on the token function and I think it's considerably improved. In the event->grob and event->output-attribute-list functions you can set what properties you want for what grob/event, making it easier to expand the funcion as needed instead of having to manually write the function for each case.

I made it so that the syntax for \token is the same as the syntax for \tweak since I think that will be more consistent with Lilypond's already implemented syntax. In the example there is a comment with a quick explanation nevertheless, and it should be apparent why there is a problem with the "\token f\markup {'foobar'}" example you described in your previous email.

The bad news is that I checked the Internals Reference and I don't know how to find absolute coordinates for TextScripts, since they are placed relative to other objects. Perhaps someone else can help with this.

%%%%%%%%%%%%%%%%%%%%
\version "2.19.83"

% Syntax: same as \tweak:
%   \tweak Beam.color #red c8 d e c        --- valid
%   \tweak Beam.color #red c8 [ d e c ]    --- invalid
%   c8 -\tweak Beam.color #red [ d e c ]   --- use this instead of invalid example above
% In short, if the object that is to be modified is found in the music input, the tweak
% must be placed before the object. Only \tweak before a note if the grob to be modified
% is created from the note event (for example, noteheads, stems, accidentals, etc).

token = #(let* ((ctr 0)
                (ctr!
                 (lambda ()
                   (set! ctr (1+ ctr))
                   ctr))
                (event->grob '())
                (event->output-attribute-list '()))
           (set! event->grob
                 (define-scheme-function (evt) (symbol?)
                   (case evt
                     ((BeamEvent) 'Beam)
                     ((NoteEvent) (event->grob 'BeamEvent)) ;modify an automatic beam
                     ((TextScriptEvent) 'TextScript)
                     (else (ly:error (format "token can't handle ~a\n" evt))))))
           (set! event->output-attribute-list
                 (define-scheme-function (evt) (symbol?)
                   (case evt
                     ((BeamEvent) '(beam-thickness))
                     ((NoteEvent) (event->output-attribute-list 'BeamEvent)) ;modify an automatic beam
                     ((TextScriptEvent) '(direction))
                     (else '()))))
           
   (define-music-function (mus) (ly:music?)
     (let* ((id (format #f "foobar_~a" (ctr!)))
            (type (ly:music-property mus 'name))
            (sym (event->grob type))
            (atts (event->output-attribute-list type)))
       #{ \tweak #(list sym 'after-line-breaking) #(lambda (grob)
            (let* ((output-atts (ly:grob-property grob 'output-attributes))
                   (atts-to-append
                    (map (lambda (att)
                           (cons att (ly:grob-property grob att)))
                      atts))
                   (output-atts (append output-atts atts-to-append)))
              (ly:grob-set-property! grob 'output-attributes output-atts)))
          \tweak #(list sym 'output-attributes 'id) #id
          #mus #} )))

\relative { c'4 \token d8 -\token -\markup "hello" e f -\token [ g e] c }
%%%%%%%%%%%%%%%%%%%%


Hope this helps!

El lun., 23 dic. 2019 a las 6:08, Paolo Prete (<address@hidden>) escribió:
Hi Stefano,

1) I need to store in the output-attributes the "direction"  of the TextScript (it says if the object is above or below the staff)
I can obtain this info with map-some-music() [ by looking at (ly:music-property evt 'direction) ]. But in this way I need to set the direction in the music _expression_.

\token f^\markup {'foobar'} 

Instead, I want to obtain this info also when it's not set by the me in the music _expression_, and it's calculated by Lilypond:

\token f\markup {'foobar'} 

2) I need to obtain the absolute and relative coordinates calculated by Lilypond for the same TextScript.

Point 1) is very important, because I don't have this info in the svg output.
About the coordinates: I can calculate them by parsing the svg file, as I did for beams and slurs. But it would be better if I obtain them automatically by Lilypond and pass them to the SVG _javascript_ script.

Thanks again!
Best
P












On Mon, Dec 23, 2019 at 8:38 AM Stefano Troncaro <address@hidden> wrote:
Hi Paolo, I'm glad you found it useful! Could you give me an example of what you want to do with TextScripts? Besides giving them an id, what properties do you need stored in the svg output attributes?

El dom., 22 dic. 2019 a las 14:04, Paolo Prete (<address@hidden>) escribió:
Thank you again Stefano. This helps again and you will see how good it will fit in the library I'm coding.
However, I can't make it work for a TextScript (either before the notevent or before the markup token). I tried also map-some-music(), but it doesn't fix it.

\version "2.19.83"

token = #(let* ((ctr 0)
                (ctr! (lambda ()
                        (set! ctr (1+ ctr))
                        ctr)))
   (define-music-function (mus) (ly:music?)
     (let* ((id (format #f "foobar_~a" (ctr!)))
            (type (ly:music-property mus 'name))
            (mexp (case type
                    ((BeamEvent NoteEvent TextScriptEvent )
                      #{ \tweak TextScript.after-line-breaking #(lambda (grob)
                           (let* ((outprop (ly:grob-property grob 'direction))
                                  (prop (ly:grob-property grob 'direction))
                                  (outprop (append outprop `((beam-thickness . ,prop)))))
                             (display (format #f "\n****\n~a\n****\n" prop))
                             (ly:grob-set-property! grob 'output-attributes outprop)))
                         \tweak TextScript.output-attributes.id #id #mus #} )
                    (else #{ \tweak output-attributes.id #id #mus #} ))))
       mexp)))

\relative {  c'4 d8-\token [ e ] \token f^\markup {'iii'} g c,4  }

On Sun, Dec 22, 2019 at 4:21 PM Stefano Troncaro <address@hidden> wrote:
Hi Paolo,

The main problem here is that \tweak can only modify the object that is next to it, so you can tweak a NoteHead to modify an automatic beam, but to modify a beam that is created manually because of a [ in the input you need to place the tweak before the [. See:

%%%%%%%%%%%%%%%%%
\version "2.19.83"

\relative {
  c'8[ \tweak Beam.color #red d]   %doesn't work
  \tweak Beam.color #red e f       %works
  \tweak Beam.color #red g[ a]     %doesn't work
  b -\tweak Beam.color #red [ c ]  %works
}

%%%%%%%%%%%%%%%%%

That said, I modified the function you sent so that it also considerds NoteEvents and modifies the automatically created beams with the desired properties:

%%%%%%%%%%%%%%%%%
\version "2.19.83"

token = #(let* ((ctr 0)
                (ctr! (lambda ()
                        (set! ctr (1+ ctr))
                        ctr)))
   (define-music-function (mus) (ly:music?)
     (let* ((id (format #f "foobar_~a" (ctr!)))
            (type (ly:music-property mus 'name))
            (mexp (case type
                    ((BeamEvent NoteEvent)
                      #{ \tweak Beam.after-line-breaking #(lambda (grob)
                           (let* ((outprop (ly:grob-property grob 'output-attributes))
                                  (beam-thickness (ly:grob-property grob 'beam-thickness))
                                  (outprop (append outprop `((beam-thickness . ,beam-thickness)))))
                             ;(display (format #f "\n****\n~a\n****\n" beam-thickness))
                             (ly:grob-set-property! grob 'output-attributes outprop)))
                         \tweak Beam.output-attributes.id #id #mus #} )
                    (else #{ \tweak output-attributes.id #id #mus #} ))))
       mexp)))

\relative { c'4 d8-\token [ e ] \token f g c,4 }

%%%%%%%%%%%%%%%%%

The code could be cleaner I think, I'll try to improve it if I get some free time. Meanwhile I hope this helps

El dom., 22 dic. 2019 a las 7:58, Paolo Prete (<address@hidden>) escribió:
Hello all.

the following function (thanks to Stefano!) inserts the beam-thickness property of a Beam in the list of output-attributes of the corresponding SVG item. It does its job if I place the function soon before a beam symbol "[".  But it doesn't work (no errors, but the output-attributes property is not set) if  place it before a notename. How can I fix that? Should I map-some-music() and iterate until I find the BeamEvent? I tried that too, but without success.
Thanks.

token = #(let* ((ctr 0)
                (ctr! (lambda ()
                        (set! ctr (1+ ctr))
                        ctr)))
   (define-music-function (mus) (ly:music?)
     (let* ((id (format #f "foobar_~a" (ctr!)))
            (mexp #{ \tweak output-attributes.id #id #mus #} )
            (type (ly:music-property mus 'name))
            (mexp (case type
                    ('BeamEvent
                      #{ \tweak Beam.after-line-breaking #(lambda (grob)
                           (let* ((outprop (ly:grob-property grob 'output-attributes))
                                  (beam-thickness (ly:grob-property grob 'beam-thickness))
                                  (outprop (append outprop `((beam-thickness . ,beam-thickness)))))
                             (begin
                                  (ly:grob-set-property! grob 'output-attributes outprop)
                                  (display "\n****\n")
                                  (display beam-thickness)
                                  (display "\n****\n"))))
                      #mexp #} )
                    (else mexp))))
       mexp)))

\relative { c'4 d8-\token [ e ] \token f[ g ] c,4 }

reply via email to

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