Menu

#4955 tie-configuration is partially ignored

Fixed
Documentation
2020-03-17
2016-08-12
No

https://codereview.appspot.com/567350043

\version "2.19.46"

\header { texidoc = "
LilyPond should obey the vertical positions of ties as specified with
@code{tie-configuration}.

Here is a counterexample, where the positions of longer ties get
changed.
" }

\paper { line-width = 80\mm }

\relative {
  \override TieColumn.tie-configuration =
    #'((0 . 1) (2 . 1) (4 . 1))
  <b'^~ d^~ f^~>1 | \break
  q |
}
1 Attachments

Discussion

1 2 > >> (Page 1 of 2)
  • David Kastrup

    David Kastrup - 2016-08-14

    So what did you expect to see? Where does the visual result differ? What does "positions of longer ties get changed" mean? From what? What are "longer ties"? With a line break? If so, which part of the ties behaves incorrectly? Before break, after break, both?

    Yes, it is good and important that you include a minimal example but it doesn't replace a problem description. You assume that any person who might investigate this problem (or even just be interested enough about it to follow the bug tracker or search for similar known problems) knows exactly what tie-configuration is supposed to do here according to your understanding of it.

     
    • Werner LEMBERG

      Werner LEMBERG - 2016-08-14

      Sorry for being too sparse.

      So what did you expect to see?

      The same vertical positions of the ties before and after the break – I'm manually setting the distances, so I expect that lilypond obeys, even if the result might be suboptimal.

      What does "positions of longer ties get changed" mean?

      For short ties (as after the break), lilypond uses the positions given in tie-configuration, but for longer ties (I haven't tried to find out the exact length) something else influences the vertical positions, which is unexpected and thus bad. I suspect that lilypond tries to avoid that ties touch the staff lines or something like that. However, it shouldn't do that for manually positioned stuff.

      With a line break?

      The line break itself doesn't matter, AFAICS. It's just a means to make the example small.

      If so, which part of the ties behaves incorrectly? Before break, after break, both?

      The ties before the break are not positioned as specified in tie-configuration.

       
  • Thomas Morley

    Thomas Morley - 2016-08-14

    At first sight I had difficulties to understand the issue, too...

    Then I did some empirical research. Obviously, setting tie-configuration will result in newly calculated control-points. They are based on the car of each given pair to determine the y-values (the calculating-mechanism isn't entirely clear to me, though) and the cdr for the direction.
    The NR states: "The first number indicates the distance from the center of the staff in half staff-spaces, and the second number indicates the direction (1 = up, -1 = down). "
    Seems pretty clear to me. It dos not explain the calculating mechanism from getting the pairs car to the resulting control-point-value, but this would ofcourse beyond the intention of the NR.

    I'd say the bad output results more in insufficient values for 'tie-configuration.
    Try '((0 . 1) (3 . 1) (5 . 1)) which will almost exactly return the same output compared with not setting 'tie-configuration.

    I used the following test-code:

    \version "2.19.47"
    
    \paper { indent = 0 line-width = 80\mm }
    
    tieTest =
    #(define-music-function (strg which)(string? procedure?)
    #{
      \once \override Tie.after-line-breaking = 
      #(lambda (grob)
        (let* ((orig (ly:grob-original grob))
               (siblings (if (ly:grob? orig)
                             (ly:spanner-broken-into orig)
                             '())))
         (if (not (null? siblings))
             (format #t "Y-values of control-points ~a:\n~y" 
               strg
               (map cdr (ly:grob-property (which siblings) 'control-points))))))
    #})
    
    \relative b' {
        \omit Staff.TimeSignature
      \tieTest "with tie-configuration applied" #first
      \override TieColumn.tie-configuration = 
      #'((0 . 1) (3 . 1) (5 . 1))
    
      <b^~ d^~ f^~ >1 \break q
      \revert TieColumn.tie-configuration
    
      \break
    
      \tieTest "without tie-configuration" #last
      <b^~ d^~ f^~ >1 \break q
    }
    

    Otoh, if the NR is not clear enough, could you suggest a better wording?

     
    • Werner LEMBERG

      Werner LEMBERG - 2016-08-14

      I'd say the bad output results more in insufficient values for tie-configuration.
      Try '((0 . 1) (3 . 1) (5 . 1)) which will almost exactly return the same
      output compared with not setting tie-configuration.

      I disagree. I don't want lilypond to override my manual settings. This makes it impossible to fine-tune the vertical positions: I would have (a) to rely on trial and error, and (b) to re-do the positioning in case the layout changes.

       
  • Carl Sorensen

    Carl Sorensen - 2016-08-14

    There is somethign weird about the value of 0 in tie configuration.

    If you use the following, it is respected.

    \paper { line-width = 80\mm }

    \relative {
    \override TieColumn.tie-configuration =
    #'((0.01 . 1) (2 . 1) (4 . 1))
    <b'^~ d^~="" f^~="">1 | \break
    q |
    }

     
  • Thomas Morley

    Thomas Morley - 2016-08-14

    Well, from your replies so far, I must state, I completely misunderstood what this issue is about.

    I hope(!) I understand better now ...
    One observation, it makes a big difference whether zero is put in as 0 or as 0.0.
    Compare the output for
    '((0.0 . 1) (2 . 1) (4 . 1))
    with the one for
    '((0 . 1) (2 . 1) (4 . 1))
    Bad check for exactness somewhere?

     
  • David Kastrup

    David Kastrup - 2016-08-14

    You can say that again.

    lily/tie-formatting-problem.cc:1192
    [...]
    if (scm_is_pair (entry))
    {
    Tie_specification &spec = specifications_[k];

          if (scm_is_number (scm_car (entry)))
            {
              spec.has_manual_position_ = true;
              spec.manual_position_ = scm_to_double (scm_car (entry));
              /* TODO: check whether inexact? is an appropriate condition here */
              spec.has_manual_delta_y_ = (scm_is_true (scm_inexact_p (scm_car (entry))));
            }
    
          if (scm_is_number (scm_cdr (entry)))
            {
              spec.has_manual_dir_ = true;
              spec.manual_dir_ = Direction (scm_to_int (scm_cdr (entry)));
            }
        }
      k++;
    

    So what is the deal with "has_manual_position" as opposed to "has_manual_delta_y" ?

    The doc for the property just states:
    (tie-configuration ,list? "List of @code{(@var{position} .
    @var{dir})} pairs, indicating the desired tie configuration, where
    @var{position} is the offset from the center of the staff in staff
    space and @var{dir} indicates the direction of the tie (@code{1}=>up,
    @w{@code{-1}}=>down, @code{0}=>center). A non-pair entry
    in the list causes the corresponding tie to be formatted
    automatically.")

    Obviously, somebody had a plan for something here.

     
  • Carl Sorensen

    Carl Sorensen - 2016-08-14

    It's not my plan, but I note that integer positions are the positions of note heads (because the units are half staff spaces). So perhaps the thinking is that if you use an integer, you're specifiying a standard note head position; if you use a non-integer, you're specifying an offset from a standard note head position.

     
  • Thomas Morley

    Thomas Morley - 2016-08-14

    Whatever plan it is/was, the following values for 'tie-configuration return different values for the control-points.
    The difference is hard to see in pdf, use high resolution or read out the values with my function above.

    #`(,(cons (/ 1 4) 1) (2 . 1) (4 . 1))
    #'((0.25 . 1) (2 . 1) (4 . 1))
    

    Supporting different behaviour for both inputs does not do a favour to anyone.
    I suggest we take the input, may it be exact or not, as what the user wants. Not further fiddling around with it in any way.

     
    • Werner LEMBERG

      Werner LEMBERG - 2016-08-14

      I suggest we take the input, may it be exact or not, as what the user wants.
      Not further fiddling around with it in any way.

      I fully support that, and thanks to all for helping with the issue and identifying the cause.

       
  • Werner LEMBERG

    Werner LEMBERG - 2016-08-19

    I've just found the tie-manual-vertical-tune.ly regtest. After some thinking I believe that Han-Wen's idea is sensible and useful. Maybe it's sufficient to simply document it? We might decide on a different interface later on in case someone comes up with something better.

    If you agree, I'll provide a documentation patch.

     
  • Thomas Morley

    Thomas Morley - 2016-08-19

    At leat the description in said regtest is wrong:

    guile> (integer? 3.0)
    #t
    

    It's rather a matter of exactness:

    guile> (exact? 3.0)
    #f
    guile> (exact? 3)
    #t
    

    And what to do with (/ 4 5)?

    guile> (exact? (/ 4 5))
    #t
    
     
  • Werner LEMBERG

    Werner LEMBERG - 2016-08-19

    Well, the description of the regtest sounds sensible :-) Would it be possible to change the code so that it does exactly what the regtest talks about, i.e., only making a difference between an integer (i.e., a number without a decimal point) and a float?

     
  • Werner LEMBERG

    Werner LEMBERG - 2016-08-20

    What about the following ad-hoc code to test for exact integers?

    --- a/lily/tie-formatting-problem.cc
    +++ b/lily/tie-formatting-problem.cc
    @@ -1204,8 +1204,14 @@ Tie_formatting_problem::set_manual_tie_configuration (SCM manual_configs)
                 {
                   spec.has_manual_position_ = true;
                   spec.manual_position_ = scm_to_double (scm_car (entry));
    -              /* TODO: check whether inexact? is an appropriate condition here */
    -              spec.has_manual_delta_y_ = (scm_is_true (scm_inexact_p (scm_car (entry))));
    +              spec.has_manual_delta_y_ =
    +                // values -10000 and 10000 are arbitrary
    +                spec.manual_position_ < 10000
    +                && spec.manual_position_ > -10000
    +                // scm_is_signed_integer is true for exact integers only
    +                && scm_is_false (scm_is_signed_integer (scm_car (entry),
    +                                                        -10000,
    +                                                        10000));
                 }
    
               if (scm_is_number (scm_cdr (entry)))
    
     
    • David Kastrup

      David Kastrup - 2016-08-20

      Where does that leave the people with fractional use of bar lines, like various "uniform" systems for the chromatic scale?

      I think that as long as we stay with a single property with multiple meanings, the current behavior might make sense. I just don't think that staying with a single property with multiple meanings is doing anybody a favor here.

       
  • Werner LEMBERG

    Werner LEMBERG - 2016-08-20

    I fully agree that a better, generalized interface might a good idea. However, the above only tries to make the implementation work as described in the regtest, which is better than the current state, I believe. Note that I'm not happy about the ad-hoc integer constants -10000 and 10000; any suggestions how to improve that?

    I'm very bad at designing interfaces, so I leave a fundamental fix to the issue – in case there is a desire to do this – to other people.

     
    • David Kastrup

      David Kastrup - 2016-08-20

      I fully agree that a better, generalized interface might a good idea. However, the above only tries to make the implementation work as described in the regtest, which is better than the current state, I believe.

      Because? It complicates the test and creates a condition that may be slightly easier to state in informal words and harder in Scheme.

       
  • Werner LEMBERG

    Werner LEMBERG - 2016-08-20

    So you prefer the opposite? Fixing the description of the regtest (plus documenting this feature)? I don't have a preference here.

     
    • David Kastrup

      David Kastrup - 2016-08-20

      If those are the only two considered options, I think I prefer going with keeping the behavior and changing the documentation.

      But frankly, this is an abomination. A user should just be able to tweak the ties individually and be done (and then relative position is available anyway via \offset without requiring extra folderol). The whole tie-configuration thing stinks.

      If that's not on the table, I think I prefer going with changing the documentation. One slight advantage is that we don't get any incompatibilities until we indeed change this to work via per-tie tweaks.

       
  • Carl Sorensen

    Carl Sorensen - 2016-08-20

    I think that the best thing to do is change the documentation so instead of saying integer or non-integer, we say exact or non-exact. That allows fractional spaces; they just have to be exact fractions, which Scheme (and hence LilyPond) can handle.

     
  • Trevor Daniels

    Trevor Daniels - 2016-09-27
    • status: New --> Accepted
    • Type: Defect --> Documentation
     
  • Trevor Daniels

    Trevor Daniels - 2016-09-27

    Sounds like we're agreed just a doc change is required at this stage.

     
  • Trevor Daniels

    Trevor Daniels - 2017-08-20
    • status: Accepted --> Started
    • assigned_to: Trevor Daniels
     
  • Trevor Daniels

    Trevor Daniels - 2017-08-20

    I'll have a look at changing the docs to reflect this behaviour.

     
  • Trevor Daniels

    Trevor Daniels - 2017-08-20

    I think the best place to document this is in the snippet "Engraving ties manually", which is included in the NR at the end of http://lilypond.org/doc/v2.19/Documentation/notation/writing-rhythms#ties .

    In addition, two further small mods: one to correct the wording of the regtest tie-manual-vertical-tune.ly to say "If using integers or fractions, the tie will be vertically tuned for staff line avoidance. ...", and one to the LM where it discusses staff-position in section 4.6.2, to point to the amended snippet in the NR.

    Does that sound reasonable?

     
1 2 > >> (Page 1 of 2)