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 (<paolopr...@gmail.com>)
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 <
> stefanotronc...@gmail.com> 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 (<paolopr...@gmail.com>)
>> 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 <
>>> stefanotronc...@gmail.com> 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 (<paolopr...@gmail.com>)
>>>> 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