On 1/19/19, Davide Bonetti <d...@davidebonetti.it> wrote: > For the sake of the discussion, I copy there the code as it now is:
Greetings Davide and everybody, although these chord-transform functions were only intended for written voicings (i.e. not ChordNames), David K. had a brilliant idea: by setting the 'octavation property for every transposed pitch, we can print the intended voicing *without* causing the chord to loose its name. Problem: the version I tried to modify (see below) works nicely for primary \dropNote and \raiseNote commands, but when they’re nested (e.g. with \invertChords) it gives erratic results. There’s obviously something I missed; could anybody give it a try and tell me where it’s going off the rails? %%%%%%%%%%%%%%%%%%%%%%%%% \version "2.21.0" #(define-public (move-chord-note n direction) (_i "Transpose a note (numbered as @var{n}) by one octave in @var{direction}.") (lambda (music) (let* ((elts (ly:music-property music 'elements)) (l (length elts)) ;; if direction is up, count from the bottom note upward, ;; if direction is down, count from the top note downward. (count-from (cond ((= direction UP) (- n 1)) ((= direction DOWN) (- l n)))) ;; Notes may not have been entered from bottom to top; ;; extract the pitches and put them in order. (pitches (map (lambda (x) (ly:music-property x 'pitch)) (filter (lambda (y) (music-is-of-type? y 'note-event)) elts))) (sorted (sort pitches ly:pitch<?))) (if (and (music-is-of-type? music 'event-chord) (not (zero? n)) (>= l n)) (begin ;; first apply the sorted pitches ;; to the actual notes. (map (lambda (e p) (ly:music-set-property! e 'pitch p)) elts sorted) ;; then transpose the note up or ;; down, depending on direction. (let* ((note (list-ref elts count-from)) (oct (ly:music-property note 'octavation))) (list-set! elts count-from (ly:music-transpose note (ly:make-pitch (cond ((= direction UP) +1) ((= direction DOWN) -1)) 0))) (ly:music-set-property! note 'octavation (+ (cond ((= direction UP) 1) ((= direction DOWN) -1)) (if (null? oct) 0 oct)))) )) music))) dropNote = #(define-music-function (parser location num music) (integer? ly:music?) (_i "Drop a note of any chords in @var{music}, in @var{num} position from above.") (music-map (move-chord-note num down) music)) raiseNote = #(define-music-function (parser location num music) (integer? ly:music?) (_i "Raise a note of any chords in @var{music}, in @var{num} position from below.") (music-map (move-chord-note num up) music)) invertChords = #(define-music-function (num music) (integer? ly:music?) (_i "Invert any chords in @var{music} into their @var{num}-th position. (Chord inversions may be directed downwards using negative integers.)") (let loop ((num num) (music music)) (cond ((zero? num) music) ((negative? num) (loop (1+ num) (dropNote 1 music))) (else (loop (1- num) (raiseNote 1 music)))))) ac = \chordmode { \dropNote 2 c:maj \raiseNote 1 d:m7 \invertChords 2 e:m7 } << \chords { \ac } { <>^\markup \sans "(should be: C△, Dm7 and Em7)" \ac \bar "||" } >> %%%%%%%%%%%%%%%%% Thanks! V. _______________________________________________ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user