Hallo,
ich hab' mal weiter an dem Problem gearbeitet.
Um zentrieren zu können muß man die BarLines davor und danach in die Berechnung einbeziehen.
Ich habe also ein neues property definiert, welches zur Markierung benutzt wird, sowie die Funktion
\markBarLine, die das dann ausführt. Diese Idee stammt ursprünglich von
Arnold.Nach
diesem Vorbild anschließend
center-note-column um die NoteColumn zu zentrieren sowie die Funktion
\centerNotes. Es ist ganz hilfreich das die NoteColumn nicht nur die Notenköpfe sondern auch die Notenhälse und Bögen bestimmt. Allerdings nicht die Punkte von punktierten Notenwerten und die Vorzeichen auch nicht. Insofern mußte ich DotColumn und AccidentalPlacement auch in
\centerNotes und
center-note-column einbeziehen.
Leider ist es mir nicht gelungen die Markierung der Taktstriche zu automatisieren. Das mag daran liegen, daß ein selbst gebautes property natürlich kein call-back, interface etc hat.
Ich habe es auch nicht geschafft
\centerNotes und
\markBarLine in eine einzige Funktion zu packen.
Anwendung:
Mit
\markBarLine werden die Taktstriche markiert. Ich empfehle die Taktzahlen zu benutzen. Nach Takt eins kommt also
\markBarLine #1 etc. Wichtig ist, daß immer vor und nach dem zu zentrierenden Objekt die Taktstriche markiert sind. Man braucht aber nur dort zu markieren, wo etwas zentriert werden soll, nicht etwa das ganze Stück.
Das erste Argument von
\centerNotes ist dann die Taktzahl des Taktes der zentriert werden soll. Da manchmal doch noch nachträgliche Verbesserungen nötig sind habe ich eine Korrekturliste eingebaut:#'(0 0 0) gibt das default-Verhalten von
\centerNotes aus. Der erste Wert kann die NoteColumn beeinflussen. Der zweite das AccidentalPlacement, der dritte die DotColumn.
Im Code habe ich all das in eine eigene Stimme gepackt.
\version "2.14.2"
#(define (define-grob-custom-property symbol type? description)
(if (not (equal? (object-property symbol 'backend-doc) #f))
(ly:error (_ "symbol ~S redefined") symbol))
(set-object-property! symbol 'backend-type? type?)
(set-object-property! symbol 'backend-doc description)
symbol)
#(define all-user-grob-custom-properties
(map
(lambda (x)
(apply define-grob-custom-property x))
`(
(markers ,list? "Tag marker(s) in grob for function center-between")
)))
#(define ((center-note-column symbol tags extra-X-offset) grob)
(let* ((refp (ly:grob-system grob))
(all-grobs (ly:grob-array->list (ly:grob-object refp 'all-elements)))
(grob-ext (ly:grob-extent grob refp X))
(note-head (ly:grob-parent grob X))
(note-head-ext (ly:grob-extent note-head refp X))
(X-extent (lambda (q) (ly:grob-extent q refp X)))
(targets (filter (lambda (q) (member tags (ly:grob-property q 'markers))) all-grobs)))
(cond ((not (pair? targets)) (ly:programming-error (_ "no grobs marked ~S") tags))
((= (length targets) 1) (ly:programming-error (_ "only one grob marked ~S") tags))
((> (length targets) 2) (ly:programming-error (_ "more than two grobs marked ~S") tags))
(else
(begin
(if (> (car (X-extent (car targets))) (car (X-extent (cadr targets))))
(set! targets (reverse targets)))
(let ((left (if (> (cdr (X-extent (car targets)))
(car (X-extent (cadr targets))))
(car (X-extent (car targets)))
(cdr (X-extent (car targets)))))
(right (car (X-extent (cadr targets)))))
(cond ((equal? symbol "NoteColumn")
(ly:grob-translate-axis! grob
(+ (- (- (interval-center (X-extent grob))
(/ (+ left right) 2)))
extra-X-offset)
X))
((equal? symbol "AccidentalPlacement")
(ly:grob-translate-axis! grob
(+ (- (- (interval-center (X-extent grob))
(/ (+ (- left (interval-length (interval-widen note-head-ext (/ (interval-length grob-ext) 1.5)))) right) 2)))
extra-X-offset)
X))
((equal? symbol "DotColumn")
(ly:grob-translate-axis! grob
(+ (- (- (- (interval-center (X-extent grob)) (/ (interval-length note-head-ext) 2))
(/ (+ left right) 2)))
extra-X-offset)
X))
)
))))))
markBarLine =
#(define-music-function (parser location barnumber)(number?)
#{
\once\override Staff.BarLine #'markers = #(list $barnumber (+ $barnumber 1))
#})
centerNotes =
#(define-music-function (parser location between? corr)(number? list?)
#{
\once\override PianoStaff.NoteColumn #'after-line-breaking =
#(center-note-column "NoteColumn" $between? $(car corr))
\once\override PianoStaff.AccidentalPlacement #'after-line-breaking =
#(center-note-column "AccidentalPlacement" $between? $(cadr corr))
\once\override PianoStaff.DotColumn #'after-line-breaking =
#(center-note-column "DotColumn" $between? $(caddr corr))
#})
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\paper {
indent = 40
ragged-right = ##f
}
voice = \relative c' {
\key b\minor
\time 3/4
b'2_"Zeit?" r4
R2.*6
R2.*1\fermataMarkup
\bar "|."
}
centerVoice = {
\key b\minor
\clef "bass"
%1
s2.
\markBarLine #1
%2
\centerNotes #2 #'(0 0 0)
s
\markBarLine #2
%3
\centerNotes #3 #'(0 0 0)
s
\markBarLine #3
%4
\centerNotes #4 #'(0 0 0)
s
\markBarLine #4
%5
\centerNotes #5 #'(-0.7 0 -1.8)
s
\markBarLine #5
%6
\centerNotes #6 #'(0 0 0)
s
\markBarLine #6
%7
\centerNotes #7 #'(0 0 0)
s
\markBarLine #7
%8
\centerNotes #8 #'(0 0 -0.3)
s
\markBarLine #8
}
pUp = \relative c' {
\key b\minor
\clef "bass"
<d, fis b>2.\pp (
<fis ais>
<fis d'>
<e g c!> )
<dis fis a! b>\ppp^\markup \with-color #red "hier" (
<e g b> )
<dis fis b> ~
<dis fis b>\fermata
}
pDown = \relative c' {
\key b\minor
\clef "bass"
<b,, fis' b>2. ( |
<ais fis' ais> |
<d fis d'> |
<c g' c> ) |
<b b'> ~ |
<b b'> |
<b b'> ~ |
<b b'>\fermata |
}
<<
\new Staff \voice
\new PianoStaff <<
\new Staff <<
\new Voice \pUp
\new Voice \centerVoice
>>
\new Staff \pDown
>>
>>Wenn man sich den output genau ansieht, so kann man an der mit "hier" markierten Stelle ein nicht so besonders schönes Ergebnis beobachten. Das liegt an den links und rechts vom Notenhals platzierten Notenköpfen in der rechten Hand. Die NoteColumn wird absolut korrekt zentriert (wenn man die Liste an dieser Stelle auf '(0 0 0) zurücksetzt), aber sie hat jetzt in x-Richtung eine größere Ausdehnung, so daß die NoteColumn in der linken Hand nicht mehr so ganz dazu passt. Ich würde hier auf das schon oben erwähnte Verfahren mittels 'extra-spacing-width zurückgehen und die NoteColumn nicht verschieben.
Vielleicht kann jemand anderes das noch verbessern.
Gruß,
Harm