lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Horizontal shifting of chords


From: Robert Blackstone
Subject: Re: Horizontal shifting of chords
Date: Tue, 5 Feb 2019 11:11:07 +0100

Hi Andrew,

Thank you for your reaction.

I can understand that you did not understand why I wanted to centre the final chord. I was thinking of the perectly centered final rests, and if the last bar had not contained a \breve chord but a rest R1*2 would have produced it.
I thought that such a thing should somehow also be possible for a chord but I could not find out how. Hence the subject title of my question.

I will have a go with the extensive and complicated thing you forwarded. (But not today. ) 

Best regards,

Robert

On 4 Feb 2019, at 10:07 , Andrew Bernard <address@hidden> wrote:

You asked to centre the chord, but  then if you add barline offset it's not centred, so I am a bit confused what you mean. although the picture makes it clear.

I just wanted to say that there are often times when you really do want to centre a chord or a rest in a single, especially in Baroque music. To this end, when I asked about this in the past, David Nalesnik and Thomas Morley produced this excellent code. Note that it only works for one thing in a bar, but it's great.

Hope this may help.

One of those things that ought to go in LSR I suppose.


Andrew

%====
% Thanks to David Nalesnik and Thomas Morley.

#(define (sort-by-X-coord sys grob-lst)
   "Arranges a list of grobs in ascending order by their X-coordinates"
   (let* ((X-coord (lambda (x) (ly:grob-relative-coordinate x sys X)))
          (comparator (lambda (p q) (< (X-coord p) (X-coord q)))))

     (sort grob-lst comparator)))

#(define (find-bounding-grobs note-column grob-lst)
   (let* ((sys (ly:grob-system note-column))
          (X-coord (lambda (n) (ly:grob-relative-coordinate n sys X)))
          (note-column-X (X-coord note-column)))

     (define (helper lst)
       (if (and (< (X-coord (car lst)) note-column-X)
                (> (X-coord (cadr lst)) note-column-X))
           (cons (car lst) (cadr lst))
           (if (null? (cddr lst))
               (cons note-column note-column)
               (helper (cdr lst)))))

     (helper grob-lst)))

#(define (read-out ls1 ls2 ls3 symbol)
   "Filters all elements of ls1 from ls2 and appends it to ls3"
   (set! ls3 (append ls3 (filter (lambda (x) (eq? (car ls1) (symbol x))) ls2)))
   (if (null? (cdr ls1))
       ls3
       (read-out (cdr ls1) ls2 ls3 symbol)))

#(define ((center-note-column x-offs) grob)
   (let* ((sys (ly:grob-system grob))
          (elements-lst (ly:grob-array->list (ly:grob-object sys 'all-elements)))
          (grob-name (lambda (x) (assq-ref (ly:grob-property x 'meta) 'name)))
          (X-extent (lambda (q) (ly:grob-extent q sys X)))
          ;; NoteColumn
          (note-column-coord (ly:grob-relative-coordinate grob sys X))
          (grob-ext (X-extent grob))
          (grob-length (interval-length grob-ext))
          ;; NoteHeads
          (note-heads (ly:grob-object grob 'note-heads))
          (note-heads-grobs (if (not (null? note-heads))
                                (ly:grob-array->list note-heads)
                                '()))
          (one-note-head (if (not (null? note-heads-grobs))
                             (car note-heads-grobs)
                             '()))
          (one-note-head-length (if (not (null? one-note-head))
                                    (interval-length (X-extent one-note-head)) ;; NB
                                    0))
          ;; Stem
          (stem (ly:grob-object grob 'stem))
          (stem-dir (ly:grob-property stem 'direction))
          (stem-length-x (interval-length (X-extent stem))) ;; NB
          ;; DotColumn
          (dot-column (ly:note-column-dot-column grob))
          ;; AccidentalPlacement
          (accidental-placement (ly:note-column-accidentals grob))
          ;; Arpeggio
          (arpeggio (ly:grob-object grob 'arpeggio))
          ;; Rest
          (rest (ly:grob-object grob 'rest))
          ;; Grobs to center between
          (args (list 'BarLine
                  'Clef
                  'KeySignature
                  'KeyCancellation
                  'TimeSignature))
          (grob-lst (read-out args elements-lst '() grob-name))
          (new-grob-lst (remove (lambda (x) (interval-empty? (X-extent x))) grob-lst))
          (sorted-grob-lst (sort-by-X-coord sys new-grob-lst))
          ;; Bounds
          (bounds (find-bounding-grobs grob sorted-grob-lst))
          (left (cdr (X-extent (car bounds))))
          (right (car (X-extent (cdr bounds))))

          ;;(bounds-coord (cons left right)) ;; delete

          (basic-offset
           (- (average left right)
             (interval-center (X-extent grob))
             (* -1 x-offs)))
          (dir-correction
           (if (> grob-length one-note-head-length)
               (* stem-dir (* -2 stem-length-x) grob-length)
               0))

          ) ;; End of Defs in let*

     ;; Calculation
     (begin
      ;;(display "\n\tbounds: \t")(write bounds)
      (for-each
       (lambda (x)
         (cond ((ly:grob? x)
                (ly:grob-translate-axis!
                 x
                 (- basic-offset dir-correction)
                 X))))
       (list
        (cond ((not (null? note-heads)) grob))
        dot-column accidental-placement arpeggio rest))
      )))

centerNoteColumnOn = \override Staff.NoteColumn #'after-line-breaking = #(center-note-column 0)

centerNoteColumnOff = \revert Staff.NoteColumn #'after-line-breaking

>#(define-music-function (x-offs)(number?)
   #{
     \once \override Staff.NoteColumn #'after-line-breaking = #(center-note-column x-offs)
   #})


%====


reply via email to

[Prev in Thread] Current Thread [Next in Thread]