foo1 __ bar2. __ _4 baz1 __ }
> })
+If you want to have hyphens centred between syllables (rather than attached
+to the end of the first syllable) you can use the special code(--) lyric as
+separate word between syllables. This will result in a hyphen whose length
+varies depending on the space between syllables, and centred between the
+syllables. For example:
+mudela(verbatim)(\score{
+ < \notes \transpose c'' {c d e c | c d e c | e f g'2 |
+ e'4 f g'2 \bar "|."; }
+ \context Lyrics \lyrics {
+ DOEXPAND(Fr\)`e4 -- re Ja -- que DOEXPAND(Fr\)`e -- re Ja -- que
+ Dor -- mez vous?2 Dor4 -- mez vous?2 }
+ >
+})
+
+
sect(Time)
-
+pl 53.gp1
+ - added Hyphen-engraver, Hyphen-spanner
+************
pl 52.jcn3
- bf: mi2mu: midi without key
- try at grace-performer-group; breaks MIDI output even when no \grace
MAJOR_VERSION=1
MINOR_VERSION=1
PATCH_LEVEL=53
-MY_PATCH_LEVEL=
+MY_PATCH_LEVEL=gp1
# use the above to send patches: MY_PATCH_LEVEL is always empty for a
# released version.
--- /dev/null
+\score{
+ <
+ \context Staff \notes { c' () c' () c' c' }
+ \context Lyrics \context LyricVoice \lyrics { bla -- alb xxx -- yyy }
+ >
+}
+
+\version "1.0.21";
+
+
+
--- /dev/null
+/*
+ hyphen-engraver.cc -- implement Hyphen_engraver
+
+ (c) 1999 Glen Prideaux <glenprideaux@iname.com>
+*/
+
+#include "proto.hh"
+#include "musical-request.hh"
+#include "hyphen-engraver.hh"
+#include "hyphen-spanner.hh"
+#include "score-column.hh"
+#include "text-item.hh"
+#include "extender-engraver.hh"
+
+ADD_THIS_TRANSLATOR (Hyphen_engraver);
+
+Hyphen_engraver::Hyphen_engraver ()
+{
+ hyphen_spanner_p_ = 0;
+ req_l_ = 0;
+}
+
+void
+Hyphen_engraver::acknowledge_element (Score_element_info i)
+{
+ if (Text_item* t = dynamic_cast<Text_item*> (i.elem_l_))
+ {
+ Rhythmic_req * rh = dynamic_cast<Rhythmic_req*> (i.req_l_);
+ if (!rh)
+ return;
+
+ now_lyrics_.push (Text_lyric_tuple (t, rh, now_mom () + rh->length_mom ()));
+ /*
+ UGH. What do we do in case of multiple alternatives?
+ */
+ if (hyphen_spanner_p_
+ && !hyphen_spanner_p_->spanned_drul_[RIGHT]
+ )
+ {
+ hyphen_spanner_p_->set_textitem (RIGHT, t);
+ }
+ }
+}
+
+
+bool
+Hyphen_engraver::do_try_music (Music* r)
+{
+ if (Hyphen_req* p = dynamic_cast <Hyphen_req *> (r))
+ {
+ if (req_l_)
+ return false;
+
+ req_l_ = p;
+ return true;
+ }
+ return false;
+}
+
+void
+Hyphen_engraver::do_removal_processing ()
+{
+ if (hyphen_spanner_p_)
+ {
+ req_l_->warning (_ ("unterminated hyphen"));
+ hyphen_spanner_p_->set_bounds(RIGHT, get_staff_info ().command_pcol_l ());
+ }
+}
+
+void
+Hyphen_engraver::do_process_requests ()
+{
+ Array<Text_lyric_tuple> stopped_texts;
+ Moment now = now_mom ();
+
+ stopped_texts.clear ();
+ while (past_lyrics_pq_.size ()
+ && past_lyrics_pq_.front ().end_ == now)
+ stopped_texts.push (past_lyrics_pq_.get ());
+
+ if (req_l_)
+ {
+ if (!stopped_texts.size ())
+ {
+ req_l_->warning ("Nothing to connect hyphen to on the left. Ignoring hyphen request");
+ return;
+ }
+
+ hyphen_spanner_p_ = new Hyphen_spanner;
+ hyphen_spanner_p_->set_textitem (LEFT, stopped_texts[0].text_l_);
+ announce_element (Score_element_info (hyphen_spanner_p_, req_l_));
+ }
+}
+
+
+void
+Hyphen_engraver::do_pre_move_processing ()
+{
+ for (int i=0; i < now_lyrics_.size (); i++)
+ {
+ past_lyrics_pq_.insert (now_lyrics_[i]);
+ }
+ now_lyrics_.clear ();
+
+ if (hyphen_spanner_p_)
+ {
+ typeset_element (hyphen_spanner_p_);
+ hyphen_spanner_p_ = 0;
+ }
+}
+void
+Hyphen_engraver::do_post_move_processing ()
+{
+ Moment now = now_mom ();
+ while (past_lyrics_pq_.size () && past_lyrics_pq_.front ().end_ < now)
+ past_lyrics_pq_.delmin ();
+
+ req_l_ =0;
+}
+
+
--- /dev/null
+/*
+ hyphen-spanner.cc -- implement Hyphen_spanner
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1999 Glen Prideaux <glenprideaux@iname.com>
+
+ (adapted from extender-spanner)
+*/
+
+/*
+ TODO: too complicated implementation. Why the dx_drul?.
+ */
+
+#include <math.h>
+#include "box.hh"
+#include "debug.hh"
+#include "lookup.hh"
+#include "molecule.hh"
+#include "p-col.hh"
+#include "paper-def.hh"
+#include "hyphen-spanner.hh"
+
+Hyphen_spanner::Hyphen_spanner ()
+ : Directional_spanner ()
+{
+ dx_f_drul_[LEFT] = dx_f_drul_[RIGHT] = 0.0;
+}
+
+// UGH - is this even used?
+Offset
+Hyphen_spanner::center () const
+{
+ Real dx = extent (X_AXIS).length ();
+
+ return Offset (dx / 2, 0);
+}
+
+Molecule*
+Hyphen_spanner::do_brew_molecule_p () const
+{
+ Molecule* mol_p = new Molecule;
+
+ Real w = extent (X_AXIS).length ();
+
+ w += (dx_f_drul_[RIGHT] - dx_f_drul_[LEFT]);
+
+ Real th = paper_l ()->get_realvar (hyphen_thickness_scm_sym);
+ Real h = paper_l ()->get_realvar (hyphen_height_scm_sym);
+
+ // UGH. First try: just make the hyphen take 1/3 of the available space
+ // for length, use a geometric mean of the available space and some minimum
+ Real l = paper_l ()->get_realvar (hyphen_minimum_length_scm_sym);
+ if(l < w)
+ l = sqrt(l*w);
+ Molecule a = lookup_l ()->filledbox ( Box (Interval ((w-l)/2,(w+l)/2), Interval (h,h+th)));
+ a.translate (Offset (dx_f_drul_[LEFT], 0));
+
+ mol_p->add_molecule (a);
+
+ return mol_p;
+}
+
+Interval
+Hyphen_spanner::do_height () const
+{
+ return Interval (0,0);
+}
+
+void
+Hyphen_spanner::do_post_processing ()
+{
+ // UGH
+ Real nw_f = paper_l ()->note_width () * 0.8;
+
+ Direction d = LEFT;
+ do
+ {
+ Item* t = spanned_drul_[d]
+ ? spanned_drul_[d] : spanned_drul_[(Direction)-d];
+ if (d == LEFT)
+ dx_f_drul_[d] += t->extent (X_AXIS).length ();
+ else
+ dx_f_drul_[d] -= d * nw_f / 2;
+ }
+ while (flip(&d) != LEFT);
+}
+
+
+void
+Hyphen_spanner::set_textitem (Direction d, Item* textitem_l)
+{
+ set_bounds (d, textitem_l);
+ add_dependency (textitem_l);
+}
+
--- /dev/null
+/*
+ hyphen-engraver.hh -- declare Hyphen_engraver
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1999 Glen Prideaux <glenprideaux@iname.com>
+*/
+
+#ifndef HYPHEN_ENGRAVER_HH
+#define HYPHEN_ENGRAVER_HH
+
+#include "engraver.hh"
+#include "drul-array.hh"
+#include "hyphen-spanner.hh"
+#include "pqueue.hh"
+#include "extender-engraver.hh"
+
+
+/**
+ Generate an centred hyphen. Should make a Hyphen_spanner that typesets
+ a nice centred hyphen of varying length depending on the gap between syllables.
+
+ We remember all Text_items that come across, and store their
+ termination times. When we get a request, we create the spanner, and
+ attach the left point to the finished lyrics, and the right point to
+ any lyrics we receive by then.
+*/
+class Hyphen_engraver : public Engraver
+{
+ PQueue<Text_lyric_tuple> past_lyrics_pq_;
+ Array<Text_lyric_tuple> now_lyrics_;
+ Array<Text_lyric_tuple> stopped_lyrics_;
+
+ Hyphen_req* req_l_;
+ Hyphen_spanner* hyphen_spanner_p_;
+
+
+public:
+ Hyphen_engraver ();
+ VIRTUAL_COPY_CONS (Translator);
+
+protected:
+ virtual void acknowledge_element (Score_element_info);
+ virtual void do_removal_processing();
+ virtual void do_process_requests();
+ virtual bool do_try_music (Music*);
+ virtual void do_pre_move_processing();
+ virtual void do_post_move_processing ();
+private:
+
+};
+
+#endif // HYPHEN_ENGRAVER_HH
--- /dev/null
+/*
+ hyphen-spanner.hh -- part of GNU LilyPond
+
+ (c) 1999 Glen Prideaux <glenprideaux@iname.com>
+*/
+
+#ifndef HYPHEN_SPANNER_HH
+#define HYPHEN_SPANNER_HH
+
+#include "directional-spanner.hh"
+
+/**
+ centred hyphen
+
+ A centred hyphen is a simple line between lyrics used to
+ divide syllables.
+
+ The length of the hyphen line should stretch based on the
+ size of the gap between syllables.
+ */
+class Hyphen_spanner : public Directional_spanner
+{
+public:
+Hyphen_spanner ();
+ Offset center () const;
+ void set_textitem (Direction, Item*);
+
+protected:
+ virtual Molecule* do_brew_molecule_p () const;
+ Interval do_height () const;
+
+ void do_post_processing ();
+
+ VIRTUAL_COPY_CONS (Score_element);
+
+ Drul_array<Real> dx_f_drul_;
+};
+
+#endif // HYPHEN_SPANNER_HH
+
struct Change_translator;
struct Chord;
struct Chord_name_engraver;
+struct CHyphen_req;
struct Clef_change_req;
struct Clef_item;
struct Clef_engraver;
DECLARE_LY_SYMBOL(dir_forced);
DECLARE_LY_SYMBOL(dir_list);
DECLARE_LY_SYMBOL(extender_height);
+DECLARE_LY_SYMBOL(hyphen_thickness);
+DECLARE_LY_SYMBOL(hyphen_height);
+DECLARE_LY_SYMBOL(hyphen_minimum_length);
DECLARE_LY_SYMBOL(filledbox);
DECLARE_LY_SYMBOL(fontsize);
DECLARE_LY_SYMBOL(grace);
VIRTUAL_COPY_CONS(Music);
};
+/// a centred hyphen
+class Hyphen_req : public Request {
+public:
+ VIRTUAL_COPY_CONS(Music);
+};
+
#endif // MUSICALREQUESTS_HH
LYRICS ({AA}|{TEX})[^0-9 \t\n\f]*
ESCAPED [nt\\'"]
EXTENDER __
-
+HYPHEN --
%%
String s (YYText ());
if (s == "__")
return yylval.i = EXTENDER;
+ if (s == "--")
+ return yylval.i = HYPHEN;
int i = 0;
while ((i=s.index_i ("_")) != -1) // change word binding "_" to " "
*(s.ch_l () + i) = ' ';
%token CADENZA
%token CHORDMODIFIERS
%token CHORDS
+%token HYPHEN
%token CLEF
%token CM_T
%token CONSISTS
%type <request> post_request
%type <request> command_req verbose_command_req
%type <request> extender_req
+%type <request> hyphen_req
%type <string> string
%type <score> score_block score_body
%type <intarr> shape_array
extender_req {
$$ = $1;
}
+ | hyphen_req {
+ $$ = $1;
+ }
| '|' {
$$ = new Barcheck_req;
}
}
;
+hyphen_req:
+ HYPHEN {
+ if (!THIS->lexer_p_->lyric_state_b ())
+ THIS->parser_error (_ ("have to be in Lyric mode for lyrics"));
+ $$ = new Hyphen_req;
+ }
+ ;
+
close_request:
close_request_parens {
$$ = $1;
\consists "Separating_line_group_engraver";
\consists "Lyric_engraver";
\consists "Extender_engraver";
+ \consists "Hyphen_engraver";
}
\translator {
extender_height = 0.8*\staffline;
+hyphen_thickness = 0.05*\font_normal;
+hyphen_height = 0.2*\font_normal;
+hyphen_minimum_length = 0.25*\font_normal;
+
% Multi-measure rests
mmrest_x_minimum = 2.0*\staffheight;