Hello Harm, I just started playing around with this but it’s obviously a huge improvement. Thanks a lot for nailing yet another one of my nagging Lilypond issues!
Best, Edward --- Dr. Edward Neeman www.neemanpianoduo.com > On 22 Jul 2018, at 8:04 pm, Thomas Morley <[email protected]> wrote: > > 2018-07-22 6:30 GMT+02:00 Edward Neeman <[email protected]>: >> Hello, >> >> This snippet produces very nice slashed grace note beams: >> http://lsr.di.unimi.it/LSR/Snippet?id=721 >> >> However the slashes don’t adjust properly for smaller staves that are >> tweaked with the \magnifyStaff function. In the example below, the slash on >> the second (smaller) staff is too high and too long. How might I change the >> function to accommodate the \magnifyStaff value? >> >> Thanks, >> Edward >> >> \version "2.19.80" >> >> slash = >> #(define-music-function (ang stem-fraction protrusion) >> (number? number? number?) >> (remove-grace-property 'Voice 'Stem 'direction) ; necessary? >> #{ >> \once \override Stem #'stencil = >> #(lambda (grob) >> (let* ((X-parent (ly:grob-parent grob X)) >> (is-rest? (ly:grob? (ly:grob-object X-parent 'rest)))) >> (if is-rest? >> empty-stencil >> (let* ((ang (degrees->radians ang)) >> ; We need the beam and its slope so that slash will >> ; extend uniformly past the stem and the beam >> (beam (ly:grob-object grob 'beam)) >> (beam-X-pos (ly:grob-property beam 'X-positions)) >> (beam-Y-pos (ly:grob-property beam 'positions)) >> (beam-slope (/ (- (cdr beam-Y-pos) (car beam-Y-pos)) >> (- (cdr beam-X-pos) (car beam-X-pos)))) >> (beam-angle (atan beam-slope)) >> (stem-Y-ext (ly:grob-extent grob grob Y)) >> ; Stem.length is expressed in half staff-spaces >> (stem-length (/ (ly:grob-property grob 'length) 2.0)) >> (dir (ly:grob-property grob 'direction)) >> ; if stem points up. car represents segment of stem >> ; closest to notehead; if down, cdr does >> (stem-ref (if (= dir 1) (car stem-Y-ext) (cdr >> stem-Y-ext))) >> (stem-segment (* stem-length stem-fraction)) >> ; Where does slash cross the stem? >> (slash-stem-Y (+ stem-ref (* dir stem-segment))) >> ; These are values for the portion of the slash that >> ; intersects the beamed group. >> (dx (/ (- stem-length stem-segment) >> (- (tan ang) (* dir beam-slope)))) >> (dy (* (tan ang) dx)) >> ; Now, we add in the wings >> (protrusion-dx (* (cos ang) protrusion)) >> (protrusion-dy (* (sin ang) protrusion)) >> (x1 (- protrusion-dx)) >> (y1 (- slash-stem-Y (* dir protrusion-dy))) >> (x2 (+ dx protrusion-dx)) >> (y2 (+ slash-stem-Y >> (* dir (+ dy protrusion-dy)))) >> (th (ly:staff-symbol-line-thickness grob)) >> (stil (ly:stem::print grob))) >> >> (ly:stencil-add >> stil >> (make-line-stencil th x1 y1 x2 y2)))))) >> #}) >> >> slashI = { >> \slash 50 0.6 1.0 >> } >> >> << >> \new Staff { \grace { \slashI b''8[ c'''] } c'' } >> \new Staff \with { \magnifyStaff #2/3 } { \grace { \slashI b''8[ c'''] } >> c'' } >>>> >> >> --- >> Dr. Edward Neeman >> www.neemanpianoduo.com > > > Hi, > > the LSR-snippet does not take the changed staff-space into account, > thus the calculations are wrong, if staff-space isn't default. > The used trigonomitrcs makes it even harder to debug: Simply applying > the changed staff-space to the found x1/2 y1/2 values will not > succeed. > > Further more I was always dissatisfied, because no automatic slashed > beams were possible. > > Over the years I repeatedly tried different approaches and erlier this > year I've finally found something more satisfying. > > It overrides Beam not Stem. > > No trogonometrics. > > Several adjustments are possible by overriding sub-properties of > Beam.details. Here the defaults as overrides: > %% defaults: > %% \override Beam.details.attach-side = #'left > %% \override Beam.details.stem-part = 1 > %% \override Beam.details.slash-gradient = 1/2 > %% \override Beam.details.slash-x-y-over-shoot = #'(0.3 . 0.8) > %% \override Beam.details.slash-thickness = 0.1 > They suited me well in an own project, though for Beams of 8th-notes > the slash may collide with the NoteHead. > I always found Stems of 8th-notes are too often at minimum size in > LilyPond in general. For adding a slash this means there is (too) > little space. > It's one of the TODOs: automatic adjust slash-placement depending on > the duration. > For the examples below I therefore used modified values. > The other TODO is 'attach-side 'right. Atm it's buggy, it is possible > to adjust the other details sub-properties to get a nice output, but > not out-of-the-box. > > > But here the code with your example, additionally I included the LSR-examples. > > > > \version "2.19.82" > > %% c/p from lily-library.scm (it is not public) > #(define (sign x) > (if (= x 0) > 0 > (if (< x 0) -1 1))) > > #(define (slashed-beam beam-stil) > (lambda (grob) > (let* ((orig-grob (ly:grob-original grob)) > (broken-beams (ly:spanner-broken-into orig-grob)) > (beam-stil-x-ext (ly:stencil-extent beam-stil X)) > (side > (assoc-get 'attach-side (ly:grob-property grob 'details) 'left)) > ;; which side? > (on-left? (eq? side 'left)) > ;; get beam direction, can be found by examining stem direction. > (stems (ly:grob-object grob 'stems)) > ;; on the left, use the first stem. on the right, use last stem. > ;; this allows the function to work with kneed beams as well. > (stem > (if on-left? > (ly:grob-array-ref stems 0) > (ly:grob-array-ref stems (1- (ly:grob-array-length stems))))) > (stem-dir (ly:grob-property stem 'direction #f)) > (beam-X-pos (ly:grob-property grob 'X-positions)) > (beam-Y-pos (ly:grob-property grob 'positions)) > (beam-start-y (car beam-Y-pos)) > (beam-end-y (cdr beam-Y-pos)) > (beam-gradient > (/ (- beam-end-y beam-start-y) > (interval-length beam-X-pos))) > (beam-slope > (* stem-dir (sign (- (abs beam-end-y) (abs beam-start-y))))) > (relevant-beam-y > (if on-left? > beam-start-y > beam-end-y)) > (beam-thick (ly:grob-property grob 'beam-thickness)) > (half-beam-thick (/ beam-thick 2)) > (length-fraction (ly:grob-property grob 'length-fraction 1)) > (stem-part > (assoc-get 'stem-part (ly:grob-property grob 'details) 1)) > (slash-thick > (assoc-get > 'slash-thickness > (ly:grob-property grob 'details) > (ly:output-def-lookup > (ly:grob-layout grob) > 'line-thickness > 0.1))) > (slash-gradient > (assoc-get > 'slash-gradient > (ly:grob-property grob 'details) > (cons 1 2))) > (slash-gradient-fraction > (/ (cdr slash-gradient) (car slash-gradient))) > (slash-x-y-over-shoot > (assoc-get > 'slash-x-y-over-shoot > (ly:grob-property grob 'details) > '(0.3 . 0.8))) > (stick-out-x (car slash-x-y-over-shoot)) > (stick-out-y (cdr slash-x-y-over-shoot)) > ;; We first construct a line starting at the relevant stem, ending > ;; in the middle of the beam, relying on an appropriate move in > ;; y-direction, ensured by `stem-y' > (stem-y > (- relevant-beam-y (* length-fraction stem-part stem-dir))) > ;; Get a x-value, where the slash will match the beam > (inner-x > (if on-left? > (/ (* -1 length-fraction stem-part stem-dir) > (- beam-gradient (* stem-dir slash-gradient-fraction))) > (/ (* length-fraction stem-part stem-dir) > (+ beam-gradient (* stem-dir slash-gradient-fraction))))) > ;; We ensure a constant gap between the end-point of the slash and > ;; the beam, by transforming the given `stick-out-y' into a value > ;; which is added to `inner-x' later. > (add-x > (if (or (and (> stem-dir 0) on-left?) > (and (<= stem-dir 0) (not on-left?))) > (/ stick-out-y (- slash-gradient-fraction beam-gradient)) > (/ stick-out-y (+ slash-gradient-fraction beam-gradient)))) > ;; To get the slash sticking out to the left, apply `stick-out-x' > ;; to the starting x-value and apply `slash-gradient-fraction' to > the > ;; starting y-value. > (slash-start-x > (if on-left? > (- (car beam-stil-x-ext) stick-out-x) > (+ (cdr beam-stil-x-ext) stick-out-x))) > (slash-start-y > (+ stem-y > (* > stem-dir > (- (+ half-beam-thick stick-out-x)) > slash-gradient-fraction))) > (slash-end-x > (if on-left? > (+ inner-x add-x) > (- (cdr beam-stil-x-ext) (+ inner-x add-x)))) > (slash-end-y > (+ stem-y > (* stem-dir (+ inner-x add-x) slash-gradient-fraction))) > (staff-space (ly:staff-symbol-staff-space grob))) > (ly:stencil-add > beam-stil > (if (or (not (pair? broken-beams)) > (equal? grob (car broken-beams))) > ;; for debugging purposes we let the color in place, commented > ;(stencil-with-color > (make-line-stencil > ;; thick > slash-thick > ;; start-coords > (* staff-space slash-start-x) > (* staff-space slash-start-y) > ;; end-coords > (* staff-space slash-end-x) > (* staff-space slash-end-y)) > ; red) > empty-stencil))))) > > slashedBeam = > \override Beam.stencil = > #(lambda (grob) > ;; TODO > ;; this will catch the default-stencil, to get an already tweaked > ;; stencil call (ly:grob-property grob 'stencil) and apply it > ;; and set the stencil 'after-line-breaking. > (slashed-beam (ly:beam::print grob))) > > startAcciaccaturaMusic = { > <>\startGraceSlur > \temporary \override Flag.stroke-style = #"grace" > \temporary \slashedBeam > } > > stopAcciaccaturaMusic = { > \revert Flag.stroke-style > \revert Beam.stencil > <>\stopGraceSlur > } > > %%%%%%%%%%%%%%%%%%%%%% > %% EXAMPLES > %%%%%%%%%%%%%%%%%%%%%% > > \layout { > \override Beam.details.stem-part = 0.8 > \override Beam.details.slash-gradient = 2/3 > \override Beam.details.slash-x-y-over-shoot = #'(0.3 . 0.6) > } > > << > \new Staff > { > \grace { \slashedBeam b''8[ c'''] } c'' > } > \new Staff > \with { \magnifyStaff #2/3 } > { > \grace { \slashedBeam b''8[ c'''] } c'' > } >>> > > %% Examples from http://lsr.di.unimi.it/LSR/Snippet?id=721 > %% \magnifyStaff #2/3 always applied > > \new Staff \with { \magnifyStaff #2/3 } { > \relative c' { > \acciaccatura { d8[ e f g] } d4 > \acciaccatura { g8[ a b c] } d4 > \acciaccatura { g8[ a b c] } d4 > \acciaccatura { g8[ a b c ] } d4 > \clef bass > \acciaccatura { d,,,8[ c b a ] } g4 > \acciaccatura { d8[ c b a ] } g4 > \acciaccatura { d8[ c b a ] } g4 > \acciaccatura { d8[ c b a ] } g4 > } > } > > \new Staff \with { \magnifyStaff #2/3 } { > \relative c'' { > \acciaccatura { > dis32[ e, a' bes, cis, d' ] > } > es,4 > } > } > > \new PianoStaff << > \new Staff = "1" \with { \magnifyStaff #2/3 } { > s1*0 > \grace { > \slashedBeam > \stemDown > a'''16[ > \change Staff = "2" > \stemUp > bes, > \change Staff = "1" > \stemDown > fis''16 > \change Staff = "2" > \stemUp > g] > } > \change Staff = "1" > es'4 > } > \new Staff = "2" \with { \magnifyStaff #2/3 } { > \clef bass > \grace s4 > s4 > } >>> > > > I've used this in a large own project, so I think it's pretty robust. > > > HTH, > harm _______________________________________________ lilypond-user mailing list [email protected] https://lists.gnu.org/mailman/listinfo/lilypond-user
