]> git.donarmstrong.com Git - lilypond.git/blob - lily/hyphen-engraver.cc
* lily/parser.yy (Music_list): add error-found to music with errors.
[lilypond.git] / lily / hyphen-engraver.cc
1 /*
2   hyphen-engraver.cc -- implement Hyphen_engraver
3
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 1999--2004 Glen Prideaux <glenprideaux@iname.com>,
7                   Han-Wen Nienhuys <hanwen@cs.uu.nl>,
8                   Jan Nieuwenhuizen <janneke@gnu.org>
9 */
10
11 #include "warn.hh"
12 #include "item.hh"
13 #include "engraver.hh"
14 #include "spanner.hh"
15
16 class Hyphen_engraver : public Engraver
17 {
18   Music *ev_;
19   Spanner *hyphen_;
20   Spanner *finished_hyphen_;  
21 public:
22   TRANSLATOR_DECLARATIONS (Hyphen_engraver);
23
24 protected:
25   virtual void acknowledge_grob (Grob_info);
26   virtual void finalize ();
27   virtual bool try_music (Music*);
28   virtual void stop_translation_timestep ();
29   virtual void process_music ();
30 private:
31
32 };
33
34
35
36
37 Hyphen_engraver::Hyphen_engraver ()
38 {
39   hyphen_ = 0;
40   finished_hyphen_ = 0;
41   ev_ = 0;
42 }
43
44 void
45 Hyphen_engraver::acknowledge_grob (Grob_info i)
46 {
47   Item * item =  dynamic_cast<Item*> (i.grob_);
48   // -> Text_item
49   if (item && item->internal_has_interface (ly_symbol2scm ("lyric-syllable-interface")))
50     {
51       if (hyphen_)
52         hyphen_->set_bound (LEFT, item);
53
54       if (finished_hyphen_)
55         finished_hyphen_->set_bound (RIGHT, item);
56     }
57 }
58
59
60 bool
61 Hyphen_engraver::try_music (Music* r)
62 {
63   if (ev_)
64     return false;
65
66   ev_ = r;
67   return true;
68 }
69
70 void
71 completize_hyphen (Spanner* sp)
72 {
73   if (!sp->get_bound (RIGHT))
74     {
75       SCM heads = sp->get_property ("heads");
76       if (scm_is_pair (heads))
77         {
78           Item* it = dynamic_cast<Item*> (unsmob_grob (scm_car (heads)));
79           if (it)
80             sp->set_bound (RIGHT, it);
81         }
82     }
83 }
84
85   
86
87 void
88 Hyphen_engraver::finalize ()
89 {
90   if (hyphen_)
91     {
92       completize_hyphen (hyphen_);
93
94       if (!hyphen_->get_bound (RIGHT))
95         {
96           hyphen_->warning (_ ("removing unterminated hyphen"));
97           hyphen_->suicide ();
98         }
99
100       hyphen_ = 0;
101     }
102
103   if (finished_hyphen_)
104     {
105       completize_hyphen (finished_hyphen_);
106
107       if (!finished_hyphen_->get_bound (RIGHT))
108         {
109           finished_hyphen_->warning (_("unterminated hyphen; removing"));
110           finished_hyphen_->suicide ();
111         }
112       finished_hyphen_ =0;
113     }
114 }
115
116 void
117 Hyphen_engraver::process_music ()
118 {
119   if (ev_)
120     {
121       hyphen_ = make_spanner ("LyricHyphen", ev_->self_scm ()
122 );
123     }
124 }
125
126
127 void
128 Hyphen_engraver::stop_translation_timestep ()
129 {
130   if (finished_hyphen_ && finished_hyphen_->get_bound (RIGHT))
131     {
132       finished_hyphen_ = 0;
133     }
134
135   if (finished_hyphen_ && hyphen_)
136     {
137       programming_error ("Haven't finished hyphen yet.");
138       finished_hyphen_ =0;
139     }
140   
141   if (hyphen_)
142     finished_hyphen_ = hyphen_;
143   hyphen_ = 0;
144
145   ev_ = 0;
146 }
147
148
149
150
151 ENTER_DESCRIPTION (Hyphen_engraver,
152 /* descr */       "Create lyric hyphens",
153 /* creats*/       "LyricHyphen",
154 /* accepts */     "hyphen-event",
155 /* acks  */      "lyric-syllable-interface",
156 /* reads */       "",
157 /* write */       "");