1 % DO NOT EDIT this file manually; it is automatically
2 % generated from Documentation/snippets/new
3 % Make any changes in Documentation/snippets/new/
4 % and then run scripts/auxiliar/makelsr.py
6 % This file is in the public domain.
7 %% Note: this file works from version 2.15.35
11 %% Translation of GIT committish: 28097cf54698db364afeb75658e4c8e0e0ccd716
13 Le code ci-dessous illustre la manière de concevoir un graveur en
14 Scheme, ici chargé de connecter des hampes entre les portées. Nul n'est
15 besoin de spécifier la taille des hampes ; la fonction tient compte de
16 la distance relative des têtes de note avec les portées.
19 doctitlefr = "Graveur de hampes inter-portées"
21 lsrtags = "staff-notation, tweaks-and-overrides, contexts-and-engravers"
22 texidoc = "This file defines and demonstrates a scheme engraver that
23 connects stems across staves. The stem length need not be specified, as
24 the code takes care of the variable distance between noteheads and staves."
25 doctitle = "Stem cross staff engraver"
30 A new stem (referred to as span in the code) is created to connect the
31 original stems. The original stems are made transparent.
33 The span is created as a child of the "root" stem, that is the stem
34 connected to a notehead with the end that is not to be extended.
36 Both stem directions are supported. Connecting more than two stems is
40 % Values are close enough to ignore the difference
41 #(define (close-enough? x y)
42 (< (abs (- x y)) 0.0001))
44 % Combine a list of extents
45 #(define (extent-combine extents)
46 (if (pair? (cdr extents))
47 (interval-union (car extents) (extent-combine (cdr extents)))
50 % Check if the stem is connectable to the root
51 #(define ((stem-connectable? ref root) stem)
52 ; The root is always connectable to itself
55 ; Horizontal positions of the stems must be almost the same
56 (close-enough? (car (ly:grob-extent root ref X))
57 (car (ly:grob-extent stem ref X)))
58 ; The stem must be in the direction away from the root's notehead
59 (positive? (* (ly:grob-property root 'direction)
60 (- (car (ly:grob-extent stem ref Y))
61 (car (ly:grob-extent root ref Y))))))))
63 % Connect stems if we have at least one stems connectable to the root
64 #(define (stem-span-stencil span)
65 (let* ((system (ly:grob-system span))
66 (root (ly:grob-parent span X))
67 (stems (filter (stem-connectable? system root)
68 (ly:grob-object span 'stems))))
69 (if (<= 2 (length stems))
70 (let* ((yextents (map (lambda (st)
71 (ly:grob-extent st system Y)) stems))
72 (yextent (extent-combine yextents))
73 (layout (ly:grob-layout root))
74 (blot (ly:output-def-lookup layout 'blot-diameter)))
77 (set! (ly:grob-property st 'transparent) #t))
79 ; Draw a nice looking stem with rounded corners
80 (ly:round-filled-box (ly:grob-extent root root X) yextent blot))
81 ; Nothing to connect, don't draw the span
84 % Create a stem span as a child of the cross-staff stem (the root)
85 #(define ((make-stem-span! stems trans) root)
86 (let ((span (ly:engraver-make-grob trans 'Stem '())))
87 (ly:grob-set-parent! span X root)
88 (set! (ly:grob-object span 'stems) stems)
89 ; Suppress positioning, the stem code is confused by this weird stem
90 (set! (ly:grob-property span 'X-offset) 0)
91 (set! (ly:grob-property span 'stencil) stem-span-stencil)))
93 % Set cross-staff property of the stem to this function to connect it to
94 % other stems automatically
95 #(define (cross-staff-connect stem)
98 % Check if automatic connecting of the stem was requested. Stems connected
99 % to cross-staff beams are cross-staff, but they should not be connected to
100 % other stems just because of that.
101 #(define (stem-is-root? stem)
102 (eq? cross-staff-connect (ly:grob-property-data stem 'cross-staff)))
104 % Create stem spans for cross-staff stems
105 #(define (make-stem-spans! ctx stems trans)
106 ; Cannot do extensive checks here, just make sure there are at least
107 ; two stems at this musical moment
108 (if (<= 2 (length stems))
109 (let ((roots (filter stem-is-root? stems)))
110 (map (make-stem-span! stems trans) roots))))
112 % Connect cross-staff stems to the stems above in the system
113 #(define (Span_stem_engraver ctx)
116 ; Record all stems for the given moment
118 ((stem-interface trans grob source)
119 (set! stems (cons grob stems))))
120 ; Process stems and reset the stem list to empty
121 ((process-acknowledged trans)
122 (make-stem-spans! ctx stems trans)
126 #(define-music-function (parser location notes) (ly:music?) #{
127 \override Stem #'cross-staff = #cross-staff-connect
129 \revert Stem #'cross-staff
135 \consists #Span_stem_engraver
139 \parallelMusic #'(voiceA voiceB voiceC) {
140 % Bar 1 - durations, beams, flags
141 g'2 g'4 g'8 [ g'16 ] g'16 |
142 \crossStaff { c'2 c'4 c'8 [ c'16 ] c'16 } |
146 g'8 \stemDown g'8 \crossStaff g'8 \stemNeutral g'8 g'4 r4 |
147 \crossStaff { c'8 \stemDown c'8 } c'8 \stemNeutral c'8 r4 r4 |
148 c8 \stemDown c8 c8 \stemNeutral \crossStaff { c8 c4 c4 } |
150 % Bar 3 - multiple voice styles
151 << c''2 \\ \crossStaff d'2 \\ a'2 \\ \crossStaff f'2 >> g'2 |
152 << b'2 \\ c'2 \\ g'2 \\ e'2 >> << e'2 \\ \\ \crossStaff c'2 >> |
153 << \crossStaff b2 \\ c2 \\ \crossStaff g2 \\ e2 >> r2 |
155 % Bar 4 - grace notes
156 \grace g'8 a'2 \stemDown \crossStaff { \grace g'8 a'2 } \stemNeutral |
157 \grace c'8 d'2 \stemDown \grace c'8 d'2 \stemNeutral |
158 \crossStaff { \grace c8 d2 } \stemDown \grace c8 d2 \stemNeutral |
160 % Bar 5 - cross-staff beams
163 \crossStaff { c8 [ \change Staff=stafftwo c''8 ] }
164 \change Staff=staffthree c8 [ \change Staff=stafftwo c''8 ] r2 |
169 \new Staff = "staffone" <<
174 \new Staff = "stafftwo" <<
179 \new Staff = "staffthree" <<
181 \autoBeamOff \clef bass \voiceC