Jakub Pavlík <jkb.pav...@gmail.com> writes:

> I've run into a surprising edge case with \applyContext.

Neither surprising nor an edge case.

> The example score below has Stem.length overridden in the layout
> block.

Are you sure you know what you are doing there?  This does not look like
anything you picked from LilyPond's documentation, rather like something
you tried out of a whim and decided it must be correct because it worked
in some manner.

Let me quote this:

   \layout {
     \override Stem.length = #0
   }

What you are doing here is putting music into the \layout block that
serves as a template for settings you want.  This is different from what
"\override" in a \context block does.

As music, \override Stem.length ... is a shorthand for
\override Bottom.Stem.length ...

Inside of a \layout block, this is translated into the respective
\override for _every_ context type that is a bottom context (namely any
context not having a \defaultchild).  This includes the Voice context
type, the TabVoice context type, the Lyrics context type and numerous
others.  It doesn't include the Score context type or the Staff context
type.

> \applyContext is called before and after the first note, logging the value
> of Stem.length to the standard output. I would expect both instances to
> print the value set by the override, i.e. 0. But instead, the first call
> prints the ly:stem::pure-calc-length function, i.e. the default value of
> Stem.length.

Let me quote again:

> \score {
>   \relative c'' {
>     \applyContext #displayStemLength
>     g4
>     \applyContext #displayStemLength
>     g
>   }

That's because at the point of the first call, you haven't yet descended
into a Voice or even Staff context from the surrounding Score context.
So \applyContext prints the Stem.length setting for the Score context
which has not been changed (you only changed the default for every
bottom context).

If you want to override Stem.length at the Score level, either write

\override Score.Stem.length = ...

in your \layout block, or write things like described in the docs,
namely

\layout {
  \context {
    \Score
    \override Stem.length = ...
  }
}

You cannot just invent syntax and then complain that it does something
different from what you expected.

> What am I missing? Why isn't the value set by \override in the layout block
> visible at the very beginning of the score?
>
> % MWE beginning ----------------
> \version "2.24.1"
>
> displayStemLength =
> #(lambda (context)
>    (let* ((grob-def (ly:context-grob-definition context 'Stem))
>           (length (ly:assoc-get 'length grob-def)))
>      (display "+ ")
>      (display length)
>      (newline)))
>
> \score {
>   \relative c'' {
>     \applyContext #displayStemLength
>     g4
>     \applyContext #displayStemLength
>     g
>   }
>   \layout {
>     \override Stem.length = #0
>   }
> }
> % MWE end --------------
>
> Best regards,
> Jakub

-- 
David Kastrup


Reply via email to