Accidental adjustments for single-voice polyphony: Difference between revisions
m Replace version="2.24.0" with version="2.24" now that the LilyWiki extension supports auto-selecting the latest release in a stable series |
m New category Tags: Mobile edit Mobile web edit |
||
| (2 intermediate revisions by the same user not shown) | |||
| Line 3: | Line 3: | ||
Unfortunately, these adjustments are quite complex. The Scheme code in this snippet provides a new engraver <code>custom_accidental_placement_engraver</code> that introduces a <code>details</code> subproperty flag called <code>capture</code> for the <code>Accidental</code> grob. If this flag is set, the current voice “captures” the accidental so that it is no longer aligned with the other accidentals in a note column. Together with other properties (<code>force-hshift</code> and <code>ignore-collision</code>) it is possible to achieve the desired result. | Unfortunately, these adjustments are quite complex. The Scheme code in this snippet provides a new engraver <code>custom_accidental_placement_engraver</code> that introduces a <code>details</code> subproperty flag called <code>capture</code> for the <code>Accidental</code> grob. If this flag is set, the current voice “captures” the accidental so that it is no longer aligned with the other accidentals in a note column. Together with other properties (<code>force-hshift</code> and <code>ignore-collision</code>) it is possible to achieve the desired result. | ||
<lilypond version="2.24" | <lilypond version="2.24"> | ||
% written 2023 by Valentin Petzel | % written 2023 by Valentin Petzel | ||
% | % | ||
| Line 32: | Line 32: | ||
(when (assoc-get 'capture (ly:grob-property grob 'details) #f) | (when (assoc-get 'capture (ly:grob-property grob 'details) #f) | ||
(when (not placement) | (when (not placement) | ||
(set! placement (ly:engraver-make-grob engraver | (set! placement | ||
(ly:engraver-make-grob engraver | |||
(ly:grob-set-parent! placement X | 'AccidentalPlacement '())) | ||
(ly:grob-set-parent! | |||
(let ((padding (ly:grob-property-data placement 'right-padding))) | placement X | ||
(ly:grob-parent (ly:grob-parent grob Y) X)) | |||
(let ((padding (ly:grob-property-data placement | |||
'right-padding))) | |||
(set! | (set! | ||
right-padding | right-padding | ||
| Line 43: | Line 46: | ||
((grobs (ly:grob-object grob 'accidental-grobs)) | ((grobs (ly:grob-object grob 'accidental-grobs)) | ||
(grobs (apply append (map cdr grobs))) | (grobs (apply append (map cdr grobs))) | ||
(heads (map (lambda (x) (ly:grob-parent x Y)) grobs)) | (heads (map (lambda (x) | ||
(stems (map (lambda (x) (ly:grob-object x 'stem)) heads)) | (ly:grob-parent x Y)) grobs)) | ||
(cols (map (lambda (x) (ly:grob-parent x X)) heads)) | (stems (map (lambda (x) | ||
(collisions (map (lambda (x) (ly:grob-parent x X)) cols)) | (ly:grob-object x 'stem)) heads)) | ||
(cols (map (lambda (x) | |||
(ly:grob-parent x X)) heads)) | |||
(collisions (map (lambda (x) | |||
(ly:grob-parent x X)) cols)) | |||
(cols2 | (cols2 | ||
(apply append | (apply append | ||
(map | (map | ||
(lambda (x) | (lambda (x) | ||
(grob-array->list (ly:grob-object | (grob-array->list (ly:grob-object | ||
| Line 79: | Line 86: | ||
offset)))))) | offset)))))) | ||
(let* ((src-placement (ly:grob-parent grob X)) | (let* ((src-placement (ly:grob-parent grob X)) | ||
(grobs (ly:grob-object src-placement 'accidental-grobs)) | (grobs (ly:grob-object src-placement | ||
(has-grob? (map (lambda (pair) (memq grob (cdr pair))) grobs)) | 'accidental-grobs)) | ||
(has-grob? (map (lambda (pair) | |||
(memq grob (cdr pair))) grobs)) | |||
(pair (list-ref grobs (which has-grob?))) | (pair (list-ref grobs (which has-grob?))) | ||
(notename (car pair)) | (notename (car pair)) | ||
(groblist (cdr pair)) | (groblist (cdr pair)) | ||
(new-grobs (ly:grob-object placement 'accidental-grobs)) | (new-grobs (ly:grob-object placement | ||
'accidental-grobs)) | |||
(new-groblist (assoc-get notename new-grobs '())) | (new-groblist (assoc-get notename new-grobs '())) | ||
(groblist (delete grob groblist eq?)) | (groblist (delete grob groblist eq?)) | ||
(new-groblist (cons grob new-groblist)) | (new-groblist (cons grob new-groblist)) | ||
(grobs (assoc-set! grobs notename groblist)) | (grobs (assoc-set! grobs notename groblist)) | ||
(new-grobs (assoc-set! new-grobs notename new-groblist))) | (new-grobs | ||
(assoc-set! new-grobs notename new-groblist))) | |||
(when (not (ly:grob-property | (when (not (ly:grob-property | ||
(ly:grob-parent (ly:grob-parent grob Y) X) | (ly:grob-parent (ly:grob-parent grob Y) X) | ||
'ignore-collision #f)) | 'ignore-collision #f)) | ||
(ly:grob-set-property! | |||
placement 'right-padding right-padding)) | |||
(ly:grob-set-object! src-placement 'accidental-grobs grobs) | (ly:grob-set-object! src-placement 'accidental-grobs grobs) | ||
(ly:grob-set-object! placement 'accidental-grobs new-grobs) | (ly:grob-set-object! placement 'accidental-grobs new-grobs) | ||
| Line 115: | Line 127: | ||
<< | << | ||
\new Staff { | \new Staff { | ||
<< | << | ||
\repeat unfold 4 { <b'! e''!>2. <c'' f''>4 } | \repeat unfold 4 { <b'! e''!>2. <c'' f''>4 } | ||
\\ | \\ | ||
| Line 170: | Line 182: | ||
} | } | ||
>> | >> | ||
</lilypond> | </lilypond> | ||
| Line 178: | Line 188: | ||
[[Category:Tweaks and overrides]] | [[Category:Tweaks and overrides]] | ||
[[Category:Workaround]] | [[Category:Workaround]] | ||
[[Category:Snippet]] | |||