1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3 
4   Copyright (C) 1999--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 "engraver.hh"
21 #include "context.hh"
22 #include "item.hh"
23 #include "lily-imports.hh"
24 #include "pitch.hh"
25 #include "stream-event.hh"
26 #include "text-interface.hh"
27 
28 #include "translator.icc"
29 
30 using std::string;
31 using std::vector;
32 
33 class Note_name_engraver : public Engraver
34 {
35 public:
36   TRANSLATOR_DECLARATIONS (Note_name_engraver);
37 
38   vector<Stream_event *> events_;
39   void listen_note (Stream_event *);
40   void process_music ();
41   void stop_translation_timestep ();
42 };
43 
44 void
listen_note(Stream_event * ev)45 Note_name_engraver::listen_note (Stream_event *ev)
46 {
47   events_.push_back (ev);
48 }
49 
50 void
process_music()51 Note_name_engraver::process_music ()
52 {
53   SCM markup_list = SCM_EOL;
54 
55   for (vsize i = 0; i < events_.size (); i++)
56     {
57       SCM pitch = get_property (events_[i], "pitch");
58       SCM proc = get_property (this, "noteNameFunction");
59       SCM sep = get_property (this, "noteNameSeparator");
60 
61       if (i)
62         markup_list = scm_append (scm_list_2 (scm_list_1 (Text_interface::is_markup (sep) ? sep : ly_string2scm (" ")),
63                                               markup_list));
64 
65       if (ly_is_procedure (proc))
66         {
67           SCM pitch_name = scm_call_2 (proc, pitch, context ()->self_scm ());
68           markup_list = scm_append (scm_list_2 (scm_list_1 (pitch_name), markup_list));
69         }
70       else
71         programming_error ("No translation function defined as noteNameFunction.");
72     }
73   if (!scm_is_null (markup_list))
74     {
75       Item *n = make_item ("NoteName", events_[0]->self_scm ());
76       SCM text = Lily::make_concat_markup (scm_reverse (markup_list));
77       set_property (n, "text", text);
78     }
79 }
80 
81 void
stop_translation_timestep()82 Note_name_engraver::stop_translation_timestep ()
83 {
84   events_.clear ();
85 }
86 
Note_name_engraver(Context * c)87 Note_name_engraver::Note_name_engraver (Context *c)
88   : Engraver (c)
89 {
90 }
91 
92 void
boot()93 Note_name_engraver::boot ()
94 {
95   ADD_LISTENER (Note_name_engraver, note);
96 }
97 
98 ADD_TRANSLATOR (Note_name_engraver,
99                 /* doc */
100                 "Print pitches as words.",
101 
102                 /* create */
103                 "NoteName ",
104 
105                 /* read */
106                 "noteNameFunction "
107                 "noteNameSeparator "
108                 "printAccidentalNames "
109                 "printNotesLanguage "
110                 "printOctaveNames ",
111 
112                 /* write */
113                 ""
114                );
115