]> git.donarmstrong.com Git - lilypond.git/commitdiff
Doc: Example of Cross-staff stems
authorPavel Roskin <proski@gnu.org>
Sun, 15 Apr 2012 15:52:38 +0000 (16:52 +0100)
committerJames Lowe <pkx166h@gmail.com>
Tue, 17 Apr 2012 21:04:31 +0000 (22:04 +0100)
Add an example of cross-staff stems

Issue 2427

Documentation/snippets/changing-the-size-of-woodwind-diagrams.ly
Documentation/snippets/dynamics-custom-text-spanner-postfix.ly
Documentation/snippets/dynamics-text-spanner-postfix.ly
Documentation/snippets/formatting-lyrics-syllables.ly
Documentation/snippets/graphical-and-text-woodwind-diagrams.ly
Documentation/snippets/hymn-template.ly
Documentation/snippets/new/stem-cross-staff-engraver.ly [new file with mode: 0644]
Documentation/snippets/partcombine-and-autobeamoff.ly
Documentation/snippets/stem-cross-staff-engraver.ly [new file with mode: 0644]
Documentation/snippets/woodwind-diagrams-listing.ly

index 9fc2ae5e8d45e93c64c852d8502d7cb796158a24..0f239f50b6ba817260cd2f625224c0ea398e893e 100644 (file)
@@ -19,7 +19,12 @@ posiciones para instrumentos de viento madera.
 "
 
   doctitlees = "Modificar el tamaño de los diagramas de viento madera"
+%%%    Translation of GIT committish: ab9e3136d78bfaf15cc6d77ed1975d252c3fe506
+
 
+  texidocde="
+Die Größe und Dicke der Holzbläserdiagramme kann geändert werden.
+"
 %%%    Translation of GIT committish: ab9e3136d78bfaf15cc6d77ed1975d252c3fe506
 
 
@@ -29,7 +34,6 @@ Die Größe und Dicke der Holzbläserdiagramme kann geändert werden.
 
   doctitlede = "Größe von Holzbläserdiagrammen ändern"
 
-
 %% Translation of GIT committish: 3b125956b08d27ef39cd48bfa3a2f1e1bb2ae8b4
   texidocfr = "
 La taille et l'épaisseur des diagrammes de doigté pour bois est modifiable
index 4d313e95c3feaae91ba099d6db175c2a544605c8..74d36a9c5c156b186c643f55de409b6e6cf8aaa1 100644 (file)
@@ -20,7 +20,6 @@ comienzo del eobjeto de extensión se asignará a la nota siguiente.
 "
 
   doctitlees = "Objeto personalizado de extensión de texto de matices dinámicos postfijo"
-
 %%   Translation of GIT committish: ab9e3136d78bfaf15cc6d77ed1975d252c3fe506
 
 
index 51a0c4420d897d1f3d65a718d1c1a7a03c0c880c..94a407fb5ea033fa60ae07d1781e5fd9c11d07e9 100644 (file)
@@ -23,7 +23,6 @@ extensores de texto de forma predeterminada.
 "
 
   doctitlees = "Objetos extensores de texto postfijos para dinámica"
-
 %%   Translation of GIT committish: ab9e3136d78bfaf15cc6d77ed1975d252c3fe506
 
 
index bbd2c35c0b5dca2a9b1245e076253d8dd56c337b..487e6aa567df2c57308376a4f59501424b1caaf9 100644 (file)
@@ -16,7 +16,6 @@ individuales dentro de la letra.
 
 "
   doctitlees = "Dar formato a sílabas de la letra"
-
 %%%    Translation of GIT committish: f86f00c1a8de0f034ba48506de2801c074bd5422
   texidocde = "
 Textbeschriftungsmodus kann eingesetzt werden, um individuelle Silben im Gesangstext
@@ -24,7 +23,6 @@ zu formatieren.
 
 "
   doctitlede = "Silben im Gesangstext formatieren"
-
 %%  Translation of GIT committish: d9d1da30361a0bcaea1ae058eb1bc8dd3a5b2e4c
   texidocfr = "
 Le mode markup permet d'individualiser la mise en forme de certaines syllabes.
index 0eb43f4de15df088c117da7cf937a1997ad6d1e3..6a70ea23d3dfa1aa558440003804a89fac60ed8a 100644 (file)
@@ -18,7 +18,15 @@ pueden presentar por el nombre de la llave así como de forma gráfica.
 "
 
   doctitlees = "Diagramas para viento madera gráficos y textuales"
