Hello Dirck, you might be interested in something I recently made for music SE. Essentially this will add two new engravers that automatically annotate the string tuning whenever it changes.
Cheers, Valentin
\version "2.24"
% Used for printing the actual changes. A procedure that takes the tuning and the old tuning
% as optional argument and returns a markup.
#(set-object-property! 'stringTuningColumnFormatter
'translation-type?
procedure?)
% Create a tuning column reahearsal mark whenever the string tuning changes
#(define (string-tuning-engraver context)
(let ((current-tuning #f))
(make-engraver
((process-music engraver)
(let ((tuning (ly:context-property context 'stringTunings))
(formatter (ly:context-property context 'stringTuningColumnFormatter)))
(if (not (equal? tuning current-tuning))
(let* ((mark (ly:engraver-make-grob engraver 'RehearsalMark '())))
(ly:grob-set-property! mark 'text (formatter tuning current-tuning))
(ly:grob-set-property! mark 'font-size 0)
(ly:grob-set-property! mark 'self-alignment-X LEFT)
(set! current-tuning tuning))))))))
% Print tuning supplied in details.string-tuning on the line positions
#(define (key-signature-interface::tuning-column-print grob)
(let* ((staff-symbol (ly:grob-object grob 'staff-symbol))
(pos (ly:grob-property staff-symbol 'line-positions #f))
; With 2.25 line-positions will be used by default. Before this might not be set, so
; in case we recalculate this here to make the code compatible with 2.24
(pos (or pos
(let* ((count (ly:grob-property staff-symbol 'line-count)))
(map (lambda (i) (- count (* 2 i) 1)) (iota count)))))
(ssp (ly:staff-symbol-staff-space staff-symbol))
(tuning (assoc-get 'string-tuning (ly:grob-property grob 'details)))
(mups (map (lambda (p) (markup #:whiteout #:pad-markup 0.1 (note-name->markup p #f))) tuning))
(stcs (map (lambda (m)
(ly:stencil-aligned-to
(grob-interpret-markup grob m)
Y CENTER))
mups))
(common-center (interval-center (ly:stencil-extent (grob-interpret-markup grob "A") X)))
(tstcs (map
(lambda (s p) (ly:stencil-translate s (cons (- common-center) (* ssp 0.5 p))))
stcs pos)))
(apply ly:stencil-add tstcs)))
% Create a "tuning key signature" whenever tuning changes
#(define (tab-staff-string-tuning-key-engraver context)
(let ((current-tuning #f))
(make-engraver
((process-music engraver)
(let ((tuning (ly:context-property context 'stringTunings)))
(if (not (equal? tuning current-tuning))
(let* ((mark (ly:engraver-make-grob engraver 'KeySignature '())))
(ly:grob-set-nested-property! mark '(details string-tuning) tuning)
(ly:grob-set-property! mark 'stencil key-signature-interface::tuning-column-print)
(set! current-tuning tuning))))))))
% Print a column of all tunings. Optional argument str-nos specifies tho 0 indexed string numbers.
% Keyword arg show-change specifies if only the tuning should be printed or also the change from
% previous tuning.
#(define* (tuning-column::full-formatter
tuning
#:optional (old-tuning #f) (str-nos #f)
#:key (show-change #f))
(if (not str-nos)
(set! str-nos (iota (length tuning))))
(let ((mup
(map
(lambda (n o i)
#{
\markup {
\vcenter \circle \dynamic #(number->string (1+ i))
\hspace #0.3
\vcenter
#(if (or (equal? n o) (not show-change))
(note-name->markup n #f)
(make-concat-markup
(list (note-name->markup o #f)
"→"
(note-name->markup n #f))))
}
#})
tuning (if old-tuning old-tuning tuning) str-nos)))
(markup #:override '(baseline-skip . 3) #:fontsize -4 (make-column-markup mup))))
% Like tuning-column::full-formatter, but with show-change = #t
#(define* (tuning-column::full-formatter-change . args)
(apply tuning-column::full-formatter (append args (list #:show-change #t))))
% Like tuning-column::full-formatter, but only print strings with changed tuning
#(define* (tuning-column::diff-formatter tuning
#:optional (old-tuning #f) (str-nos #f)
#:key (show-change #f))
(if (not str-nos)
(set! str-nos (iota (length tuning))))
(if old-tuning
(let* ((triplets (map list tuning old-tuning str-nos))
(triplets (filter (lambda (x) (not (equal? (car x) (cadr x)))) triplets)))
(set! tuning (map car triplets))
(set! old-tuning (map cadr triplets))
(set! str-nos (map caddr triplets))))
(tuning-column::full-formatter tuning old-tuning str-nos #:show-change show-change))
% Like tuning-column::diff-formatter, but with show-change = #t
#(define* (tuning-column::diff-formatter-change . args)
(apply tuning-column::diff-formatter (append args (list #:show-change #t))))
% Set default formatter to diff with change. Add tuning columns to Staff and TabStaff.
% Add tuning key to TabStaff
\layout {
\context {
\Score
stringTuningColumnFormatter = #tuning-column::diff-formatter-change
}
\context {
\Staff
\consists #string-tuning-engraver
}
\context {
\TabStaff
\consists #string-tuning-engraver
\consists #tab-staff-string-tuning-key-engraver
\override KeySignature.font-size = #-4
\override KeySignature.break-visibility = #all-visible
}
}
%%%%%%%%% EXAMPLE %%%%%%%%%%
\layout {
\revert TabStaff.TimeSignature.stencil
}
\paper {
ragged-right = ##t
}
music = {
<c c'>4 4 4 4
\set Staff.stringTunings = \stringTuning <e, ais, d g c' e'>
<c c'>4 <c c'>4
\set Staff.stringTunings = \stringTuning <e, a, d g b e'>
<c c'>4 4
\break
\set Staff.stringTunings = \stringTuning <e, ais, d g c' e'>
<c c'>4 4 4 4
}
<<
\new Staff \with {
stringTuningColumnFormatter = #tuning-column::full-formatter
\clef "treble_8"
} \music
\new Staff \with {
stringTuningColumnFormatter = #tuning-column::full-formatter-change
\clef "treble_8"
} \music
\new Staff \with {
stringTuningColumnFormatter = #tuning-column::diff-formatter
\clef "treble_8"
} \music
\new Staff \with {
stringTuningColumnFormatter = #tuning-column::diff-formatter-change
\clef "treble_8"
} \music
\new TabStaff \music
>>
signature.asc
Description: This is a digitally signed message part.
