Persistent accidentals
Appearance
Tired of having to remember where flats and sharps are supposed to go in your scores? Here's a solution: all accidentals are remembered and applied to subsequent natural pitches, until a natural gets forced.
This snippet shows two methods of achieving that: by using a music function, or with a Scheme engraver.
\version "2.24.0"
%% Contributed by V.V. on
%% https://lists.gnu.org/archive/html/lilypond-user/2020-05/msg00125.html
someMusic = \relative c' {
c des e fis g f e f! e d' g, d
}
%% Method 0: using a music function
persistentAccidentals =
#(define-music-function (music) (ly:music?)
(let ((alt-alist '())
(m (ly:music-deep-copy music)))
(music-map
(lambda (note)
(let ((pitch (ly:music-property note 'pitch))
(force? (ly:music-property note 'force-accidental)))
(if (ly:pitch? pitch)
(let* ((alt (ly:pitch-alteration pitch))
(n (ly:pitch-notename pitch))
(o (ly:pitch-octave pitch))
(mem-alt (assoc-get n alt-alist)))
(if (eq? force? #t)
(set! alt-alist
(assoc-remove! alt-alist n))
(if (= alt 0)
(if mem-alt
(ly:music-set-property!
note 'pitch
(ly:make-pitch o n mem-alt)))
(set! alt-alist
(assoc-set! alt-alist n alt))))))
note))
m)
m))
\persistentAccidentals \someMusic
%% Method 1: using a Scheme engraver.
#(define Persistent_accidentals_translator
(lambda (context)
(let ((alt-alist '()))
(make-engraver
(listeners
((note-event engraver event)
(let ((note (ly:prob-property event 'music-cause)))
(if (ly:music? note)
(let ((pitch (ly:music-property note 'pitch))
(force? (ly:music-property note 'force-accidental)))
(if (ly:pitch? pitch)
(let* ((alt (ly:pitch-alteration pitch))
(n (ly:pitch-notename pitch))
(o (ly:pitch-octave pitch))
(mem-alt (assoc-get n alt-alist)))
(if (eq? force? #t)
(set! alt-alist
(assoc-remove! alt-alist n))
(if (= alt 0)
(if mem-alt
(ly:music-set-property!
note 'pitch
(ly:make-pitch o n mem-alt)))
(set! alt-alist
(assoc-set! alt-alist n alt))))))
note)))))))))
\score {
\new Staff \someMusic
\layout {
\context {
\Voice
\consists #Persistent_accidentals_translator
}
}
}
%%%%