+%%%    Translation of GIT committish: ab9e3136d78bfaf15cc6d77ed1975d252c3fe506
+
 
+  texidocde="
+In vielen Fällen können die nicht in der mittleren Reihe befindlichen
+Löcher dargestellt werden, indem man die Lochbezeichnung oder
+graphische Zeichen benutzt.
+
+"
 %%%    Translation of GIT committish: ab9e3136d78bfaf15cc6d77ed1975d252c3fe506
 
 
@@ -31,7 +39,6 @@ graphische Zeichen benutzt.
 
   doctitlede = "Graphische und Text-Holzbläserdiagramme"
 
-
 %% Translation of GIT committish: 496c48f1f2e4d345ae3637b2c38ec748a55cda1d
   texidocfr = "
 Dans certains cas, vous pouvez opter pour l'affichage textuel d'une clé
index 22af0c489af0e9943e8feda021b79a6c388aecb0..a5f9d5e37a20a80a5223ff06b412493d22c1c939 100644 (file)
@@ -27,7 +27,6 @@ strofe come testo separato sotto la musica.
 
 "
   doctitleit = "Modello per inno"
-
 %%    Translation of GIT committish: ab9e3136d78bfaf15cc6d77ed1975d252c3fe506
 
   texidocde = "
diff --git a/Documentation/snippets/new/stem-cross-staff-engraver.ly b/Documentation/snippets/new/stem-cross-staff-engraver.ly
new file mode 100644 (file)
index 0000000..ba21195
--- /dev/null
@@ -0,0 +1,168 @@
+\version "2.15.35"
+
+\header {
+  lsrtags = "staff-notation, tweaks-and-overrides, contexts-and-engravers"
+  texidoc = "This file defines and demonstrates a scheme engraver that
+connects stems across staves.  The stem length need not be specified, as
+the code takes care of the variable distance between noteheads and staves."
+  doctitle = "Stem cross staff engraver"
+}
+
+%{
+  A new stem (referred to as span in the code) is created to connect the
+  original stems.  The original stems are made transparent.
+
+  The span is created as a child of the "root" stem, that is the stem
+  connected to a notehead with the end that is not to be extended.
+
+  Both stem directions are supported.  Connecting more than two stems is
+  possible.
+%}
+
+% Values are close enough to ignore the difference
+#(define (close-enough? x y)
+   (< (abs (- x y)) 0.0001))
+
+% Combine a list of extents
+#(define (extent-combine extents)
+   (if (pair? (cdr extents))
+       (interval-union (car extents) (extent-combine (cdr extents)))
+       (car extents)))
+
+% Check if the stem is connectable to the root
+#(define ((stem-connectable? ref root) stem)
+   ; The root is always connectable to itself
+   (or (eq? root stem)
+       (and
+        ; Horizontal positions of the stems must be almost the same
+        (close-enough? (car (ly:grob-extent root ref X))
+          (car (ly:grob-extent stem ref X)))
+        ; The stem must be in the direction away from the root's notehead
+        (positive? (* (ly:grob-property root 'direction)
+                     (- (car (ly:grob-extent stem ref Y))
+                       (car (ly:grob-extent root ref Y))))))))
+
+% Connect stems if we have at least one stems connectable to the root
+#(define (stem-span-stencil span)
+   (let* ((system (ly:grob-system span))
+          (root (ly:grob-parent span X))
+          (stems (filter (stem-connectable? system root)
+                         (ly:grob-object span 'stems))))
+     (if (<= 2 (length stems))
+         (let* ((yextents (map (lambda (st)
+                                 (ly:grob-extent st system Y)) stems))
+                (yextent (extent-combine yextents))
+                (layout (ly:grob-layout root))
+                (blot (ly:output-def-lookup layout 'blot-diameter)))
+           ; Hide spanned stems
+           (map (lambda (st)
+                  (set! (ly:grob-property st 'transparent) #t))
+             stems)
+           ; Draw a nice looking stem with rounded corners
+           (ly:round-filled-box (ly:grob-extent root root X) yextent blot))
+         ; Nothing to connect, don't draw the span
+         #f)))
+
+% Create a stem span as a child of the cross-staff stem (the root)
+#(define ((make-stem-span! stems trans) root)
+   (let ((span (ly:engraver-make-grob trans 'Stem '())))
+     (ly:grob-set-parent! span X root)
+     (set! (ly:grob-object span 'stems) stems)
+     ; Suppress positioning, the stem code is confused by this weird stem
+     (set! (ly:grob-property span 'X-offset) 0)
+     (set! (ly:grob-property span 'stencil) stem-span-stencil)))
+
+% Set cross-staff property of the stem to this function to connect it to
+% other stems automatically
+#(define (cross-staff-connect stem)
+   #t)
+
+% Check if automatic connecting of the stem was requested.  Stems connected
+% to cross-staff beams are cross-staff, but they should not be connected to
+% other stems just because of that.
+#(define (stem-is-root? stem)
+   (eq? cross-staff-connect (ly:grob-property-data stem 'cross-staff)))
+
+% Create stem spans for cross-staff stems
+#(define (make-stem-spans! ctx stems trans)
+   ; Cannot do extensive checks here, just make sure there are at least
+   ; two stems at this musical moment
+   (if (<= 2 (length stems))
+       (let ((roots (filter stem-is-root? stems)))
+         (map (make-stem-span! stems trans) roots))))
+
+% Connect cross-staff stems to the stems above in the system
+#(define (Span_stem_engraver ctx)
+   (let ((stems '()))
+     (make-engraver
+      ; Record all stems for the given moment
+      (acknowledgers
+       ((stem-interface trans grob source)
+        (set! stems (cons grob stems))))
+      ; Process stems and reset the stem list to empty
+      ((process-acknowledged trans)
+       (make-stem-spans! ctx stems trans)
+       (set! stems '())))))
+
+crossStaff =
+#(define-music-function (parser location notes) (ly:music?) #{
+  \override Stem #'cross-staff = #cross-staff-connect
+  $notes
+  \revert Stem #'cross-staff
+#})
+
+\layout {
+  \context {
+    \StaffGroup
+    \consists #Span_stem_engraver
+  }
+}
+
+\parallelMusic #'(voiceA voiceB voiceC) {
+  % Bar 1 - durations, beams, flags
+  g'2 g'4 g'8 [ g'16 ] g'16 |
+  \crossStaff { c'2 c'4 c'8 [ c'16 ] c'16 } |
+  R1 |
+
+  % Bar 2 - direction
+  g'8 \stemDown g'8 \crossStaff g'8 \stemNeutral g'8 g'4 r4 |
+  \crossStaff { c'8 \stemDown c'8 } c'8 \stemNeutral c'8 r4 r4 |
+  c8 \stemDown c8 c8 \stemNeutral \crossStaff { c8 c4 c4 } |
+
+  % Bar 3 - multiple voice styles
+  << c''2 \\ \crossStaff d'2 \\ a'2 \\ \crossStaff f'2 >> g'2 |
+  << b'2 \\ c'2 \\ g'2 \\ e'2 >> << e'2 \\ \\ \crossStaff c'2 >> |
+  << \crossStaff b2 \\ c2 \\ \crossStaff g2 \\ e2 >> r2 |
+
+  % Bar 4 - grace notes
+  \grace g'8 a'2 \stemDown \crossStaff { \grace g'8 a'2 } \stemNeutral |
+  \grace c'8 d'2 \stemDown \grace c'8 d'2 \stemNeutral |
+  \crossStaff { \grace c8 d2 } \stemDown \grace c8 d2 \stemNeutral |
+
+  % Bar 5 - cross-staff beams
+  g'8 g'8 g'8 g'8 r2 |
+  s1 |
+  \crossStaff { c8 [ \change Staff=stafftwo c''8 ] }
+    \change Staff=staffthree c8 [ \change Staff=stafftwo c''8 ] r2 |
+}
+
+\score {
+  \new StaffGroup <<
+    \new Staff = "staffone" <<
+      \new Voice {
+        \autoBeamOff \voiceA
+      }
+    >>
+    \new Staff = "stafftwo" <<
+      \new Voice {
+        \autoBeamOff \voiceB
+      }
+    >>
+    \new Staff = "staffthree" <<
+      \new Voice {
+        \autoBeamOff \clef bass \voiceC
+      }
+    >>
+  >>
+  \layout { }
+}
index d80d9abd2d1d73cfdf4e412d0cac047531bb2142..5820440506c93532f73b6742db05f9d7d2fb428d 100644 (file)
@@ -47,7 +47,6 @@ necesario hacer tres llamadas a @code{\\autoBeamOff}.
 
 "
   doctitlees = "Partcombine y autoBeamOff"
-
 %%   Translation of GIT committish: ab9e3136d78bfaf15cc6d77ed1975d252c3fe506
 
   texidocde = "
@@ -79,7 +78,6 @@ wenn man es mit @code{\\partcombine} verwendet, muss @code{\\autoBeamOff}
 "
 doctitlede = "Partcombine und autoBeamOff"
 
-
 %% Translation of GIT committish: 3b125956b08d27ef39cd48bfa3a2f1e1bb2ae8b4
   texidocfr = "
 La fonction @code{\\autoBeamOff} dans le cadre d'un
diff --git a/Documentation/snippets/stem-cross-staff-engraver.ly b/Documentation/snippets/stem-cross-staff-engraver.ly
new file mode 100644 (file)
index 0000000..e04cae5
--- /dev/null
@@ -0,0 +1,176 @@
+% DO NOT EDIT this file manually; it is automatically
+% generated from Documentation/snippets/new
+% Make any changes in Documentation/snippets/new/
+% and then run scripts/auxiliar/makelsr.py
+%
+% This file is in the public domain.
+%% Note: this file works from version 2.15.35
+\version "2.15.35"
+
+\header {
+  lsrtags = "staff-notation, tweaks-and-overrides, contexts-and-engravers"
+  texidoc = "This file defines and demonstrates a scheme engraver that
+connects stems across staves.  The stem length need not be specified, as
+the code takes care of the variable distance between noteheads and staves."
+  doctitle = "Stem cross staff engraver"
+} % begin verbatim
+
+
+%{
+  A new stem (referred to as span in the code) is created to connect the
+  original stems.  The original stems are made transparent.
+
+  The span is created as a child of the "root" stem, that is the stem
+  connected to a notehead with the end that is not to be extended.
+
+  Both stem directions are supported.  Connecting more than two stems is
+  possible.
+%}
+
+% Values are close enough to ignore the difference
+#(define (close-enough? x y)
+   (< (abs (- x y)) 0.0001))
+
+% Combine a list of extents
+#(define (extent-combine extents)
+   (if (pair? (cdr extents))
+       (interval-union (car extents) (extent-combine (cdr extents)))
+       (car extents)))
+
+% Check if the stem is connectable to the root
+#(define ((stem-connectable? ref root) stem)
+   ; The root is always connectable to itself
+   (or (eq? root stem)
+       (and
+        ; Horizontal positions of the stems must be almost the same
+        (close-enough? (car (ly:grob-extent root ref X))
+          (car (ly:grob-extent stem ref X)))
+        ; The stem must be in the direction away from the root's notehead
+        (positive? (* (ly:grob-property root 'direction)
+                     (- (car (ly:grob-extent stem ref Y))
+                       (car (ly:grob-extent root ref Y))))))))
+
+% Connect stems if we have at least one stems connectable to the root
+#(define (stem-span-stencil span)
+   (let* ((system (ly:grob-system span))
+          (root (ly:grob-parent span X))
+          (stems (filter (stem-connectable? system root)
+                         (ly:grob-object span 'stems))))
+     (if (<= 2 (length stems))
+         (let* ((yextents (map (lambda (st)
+                                 (ly:grob-extent st system Y)) stems))
+                (yextent (extent-combine yextents))
+                (layout (ly:grob-layout root))
+                (blot (ly:output-def-lookup layout 'blot-diameter)))
+           ; Hide spanned stems
+           (map (lambda (st)
+                  (set! (ly:grob-property st 'transparent) #t))
+             stems)
+           ; Draw a nice looking stem with rounded corners
+           (ly:round-filled-box (ly:grob-extent root root X) yextent blot))
+         ; Nothing to connect, don't draw the span
+         #f)))
+
+% Create a stem span as a child of the cross-staff stem (the root)
+#(define ((make-stem-span! stems trans) root)
+   (let ((span (ly:engraver-make-grob trans 'Stem '())))
+     (ly:grob-set-parent! span X root)
+     (set! (ly:grob-object span 'stems) stems)
+     ; Suppress positioning, the stem code is confused by this weird stem
+     (set! (ly:grob-property span 'X-offset) 0)
+     (set! (ly:grob-property span 'stencil) stem-span-stencil)))
+
+% Set cross-staff property of the stem to this function to connect it to
+% other stems automatically
+#(define (cross-staff-connect stem)
+   #t)
+
+% Check if automatic connecting of the stem was requested.  Stems connected
+% to cross-staff beams are cross-staff, but they should not be connected to
+% other stems just because of that.
+#(define (stem-is-root? stem)
+   (eq? cross-staff-connect (ly:grob-property-data stem 'cross-staff)))
+
+% Create stem spans for cross-staff stems
+#(define (make-stem-spans! ctx stems trans)
+   ; Cannot do extensive checks here, just make sure there are at least
+   ; two stems at this musical moment
+   (if (<= 2 (length stems))
+       (let ((roots (filter stem-is-root? stems)))
+         (map (make-stem-span! stems trans) roots))))
+
+% Connect cross-staff stems to the stems above in the system
+#(define (Span_stem_engraver ctx)
+   (let ((stems '()))
+     (make-engraver
+      ; Record all stems for the given moment
+      (acknowledgers
+       ((stem-interface trans grob source)
+        (set! stems (cons grob stems))))
+      ; Process stems and reset the stem list to empty
+      ((process-acknowledged trans)
+       (make-stem-spans! ctx stems trans)
+       (set! stems '())))))
+
+crossStaff =
+#(define-music-function (parser location notes) (ly:music?) #{
+  \override Stem #'cross-staff = #cross-staff-connect
+  $notes
+  \revert Stem #'cross-staff
+#})
+
+\layout {
+  \context {
+    \StaffGroup
+    \consists #Span_stem_engraver
+  }
+}
+
+\parallelMusic #'(voiceA voiceB voiceC) {
+  % Bar 1 - durations, beams, flags
+  g'2 g'4 g'8 [ g'16 ] g'16 |
+  \crossStaff { c'2 c'4 c'8 [ c'16 ] c'16 } |
+  R1 |
+
+  % Bar 2 - direction
+  g'8 \stemDown g'8 \crossStaff g'8 \stemNeutral g'8 g'4 r4 |
+  \crossStaff { c'8 \stemDown c'8 } c'8 \stemNeutral c'8 r4 r4 |
+  c8 \stemDown c8 c8 \stemNeutral \crossStaff { c8 c4 c4 } |
+
+  % Bar 3 - multiple voice styles
+  << c''2 \\ \crossStaff d'2 \\ a'2 \\ \crossStaff f'2 >> g'2 |
+  << b'2 \\ c'2 \\ g'2 \\ e'2 >> << e'2 \\ \\ \crossStaff c'2 >> |
+  << \crossStaff b2 \\ c2 \\ \crossStaff g2 \\ e2 >> r2 |
+
+  % Bar 4 - grace notes
+  \grace g'8 a'2 \stemDown \crossStaff { \grace g'8 a'2 } \stemNeutral |
+  \grace c'8 d'2 \stemDown \grace c'8 d'2 \stemNeutral |
+  \crossStaff { \grace c8 d2 } \stemDown \grace c8 d2 \stemNeutral |
+
+  % Bar 5 - cross-staff beams
+  g'8 g'8 g'8 g'8 r2 |
+  s1 |
+  \crossStaff { c8 [ \change Staff=stafftwo c''8 ] }
+    \change Staff=staffthree c8 [ \change Staff=stafftwo c''8 ] r2 |
+}
+
+\score {
+  \new StaffGroup <<
+    \new Staff = "staffone" <<
+      \new Voice {
+        \autoBeamOff \voiceA
+      }
+    >>
+    \new Staff = "stafftwo" <<
+      \new Voice {
+        \autoBeamOff \voiceB
+      }
+    >>
+    \new Staff = "staffthree" <<
+      \new Voice {
+        \autoBeamOff \clef bass \voiceC
+      }
+    >>
+  >>
+  \layout { }
+}
index 9e4830830a360e2d550217db47ae59f48365ef24..b3cd25b6d45ef0b56dd836c6508da1e0445dc7b6 100644 (file)
@@ -17,7 +17,14 @@ el momento.
 
 "
   doctitlees = "Listado de los diagramas para viento madera"
+%%%    Translation of GIT committish: ab9e3136d78bfaf15cc6d77ed1975d252c3fe506
+
+
+  texidocde="
+Folgende Noten zeige alle Holzbläserdiagramme, die für LilyPond
+definiert sind.
 
+"
 %%%    Translation of GIT committish: ab9e3136d78bfaf15cc6d77ed1975d252c3fe506
 
 
@@ -28,7 +35,6 @@ definiert sind.
 "
   doctitlede = "Liste der Holzbläserdiagramme"
 
-
 %% Translation of GIT committish: 496c48f1f2e4d345ae3637b2c38ec748a55cda1d
   texidocfr = "
 Voici la liste des différents instruments à vent de la section des bois