From: Pavel Roskin Date: Sun, 15 Apr 2012 15:52:38 +0000 (+0100) Subject: Doc: Example of Cross-staff stems X-Git-Tag: release/2.15.37-1~5 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=867fd6028e21718195d9903515371576af2c22c3;p=lilypond.git Doc: Example of Cross-staff stems Add an example of cross-staff stems Issue 2427 --- diff --git a/Documentation/snippets/changing-the-size-of-woodwind-diagrams.ly b/Documentation/snippets/changing-the-size-of-woodwind-diagrams.ly index 9fc2ae5e8d..0f239f50b6 100644 --- a/Documentation/snippets/changing-the-size-of-woodwind-diagrams.ly +++ b/Documentation/snippets/changing-the-size-of-woodwind-diagrams.ly @@ -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 diff --git a/Documentation/snippets/dynamics-custom-text-spanner-postfix.ly b/Documentation/snippets/dynamics-custom-text-spanner-postfix.ly index 4d313e95c3..74d36a9c5c 100644 --- a/Documentation/snippets/dynamics-custom-text-spanner-postfix.ly +++ b/Documentation/snippets/dynamics-custom-text-spanner-postfix.ly @@ -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 diff --git a/Documentation/snippets/dynamics-text-spanner-postfix.ly b/Documentation/snippets/dynamics-text-spanner-postfix.ly index 51a0c4420d..94a407fb5e 100644 --- a/Documentation/snippets/dynamics-text-spanner-postfix.ly +++ b/Documentation/snippets/dynamics-text-spanner-postfix.ly @@ -23,7 +23,6 @@ extensores de texto de forma predeterminada. " doctitlees = "Objetos extensores de texto postfijos para dinámica" - %% Translation of GIT committish: ab9e3136d78bfaf15cc6d77ed1975d252c3fe506 diff --git a/Documentation/snippets/formatting-lyrics-syllables.ly b/Documentation/snippets/formatting-lyrics-syllables.ly index bbd2c35c0b..487e6aa567 100644 --- a/Documentation/snippets/formatting-lyrics-syllables.ly +++ b/Documentation/snippets/formatting-lyrics-syllables.ly @@ -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. diff --git a/Documentation/snippets/graphical-and-text-woodwind-diagrams.ly b/Documentation/snippets/graphical-and-text-woodwind-diagrams.ly index 0eb43f4de1..6a70ea23d3 100644 --- a/Documentation/snippets/graphical-and-text-woodwind-diagrams.ly +++ b/Documentation/snippets/graphical-and-text-woodwind-diagrams.ly @@ -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é diff --git a/Documentation/snippets/hymn-template.ly b/Documentation/snippets/hymn-template.ly index 22af0c489a..a5f9d5e37a 100644 --- a/Documentation/snippets/hymn-template.ly +++ b/Documentation/snippets/hymn-template.ly @@ -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 index 0000000000..ba21195648 --- /dev/null +++ b/Documentation/snippets/new/stem-cross-staff-engraver.ly @@ -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 { } +} diff --git a/Documentation/snippets/partcombine-and-autobeamoff.ly b/Documentation/snippets/partcombine-and-autobeamoff.ly index d80d9abd2d..5820440506 100644 --- a/Documentation/snippets/partcombine-and-autobeamoff.ly +++ b/Documentation/snippets/partcombine-and-autobeamoff.ly @@ -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 index 0000000000..e04cae57b3 --- /dev/null +++ b/Documentation/snippets/stem-cross-staff-engraver.ly @@ -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 { } +} diff --git a/Documentation/snippets/woodwind-diagrams-listing.ly b/Documentation/snippets/woodwind-diagrams-listing.ly index 9e4830830a..b3cd25b6d4 100644 --- a/Documentation/snippets/woodwind-diagrams-listing.ly +++ b/Documentation/snippets/woodwind-diagrams-listing.ly @@ -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