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 } >>>>> >>>>