lilypond-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Engraver_group with parent context type?


From: Jean Abou Samra
Subject: Re: Engraver_group with parent context type?
Date: Mon, 1 Nov 2021 21:40:05 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.1.2

Le 01/11/2021 à 20:39, Lukas-Fabian Moser a écrit :
Folks,

while trying to tidy up ly/engraver-init.ly a bit (which seems to have experienced some rank growth over the years) I stumbled upon:

\context {
  \Staff
  \type "Engraver_group"
  \name "DrumStaff"
  \alias "Staff"

  % (etc.)

}

That's the only instance of a context definition that contains _both_ a parent context type (\Staff) _and_ \type "Engraver_group".

Is that correct? I don't know enough about the inner workings to judge reliably.


I'm not really familiar with that code, so take
this with a pinch of salt. What I understand is
that \Staff doesn't really bring a relationship
between context defs. It just adds all mods from
the Staff definition into the mod being created.
If that changes the name, so be it. At any rate,
the \name that is eventually the current value
in the context def gets interpreted as the name
of a variable that is assigned in the output def.
The relevant code is in output-def.cc at line 75:

void
assign_context_def (Output_def *m, SCM transdef)
{
  Context_def *tp = unsmob<Context_def> (transdef);
  assert (tp);

  if (tp)
    {
      SCM sym = tp->get_context_name ();
      m->set_variable (sym, transdef);
    }
}

Try

\layout {
  #(display Staff)
}

and see the end of context-def.cc for what
you can do with that value in Scheme.

So when you bring \Staff, this adds a bunch of
modifications. Then you add \type, which just
sets a new type -- a no-op in this case because
there is already the same type. The code making
the modification is parser.yy around line 900:

context_def_spec_body:
    /**/ {
        $$ = SCM_UNSPECIFIED;
    }
    | context_def_spec_body context_mod {
        if (!SCM_UNBNDP ($2)) {
            Context_def *td = unsmob<Context_def> ($$);
            if (!td) {
                $$ = Context_def::make_scm ();
                td = unsmob<Context_def> ($$);
            }
            unsmob<Context_def> ($$)->add_context_mod ($2);
        }
    }
    ...

which calls context-def.cc line 125:

void
Context_def::add_context_mod (SCM mod)
{
  SCM tag = scm_car (mod);
  if (scm_is_eq (tag, ly_symbol2scm ("description")))
    {
      description_ = scm_cadr (mod);
      return;
    }

  /*
    other modifiers take symbols as argument.
  */
  SCM sym = scm_cadr (mod);
  if (scm_is_string (sym))
    sym = scm_string_to_symbol (sym);

  if (scm_is_eq (tag, ly_symbol2scm ("default-child")))
    acceptance_.accept_default (sym);
  else if (scm_is_eq (tag, ly_symbol2scm ("consists"))
           || scm_is_eq (tag, ly_symbol2scm ("remove")))
    {
      translator_mods_ = scm_cons (scm_list_2 (tag, sym), translator_mods_);
    }
  else if (scm_is_eq (tag, ly_symbol2scm ("accepts")))
    acceptance_.accept (sym);
  else if (scm_is_eq (tag, ly_symbol2scm ("denies")))
    acceptance_.deny (sym);
  else if (scm_is_eq (tag, ly_symbol2scm ("pop"))
           || scm_is_eq (tag, ly_symbol2scm ("push"))
           || scm_is_eq (tag, ly_symbol2scm ("assign"))
           || scm_is_eq (tag, ly_symbol2scm ("unset"))
           || scm_is_eq (tag, ly_symbol2scm ("apply")))
    property_ops_ = scm_cons (mod, property_ops_);
  else if (scm_is_eq (tag, ly_symbol2scm ("alias")))
    context_aliases_ = scm_cons (sym, context_aliases_);
  else if (scm_is_eq (tag, ly_symbol2scm ("translator-type")))
    translator_group_type_ = sym;
  else if (scm_is_eq (tag, ly_symbol2scm ("context-name")))
    context_name_ = sym;
  else
    programming_error ("unknown context mod tag");
}

In short: useless but not problematic.

Hope that helps,
Jean






reply via email to

[Prev in Thread] Current Thread [Next in Thread]