* lily/include/lily-guile.hh: many new ly_ functions. Thanks to
[lilypond.git] / lily / engraver-group-engraver.cc
blobdc51fd495f52acbd7a9e365c0a8a4a5207788c3b
1 /*
2 engraver-group-engraver.cc -- implement Engraver_group_engraver
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
9 #include "flower-proto.hh"
10 #include "engraver-group-engraver.hh"
11 #include "engraver.hh"
12 #include "warn.hh"
13 #include "paper-score.hh"
14 #include "grob.hh"
15 #include "context.hh"
19 void
20 Engraver_group_engraver::announce_grob (Grob_info info)
22 announce_infos_.push (info);
23 get_daddy_engraver ()->announce_grob (info);
27 SCM find_acknowledge_engravers (SCM gravlist, SCM meta);
28 SCM find_accept_engravers (SCM gravlist, SCM music_descr);
30 void
31 Engraver_group_engraver::acknowledge_grobs ()
33 if (!announce_infos_.size ())
34 return ;
36 SCM tab = get_property ("acknowledgeHashTable");
37 SCM name_sym = ly_symbol2scm ("name");
38 SCM meta_sym = ly_symbol2scm ("meta");
41 for (int j =0; j < announce_infos_.size (); j++)
43 Grob_info info = announce_infos_[j];
45 SCM meta = info.grob_->internal_get_property (meta_sym);
46 SCM nm = scm_assoc (name_sym, meta);
47 if (ly_pair_p (nm))
48 nm = ly_cdr (nm);
49 else
52 it's tempting to put an assert for
53 immutable_property_alist_ == '(), but in fact, some
54 engravers (clef-engraver) add some more information to the
55 immutable_property_alist_ (after it has been '()-ed).
57 We ignore the grob anyway. He who has no name, shall not
58 be helped. */
60 continue;
63 SCM acklist = scm_hashq_ref (tab, nm, SCM_UNDEFINED);
64 if (acklist == SCM_BOOL_F)
66 acklist = find_acknowledge_engravers (scm_cons (self_scm (), get_simple_trans_list ()), meta);
67 scm_hashq_set_x (tab, nm, acklist);
70 for (SCM p = acklist; ly_pair_p (p); p = ly_cdr (p))
72 Translator * t = unsmob_translator (ly_car (p));
73 Engraver * eng = dynamic_cast<Engraver*> (t);
74 if (eng && eng != info.origin_trans_)
75 eng->acknowledge_grob (info);
81 void
82 Engraver_group_engraver::do_announces ()
86 engraver_each (get_simple_trans_list (),
87 &Engraver::process_acknowledged_grobs);
89 if (!announce_infos_.size ())
90 break;
92 acknowledge_grobs ();
93 announce_infos_.clear ();
95 while (1);
100 void
101 Engraver_group_engraver::initialize ()
103 SCM tab = scm_make_vector (scm_int2num (61), SCM_BOOL_F);
104 daddy_context_->set_property ("acknowledgeHashTable", tab);
106 Translator_group::initialize ();
109 Engraver_group_engraver::Engraver_group_engraver () {}
111 ENTER_DESCRIPTION (Engraver_group_engraver,
112 /* descr */ "A group of engravers taken together",
113 /* creats*/ "",
114 /* accepts */ "",
115 /* acks */ "",
116 /* reads */ "",
117 /* write */ "");
121 /*****************/
124 bool
125 engraver_valid (Translator*tr, SCM ifaces)
127 SCM ack_ifs = scm_assoc (ly_symbol2scm ("interfaces-acked"), tr->translator_description ());
128 ack_ifs = ly_cdr (ack_ifs);
129 for (SCM s = ifaces; ly_pair_p (s); s = ly_cdr (s))
130 if (scm_c_memq (ly_car (s), ack_ifs) != SCM_BOOL_F)
131 return true;
132 return false;
138 find_acknowledge_engravers (SCM gravlist, SCM meta_alist)
140 SCM ifaces = ly_cdr (scm_assoc (ly_symbol2scm ("interfaces"), meta_alist));
142 SCM l = SCM_EOL;
143 for (SCM s = gravlist; ly_pair_p (s); s = ly_cdr (s))
145 Translator* tr = unsmob_translator (ly_car (s));
146 if (engraver_valid (tr, ifaces))
147 l = scm_cons (tr->self_scm (), l);
149 l = scm_reverse_x (l, SCM_EOL);
151 return l;
155 /* c&p engraver-group.cc */
156 void
157 recurse_down_engravers (Context * c, Engraver_method ptr, bool context_first)
159 Engraver_group_engraver * tg
160 = dynamic_cast<Engraver_group_engraver*> (unsmob_translator (c->implementation_));
163 if (!context_first)
165 engraver_each (tg->get_simple_trans_list (),
166 ptr);
168 (tg->*ptr) ();
171 for (SCM s = c->context_list_ ; ly_pair_p (s);
172 s =ly_cdr (s))
174 recurse_down_engravers (unsmob_context (ly_car (s)), ptr, context_first);
177 if (context_first)
179 engraver_each (tg->get_simple_trans_list (),
180 ptr);
181 (tg->*ptr) ();
186 void
187 engraver_each (SCM list, Engraver_method method)
189 for (SCM p = list; ly_pair_p (p); p = ly_cdr (p))
191 Engraver * e = dynamic_cast<Engraver*>(unsmob_translator (ly_car (p)));
192 if (e)
193 (e->*method) ();