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