]> git.donarmstrong.com Git - lilypond.git/blob - lily/property-engraver.cc
release: 1.3.93
[lilypond.git] / lily / property-engraver.cc
1 /*   
2   property-engraver.cc --  implement Property engraver
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 1999--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   
8  */
9
10 #include "lily-guile.hh"
11 #include "engraver.hh"
12 #include "dictionary.hh"
13 #include "score-element.hh"
14 #include "scm-hash.hh"
15 #include "translator-group.hh"
16
17 /*
18   JUNKME: should use pushproperty everywhere.
19   
20  */
21 class Property_engraver : public Engraver
22 {
23   /*
24     UGH. Junk Dictionary
25   */
26   Scheme_hash_table *prop_dict_;        // junkme
27   void apply_properties (SCM, Score_element*, Translator_group *origin);
28
29 protected:
30   virtual void acknowledge_element (Score_element_info ei);
31   virtual void do_creation_processing ();
32   virtual void do_removal_processing ();
33 public:
34   ~Property_engraver();
35   Property_engraver();
36   VIRTUAL_COPY_CONS(Translator);
37 };
38
39
40
41 Property_engraver::Property_engraver()
42 {
43   prop_dict_ = 0;
44 }
45 void
46 Property_engraver::do_removal_processing()
47 {
48   
49 }
50
51 Property_engraver::~Property_engraver ()
52 {
53   if (prop_dict_)
54     scm_unprotect_object (prop_dict_->self_scm ());
55 }
56
57 void
58 Property_engraver::do_creation_processing ()
59 {
60   prop_dict_ = new Scheme_hash_table;
61
62   SCM plist = get_property (ly_symbol2scm ("Generic_property_list"));
63   for (; gh_pair_p (plist); plist = gh_cdr (plist))
64     {
65       SCM elt_props = gh_car (plist);
66       prop_dict_->set (gh_car (elt_props), gh_cdr (elt_props));
67     }
68 }
69
70 void
71 Property_engraver::acknowledge_element (Score_element_info i)
72 {
73   SCM ifs = i.elem_l_->get_elt_property ("interfaces");
74   SCM props;
75   for (; gh_pair_p (ifs); ifs = gh_cdr (ifs))
76     {      
77       if (prop_dict_->try_retrieve (gh_car (ifs), &props))
78         {
79           apply_properties (props,i.elem_l_, i.origin_trans_l_->daddy_trans_l_);
80         }
81     }
82
83   if (prop_dict_->try_retrieve (ly_symbol2scm ("all"), &props))
84     {
85       apply_properties (props, i.elem_l_, i.origin_trans_l_->daddy_trans_l_);
86     }
87 }
88
89
90 void
91 Property_engraver::apply_properties (SCM p, Score_element *e, Translator_group*origin)
92 {
93   for (; gh_pair_p (p); p = gh_cdr (p))
94     {
95       /*
96         Try each property in order; earlier descriptions take
97         precedence over later ones, and we don't touch elt-properties if
98         they're already set.
99       */
100       
101       SCM entry = gh_car (p);
102       SCM prop_sym = gh_car (entry);
103       SCM type_p   = gh_cadr (entry);
104       SCM elt_prop_sym = gh_caddr (entry);
105
106       SCM preset = scm_assq(elt_prop_sym, e->mutable_property_alist_);
107       if (preset != SCM_BOOL_F)
108         continue;
109   
110       SCM val = get_property (prop_sym);
111
112       if (val == SCM_UNDEFINED)
113         ;                       // Not defined in context.
114       else if (gh_apply (type_p, scm_listify (val, SCM_UNDEFINED))
115                == SCM_BOOL_T)   // defined and  right type: do it
116         {
117           e->set_elt_property (elt_prop_sym, val);
118
119           String msg = "Property_engraver is deprecated. Use\n \\property "
120             + origin->type_str_
121             + ".basicXXXXProperties"
122             + " \\push #'"
123             + ly_symbol2string (elt_prop_sym)
124             + " = #";
125           warning (msg);
126           scm_display (val, scm_current_error_port ());
127         }
128       else
129
130         /*
131             we don't print a warning if VAL == #f, because we would
132             get lots of warnings when we restore stuff to default, eg.
133
134             slurDash = #1 [...] slurDash = ##f
135
136             should not cause "type error: slurDash expects number not
137             boolean"
138
139         */
140         if (val != SCM_BOOL_F)
141           {                     // not the right type: error message.
142             SCM errport = scm_current_error_port ();
143             warning (_("Wrong type for property"));
144             scm_display (prop_sym, errport);
145             scm_puts (", type predicate: ", errport);
146             scm_display (type_p, errport);
147             scm_puts (", value found: ", errport);
148             scm_display (val, errport);
149             scm_puts (" type: ", errport);
150             scm_display (ly_type (val), errport);
151             scm_puts ("\n", errport);
152           }
153     }
154 }
155
156 ADD_THIS_TRANSLATOR(Property_engraver);