]> git.donarmstrong.com Git - lilypond.git/blob - lily/hyphen-engraver.cc
Merge branch 'lilypond/translation' of ssh://git.sv.gnu.org/srv/git/lilypond
[lilypond.git] / lily / hyphen-engraver.cc
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 1999--2010 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   bool current_lyric_is_skip_;
40
41 public:
42   TRANSLATOR_DECLARATIONS (Hyphen_engraver);
43
44 protected:
45
46   DECLARE_ACKNOWLEDGER (lyric_syllable);
47   DECLARE_TRANSLATOR_LISTENER (hyphen);
48
49   virtual void finalize ();
50
51   void stop_translation_timestep ();
52   void process_music ();
53 };
54
55 Hyphen_engraver::Hyphen_engraver ()
56 {
57   current_lyric_is_skip_ = false;
58   hyphen_ = 0;
59   finished_hyphen_ = 0;
60   finished_ev_ = 0;
61   ev_ = 0;
62 }
63
64 void
65 Hyphen_engraver::acknowledge_lyric_syllable (Grob_info i)
66 {
67   Item *item = i.item ();
68   SCM text = item->get_property ("text");
69   current_lyric_is_skip_ = ly_is_equal (text, scm_from_locale_string (" "));
70   
71   if (!hyphen_ && !current_lyric_is_skip_)
72     hyphen_ = make_spanner ("LyricSpace", item->self_scm ());
73
74   if (hyphen_)
75     hyphen_->set_bound (LEFT, item);
76       
77   if (finished_hyphen_ && !current_lyric_is_skip_)
78     finished_hyphen_->set_bound (RIGHT, item);
79 }
80
81 IMPLEMENT_TRANSLATOR_LISTENER (Hyphen_engraver, hyphen);
82 void
83 Hyphen_engraver::listen_hyphen (Stream_event *ev)
84 {
85   ASSIGN_EVENT_ONCE (ev_, ev);
86 }
87
88 void
89 completize_hyphen (Spanner *sp)
90 {
91   if (!sp->get_bound (RIGHT))
92     {
93       extract_item_set (sp, "heads", heads);
94       if (heads.size ())
95         sp->set_bound (RIGHT, heads.back ());
96     }
97 }
98
99 void
100 Hyphen_engraver::finalize ()
101 {
102   if (hyphen_)
103     {
104       completize_hyphen (hyphen_);
105
106       if (!hyphen_->get_bound (RIGHT))
107         {
108           hyphen_->warning (_ ("removing unterminated hyphen"));
109           hyphen_->suicide ();
110         }
111
112       hyphen_ = 0;
113     }
114
115   if (finished_hyphen_)
116     {
117       completize_hyphen (finished_hyphen_);
118
119       if (!finished_hyphen_->get_bound (RIGHT))
120         {
121           if (finished_ev_)
122             finished_hyphen_->warning (_ ("unterminated hyphen; removing"));
123           finished_hyphen_->suicide ();
124         }
125       finished_hyphen_ = 0;
126     }
127 }
128
129 void
130 Hyphen_engraver::process_music ()
131 {
132   if (ev_)
133     hyphen_ = make_spanner ("LyricHyphen", ev_->self_scm ());
134 }
135
136 void
137 Hyphen_engraver::stop_translation_timestep ()
138 {
139   if (finished_hyphen_ && finished_hyphen_->get_bound (RIGHT))
140     {
141       finished_hyphen_ = 0;
142       finished_ev_ = 0;
143     }
144   
145   if (finished_hyphen_ && hyphen_ && !current_lyric_is_skip_)
146     {
147       programming_error ("hyphen not finished yet");
148       finished_hyphen_ = 0;
149       finished_ev_ = 0;
150     }
151
152   if (hyphen_)
153     {
154       finished_hyphen_ = hyphen_;
155       finished_ev_ = ev_;
156     }
157   
158   hyphen_ = 0;
159   ev_ = 0;
160 }
161
162 ADD_ACKNOWLEDGER (Hyphen_engraver, lyric_syllable);
163
164 ADD_TRANSLATOR (Hyphen_engraver,
165                 /* doc */
166                 "Create lyric hyphens and distance constraints between words.",
167
168                 /* create */
169                 "LyricHyphen "
170                 "LyricSpace ",
171
172                 /* read */
173                 "",
174
175                 /* write */
176                 ""
177                 );