2 translator-def.cc -- implement Translator_def
4 source file of the GNU LilyPond music typesetter
6 (c) 2000--2003 Han-Wen Nienhuys <hanwen@cs.uu.nl>
10 #include "lily-proto.hh"
11 #include "translator-def.hh"
12 #include "translator-group.hh"
14 #include "music-output-def.hh"
15 #include "ly-smobs.icc"
18 Translator_def::print_smob (SCM smob, SCM port, scm_print_state*)
20 Translator_def* me = (Translator_def*) SCM_CELL_WORD_1 (smob);
22 scm_puts ("#<Translator_def ", port);
23 scm_display (me->type_name_, port);
30 Translator_def::mark_smob (SCM smob)
32 Translator_def* me = (Translator_def*) SCM_CELL_WORD_1 (smob);
34 scm_gc_mark (me->description_);
35 scm_gc_mark (me->type_aliases_);
36 scm_gc_mark (me->consists_name_list_);
37 scm_gc_mark (me->accepts_name_list_);
38 scm_gc_mark (me->end_consists_name_list_);
39 scm_gc_mark (me->property_ops_);
40 scm_gc_mark (me->translator_group_type_);
41 return me->type_name_;
45 Translator_def::Translator_def ()
47 type_aliases_ = SCM_EOL;
48 translator_group_type_ = SCM_EOL;
49 accepts_name_list_ = SCM_EOL;
50 consists_name_list_ = SCM_EOL;
51 end_consists_name_list_ = SCM_EOL;
52 property_ops_ = SCM_EOL;
54 description_ = SCM_EOL;
59 Translator_def::~Translator_def ()
63 Translator_def::Translator_def (Translator_def const & s)
66 type_aliases_ = SCM_EOL;
67 translator_group_type_ = SCM_EOL;
68 accepts_name_list_ = SCM_EOL;
69 consists_name_list_ = SCM_EOL;
70 end_consists_name_list_ = SCM_EOL;
71 property_ops_ = SCM_EOL;
73 description_ = SCM_EOL;
76 description_ = s.description_;
78 consists_name_list_ = scm_list_copy (s.consists_name_list_);
79 end_consists_name_list_ = scm_list_copy (s.end_consists_name_list_);
80 accepts_name_list_ = scm_list_copy (s.accepts_name_list_);
81 property_ops_ = scm_list_copy (s.property_ops_);
82 type_aliases_ = scm_list_copy (s.type_aliases_);
83 translator_group_type_ = s.translator_group_type_;
84 type_name_ = s.type_name_;
90 Translator_def::set_acceptor (SCM name, bool add)
92 assert (gh_symbol_p (name));
94 this->accepts_name_list_ = gh_cons (name, this->accepts_name_list_);
96 this->accepts_name_list_ = scm_delete_x (name, this->accepts_name_list_);
101 Translator_def::modify_definition (SCM list, SCM str, bool add)
103 String s = ly_scm2string (str);
104 if (!get_translator (s))
105 error (_ ("Program has no such type"));
109 if (scm_memq (str, list) != SCM_BOOL_F)
111 warning (_f ("Already contains: `%s'", s));
112 warning (_f ("Not adding translator: `%s'", s));
115 list= gh_cons (str, list);
119 list = scm_delete_x (str, list);
127 Translator_def::remove_element (SCM s)
129 this->end_consists_name_list_ = modify_definition (this->end_consists_name_list_, s, false);
130 this->consists_name_list_ = modify_definition (this->consists_name_list_, s, false);
134 Translator_def::add_element (SCM s)
136 this->consists_name_list_ = modify_definition (this->consists_name_list_, s, true);
140 Translator_def::add_last_element (SCM s)
142 this->end_consists_name_list_ = modify_definition (this->end_consists_name_list_, s, true);
146 Translator_def::add_property_operation (SCM what)
148 this->property_ops_ = gh_cons (what, this->property_ops_);
153 Link_array<Translator_def>
154 Translator_def::path_to_acceptable_translator (SCM type_sym, Music_output_def* odef) const
156 assert (gh_symbol_p (type_sym));
158 Link_array<Translator_def> accepteds;
159 for (SCM s = accepts_name_list_; gh_pair_p (s); s = ly_cdr (s))
161 Translator_def *t = unsmob_translator_def (odef->find_translator (ly_car (s)));
167 Link_array<Translator_def> best_result;
168 for (int i=0; i < accepteds.size (); i++)
171 don't check aliases, because \context Staff should not create RhythmicStaff.
173 if (gh_equal_p (accepteds[i]->type_name_, type_sym))
175 best_result.push (accepteds[i]);
180 int best_depth= INT_MAX;
181 for (int i=0; i < accepteds.size (); i++)
183 Translator_def * g = accepteds[i];
185 Link_array<Translator_def> result
186 = g->path_to_acceptable_translator (type_sym, odef);
187 if (result.size () && result.size () < best_depth)
190 best_result = result;
193 this following line was added in 1.9.3, but hsould've been
194 there all along... Let's hope it doesn't cause nightmares.
196 best_depth = result.size();
203 IMPLEMENT_SMOBS (Translator_def);
204 IMPLEMENT_DEFAULT_EQUAL_P (Translator_def);
208 trans_list (SCM namelist, Translator_group*tg)
211 for (SCM s = namelist; gh_pair_p (s) ; s = ly_cdr (s))
213 Translator * t = get_translator (ly_scm2string (ly_car (s)));
215 warning (_f ("can't find: `%s'", s));
218 Translator * tr = t->clone ();
219 SCM str = tr->self_scm ();
220 l = gh_cons (str, l);
222 tr->daddy_trans_ = tg;
223 tr->output_def_ = tg->output_def_;
225 scm_gc_unprotect_object (str);
233 Translator_def::instantiate (Music_output_def* md)
235 Translator * g = get_translator (ly_scm2string (translator_group_type_));
238 Translator_group *tg = dynamic_cast<Translator_group*> (g);
239 tg->output_def_ = md;
240 tg->definition_ = self_scm ();
243 TODO: ugh. we're reversing CONSISTS_NAME_LIST_ here
245 SCM l1 = trans_list (consists_name_list_, tg);
246 SCM l2 =trans_list (end_consists_name_list_,tg);
247 l1 = scm_reverse_x (l1, l2);
249 tg->simple_trans_list_ = l1;
255 Translator_def::apply_default_property_operations (Translator_group*tg)
257 apply_property_operations (tg, property_ops_);
262 Translator_def::clone_scm () const
264 Translator_def * t = new Translator_def (*this);
265 scm_gc_unprotect_object (t->self_scm());
266 return t->self_scm();
270 Translator_def::make_scm ()
272 Translator_def* t = new Translator_def;
273 scm_gc_unprotect_object (t->self_scm());
274 return t->self_scm();
279 Default child context as a SCM string, or something else if there is
283 Translator_def::default_child_context_name ()
285 SCM d = accepts_name_list_;
286 return gh_pair_p (d) ? ly_car (scm_last_pair (d)) : SCM_EOL;
290 Translator_def::to_alist () const
294 l = gh_cons (gh_cons (ly_symbol2scm ("consists"), consists_name_list_), l);
295 l = gh_cons (gh_cons (ly_symbol2scm ("description"), description_), l);
296 l = gh_cons (gh_cons (ly_symbol2scm ("aliases"), type_aliases_), l);
297 l = gh_cons (gh_cons (ly_symbol2scm ("end-consists"),
298 end_consists_name_list_), l);
299 l = gh_cons (gh_cons (ly_symbol2scm ("accepts"), accepts_name_list_), l);
300 l = gh_cons (gh_cons (ly_symbol2scm ("property-ops"), property_ops_), l);
305 l = gh_cons (gh_cons (ly_symbol2scm ("type-name"), type_name_), l);
307 l = gh_cons (gh_cons (ly_symbol2scm ("group-type"), translator_group_type_), l);