Hi Dave,

Here is my code for centering notes in a bar. It's based on work by David
Nalesnik and Thomas Morley, to whom many thanks.

Works for 2.19.80. Not for 2.18.

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

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



On 30 December 2017 at 00:37, Dave Higgins <dave.higg...@dkds.us> wrote:

> Is there a way to center a whole notehead in the bar?
>
> << { c'1 } \new Dynamics { \override Hairpin #'minimum-length = #8 s8\> s
> s s s\p\< s s s\! } >>
>
> I know I could use silence and fractional note lengths, but that seems
> sloppy.
>
> Also, why doesn't R1*1 work like R1*2 (by putting the 2 in position over
> the rest)? (rhetorical)  Yes, I have a solution for this too, but again,
> sloppy.
> --
> Dave
>
>
> _______________________________________________
> lilypond-user mailing list
> lilypond-user@gnu.org
> https://lists.gnu.org/mailman/listinfo/lilypond-user
>
>
_______________________________________________
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to