Hi, Finally getting a chance to play around with this. Thanks for writing up this proof of concept! I'm learning a lot.
A few questions: 1) When you build alive?-instr-list you seem to assume a correspondence between vertical-axis-group-list and instrument-names-list. But is that actually guaranteed? Is the list of all grobs ordered that way to begin with, and does filter preserve that ordering? 2) Is there a way to check if two VerticalAxisGroups belong to the same StaffGroup, for instance? What I want to do is modify this so for each staff with the callback defined, it only looks at the other staves within the same lowest-level staff grouping. That way, it could be used in a score with multiple groups of staves. My first shot at just grabbing the related staves was: (filter (lambda (x) (equal? (ly:grob-parent grob 1) (ly:grob-parent x 1))) vertical-axis-group-list) But it seems all VerticalAlignments are the same or something? Hopefully it's sort of clear what I'm trying to do? Thanks! On Sat, Jun 17, 2017 at 3:42 AM, Thomas Morley <thomasmorle...@gmail.com> wrote: > 2017-06-16 23:47 GMT+02:00 Shevek <saul.james.to...@gmail.com>: > > Following up on an aspect of the discussion on parts sharing a staff > > (http://lilypond.1069038.n5.nabble.com/parts-sharing-a- > staff-tt203873.html). > > > > I've spent quite a few hours over the last day trying to figure out how > > engravers work and how I might take a crack at writing something to > > automatically handle changing Staff names for divisi staves. I feel like > > I've understood most of what I've read, but I'm still totally befuddled. > > This seems like a difficult problem because: > > > > 1) It's completely opaque to me how one would check if a Staff is > visible or > > not on a given system. The hara-kiri-group-spanner, as far as I can tell, > > does its work without telling anybody about it. There's not like a > boolean > > function you can call to find out if a context will be visible. > > > > 2) One needs to do something in one context depending on what happens in > a > > different context. Most of the example engravers just do something in one > > context. Keep_alive_together_engraver collects grobs from different > contexts > > and tells them about each other, but then relies on on them to figure out > > what to do with that information. That doesn't seem adequate here. > > > > 3) Such an engraver would need to step through the score by system, after > > breaking, rather than event by event, and it might need to be able to > > backtrack to insert an event to change the instrument name prior to the > most > > recent system break. The code and documentation I've read has not given > me > > any insight into how one might do such a thing. > > > > I'd love some feedback and guidance. > > > > Hi, > > I doubt an engraver will ever work for this purpose. As far as I > understand an engraver usually puts in stuff far too early. You can > assign a procedure to a grob via 'after-line-breaking, but you will > not be able to access whatever the procedure returns _in_ the > engraver. > I may be proven wrong, though. > > Nevertheless, I tried a different approach: > > \version "2.19.62" > > %% NB > %% It's a proof of concept, nothing more!! > %% Currently it will fail for various reasons with extended examples > #(define change-instr-names > (lambda (grob) > (let* ((sys (ly:grob-system grob)) > (sys-all-elts (ly:grob-object sys 'all-elements)) > (sys-all-elts-list > (if (ly:grob-array? sys-all-elts) > (ly:grob-array->list sys-all-elts) > '())) > ;; get all VerticalAxisGroup-grobs per System > (vertical-axis-group-list > (filter > (lambda (g) > (grob::has-interface g 'hara-kiri-group-spanner- > interface)) > sys-all-elts-list)) > ;; get all InstrumentName-grobs per System > (instrument-names-list > (filter > (lambda (g) > (grob::has-interface g 'system-start-text-interface)) > sys-all-elts-list)) > ;; construct a nested list like > ;; ((#t #<Grob InstrumentName >) > ;; (#f #<Grob InstrumentName >)) > ;; the boolean indicates whether the Staff is alive, derived > from > ;; VerticalAxisGroup.Y-extent > (alive?-instr-list > (map > (lambda (v i) > (list (interval-sane? (ly:grob-property v 'Y-extent)) i)) > vertical-axis-group-list > instrument-names-list))) > > ;(pretty-print alive?-instr-list) > > ;; First constructing a list and then fragmenting it in various ways > is > ;; not elegant, to say the least. > ;; Just a proof of concept... > (if (any not (map car alive?-instr-list)) > (let* ((instr-to-set > (remove > (lambda (e) > (not (car e))) > alive?-instr-list))) > (ly:grob-set-property! (cadar instr-to-set) 'text > (make-column-markup > (map > (lambda (arg) > (ly:grob-property arg 'text)) > (map cadr alive?-instr-list))))))))) > > %%%%%%%%%%%%%%%%%%%%%%%%%%%% > %% Example > %%%%%%%%%%%%%%%%%%%%%%%%%%%% > > \layout { > \context { > \Staff > \override VerticalAxisGroup.after-line-breaking = > #change-instr-names > \RemoveEmptyStaves > } > } > > << > \new Staff \with { instrumentName = "One" shortInstrumentName = "one" } > { R1 \break c \break c } > \new Staff \with { instrumentName = "Two" shortInstrumentName = "two" } > { c1 R c } > >> > > > Cheers, > Harm > _______________________________________________ lilypond-devel mailing list lilypond-devel@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-devel