Hallo Achim,
ich übergehe mal trullis Gedanken zum allgemeinen Notensatz (Anzahl der Stimmen) und zur Sinnhaftigkeit solch ausführlicher Barré-Angaben, auch wenn ich dem meisten zustimme und seine Version besser finde (ich würde das obere Ende der Klammer allerdings noch etwas höher sehen wollen).
Stattdessen zu den technischen Fragen.
(a)
Bei der Anwendung Deiner eigenen event-function ist Dir ein Versehen passiert. Im zweiten Takt muß der Barré III auf dem vierten Achtel starten, nicht auf dem dritten.
(b)
Die event-function wird ja mit der Syntax: <note>\event-function angewendet.
Eine music-function mit ähnlicher Wirkung, die wie \music-function { note1 ... noteN } angewendet werden soll, muß also vor der Note mit der der TextSpanner startet aufgerufen werden. Sie muß aber sicherstellen, daß diese Note das \startTextSpan-postevent erhält.
Dazu kannst Du versuchen <>-\tweak ... \startTextSpan zu schreiben. Die postevents von dem leeren event-chord <> werden dann der nächsten sinnvollen Möglichkeit zugeschlagen. Ob das allerdings immer zum gewünschten Ergebnis führt solltest Du sorgfältig testen.
Führt zu:
\version "2.22.0"
barre=
#(define-music-function (parser location position strings-covered music)
(number? string? ly:music?)
#{
<>
-\tweak bound-details.left.text
\markup
\column {
\line { \concat { \roman C #(format #f "~@r" position) } }
\line { \raise #1.8 \concat { \fontsize #-2 #strings-covered } }
}
-\tweak font-size -1
-\tweak font-shape #'upright
-\tweak style #'line
-\tweak bound-details.left.padding #0
-\tweak bound-details.left.attach-dir #LEFT
-\tweak bound-details.right.attach-dir #RIGHT
-\tweak bound-details.right.text
\markup
\with-dimensions #'(0 . 0) #'(-.3 . 0)
\draw-line #'(0 . -1)
-\startTextSpan
$music
\stopTextSpan
#})
keytime = {
\key d \major
\time 12/8
}
melody = \relative c' {
\keytime
r8 fis-2 e-0 fis4-2 cis8-1 b2.\3-4 |
fis'8-2 \barre #2 #"2-3" { d-3 cis-1 } \barre #3 #"2-3" { d-1 ais-1 cis-4\3 } b g b d-2 e-0 fis-2 |
}
bass = \relative c {
\keytime
d,1. |
d4.-0 fis-2 g-3 b-1 |
}
middle = \relative c' {
\keytime
\barre #2 #"2-3" { s2 a8-1 s4 } d8-3 fis-2 s4. | %3
}
lower = \relative c' {
\keytime
s1 s8 a-1 gis-1 fis-4 |
}
\score {
\new StaffGroup \with {
instrumentName = \markup { \rotate #90 "Guitar" }
} <<
\new Staff = "guitar" <<
\context Voice = "melody" {
\clef "G_8" \voiceOne
\melody
}
\context Voice = "bass" {
\clef "G_8" \voiceTwo
\bass
}
\context Voice = "middle" {
\clef "G_8" \voiceThree
\middle
}
\context Voice = "lower" {
\clef "G_8" \voiceFour
\lower
}
>>
\new TabStaff = "tab" <<
\set Staff.stringTunings = #guitar-drop-d-tuning
\context TabVoice = "melody tab" { \clef "moderntab" \voiceOne \melody }
\context TabVoice = "bass tab" { \clef "moderntab" \voiceTwo \bass }
\context TabVoice = "middle tab" { \clef "moderntab" \voiceThree \middle }
\context TabVoice = "lower tab" { \clef "moderntab" \voiceFour \lower}
>>
>>
}
(c)
Ein Barré für eine einzelne Note oder einen einzelnen Akkord, ist mit einem TextSpanner nicht darstellbar, da Du den TextSpanner nicht zum selben Zeitpunkt starten und enden lassen kannst. In solch einem Fall folge trullis Vorschlag.
(d)
Spanner wie der TextSpanner können per default nicht in verschiedenen Stimmen gestartet und beendet werden, es sei denn Du verlegst den entsprechenden engraver vom Voice- in den Staff-context.
Allerdings hat der TextSpanner die default-Beschränkung, daß nur einer pro Voice gleichzeitig möglich ist. Diese Beschränkung würde dann für den Staff-context gelten. Ich würde davon abraten, auch wenn es vielleicht möglich wäre TextSpanner mit unterschiedlicher spanner-id zu unterscheiden (so wie bei Slur, siehe NR). Wenn ich mich recht erinnere ist das für TextSpanner allerdings nicht per default implementiert, kann aber mit jeder Menge Zusatzcode ermöglicht werden. Hab ich jetzt aber nicht weiter nachgeforscht...
Allgemeine Gedanken zum Barré.
Ein Barré-Zeichen kann ja folgende Elemente beinhalten:
- zur linken eine vertikale Linie, die bis zur tiefsten Barré-Note reicht, evtl. dort eine kurze horizontale Linie (siehe Bild im Anhang)
- die Angabe der Lage, evtl mit "C", "B" oder ähnlichem
- horizontale Linie über den Noten als Angabe wie lange der Barré gelten soll
- eine kurz vertikale Linie als Abschluss
Somit unterläge der Barré mit seiner horizontalen Ausdehnung der outside-staff-priority, sowie anderen Faktoren, die ihn nach oben bzw unten schieben können.
Das hat aber natürlich direkte Auswirkungen auf die benötigte Länge der linken vertikalen Linie, die ihrerseits evtl der script-priority unterliegt. Was dann wieder Auswirkungen auf die benötigte horizontale Länge hat.
Alle dafür benötigten Werte sind aber bestenfalls bei Beendigung des Barré verfügbar.
Alle Versuche den Barré mittels eines anderen grobs zu erhalten sind hier dann aufgeschmissen und haben außerdem den Nachteil, daß das dann verwendete grob nicht mehr zum selben Zeitpunkt verwendet werden kann.
Hier der TextSpanner, in Compers Code das Arpeggio.
Eigentlich muß also ein neues grob geschaffen werden.
Tatsächlich habe ich schon des öfteren neue grobs codiert, bin aber bislang daran gescheitert diesem neuen (Barré-)grob einen stencil zuzuweisen, der obige Kriterien auch umsetzen kann.
Insoweit verwende ich meistens eine simple Implementierung via TextSpanner, deutlich einfacher als Deine eigene, und nehme weitere Einstellungen manuell mit zusätzlichen tweaks und overrides vor, da ich die Erfahrung gemacht hab, daß häufig Anpassung bei details.left/right.padding erforderlich sind. Diese in einer Funktion mit zu geben reduziert Verständlichkeit und Lesbarkeit des Codes, imho.
Aber wer weß, vielleicht komme ich ja noch dahinter wie ich ein Barré-grob sinnvoll codieren kann.
Gruß,
Harm