]> git.donarmstrong.com Git - lilypond.git/blob - lily/hyphen-engraver.cc
Run grand-replace (issue 3765)
[lilypond.git] / lily / hyphen-engraver.cc
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 1999--2014 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   DECLARE_ACKNOWLEDGER (lyric_syllable);
46   DECLARE_TRANSLATOR_LISTENER (hyphen);
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 IMPLEMENT_TRANSLATOR_LISTENER (Hyphen_engraver, hyphen);
78 void
79 Hyphen_engraver::listen_hyphen (Stream_event *ev)
80 {
81   ASSIGN_EVENT_ONCE (ev_, ev);
82 }
83
84 void
85 completize_hyphen (Spanner *sp)
86 {
87   if (!sp->get_bound (RIGHT))
88     {
89       extract_item_set (sp, "heads", heads);
90       if (heads.size ())
91         sp->set_bound (RIGHT, heads.back ());
92     }
93 }
94
95 void
96 Hyphen_engraver::finalize ()
97 {
98   if (hyphen_)
99     {
100       completize_hyphen (hyphen_);
101
102       if (!hyphen_->get_bound (RIGHT))
103         {
104           hyphen_->warning (_ ("removing unterminated hyphen"));
105           hyphen_->suicide ();
106         }
107
108       hyphen_ = 0;
109     }
110
111   if (finished_hyphen_)
112     {
113       completize_hyphen (finished_hyphen_);
114
115       if (!finished_hyphen_->get_bound (RIGHT))
116         {
117           if (finished_ev_)
118             finished_hyphen_->warning (_ ("unterminated hyphen; removing"));
119           finished_hyphen_->suicide ();
120         }
121       finished_hyphen_ = 0;
122     }
123 }
124
125 void
126 Hyphen_engraver::process_music ()
127 {
128   if (ev_)
129     hyphen_ = make_spanner ("LyricHyphen", ev_->self_scm ());
130 }
131
132 void
133 Hyphen_engraver::stop_translation_timestep ()
134 {
135   if (finished_hyphen_ && finished_hyphen_->get_bound (RIGHT))
136     {
137       finished_hyphen_ = 0;
138       finished_ev_ = 0;
139     }
140
141   if (finished_hyphen_ && hyphen_)
142     {
143       programming_error ("hyphen not finished yet");
144       finished_hyphen_ = 0;
145       finished_ev_ = 0;
146     }
147
148   if (hyphen_)
149     {
150       finished_hyphen_ = hyphen_;
151       finished_ev_ = ev_;
152     }
153
154   hyphen_ = 0;
155   ev_ = 0;
156 }
157
158 ADD_ACKNOWLEDGER (Hyphen_engraver, lyric_syllable);
159
160 ADD_TRANSLATOR (Hyphen_engraver,
161                 /* doc */
162                 "Create lyric hyphens and distance constraints between words.",
163
164                 /* create */
165                 "LyricHyphen "
166                 "LyricSpace ",
167
168                 /* read */
169                 "",
170
171                 /* write */
172                 ""
173                );