/*
- translator-def.cc -- implement Translator_def
+ translator-def.cc -- implement Context_def
source file of the GNU LilyPond music typesetter
- (c) 2000--2001 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+ (c) 2000--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
*/
#include "lily-proto.hh"
-#include "translator-def.hh"
+#include "context-def.hh"
#include "translator-group.hh"
#include "warn.hh"
#include "music-output-def.hh"
-
#include "ly-smobs.icc"
int
-Translator_def::print_smob (SCM smob, SCM port, scm_print_state*)
+Context_def::print_smob (SCM smob, SCM port, scm_print_state*)
{
- Translator_def* me = (Translator_def*) SCM_CELL_WORD_1 (smob);
+ Context_def* me = (Context_def*) SCM_CELL_WORD_1 (smob);
- scm_puts("#<Translator_def ", port);
- scm_display (me->type_name_, port);
+ scm_puts ("#<Context_def ", port);
+ scm_display (me->context_name_, port);
scm_puts (">", port);
return 1;
}
SCM
-Translator_def::mark_smob (SCM smob)
+Context_def::mark_smob (SCM smob)
{
- Translator_def* me = (Translator_def*) SCM_CELL_WORD_1 (smob);
- scm_gc_mark (me->consists_name_list_);
- scm_gc_mark (me->accepts_name_list_);
- scm_gc_mark (me->end_consists_name_list_);
+ Context_def* me = (Context_def*) SCM_CELL_WORD_1 (smob);
+
+ scm_gc_mark (me->description_);
+ scm_gc_mark (me->context_aliases_);
+ scm_gc_mark (me->accept_mods_);
+ scm_gc_mark (me->translator_mods_);
scm_gc_mark (me->property_ops_);
scm_gc_mark (me->translator_group_type_);
- return me->type_name_;
+ return me->context_name_;
}
-SCM push_sym;
-SCM assign_sym;
-static void
-foo_init ()
-{
- push_sym = scm_permanent_object (ly_symbol2scm ("push"));
- assign_sym = scm_permanent_object (ly_symbol2scm ("assign"));
-}
-
-ADD_SCM_INIT_FUNC(transdef, foo_init);
-
-Translator_def::Translator_def ()
+Context_def::Context_def ()
{
+ context_aliases_ = SCM_EOL;
translator_group_type_ = SCM_EOL;
- accepts_name_list_ = SCM_EOL;
- consists_name_list_ = SCM_EOL;
- end_consists_name_list_ = SCM_EOL;
+ accept_mods_ = SCM_EOL;
+ translator_mods_ = SCM_EOL;
property_ops_ = SCM_EOL;
- type_name_ = SCM_EOL;
+ context_name_ = SCM_EOL;
+ description_ = SCM_EOL;
+
+ smobify_self();
}
-Translator_def::~Translator_def ()
+
+Context_def::~Context_def ()
{
}
-Translator_def::Translator_def (Translator_def const & s)
+Context_def::Context_def (Context_def const & s)
: Input (s)
{
- consists_name_list_ = scm_list_copy (s.consists_name_list_);
- end_consists_name_list_ = scm_list_copy (s.end_consists_name_list_);
- accepts_name_list_ = scm_list_copy (s.accepts_name_list_);
- property_ops_ = scm_list_copy (s.property_ops_);
+ context_aliases_ = SCM_EOL;
+ translator_group_type_ = SCM_EOL;
+ accept_mods_ = SCM_EOL;
+ translator_mods_ = SCM_EOL;
+ property_ops_ = SCM_EOL;
+ context_name_ = SCM_EOL;
+ description_ = SCM_EOL;
+
+ smobify_self();
+ description_ = s.description_;
+ accept_mods_ = s.accept_mods_;
+ property_ops_ = s.property_ops_;
+ translator_mods_ = s.translator_mods_;
+ context_aliases_ = s.context_aliases_;
translator_group_type_ = s.translator_group_type_;
- type_name_ = s.type_name_;
+ context_name_ = s.context_name_;
}
-
void
-Translator_def::set_acceptor (SCM name, bool add)
-{
- if (add)
- this->accepts_name_list_ = gh_cons (name, this->accepts_name_list_);
- else
- this->accepts_name_list_ = scm_delete_x (name, this->accepts_name_list_);
-}
-
-
-SCM
-Translator_def::modify_definition (SCM list, SCM str, bool add)
+Context_def::add_context_mod (SCM mod)
{
- String s = ly_scm2string (str);
- if (!get_translator_l (s))
- error (_ ("Program has no such type"));
+ SCM tag = gh_car (mod);
+ if (ly_symbol2scm ("description") == tag)
+ {
+ description_ = gh_cadr (mod);
+ return ;
+ }
- if (add)
+ SCM sym = gh_cadr (mod);
+ if (gh_string_p (sym))
+ sym = scm_string_to_symbol (sym);
+
+ if (ly_symbol2scm ("consists") == tag
+ || ly_symbol2scm ("consists-end") == tag
+ || ly_symbol2scm ("remove") == tag)
{
- if (scm_memq (str, list) != SCM_BOOL_F)
- {
- warning (_f("Already contains: `%s'", s));
- warning (_f("Not adding translator: `%s'", s));
- }
+ if (!get_translator (sym))
+ error (_f ("Program has no such type: `%s'", ly_symbol2string (sym).to_str0 ()));
else
- list= gh_cons (str, list);
+ translator_mods_ = gh_cons (scm_list_2 (tag, sym), translator_mods_ );
+ }
+ else if (ly_symbol2scm ("accepts") == tag
+ || ly_symbol2scm ("denies") == tag)
+ {
+ accept_mods_ = gh_cons (scm_list_2 (tag, sym), accept_mods_);
+ }
+ else if (ly_symbol2scm ("poppush") == tag
+ || ly_symbol2scm ("pop") == tag
+ || ly_symbol2scm ("push") == tag
+ || ly_symbol2scm ("assign") == tag
+ || ly_symbol2scm ("unset") == tag)
+ {
+ property_ops_ = gh_cons (mod, property_ops_);
+ }
+ else if (ly_symbol2scm ("alias") == tag)
+ {
+ context_aliases_ = gh_cons (sym, context_aliases_);
+ }
+ else if (ly_symbol2scm ("translator-type") == tag)
+ {
+ translator_group_type_ = sym;
+ }
+ else if (ly_symbol2scm ("context-name") == tag)
+ {
+ context_name_ = sym;
}
else
{
- list = scm_delete_x (str, list);
+ programming_error ("Unknown context mod tag.");
}
- return list;
-}
-
-
-
-void
-Translator_def::remove_element (SCM s)
-{
- this->end_consists_name_list_ = modify_definition (this->end_consists_name_list_, s, false);
- this->consists_name_list_ = modify_definition (this->consists_name_list_, s, false);
}
-void
-Translator_def::add_element (SCM s)
-{
- this->consists_name_list_ = modify_definition (this->consists_name_list_, s, true);
-}
-void
-Translator_def::add_last_element (SCM s)
-{
- this->end_consists_name_list_ = modify_definition (this->end_consists_name_list_, s, true);
-}
-void
-Translator_def::add_push_property (SCM props, SCM syms, SCM vals)
-{
- this->property_ops_ = gh_cons (gh_list (push_sym, props, syms, vals, SCM_UNDEFINED),
- this->property_ops_);
-}
-void
-Translator_def::add_pop_property (SCM props, SCM syms)
+SCM
+Context_def::get_context_name () const
{
- this->property_ops_ = gh_cons (gh_list (push_sym, props, syms, SCM_UNDEFINED),
- this->property_ops_);
+ return context_name_;
}
-/*
- Do it. SYMS maybe a symbol or a list of symbols. VAL is
- SCM_UNDEFINED in case of a pop
-*/
-void
-Translator_def::apply_pushpop_property (Translator_group* me,SCM syms, SCM eprop, SCM val)
+SCM
+Context_def::get_accepted (SCM user_mod) const
{
- if (gh_symbol_p (syms))
- dynamic_cast<Translator_group*>(me)->execute_single_pushpop_property (syms, eprop, val);
- else for (SCM s = syms; gh_pair_p (s); s = gh_cdr (s))
- dynamic_cast<Translator_group*>(me)->execute_single_pushpop_property (gh_car (s), eprop, val);
+ SCM mods = scm_reverse_x (scm_list_copy (accept_mods_),
+ user_mod);
+ SCM acc = SCM_EOL;
+ for (SCM s = mods; gh_pair_p (s); s = gh_cdr (s))
+ {
+ SCM tag = gh_caar (s);
+ SCM sym = gh_cadar (s);
+ if (tag == ly_symbol2scm ("accepts"))
+ acc = gh_cons (sym, acc);
+ else if (tag == ly_symbol2scm ("denies"))
+ acc = scm_delete_x (sym, acc);
+ }
+ return acc;
}
-
-
-Link_array<Translator_def>
-Translator_def::path_to_acceptable_translator (SCM type_str, Music_output_def* odef) const
+
+Link_array<Context_def>
+Context_def::path_to_acceptable_translator (SCM type_sym, Music_output_def* odef) const
{
- assert (gh_string_p (type_str));
+ assert (gh_symbol_p (type_sym));
- Link_array<Translator_def> accepted_arr;
- for (SCM s = accepts_name_list_; gh_pair_p (s); s = gh_cdr (s))
+ SCM accepted = get_accepted (SCM_EOL);
+
+ Link_array<Context_def> accepteds;
+ for (SCM s = accepted; gh_pair_p (s); s = ly_cdr (s))
{
- Translator_def *t = unsmob_translator_def (odef->find_translator_l (gh_car (s)));
+ Context_def *t = unsmob_context_def (odef->find_translator (ly_car (s)));
if (!t)
continue;
- accepted_arr.push (t);
+ accepteds.push (t);
}
- Link_array<Translator_def> best_result;
- for (int i=0; i < accepted_arr.size (); i++)
- if (scm_equal_p (accepted_arr[i]->type_name_, type_str) == SCM_BOOL_T)
- {
- best_result.push (accepted_arr[i]);
- return best_result;
- }
-
+ Link_array<Context_def> best_result;
+ for (int i=0; i < accepteds.size (); i++)
+ {
+ /*
+ don't check aliases, because \context Staff should not create RhythmicStaff.
+ */
+ if (gh_equal_p (accepteds[i]->get_context_name (), type_sym))
+ {
+ best_result.push (accepteds[i]);
+ return best_result;
+ }
+ }
+
int best_depth= INT_MAX;
- for (int i=0; i < accepted_arr.size (); i++)
+ for (int i=0; i < accepteds.size (); i++)
{
- Translator_def * g = accepted_arr[i];
+ Context_def * g = accepteds[i];
- Link_array<Translator_def> result
- = g->path_to_acceptable_translator (type_str, odef);
+ Link_array<Context_def> result
+ = g->path_to_acceptable_translator (type_sym, odef);
if (result.size () && result.size () < best_depth)
{
result.insert (g,0);
best_result = result;
+
+ /*
+ this following line was added in 1.9.3, but hsould've been
+ there all along... Let's hope it doesn't cause nightmares.
+ */
+ best_depth = result.size();
}
}
return best_result;
}
-IMPLEMENT_UNSMOB(Translator_def,translator_def);
-IMPLEMENT_SMOBS(Translator_def);
-IMPLEMENT_DEFAULT_EQUAL_P(Translator_def);
+
+IMPLEMENT_SMOBS (Context_def);
+IMPLEMENT_DEFAULT_EQUAL_P (Context_def);
-static SCM
-trans_list (SCM namelist, Translator_group*tg)
+
+
+SCM
+Context_def::get_translator_names (SCM user_mod) const
{
- SCM l = SCM_EOL;
- for (SCM s = namelist; gh_pair_p (s) ; s = gh_cdr (s))
- {
- Translator * t = get_translator_l (ly_scm2string (gh_car (s)));
- if (!t)
- warning (_f ("can't find: `%s'", s));
- else
- {
- Translator * tr = t->clone ();
- SCM str = tr->self_scm ();
- l = gh_cons (str, l);
+ SCM l1 = SCM_EOL;
+ SCM l2 = SCM_EOL;
- tr->daddy_trans_l_ = tg;
- tr->output_def_l_ = tg->output_def_l_;
+ SCM mods = scm_reverse_x (scm_list_copy (translator_mods_),
+ user_mod);
+
+ for (SCM s = mods; gh_pair_p (s); s = gh_cdr (s))
+ {
+ SCM tag = gh_caar (s);
+ SCM arg = gh_cadar (s);
- scm_unprotect_object (str);
+ if (gh_string_p (arg))
+ arg = scm_string_to_symbol (arg);
+
+ if (ly_symbol2scm ("consists") == tag)
+ l1 = gh_cons (arg, l1);
+ else if (ly_symbol2scm ("consists-end") == tag)
+ l2 = gh_cons (arg, l2);
+ else if (ly_symbol2scm ("remove") == tag)
+ {
+ l1 = scm_delete_x (arg, l1);
+ l2 = scm_delete_x (arg, l2);
}
}
- return l;
+
+ return scm_append_x (scm_list_2 (l1, l2));
}
Translator_group *
-Translator_def::instantiate (Music_output_def* md)
+Context_def::instantiate (Music_output_def* md, SCM ops)
{
- Translator * g = get_translator_l (ly_scm2string (translator_group_type_));
+ Translator * g = get_translator (translator_group_type_);
g = g->clone ();
Translator_group *tg = dynamic_cast<Translator_group*> (g);
- tg->output_def_l_ = md;
+ tg->output_def_ = md;
tg->definition_ = self_scm ();
- tg->type_str_ = ly_scm2string (type_name_);
- SCM l1 = trans_list (consists_name_list_, tg);
- SCM l2 =trans_list (end_consists_name_list_,tg);
- l1 = scm_reverse_x (l1, l2);
-
- tg->simple_trans_list_ = l1;
-
+
+ SCM trans_names = get_translator_names (ops);
+ tg->simple_trans_list_ = names_to_translators (trans_names, tg);
+ tg->accepts_list_ = get_accepted (ops);
return tg;
}
-void
-Translator_def::apply_property_operations (Translator_group*tg)
-{
- SCM correct_order = scm_reverse (property_ops_); // pity of the mem.
- for (SCM s = correct_order; gh_pair_p (s); s = gh_cdr (s))
- {
- SCM entry = gh_car (s);
- SCM type = gh_car (entry);
- entry = gh_cdr (entry);
-
- if (type == push_sym)
- {
- SCM val = gh_cddr (entry);
- val = gh_pair_p (val) ? gh_car (val) : SCM_UNDEFINED;
-
- apply_pushpop_property (tg, gh_car (entry), gh_cadr (entry), val);
- }
- else if (type == assign_sym)
- {
- tg->set_property (gh_car(entry), gh_cadr (entry));
- }
- }
-}
-
SCM
-Translator_def::clone_scm () const
+Context_def::clone_scm () const
{
- Translator_def * t = new Translator_def (*this);
- return t->unprotected_smobify_self ();
+ Context_def * t = new Context_def (*this);
+ scm_gc_unprotect_object (t->self_scm());
+ return t->self_scm();
}
SCM
-Translator_def::make_scm ()
+Context_def::make_scm ()
{
- Translator_def* t = new Translator_def;
- return t->unprotected_smobify_self ();
+ Context_def* t = new Context_def;
+ scm_gc_unprotect_object (t->self_scm());
+ return t->self_scm();
}
void
-Translator_def::add_property_assign (SCM nm, SCM val)
+Context_def::apply_default_property_operations (Translator_group *tg)
{
- this->property_ops_ = gh_cons (gh_list (assign_sym, scm_string_to_symbol (nm), val, SCM_UNDEFINED),
- this->property_ops_);
+ apply_property_operations (tg , property_ops_);
}
-/*
- Default child context as a SCM string, or something else if there is
- none.
-*/
SCM
-Translator_def::default_child_context_name ()
-{
- SCM d = accepts_name_list_;
- return gh_pair_p (d) ? gh_car (scm_last_pair (d)) : SCM_EOL;
-}
-
-SCM
-Translator_def::to_alist ()const
+Context_def::to_alist () const
{
SCM l = SCM_EOL;
-
- l = gh_cons (gh_cons (ly_symbol2scm ("consists"), consists_name_list_), l);
- l = gh_cons (gh_cons (ly_symbol2scm ("end-consists"), end_consists_name_list_), l);
- l = gh_cons (gh_cons (ly_symbol2scm ("accepts"), accepts_name_list_), l);
+
+ l = gh_cons (gh_cons (ly_symbol2scm ("consists"),
+ get_translator_names (SCM_EOL)), l);
+ l = gh_cons (gh_cons (ly_symbol2scm ("description"), description_), l);
+ l = gh_cons (gh_cons (ly_symbol2scm ("aliases"), context_aliases_), l);
+ l = gh_cons (gh_cons (ly_symbol2scm ("accepts"), get_accepted (SCM_EOL)), l);
l = gh_cons (gh_cons (ly_symbol2scm ("property-ops"), property_ops_), l);
- l = gh_cons (gh_cons (ly_symbol2scm ("type-name"), type_name_), l); // junkme.
+ l = gh_cons (gh_cons (ly_symbol2scm ("context-name"), context_name_), l);
l = gh_cons (gh_cons (ly_symbol2scm ("group-type"), translator_group_type_), l);
return l;
}
+
+bool
+Context_def::is_alias (SCM sym) const
+{
+ bool b = sym == context_name_;
+
+ for (SCM a = context_aliases_; !b && gh_pair_p (a); a = ly_cdr (a))
+ b = b || sym == ly_car (a);
+
+ return b;
+}