2015-12-19 23:43 GMT+01:00 Kieren MacMillan <kieren_macmil...@sympatico.ca>:

> Hello all,
>
> The final line of the song I’m currently engraving looks like this:
>
> Questions:
>
> 1. How could I [best?] code this so that the OttavaBracket starts close to
> the top of the staff at the beginning of m. 31 (the Ab), angles upward at
> the third quarter of m. 33 (the Db), and then flattens out again for the
> last two triplet-eighths (the high Bb)?
>
> 2. Can this kind of “multi-segment” OttavaBracket (or, more generally,
> spanner) be automated and/or sugar-i-fied?
>
> Thanks for any hints/links/help,
> Kieren.
> <https://lists.gnu.org/mailman/listinfo/lilypond-user>
>

Hi Kieren,

you don't provide any code ;)
And I really dislike inline-images.

That said, it's not that easy ...
Below some code, which hopefully does what you want, though it's a quite
terrible user-interface, if one can call it so at all.
Every layout-change will likely result in the need of readjusting...
At least it works.

It would be far simpler if one could add an option to make-path-stencil to
draw dashed lines. Like pure postscript in the following markup-example:

\markup
  \postscript
    #"
     [0.5 0.5] 0.1 setdash
     0 0 moveto
     3 0 lineto
     5 3 lineto
     7 3 lineto
     7 2 lineto
     stroke
    "

But I found no way to do so. Thus I defined `make-dashed-line-stencil' and
`make-connected-dashed-line-stencil' first.
With `kneed-line' I try to give you a little easier to use code at hand,
but I'm really not convinced.

Anyway here the code:

\version "2.19.32"

#(define (make-dashed-line-stencil width startx starty endx endy)
"Make a dashed line stencil of given linewidth and set its extents
accordingly."
  (let ((xext (ordered-cons 0 (- endx startx)))
        (yext (ordered-cons 0 (- endy starty)))
        (x (- endx startx))
        (y (- endy starty)))
    (ly:make-stencil
      ;; the numerical values in the line below determine the appearance
      ;; of the dashes, the last one is the `phase', i.e. where to start
      ;; the dashed-line
      (list 'dashed-line  width 0.4 0.6 x y 0)
      ;; Since the line has rounded edges, we have to / can safely add half
the
      ;; width to all coordinates!
      (interval-widen xext (/ width 2))
      (interval-widen yext (/ width 2))
      ;xext
      ;yext
      )))

#(define (make-connected-dashed-line-stencil points-list thickness)
"Connect the given points with dashed-lines"

  (define (coords->listed-coords coords-list)
    (map
      (lambda (x y) (append x y))
      (cons (list 0 0) coords-list)
      coords-list))

  (let* ((coords (coords->listed-coords points-list)))
    (apply
      ly:stencil-add
      (map
        (lambda (coord x-move)
          (ly:stencil-translate
            (make-dashed-line-stencil
              thickness
              (car coord)
              (cadr coord)
              (caddr coord)
              (cadddr coord))
          (cons (car coord) (cadr coord))))
        coords
        (cons 0 (map car coords))))))

#(define ((kneed-line coords start-offset) grob)
"Create a (dashed) line for overriding @code{OttavaBracket.stencil} based
on a
list of @var{coords} in @code{(cons x y)} form.  @code{x} is the portion of
the
width consumed for a given line and @code{y} is the portion of the height.
For example, @code{'((0.3 . 0.7) (0.8 . 0.9) (1.0 . 1.0))} means that at
the
point where the hairpin has consumed 30% of its width, it must be at 70% of
its
height.  Once it is to 80% width, it must be at 90% height.  It finishes at
100% width and 100% height.
"
  (define (pair-to-list pair)
    (list (car pair) (cdr pair)))

  (define (normalize-coords goods x y)
    (map
     (lambda (coord)
       (cons (* x (car coord)) (* y (cdr coord))))
     goods))

  (define (my-c-p-s points thick)
    ;(make-connected-path-stencil
    ; points
    ; thick
    ; 1.0
    ; 1.0
    ; #f
    ; #f)
    (make-connected-dashed-line-stencil points thick)
    )
  ;; outer let to trigger suicide
  (let ;((sten (ly:line-spanner::print grob)))
       ((sten (ly:ottava-bracket::print grob)))
    (if (grob::is-live? grob)
        (let* ((thick (ly:grob-property grob 'thickness 1))
               (thick (* thick (layout-line-thickness grob)))
               (xex (ly:stencil-extent sten X))
               (lenx (- (interval-length xex) (car start-offset)))
               (yex (ly:stencil-extent sten Y))
               (leny (interval-length yex))
               (xtrans (car xex))
               (ytrans (car yex))
               (uplist (map pair-to-list
                            (normalize-coords coords lenx (/ leny 2)))))
          (ly:stencil-add
            (ly:stencil-translate
              (my-c-p-s uplist thick)
             (cons (+ xtrans (car start-offset)) (+ ytrans (cdr
start-offset))))
            (grob-interpret-markup grob (ly:grob-property grob 'text))))
        '())))

#(define (kneed-spanner buckles height start-offset)
  (kneed-line
    `((0 . 0)
      (,(car buckles) . 0)
      (,(cadr buckles) . ,height)
      (1 . ,height)
      (1 . ,(- height 1)))
    start-offset))

kneedSpanner =
#(define-music-function (parser location buckles height start-offset)
  (number-list? number? number-pair?)
"Returns a kneed dashed line, overriding @code{OttavaBracket.stencil}.
Relying on the settings of @code{kneed-spanner}
"
#{
  \override Staff.OttavaBracket.stencil =
    #(kneed-spanner buckles height start-offset)
  \override Staff.OttavaBracket.outside-staff-priority = ##f
#})

one = {
  \kneedSpanner #'(0.85 0.9) #3.5 #'(4.5 . 1.6)
  \key aes \major

  \ottava #1
  \tuplet 6/4 {
    \change Staff = "down" aes'8[
    \change Staff = "up" des'''
    \change Staff = "down" f''
    \change Staff = "up" bes''
    \change Staff = "down" ees''
    \change Staff = "up" aes''']~
  }
  aes'''4
  \tuplet 3/2 {
    \change Staff = "down" bes'8
    f''
    \change Staff = "up" des'''
  }
  \tuplet 6/4 {
    \change Staff = "down" b'8[
    \change Staff = "up" e'''
    \change Staff = "down" a''
    \change Staff = "up" dis'''
    \change Staff = "down" fis''
    \change Staff = "up" gis''']
  }
  cis''' a''' fis''' b'''
  \tuplet 6/4 {
    \change Staff = "down" des''8[
    \change Staff = "up" f'''!
    \change Staff = "down" aes''!
    \change Staff = "up" ees'''!
    \change Staff = "down" bes''
    \change Staff = "up" bes'''!]
  }
  \tuplet 6/4 {
    des'''![
    aes'''!
    des''''
    ees''''
    bes''''
    aes'''']~
  }
  aes''''1
  \bar "|."
}
<<
  \new Staff { \clef bass \key aes \major aes1~ aes4 r4 r2 R1*2 }
  \addlyrics { ress. __ }
  \new PianoStaff <<
    \new Staff = "up" { \tempo "Tempo Primo" 4=108 \one }
    \new Staff = "down" { \key aes \major s1 s2 r s r R1 }
  >>
>>


Nevertheless, hth,
  Harm
_______________________________________________
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to