[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Horizontal shifting of chords
From: |
Thomas Morley |
Subject: |
Re: Horizontal shifting of chords |
Date: |
Mon, 4 Feb 2019 11:24:02 +0100 |
Am Mo., 4. Feb. 2019 um 10:35 Uhr schrieb Andrew Bernard
<address@hidden>:
>
> Hi Robert,
>
> 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
>
> onceCenterNoteColumn =
> #(define-music-function (x-offs)(number?)
> #{
> \once \override Staff.NoteColumn #'after-line-breaking =
> #(center-note-column x-offs)
> #})
>
>
> %====
Iirc, this doesn't work for arpeggio anymore, due to some internal changes.
Its worth some rework anyway.
That said, here a possibility to do things manually:
\override Score.NonMusicalPaperColumn.full-measure-extra-space = 6
\overrideProperty Score.NonMusicalPaperColumn.full-measure-extra-space 6
(adjust the value to taste)
Which one to use depends... and it doesn't work for the first bar of a line.
Cheers,
Harm