Simon, you wrote Friday, September 02, 2016 1:34 AM Hi Simon,
>On 24.08.2016 11:51, Trevor Daniels wrote: >> David Kastrup wrote Wednesday, August 24, 2016 7:48 AM >>> "Trevor Daniels"<t.dani...@treda.co.uk> writes: >>>> Prompted by the recent discussion on lute tablature, I tried coding a >>>> Scheme engraver to create the duration grobs but quickly ran into a >>>> problem. I need to collect information from both a Listener and an >>>> Acknowledger so the obvious place to build the grob is in >>>> stop-translator-timestep, >>> No, no, no. stop-translator-timestep really is only for cleanup work. >>> Stuff is no longer in working order then. You want process-acknowledged >>> here I think. >>> >>> There will always be a call to process-acknowledged whenever grobs have >>> been created, and_reading_ stuff from grobs should be delayed until >>> then since other acknowledgers might_write_ stuff into a grob even >>> after your personal acknowledger has been called. So the basic workflow >>> is to use the various acknowledgers to_record_ the grobs you are >>> interested in and_write_ stuff into them (or do read/write stuff that >>> more or less is accumulative and/or really unrelated to other >>> engravers), and then use the process-acknowledged hook for processing >>> (including_reading_) the grobs you had recorded. >>> >>> You can create new grobs in process-acknowledged. That will lead to a >>> new cycle of acknowledger calls followed by process-acknowledged. Only >>> when all those cycles are over is stop-translator-timestep called, and >>> then creating grobs is no longer an option. >> >> Thanks David. That's beautifully clear. > > I just caught up with all the mailing lists, being back from holiday, > and I’d be interested in a working example for this solution. Would you > mind sharing it? There already is a helpful working example in the code base. See input/regression/scheme-engraver.ly This doesn't go as far as creating new grobs, so I've attached a simple example that does. This is a bit of a hack, used as part of a learning process, and a bit messy as it evolved from an earlier attempt, but it illustrates one way. Actually, comments from the experts on this would be very helpful. Trevor
\version "2.19.40" % Example of using Scheme engraver to add markup based on note duration % Avoids repeated durations on both chords and consecutive notes %{ TODO Handle notes with different durations at one musical moment better Add dots Add bass courses %} #(define (t->m t) "Return the current moment of translator object @var{t}." (ly:context-current-moment (ly:translator-context t))) % persistent variables for Lute_tab_duration_engraver #(define previous-duration-log #f) % to supress repeated durations #(define ev #f) % event #(define en #f) % engraver Lute_tab_duration_engraver = #(make-engraver ((initialize translator) (format 1 "\n\n~16a: (initialize)\n" (t->m translator))) ((start-translation-timestep translator) (set! ev #f) (set! en #f) (format 1 "~16a: (start-translation-timestep)\n" (t->m translator))) (listeners ((note-event engraver event) ; Save just the last event at each timestep ;TODO save shortest duration event? (set! ev event) (set! en engraver) (format 1 "~16a: detected this note event: ~a\n " (t->m engraver) event))) (acknowledgers ((note-head-interface engraver grob source-engraver) (format 1 "~16a: saw ~a coming from ~a\n" (t->m engraver) grob source-engraver))) (end-acknowledgers ((beam-interface engraver grob source-engraver) (format 1 "~16a: saw end of ~a coming from ~a\n" (t->m engraver) grob source-engraver))) ((process-music translator) (format 1 "~16a: (process-music)\n" (t->m translator)) (if ev (let ((duration-log (ly:duration-log (ly:event-property ev 'duration)))) (display duration-log) (if (not (equal? duration-log previous-duration-log)) (let ((grob (ly:engraver-make-grob en 'TextScript ev))) (set! previous-duration-log duration-log) (ly:grob-set-property! grob 'direction UP) (ly:grob-set-property! grob 'text (case duration-log ((2) (markup (#:musicglyph "rests.M2mensural"))) ((3) (markup (#:musicglyph "flags.mensuralu03"))) ((4) (markup (#:musicglyph "flags.mensuralu04"))) ((5) (markup (#:musicglyph "flags.mensuralu05"))) ((6) (markup (#:musicglyph "flags.mensuralu06"))) (else (markup " "))))))))) ((process-acknowledged translator) (format 1 "~16a: (process-acknowledged)\n" (t->m translator))) ((stop-translation-timestep translator) (format 1 "~16a: (stop-translation-timestep)\n" (t->m translator))) ((finalize translator) (format 1 "~16a: (finalize)\n" (t->m translator)))) notes = \relative c'' { \time 3/4 \partial 4. a8 r a | <f d>4. f8 <g e>4 | \break \time 4/4 c1 | cis2 d4 ees8 e16 f32 fis64 g64 | gis16 a16 bes8 c cis d ees e f | fis g gis a bes b c cis | } \score { << \new Staff { \new Voice { \notes } } \new TabStaff \with { % Use letters to indicate frets tablatureFormat = #fret-letter-tablature-format % Usual string tuning for 6-course Baroque lute stringTunings = #`(,(ly:make-pitch 1 3 NATURAL) ,(ly:make-pitch 1 1 NATURAL) ,(ly:make-pitch 0 5 NATURAL) ,(ly:make-pitch 0 3 NATURAL) ,(ly:make-pitch 0 1 NATURAL) ,(ly:make-pitch -1 5 NATURAL)) % Choose a suitable font for fret letters \override TabNoteHead.font-name = #"Fronimo Gavotta" \override Flag.style = #'straight \revert TextScript.stencil } { \new TabVoice \with { % Baroque tab uses slurs \consists "Fingering_engraver" \consists "New_fingering_engraver" \consists \Lute_tab_duration_engraver \revert Slur.stencil } { \textLengthOn % \applyMusic #(lambda (x) (music-map add-duration x)) \notes } } >> } %{ convert-ly.py (GNU LilyPond) 2.19.43 convert-ly.py: Processing `'... Applying conversion: 2.13.10, 2.13.16, 2.13.18, 2.13.20, 2.13.27, 2.13.29, 2.13.31, 2.13.36, 2.13.39, 2.13.40, 2.13.42, 2.13.44, 2.13.46, 2.13.48, 2.13.51, 2.14.0, 2.15.7, 2.15.9, 2.15.10, 2.15.16, 2.15.17, 2.15.18, 2.15.19, 2.15.20, 2.15.25, 2.15.32, 2.15.39, 2.15.40, 2.15.42, 2.15.43, 2.16.0, 2.17.0, 2.17.4, 2.17.5, 2.17.6, 2.17.11, 2.17.14, 2.17.15, 2.17.18, 2.17.19, 2.17.20, 2.17.25, 2.17.27, 2.17.29, 2.17.97, 2.18.0, 2.19.2, 2.19.7, 2.19.11, 2.19.16, 2.19.22, 2.19.24, 2.19.28, 2.19.29, 2.19.32, 2.19.40 %}
_______________________________________________ lilypond-devel mailing list lilypond-devel@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-devel