Am 29.04.2012 00:26, schrieb David Nalesnik:
Hi Urs,

On Fri, Apr 27, 2012 at 6:05 PM, Urs Liska <li...@ursliska.de <mailto:li...@ursliska.de>> wrote:

    Am 27.04.2012 19 <tel:27.04.2012%2019>:30, schrieb David Nalesnik:
    Hi Urs,

    On Fri, Apr 27, 2012 at 11:46 AM, Urs Liska <li...@ursliska.de
    <mailto:li...@ursliska.de>> wrote:

        Hi David,

        thank you for now. I'll look into it.
        But isn't it very likely that I have to reshape a slur anyway
        when it changes from  broken to unbroken?
        In that case I'd even say the errors are a 'feature' so you
        notice it ...
        Provided it is documented enough not to drive you crazy ...


    Sure, that's true.  Presumably when you're looking for that fine
    control, you've settled on the layout in all but the tiny details!
    it's not only this. I think that with any slur that one might
    decide to shape manually a change in line break will spoil it
    anyway. So I'm not so sure it's a useful goal to make such a
    function fool-proof in this respect.
    Without the modification, though, the error would cause the file
    to fail and the error message is a little opaque.  (Well, it's
    quite exact, but it takes some study to figure out how it happened.)
    Well, the file fails (at least lilypond says so), but it actually
    compiles, it's only the function that isn't applied. But you're
    right to assume that the normal user can't cope with the error
    messages ;-)

    I could create a warning here, something like: "slur is not
    broken anymore".
    If that's possible in such functions, I'd find it very useful.
    Even better: tell the user: "The slur has now X parts, please
    adapt the function call"

    One thing you can do is
    \shapeSlur #'( ... list of offsets ...)
    or
    \shapeSlur #'(( ... list of offsets ...))

    without the file failing.

    Since this function has come up again, I wonder if I could get
    your (and other people's) opinion on syntax.  When I first wrote
    the offsetting function
    (http://lsr.dsi.unimi.it/LSR/Item?id=639)I
    <http://lsr.dsi.unimi.it/LSR/Item?id=639%29I> thought that alists
    were a bother to type.  But 'control-pojnts _is_ an alist '((x1 .
    y1) (x2 . y2) ... )) , so shouldn't we have something like this?

    \shapeSlur #'((dx1 . dy1) (dx2 . dy2) ...)

    I realize that there's more to type, but wouldn't this be clearer
    to use? (As well as being more consistent with how LilyPond
    represents this type of data)?
    First: I think this is a _very_ useful function that should even
    be made more widely known.


I'm very glad that you think so!


    Second: your syntax suggestion looks very good to me.
    Of course it is more to type. But that is more than outweighed by
    the advantages. it's easier to write and it's especially much
    easier to read. When changing the offsets (which you do multiple
    times until you get a good result ...) I'm always finding me
    counting params (in order to find the right item to change) which
    surely takes more time and concentration than typing (once) a few
    brackets and points.


Yes, I also find it very easy to make mistakes when typing in lists separated only by spaces. Trying out examples for the attached file, I was pleasantly surprised at how much easier-- and faster! -- it is to use the alist notation. Certainly, it is easier to read. Plus, I think it makes the offsetting function a bit less ugly.

    Third: I suggest to add support for PhrasingSlurs and Ties in
    order to make it more general. For PhrasingSlurs it's just a
    matter of writing a new entrance function, but for Ties you need
    new shape-ties and alter-tie-curve subroutines. See the attached
    file that is the result of an earlier enquiry on this mailing list.
    The functions themselves don't incorporate your newest additions
    (sorry, it's still a bit over my head), but you'll see what I mean.


One solution is to use a syntax like this:

\shapeCurve #"Tie" #'( ((dx1 . dy1) . . . ))

and then to let the functions choose the right control-points callback from a list based on the name of the grob you're overriding. (Dmytro used this in a variant of his adaptation which I saw off-list.)

I thought it might be nice to have \shapeSlur, \shapeTie, etc. To avoid duplicating so much code, I pass the relevant 'control-points callback to the functions which need it. Of course, you can extend this list to whatever takes control-points. As you mention, \shapePhrasingSlur would be the same as \shapeSlur. You can do \shapeTupletBracket in 2.14.2, but it looks like 'control-points is gone in 2.15.

    to sum up what I said:
    If you'd volunteer to do the following it would be a very valuable
    contribution to LilyPond's usability ;-)


I'd be delighted to do whatever I can.

    - let the function check the number of arguments and give
    meaningful warnings instead of errors
    (count arguments and compare against number of slur siblings)


It will do this. In the attached examples, some warnings will appear, and you can add elements and comment them out (with ; inside of the Scheme expression instead of the ordinary %) Tell me what you think!

    - don't try to make the function robust so that it accepts wrong
    input. This may be trivial from a programmer's perspective but I
    can't imagine that it makes sense aesthetically.


It won't work at all if you write:
\shapeSlur #'()

\shapeSlur #'( () )
will work.  The () is a shorthand for "leave this segment alone".

You can write either:
\shapeSlur #'( (dx1 . dy1) . . . )
or
\shapeSlur #'( ((dx1 . dy1) . . . ) )

You'll get wacky results if you don't include enough pairs.

Thank you very much for your input. It would be great if you could try this out and see if it does what you want!
Hi David,
as promised I tried out your updated function(s).
Well, you can't call this a complete test suite, but it seems to work perfectly. Many thanks.
Attached is a version showing that it also/still works with phrasingSlurs.

I find the warnings very useful. I assume it isn't possible to find out and display the 'real' place in the source where the problem comes from? As it is, I only know that there is a changed curve that doesn't work anymore, but don't know where it is (which can of course be difficult to pin down in larger pieces. If it isn't possible to identify the calling line in the source code, would it be possible to mark the respective curve red? This way one could easily spot the problematic grob.

That a wrong number of pairs gives strange results is OK. That way one is gently pointed towards malformed input ;-)

So it works like a charm now :-)
If you could still add the colour or line number feature - or tell me that you won't or can't do it - I could make a useable and distributably version of the file - maybe as a package together with displayControlPoints (see other mail in the other thread).

