]> git.donarmstrong.com Git - lilypond.git/blob - lily/property-engraver.cc
patch::: 1.3.49.hwn1: deze dus
[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 "protected-scm.hh"
13 #include "dictionary.hh"
14 #include "score-element.hh"
15
16 class Property_engraver : public Engraver
17 {
18   /*
19     UGH. Junk Dictionary
20   */
21   Dictionary<Protected_scm> prop_dict_; // junkme
22   void apply_properties (SCM, Score_element*);
23
24 protected:
25   virtual void acknowledge_element (Score_element_info ei);
26   virtual void do_creation_processing ();
27
28   VIRTUAL_COPY_CONS(Translator);
29 };
30
31 void
32 Property_engraver::do_creation_processing ()
33 {
34   SCM plist = get_property ("Generic_property_list");
35   for (; SCM_NIMP (plist); plist = gh_cdr (plist))
36     {
37       SCM elt_props = gh_car (plist);
38       prop_dict_[ly_scm2string (gh_car (elt_props))] = gh_cdr (elt_props);
39     }
40 }
41
42 void
43 Property_engraver::acknowledge_element (Score_element_info i)
44 {
45   if (prop_dict_.elem_b (i.elem_l_->name()))
46     {
47       SCM p = prop_dict_[i.elem_l_->name()];
48       apply_properties (p,i.elem_l_);
49     }
50   if (prop_dict_.elem_b ("all"))
51     {
52       apply_properties (prop_dict_["all"], i.elem_l_);
53     }
54 }
55
56
57 void
58 Property_engraver::apply_properties (SCM p, Score_element *e)
59 {  
60   for (; gh_pair_p (p); p = gh_cdr (p))
61     {
62       /*
63         Try each property in order; earlier descriptions take
64         precedence over later ones, and we don't touch elt-properties if
65         they're already set.
66       */
67       
68       SCM entry = gh_car (p);
69       SCM prop_sym = gh_car (entry);
70       SCM type_p   = gh_cadr (entry);
71       SCM elt_prop_sym = gh_caddr (entry);
72
73       SCM preset = scm_assq(elt_prop_sym, e->element_property_alist_);
74       if (preset != SCM_BOOL_F)
75         continue;
76   
77       SCM val = get_property (prop_sym);
78
79      
80       if (val == SCM_UNDEFINED)
81         ;                       // Not defined in context.
82       else if (gh_apply (type_p, scm_listify (val, SCM_UNDEFINED))
83                == SCM_BOOL_T)   // defined and  right type: do it
84         e->set_elt_property (ly_symbol2string (elt_prop_sym), val);
85       else
86  /*
87             we don't print a warning if VAL == #f, because we would
88             get lots of warnings when we restore stuff to default, eg.
89
90             slurDash = #1 [...] slurDash = ##f
91
92             should not cause "type error: slurDash expects number not
93             boolean"
94
95           */
96         if (val != SCM_BOOL_F)
97         {                       // not the right type: error message.
98           SCM errport = scm_current_error_port ();
99           warning (_("Wrong type for property"));
100           scm_display (prop_sym, errport);
101           scm_puts (", type predicate: ", errport);
102           scm_display (type_p, errport);
103           scm_puts (", value found: ", errport);
104           scm_display (val, errport);
105           scm_puts (" type: ", errport);
106           scm_display (ly_type (val), errport);
107           scm_puts ("\n", errport);
108         }
109     }
110 }
111
112 ADD_THIS_TRANSLATOR(Property_engraver);