]> git.donarmstrong.com Git - lilypond.git/blob - lily/hyphen-engraver.cc
Issue 4957: parser.yy: loc_on_music -> loc_on_copy
[lilypond.git] / lily / hyphen-engraver.cc
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 1999--2015 Glen Prideaux <glenprideaux@iname.com>,
5   Han-Wen Nienhuys <hanwen@xs4all.nl>,
6   Jan Nieuwenhuizen <janneke@gnu.org>
7
8   LilyPond is free software: you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation, either version 3 of the License, or
11   (at your option) any later version.
12
13   LilyPond is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "engraver.hh"
23 #include "international.hh"
24 #include "item.hh"
25 #include "pointer-group-interface.hh"
26 #include "spanner.hh"
27 #include "stream-event.hh"
28 #include "warn.hh"
29
30 #include "translator.icc"
31
32 class Hyphen_engraver : public Engraver
33 {
34   Stream_event *ev_;
35   Stream_event *finished_ev_;
36
37   Spanner *hyphen_;
38   Spanner *finished_hyphen_;
39
40 public:
41   TRANSLATOR_DECLARATIONS (Hyphen_engraver);
42
43 protected:
44
45   void acknowledge_lyric_syllable (Grob_info);
46   void listen_hyphen (Stream_event *);
47
48   virtual void finalize ();
49
50   void stop_translation_timestep ();
51   void process_music ();
52 };
53
54 Hyphen_engraver::Hyphen_engraver ()
55 {
56   hyphen_ = 0;
57   finished_hyphen_ = 0;
58   finished_ev_ = 0;
59   ev_ = 0;
60 }
61
62 void
63 Hyphen_engraver::acknowledge_lyric_syllable (Grob_info i)
64 {
65   Item *item = i.item ();
66
67   if (!hyphen_)
68     hyphen_ = make_spanner ("LyricSpace", item->self_scm ());
69
70   if (hyphen_)
71     hyphen_->set_bound (LEFT, item);
72
73   if (finished_hyphen_)
74     finished_hyphen_->set_bound (RIGHT, item);
75 }
76
77 void
78 Hyphen_engraver::listen_hyphen (Stream_event *ev)
79 {
80   ASSIGN_EVENT_ONCE (ev_, ev);
81 }
82
83 void
84 completize_hyphen (Spanner *sp)
85 {
86   if (!sp->get_bound (RIGHT))
87     {
88       extract_item_set (sp, "heads", heads);
89       if (heads.size ())
90         sp->set_bound (RIGHT, heads.back ());
91     }
92 }
93
94 void
95 Hyphen_engraver::finalize ()
96 {
97   if (hyphen_)
98     {
99       completize_hyphen (hyphen_);
100
101       if (!hyphen_->get_bound (RIGHT))
102         {
103           hyphen_->warning (_ ("removing unterminated hyphen"));
104           hyphen_->suicide ();
105         }
106
107       hyphen_ = 0;
108     }
109
110   if (finished_hyphen_)
111     {
112       completize_hyphen (finished_hyphen_);
113
114       if (!finished_hyphen_->get_bound (RIGHT))
115         {
116           if (finished_ev_)
117             finished_hyphen_->warning (_ ("unterminated hyphen; removing"));
118           finished_hyphen_->suicide ();
119         }
120       finished_hyphen_ = 0;
121     }
122 }
123
124 void
125 Hyphen_engraver::process_music ()
126 {
127   if (ev_)
128     hyphen_ = make_spanner ("LyricHyphen", ev_->self_scm ());
129 }
130
131 void
132 Hyphen_engraver::stop_translation_timestep ()
133 {
134   if (finished_hyphen_ && finished_hyphen_->get_bound (RIGHT))
135     {
136       finished_hyphen_ = 0;
137       finished_ev_ = 0;
138     }
139
140   if (finished_hyphen_ && hyphen_)
141     {
142       programming_error ("hyphen not finished yet");
143       finished_hyphen_ = 0;
144       finished_ev_ = 0;
145     }
146
147   if (hyphen_)
148     {
149       finished_hyphen_ = hyphen_;
150       finished_ev_ = ev_;
151     }
152
153   hyphen_ = 0;
154   ev_ = 0;
155 }
156
157
158 void
159 Hyphen_engraver::boot ()
160 {
161   ADD_LISTENER (Hyphen_engraver, hyphen);
162   ADD_ACKNOWLEDGER (Hyphen_engraver, lyric_syllable);
163 }
164
165 ADD_TRANSLATOR (Hyphen_engraver,
166                 /* doc */
167                 "Create lyric hyphens and distance constraints between words.",
168
169                 /* create */
170                 "LyricHyphen "
171                 "LyricSpace ",
172
173                 /* read */
174                 "",
175
176                 /* write */
177                 ""
178                );