1 /*
2 This file is part of LilyPond, the GNU music typesetter.
3
4 Copyright (C) 1997--2020 Han-Wen Nienhuys <hanwen@xs4all.nl>
5
6 LilyPond is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 LilyPond is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "property-iterator.hh"
21
22 #include "context-def.hh"
23 #include "global-context.hh"
24 #include "international.hh"
25 #include "music.hh"
26
27 bool check_grob (Music *mus, SCM sym);
28
29 /**
30 There is no real processing to a property: just lookup the
31 translation unit, and set the property.
32 */
33 void
process(Moment mom)34 Property_iterator::process (Moment mom)
35 {
36 Context *o = get_context ();
37 Music *m = get_music ();
38
39 send_stream_event (o, "SetProperty", m->origin (),
40 ly_symbol2scm ("symbol"), get_property (m, "symbol"),
41 ly_symbol2scm ("value"), get_property (m, "value"),
42 ly_symbol2scm ("once"), get_property (m, "once"));
43
44 Simple_music_iterator::process (mom);
45 }
46
47 void
process(Moment mom)48 Property_unset_iterator::process (Moment mom)
49 {
50 Context *o = get_context ();
51 Music *m = get_music ();
52
53 send_stream_event (o, "UnsetProperty", m->origin (),
54 ly_symbol2scm ("symbol"), get_property (m, "symbol"),
55 ly_symbol2scm ("once"), get_property (m, "once"));
56
57 Simple_music_iterator::process (mom);
58 }
59
60 bool
check_grob(Music * mus,SCM sym)61 check_grob (Music *mus, SCM sym)
62 {
63 bool g = from_scm<bool> (scm_object_property (sym, ly_symbol2scm ("is-grob?")));
64
65 if (!g)
66 mus->warning (_f ("not a grob name, `%s'", ly_symbol2string (sym)));
67
68 return g;
69 }
70
71 SCM
get_property_path(Music * m)72 get_property_path (Music *m)
73 {
74 SCM grob_property_path = get_property (m, "grob-property-path");
75
76 SCM eprop = get_property (m, "grob-property");
77 if (scm_is_symbol (eprop))
78 {
79 grob_property_path = scm_list_1 (eprop);
80 }
81
82 return grob_property_path;
83 }
84
85 void
process(Moment m)86 Push_property_iterator::process (Moment m)
87 {
88 SCM sym = get_property (get_music (), "symbol");
89 if (check_grob (get_music (), sym))
90 {
91 SCM grob_property_path = get_property_path (get_music ());
92 SCM val = get_property (get_music (), "grob-value");
93 SCM once = get_property (get_music (), "once");
94
95 if (from_scm<bool> (get_property (get_music (), "pop-first"))
96 && !from_scm<bool> (once))
97 send_stream_event (get_context (), "Revert", origin (),
98 ly_symbol2scm ("symbol"), sym,
99 ly_symbol2scm ("property-path"), grob_property_path);
100
101 send_stream_event (get_context (), "Override", origin (),
102 ly_symbol2scm ("symbol"), sym,
103 ly_symbol2scm ("property-path"), grob_property_path,
104 ly_symbol2scm ("once"), once,
105 ly_symbol2scm ("value"), val);
106 }
107 Simple_music_iterator::process (m);
108 }
109
110 void
process(Moment mom)111 Pop_property_iterator::process (Moment mom)
112 {
113 Music *m = get_music ();
114 SCM sym = get_property (m, "symbol");
115
116 if (check_grob (m, sym))
117 {
118 SCM grob_property_path = get_property_path (m);
119
120 send_stream_event (get_context (), "Revert", m->origin (),
121 ly_symbol2scm ("symbol"), sym,
122 ly_symbol2scm ("once"), get_property (m, "once"),
123 ly_symbol2scm ("property-path"), grob_property_path);
124 }
125 Simple_music_iterator::process (mom);
126 }
127
128 IMPLEMENT_CTOR_CALLBACK (Pop_property_iterator);
129 IMPLEMENT_CTOR_CALLBACK (Push_property_iterator);
130 IMPLEMENT_CTOR_CALLBACK (Property_iterator);
131 IMPLEMENT_CTOR_CALLBACK (Property_unset_iterator);
132