Hi Jean, Am Sa., 24. Okt. 2020 um 11:55 Uhr schrieb Jean Abou Samra <j...@abou-samra.fr>:
> The problem so far is that I didn't find a proper way to set the chord > configuration at a given musical moment (note heads placed at the left or at > the right of the stem). For now I've used an extra-offset, which leads to > inconsistent spacing. There is \override Stem.note-collision-threshold = 50, > but that doesn't let you achieve the fourth chord before the end, where the > upper note is on the left and the lower note is on the right, since the usual > placement is the other way around. Stem.note-collision-threshold gives you some possibilities, but to freely position note-heads at a Stem, one needs to tackle Stem.positioning-done. #(define (distribute-note-heads-around-stem note-head-shifts) (lambda (grob) "Takes the note-heads from a stem-grob and applies offsets in X-direction taken from @var{note-head-shifts}." (let* ((nhds-array (ly:grob-object grob 'note-heads)) (nhds-list (if (ly:grob-array? nhds-array) (ly:grob-array->list nhds-array) '())) (sorted-nhds (sort nhds-list (lambda (p1 p2) (ly:pitch<? (ly:prob-property (ly:grob-property p1 'cause) 'pitch) (ly:prob-property (ly:grob-property p2 'cause) 'pitch))))) (stem-starting-nhd? (lambda (nhd) (if (positive? (ly:grob-property grob 'direction)) (equal? nhd (car sorted-nhds)) (equal? nhd (last sorted-nhds)))))) ;; Move note-heads in X-direction, looking at 'note-head-shifts' ;; If a stem starts at a moved note-head, adjust this note-head's ;; 'stem-attachment (for-each (lambda (nhd nhd-shift) (if (and (stem-starting-nhd? nhd) (not (zero? nhd-shift))) (let ((default-stem-attach (ly:note-head::calc-stem-attachment grob))) (ly:grob-set-property! nhd 'stem-attachment (cons (car default-stem-attach) (- (cdr default-stem-attach)))))) (ly:grob-translate-axis! nhd (* nhd-shift (- (interval-length (ly:grob-extent nhd nhd X)) (interval-length (ly:grob-extent grob grob X)))) X)) nhds-list note-head-shifts) #t))) distributeNoteHeads = #(define-music-function (nhd-shifts)(number-list?) "Returns an override to distribute note-heads around a stem, according to @var{nhd-shifts}." (if (not (every ly:dir? nhd-shifts)) (let ((signs (map (@@ (lily) sign) nhd-shifts))) (ly:warning "Only directions like -1, 0, 1 are accepted, transforming ~a to ~a." nhd-shifts signs) ;; sign should really be public (set! nhd-shifts (map (@@ (lily) sign) nhd-shifts)))) #{ \override Stem.positioning-done = #(distribute-note-heads-around-stem nhd-shifts) #}) { %% Test the warning \once \distributeNoteHeads #'(1.1 0) < ees' gis' > \voiceTwo \once \distributeNoteHeads #'(0 -1) < e' g' > } > Code attached, with an output that resembles the image you (Michael) sent > earlier. Note that you need a development version of LilyPond > (lilypond.org/development). Naturally, this is only a start since at this > point more details are needed about the specification of what you want to > achieve. Nevertheless, I wanted to share this code to avoid duplication of > effort in case someone else were willing to take over this topic. To your comment: % Not defined? #(define pi (acos -1)) It's defined in lily-library,scm as (define-public PI (* 4 (atan 1))) Cheers, Harm