Best
Urs



Best,
David


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

\version "2.14.2"

#(define ((offset-control-points offsets function) grob)
  (let ((coords (function grob)))
    (if (null? offsets)
        coords
        (map
          (lambda (x y)
            (coord-translate x y))
          coords offsets))))

#(define ((shape-curve offsets function) grob)
   (let* (
          ;; have we been split?
          (orig (ly:grob-original grob))
          ;; if yes, get the split pieces (our siblings)
          (siblings (if (ly:grob? orig)
                        (ly:spanner-broken-into orig) '() ))
          (total-found (length siblings))
          (grob-name
            (assoc-get 'name
              (assoc-get 'meta
                (ly:grob-basic-properties grob)))))

     (define (helper sibs offs)
       (if (and (eq? (car sibs) grob)
                (pair? offs))
           ((offset-control-points (car offs) function) grob)
           (if (pair? offs)
               (helper (cdr sibs) (cdr offs))
               ((offset-control-points '() function) grob))))

     ; standardize input so #'((dx1 . dy1) . . . )
     ; and #'( ((dx1 . dy1) . . . ) ) possible
     (if (not (list? (car offsets)))
         (set! offsets (list offsets)))

     ; warnings
     (if (not (= (length offsets) total-found))
         (if (= 0 total-found)
             (if (pair? (cdr offsets))
                 (ly:warning
                   "~a is unbroken, modifications for ~a pieces requested"
                     grob-name (length offsets)))
             (if (eq? (last siblings) grob) ; print warning only once
                 (ly:warning
                   "~a is broken into ~a pieces, modifications for ~a requested~%"
                     grob-name total-found (length offsets)))))

     (if (>= total-found 2)
         (helper siblings offsets)
         ((offset-control-points (car offsets) function) grob))))

shapeSlur =
#(define-music-function (parser location offsets)
                        (list?)
  #{
    \once \override Slur #'control-points =
      #(shape-curve offsets ly:slur::calc-control-points)
  #})

shapePhrasingSlur =
#(define-music-function (parser location offsets)
                        (list?)
  #{
    \once \override Slur #'control-points =
      #(shape-curve offsets ly:slur::calc-control-points)
  #})

shapeTie =
#(define-music-function (parser location offsets)
                        (list?)
  #{
    \once \override Tie #'control-points =
      #(shape-curve offsets ly:tie::calc-control-points)
  #})

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%% SLURS

\markup {
  \underline "Default Slurs"
}

\relative c'' {
  d4( d' b g g,8 f' e d c2)
  \bar "||"
  d4( d' b g
  \break
  g,8 f' e d c2)
}

\markup {
  \underline "Modified"
}

\relative c'' {
  %% UNBROKEN
  %% remove semicolon to see warning
  \shapeSlur #'(
    ((0 . -2.5) (-1 . 3.5) (0 . 0) (0 . -2.5))
    ;()
    )
  d4( d' b g g,8  f' e d c2)
  \bar "||"

  %% BROKEN
  %% warning will show
  \shapeSlur #'(
    ((0 . -2.5) (0 . 1.5) (0 . 1) (0 . -1))
    ()
    ()
    )

  d4(^"(1st half only)" d' b g
  \break
  g,8 f' e d c2)
  \bar "||"

  %% both halves of the slur are modified
  \shapeSlur #'(
    ((0 . -2.5) (0 . 1.5) (0 . 1) (0 . -1))
    ((1 . 2) (0 . 1) (0 . 1) (0 . 0))
    )
  d4(^"(both halves)" d' b g
  \break
  g,8 f' e d c2)
}

%% TIES

\relative c'' {
  cis1~
  cis
  \shapeTie #'((0 . 0) (0 . 1) (0 . 1) (0 . 0))
  cis~
  cis
  \shapeTie #'((0 . 0) (0 . 1) (0 . 1) (0 . 0))
  cis~
  \break
  cis
  \shapeTie #'(
    ()
    ((-0.25 . 0) (0 . -0.25) (0 . -0.25) (0 . -1))
    )
  cis~
  \break
  cis
}

\markup {
  \underline "PhrasingSlurs"
}

\relative c'' {
  %% UNBROKEN
  %% remove semicolon to see warning
  \shapePhrasingSlur #'(
    ((0 . -2.5) (-1 . 3.5) (0 . 0) (0 . -2.5))
    ;()
    )
  d4\( d' b g g,8  f' e d c2\)
  \bar "||"

  %% BROKEN
  %% warning will show
  \shapePhrasingSlur #'(
    ((0 . -2.5) (0 . 1.5) (0 . 1) (0 . -1))
    ()
    ()
    )

  d4\(^"(1st half only)" d' b g
  \break
  g,8 f' e d c2\)
  \bar "||"

  %% both halves of the slur are modified
  \shapePhrasingSlur #'(
    ((0 . -2.5) (0 . 1.5) (0 . 1) (0 . -1))
    ((1 . 2) (0 . 1) (0 . 1) (0 . 0))
    )
  d4\(^"(both halves)" d' b g
  \break
  g,8 f' e d c2\)
}

\paper {
  indent = 0
  ragged-right = ##t
}





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

Reply via email to