+1.3.76
+======
+
+* Lyric_phrasing_engraver now adjusts for melisma. (Glenn Prideaux).
+
+* Mudela-book fix for Windows95 (Mark Hindley)
+
+* Debian update (Anthony Fok)
+
+* Added beam melisma for when automaticMelismata and noAutoBeaming are both
+ #t (primarily for hymns). Courtesy Glenn Prideaux.
+
+* Bugfix: .pfa dependency on $(outdir)/mfplain.mem
+
1.3.75.mb1
==========
PACKAGE_NAME=LilyPond
MAJOR_VERSION=1
MINOR_VERSION=3
-PATCH_LEVEL=75
-MY_PATCH_LEVEL=mb1
+PATCH_LEVEL=76
+MY_PATCH_LEVEL=
# use the above to send patches: MY_PATCH_LEVEL is always empty for a
# released version.
EXTRA_DIST_FILES = README.Debian TODO $(CONF_FILES) \
control.foka ex.prerm ex.doc-base
-CONF_FILES = changelog copyright emacsen-startup \
+CONF_FILES = changelog control copyright emacsen-startup \
preinst postinst postrm rules watch
#OUTCONF_FILES = $(addprefix $(outdir)/, $(basename $(CONF_FILES))) $(OUTIN_FILES)
OUTCONF_FILES = $(OUTIN_FILES)
+lilypond1.3 (1.3.75-1) unstable; urgency=low
+
+ * New upstream release.
+ * Updated the link to the http://sca.uwaterloo.ca/lilypond/ mirror in
+ the package description.
+
+ -- Anthony Fok <foka@debian.org> Wed, 26 Jul 2000 01:56:28 -0600
+
+lilypond1.3 (1.3.58-1) unstable; urgency=low
+
+ * New upstream release with patch from Han-wen.
+
+ -- Anthony Fok <foka@debian.org> Thu, 8 Jun 2000 17:19:08 -0600
+
+lilypond1.3 (1.3.48-1) unstable; urgency=low
+
+ * New upstream release.
+ * [debian/control]: Added Depends: guile, for /usr/bin/as2text (Lintian).
+ * [debian/rules]: Changed the symlink /usr/share/lilypond/cmtfm from
+ absolute to relative.
+
+ -- Anthony Fok <foka@debian.org> Wed, 10 May 2000 12:17:54 -0600
+
lilypond1.3 (1.3.45-1) unstable; urgency=low
* New upstream release.
--- /dev/null
+Source: lilypond1.3
+Build-Depends: debhelper (>= 2.0.71), python-base (>= 1.5.2-4), libguile6-dev, tetex-bin (>= 1.0.5-1), tetex-extra (>= 1.0-1), flex (>= 2.5.4a-1), bison (>= 1:1.28-1), texinfo (>= 4.0-1), groff, gs, netpbm, pnmtopng, m4, gettext (>= 0.10.35-13)
+Section: tex
+Priority: optional
+Maintainer: Anthony Fok <foka@debian.org>
+Standards-Version: 3.1.1
+
+Package: lilypond1.3
+Architecture: any
+Replaces: lilypond
+Provides: lilypond
+Depends: ${shlibs:Depends}, tetex-bin (>= 1.0.5-1), python-base (>= 1.5.2-4), guile
+Recommends: tetex-extra (>= 1.0-1)
+Conflicts: lilypond, musixtex-fonts
+Description: A program for printing sheet music.
+ LilyPond is a music typesetter. It produces beautiful sheet music
+ using a high level description file as input. LilyPond is part of
+ the GNU Project.
+ .
+ This is the developmental 1.3 branch of LilyPond. It is not intended for
+ use with stable projects, although 1.3.75 is most likely to be less buggy
+ and much more featureful than then the old "stable" 1.2.17.
+ .
+ URLs: http://www.cs.uu.nl/~hanwen/lilypond/
+ http://www.xs4all.nl/~jantien/lilypond/
+ http://sca.uwaterloo.ca/lilypond/
+ http://www.lilypond.org/
+ Authors: Han-Wen Nienhuys <hanwen@cs.uu.nl>
+ Jan Nieuwenhuizen <janneke@gnu.org>
Architecture: any
Replaces: lilypond
Provides: lilypond
-Depends: ${shlibs:Depends}, tetex-bin (>= 1.0.5-1)
-Recommends: python-base (>= 1.5.2-4), tetex-extra (>= 1.0-1)
+Depends: ${shlibs:Depends}, tetex-bin (>= 1.0.5-1), python-base (>= 1.5.2-4), guile
+Recommends: tetex-extra (>= 1.0-1)
Conflicts: lilypond, musixtex-fonts
Description: A program for printing sheet music.
LilyPond is a music typesetter. It produces beautiful sheet music
the GNU Project.
.
This is the developmental 1.3 branch of LilyPond. It is not intended for
- use with stable projects, although arguably 1.3.45 is less buggy and much
- more featureful than then the "stable" 1.2.17.
+ use with stable projects, although 1.3.75 is most likely to be less buggy
+ and much more featureful than then the old "stable" 1.2.17.
.
URLs: http://www.cs.uu.nl/~hanwen/lilypond/
http://www.xs4all.nl/~jantien/lilypond/
- http://sca.uwaterloo.ca/~praetzel/lilypond/
+ http://sca.uwaterloo.ca/lilypond/
http://www.lilypond.org/
Authors: Han-Wen Nienhuys <hanwen@cs.uu.nl>
Jan Nieuwenhuizen <janneke@gnu.org>
+++ /dev/null
-Source: lilypond1.3
-Build-Depends: debhelper (>= 2.0.71), python-base (>= 1.5.2-4), libguile6-dev, tetex-bin (>= 1.0.5-1), tetex-base (>= 1.0-1), tetex-extra (>= 1.0-1), flex (>= 2.5.4a-1), bison (>= 1:1.28-1), texinfo (>= 4.0-1)
-Section: tex
-Priority: optional
-Maintainer: Anthony Fok <foka@debian.org>
-Standards-Version: 3.1.0
-
-Package: lilypond1.3
-Architecture: any
-Replaces: lilypond
-Provides: lilypond
-Depends: ${shlibs:Depends}, tetex-bin (>= 1.0.5-1)
-Recommends: python-base (>= 1.5.2-4), tetex-base (>= 1.0-1), tetex-extra (>= 1.0-1)
-Conflicts: lilypond, musixtex-fonts
-Description: A program for printing sheet music.
- LilyPond is a music typesetter. It produces beautiful sheet music
- using a high level description file as input. LilyPond is part of
- the GNU Project.
- .
- This is the unstable 1.3 branch of LilyPond. It is not intended for
- use with stable projects!
- .
- URLs: http://www.cs.uu.nl/~hanwen/lilypond/
- http://www.xs4all.nl/~jantien/lilypond/
- http://sca.uwaterloo.ca/~praetzel/lilypond/
- http://www.lilypond.org/
- Authors: Han-Wen Nienhuys <hanwen@cs.uu.nl>
- Jan Nieuwenhuizen <janneke@gnu.org>
on Tue, 9 Nov 1999 22:30:32 -0700
It was downloaded from
- ftp://ftp.lilypond.org/pub/LilyPond/v1.3/lilypond-1.3.45.tar.gz
+ ftp://ftp.lilypond.org/pub/LilyPond/v1.3/lilypond-1.3.74.tar.gz
It is also available at:
- ftp://ftp.cs.uu.nl/pub/GNU/LilyPond/v1.3/lilypond-1.3.45.tar.gz
+ ftp://ftp.cs.uu.nl/pub/GNU/LilyPond/v1.3/lilypond-1.3.74.tar.gz
For more information about GNU LilyPond, please visit:
http://www.cs.uu.nl/~hanwen/lilypond/
+++ /dev/null
-Source: lilypond1.3
-Build-Depends: debhelper (>= 2.0.71), python-base (>= 1.5.2-4), libguile6-dev, tetex-bin (>= 1.0.5-1), tetex-base (>= 1.0-1), tetex-extra (>= 1.0-1), flex (>= 2.5.4a-1), bison (>= 1:1.28-1), texinfo (>= 4.0-1)
-Section: tex
-Priority: optional
-Maintainer: Anthony Fok <foka@debian.org>
-Standards-Version: 3.1.0
-
-Package: lilypond1.3
-Architecture: any
-Replaces: lilypond
-Provides: lilypond
-Depends: ${shlibs:Depends}, tetex-bin (>= 1.0.5-1)
-Recommends: python-base (>= 1.5.2-4), tetex-base (>= 1.0-1), tetex-extra (>= 1.0-1)
-Conflicts: lilypond, musixtex-fonts
-Description: A program for printing sheet music.
- LilyPond is a music typesetter. It produces beautiful sheet music
- using a high level description file as input. LilyPond is part of
- the GNU Project.
- .
- This is the unstable 1.3 branch of LilyPond. It is not intended for
- use with stable projects!
- .
- URLs: http://www.cs.uu.nl/~hanwen/lilypond/
- http://www.xs4all.nl/~jantien/lilypond/
- http://sca.uwaterloo.ca/~praetzel/lilypond/
- http://www.lilypond.org/
- Authors: Han-Wen Nienhuys <hanwen@cs.uu.nl>
- Jan Nieuwenhuizen <janneke@gnu.org>
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
-# This is the debhelper compatability version to use.
+# This is the debhelper compatibility version to use.
export DH_COMPAT=1
build: build-stamp
ln -s ../../../../lilypond/afm $(r)/usr/share/texmf/fonts/afm/public/lilypond
ln -s ../../../../lilypond/tfm $(r)/usr/share/texmf/fonts/tfm/public/lilypond
+ # Change from an absolute symlink to a relative symlink (Lintian)
+ if [ -L $(r)/usr/share/lilypond/cmtfm ]; then \
+ rm -f $(r)/usr/share/lilypond/cmtfm; \
+ ln -s ../texmf/fonts/tfm/public/cm $(r)/usr/share/lilypond/cmtfm; \
+ fi
+
# Build architecture-independent files here.
binary-indep: build install
# We have nothing to do by default.
--- /dev/null
+%non of the dynamics properties work anymore
+
+\score {
+ \context Voice \notes\relative c {
+ \property Voice.verticalDirection = #-1
+ \property Voice.dynamicVerticalDirection = #-1
+ \property Voice.dynamicDirection = #-1
+ \property Voice.dynamicPadding = #40
+ c \p c \< \! c \ff\> c \!c-\p
+
+ }
+}
--- /dev/null
+%
+% Hara-kiri leaves a big gap
+%
+
+\version "1.3.59";
+
+m = \notes \relative c''{
+
+c1 | c2 c | c c | c c | \break c c | c c | c c | c c |
+}
+
+M = \notes \relative c''{
+
+c1 | c2 c | c c | R1*5
+}
+
+\score{ <
+ \context StaffGroup = wood <
+ \context Staff = flauto <
+ \property Staff.instrument = "Flauto"
+ \property Staff.instr = "Fl."
+ \m
+ >
+ \context Staff = oboe <
+ \property Staff.instrument = "Oboe"
+ \property Staff.instr = "Ob."
+ \m
+ >
+ \context Staff = clarI <
+ \property Staff.instrument = "Clarinetto I"
+ \property Staff.instr = "Cl. I"
+ \m
+ >
+ \context Staff = clarII <
+ \property Staff.instrument = "Clarinetto II"
+ \property Staff.instr = "Cl. II"
+ \m
+ >
+ \context Staff = fagotto <
+ \property Staff.instrument = "Fagotto"
+ \property Staff.instr = "Fg."
+ \m
+ >
+ >
+ \context StaffGroup = brass <
+ \context Staff = cor <
+ \property Staff.instrument = "2 Corni in F"
+ \property Staff.instr = "Cor."
+ \context Voice = corI { \stemup \M }
+ \context Voice = corII { \stemdown \M }
+ >
+ \context Staff = trp <
+ \property Staff.instrument = "2 Trp. in B\\textflat "
+ \property Staff.instr = "Trp."
+ \context Voice = trpI { \stemup \M }
+ \context Voice = trpII { \stemdown \M }
+ >
+ >
+ \context StaffGroup = percussion <\context Staff = timpani <
+ \property Staff.instrument = "Timpani"
+ \property Staff.instr = "Timp."
+ \notes{c''1 R1*8}
+ >
+ >
+ \context StaffGroup = strings <
+ \context GrandStaff = violins <
+ \context Staff = viI <
+ \property Staff.instrument = "Violin I"
+ \property Staff.instr = "Vi. I"
+ \m
+ >
+ \context Staff = viII <
+ \property Staff.instrument = "Violin II"
+ \property Staff.instr = "Vi. II"
+ \m
+ >
+ >
+ \context Staff = vla <
+ \property Staff.instrument = "Viola"
+ \property Staff.instr = "Vla."
+ \m
+ >
+ \context Staff = vlc <
+ \property Staff.instrument = "Violoncello"
+ \property Staff.instr = "Vlc"
+ \m
+ >
+ \context Staff = cb <
+ \property Staff.instrument = "Contrabasso"
+ \property Staff.instr = "C.B."
+ \m
+ >
+ >
+>
+ \paper {
+% \paper_sixteen;
+ linewidth = 185.\mm;
+ textheight = 260.\mm;
+ \translator {
+ \OrchestralScoreContext
+ barNumberScriptPadding = 10;
+ }
+ \translator { \HaraKiriStaffContext
+ marginScriptPadding = 15.0;
+% StaffMinimumVerticalExtent = #(cons -0.0 0.0)
+ }
+ }
+}
+
--- /dev/null
+% Tests a number of features:
+% * Lyric_phrasing_engraver
+% * Stanza_number_engraver
+% * Automatic melismata on beamed notes
+
+\version "1.3.59";
+\include "english.ly"
+
+\header{
+ title = "Crowned with Honour";
+ composer = "Oliver Holden (1765-1844)";
+ poet = "Thomas Kelly (1769-1855)";
+}
+
+allup = \notes{
+ \property Voice.verticalDirection = \up
+ \property Voice.slurVerticalDirection = \up
+ \property Voice.tieVerticalDirection = \up
+ \property Voice.dynamicDirection = \up
+ \autoBeamOff
+}
+alldown = \notes{
+ \property Voice.verticalDirection = \down
+ \property Voice.slurVerticalDirection = \down
+ \property Voice.tieVerticalDirection = \down
+ \property Voice.dynamicDirection = \down
+ \autoBeamOff
+}
+
+Global = \notes{
+ \key g \major;
+ \time 4/4;
+ \partial 4;
+}
+
+Soprano = \notes \relative c' {
+ \allup
+ d4 | g g b b a g a b a g b a g2.
+
+ a4 | b a g b [d16 d c8] [b a] b4 % modified to test beam melisma
+% a4 | b a g b [d8 \melisma c] \melismaEnd [b \melisma a] \melismaEnd b4
+
+ d d2 d e d4( cs8 ~ )cs d2.
+
+ b4 | d b g b [a8 g] [a b] a4
+% b4 | d b g b [a8 \melisma g] \melismaEnd [a \melisma b] \melismaEnd a4
+
+ g d'2 c b4.( c8 )a4 a g2.
+}
+Alto = \notes \relative c'{
+ \alldown
+ d4 | d d g g fs g fs g fs e g fs d2.
+ d4 | g d b g' [b8 a] [g fs] g4 fs g2 a g fs4( e8 )g fs2.
+ d4 | g g d g [fs8 e] [fs g] fs4 g f2 e d4.( d8 )d4 fs4 d2.
+}
+Tenor = \notes \relative c{
+ \allup
+ d4 | b' b d d c b c d c b d c b2.
+ a4 | b a g b [d8 c] [b a] b4 a b2 c b a a2.
+ g4 | b d b d [c8 b] [c d] c4 b g2 g g4.( a8 [fs )a] c4 b2.
+}
+Bass = \notes \relative c{
+ \alldown
+ d4 | g g g g d d d g d e d d g,2.
+ d'4 | g d b g' [b8 a] [g fs] g4 d g2 fs e a d,2.
+ g4 | g g g g d d d e b2 c d2. d4 g,2.
+}
+
+TheLyrics = \lyrics <
+ {
+ \context LyricVoice = "Soprano-1"
+ \property LyricVoice .stanza = "1:"
+ \property LyricVoice .stz = "(1)"
+ The4 head that once was crowned with thorns
+ Is crowned with glo -- ry now;
+ A roy -- al di -- a -- dem a -- dorns
+ The might -- y Vic -- tor's brow.
+ A roy -- al di -- a -- dem a -- dorns
+ The might -- y Vic -- tor's brow.
+ }
+ {
+ \context LyricVoice = "Soprano-2"
+ \property LyricVoice .stanza = "2:"
+ \property LyricVoice .stz = "(2)"
+ The4 high -- est place that heav'n af -- fords
+ Is His by sov -- 'reign right;
+ The King of kings, the Lord of lords,
+ He reigns in glo -- ry bright,
+ The King of kings, the Lord of lords,
+ He reigns in glo -- ry bright.
+ }
+ {
+ \context LyricVoice = "Soprano-3"
+ \property LyricVoice .stanza = "3:"
+ \property LyricVoice .stz = "(3)"
+ The joy of all who dwell a -- bove,
+ The joy of saints be -- low,
+ To4 whom He man -- i -- fests His love,
+ And grants His name to know,
+ To4 whom He man -- i -- fests His love,
+ And grants His name to4 know.
+ }
+>
+
+
+\score{
+ \context ChoirStaff
+ \notes
+ <
+ \property Score.barNumberScriptPadding = #10.0
+ \context Staff = "treblestaff"{
+ <
+ \context Voice = "Soprano" { }
+ \context Voice = "Alto" { }
+ >
+ }
+ \context Lyrics = mainlyrics { }
+ \context Staff = "treblestaff"{
+ <
+ \Global
+ \addlyrics { \context Voice = "Soprano" \Soprano }
+ { \context Lyrics = mainlyrics \TheLyrics }
+ \context Voice = "Alto" \Alto
+ >
+ \bar "|.";
+ }
+ \context Staff = "bassstaff"{
+ \clef "bass";
+ <
+ \context Voice = "Tenor" { \Tenor }
+ \context Voice = "Bass" { \Bass }
+ >
+ \bar "|.";
+ }
+ >
+
+ \paper {
+ \translator{
+ \VoiceContext
+ automaticMelismata = ##t;
+ noAutoBeaming = ##t;
+ \remove "Auto_beam_engraver";
+ }
+
+ }
+}
--- /dev/null
+%
+% We'd want to combine the stems, but have two slurs too...
+% Looks like the a-due engraver
+%
+\score{
+ \context Staff <
+ \context Voice=v \notes\relative c''{
+ \stemup
+ a4 c4.()g8 a4
+ }
+ \context Voice=u \notes\relative c''{
+ \stemdown
+ g4 e4.()d8 c4
+ }
+ >
+ \paper{
+ linewidth=60.\mm;
+ }
+}
Moment beam_start_mom_;
void typeset_beam ();
+ void set_melisma (bool);
protected:
virtual void do_pre_move_processing ();
virtual void do_post_move_processing ();
m->origin ()->warning (_ ("can't find start of beam"));
return false;
}
+
+ if(d == STOP)
+ {
+ SCM m = get_property ("automaticMelismata");
+ SCM b = get_property("noAutoBeaming");
+ if (to_boolean (m) && to_boolean(b))
+ {
+ set_melisma (false);
+ }
+ }
+
reqs_drul_[d ] = c;
return true;
}
return false;
}
+void
+Beam_engraver::set_melisma (bool m)
+{
+ daddy_trans_l_->set_property ("beamMelismaBusy", m ? SCM_BOOL_T :SCM_BOOL_F);
+}
+
void
Beam_engraver::do_process_music ()
Beam_engraver::do_post_move_processing ()
{
reqs_drul_ [START] =0;
+ if(beam_p_) {
+ SCM m = get_property ("automaticMelismata");
+ SCM b = get_property("noAutoBeaming");
+ if (to_boolean (m) && to_boolean(b)) {
+ set_melisma (true);
+ }
+ }
}
void
private:
void record_notehead(const String &context_id, Score_element * notehead);
void record_lyric(const String &context_id, Score_element * lyric);
+ void record_melisma(const String &context_id);
Voice_alist_entry * lookup_context_id(const String &context_id);
public:
Score_element * longest_lyric_l_;
Score_element * shortest_lyric_l_;
int alignment_i_;
-
+ bool melisma_b_;
public:
static SCM make_entry();
void set_first_in_phrase(bool f);
void set_notehead(Score_element * notehead);
void add_lyric(Score_element * lyric);
+ void set_melisma();
+ bool get_melisma() { return melisma_b_; }
+ int lyric_count() { return lyric_list_.size(); }
void clear();
bool is_empty();
bool set_lyric_align(const char *punc, Score_element *default_notehead_l);
+ void adjust_melisma_align();
int appropriate_alignment(const char *punc);
+ Real amount_to_translate();
void next_lyric();
+ void copy(Voice_alist_entry *);
private:
Voice_alist_entry();
DECLARE_SIMPLE_SMOBS(Voice_alist_entry,);
ADD_THIS_TRANSLATOR (Lyric_phrasing_engraver);
+/*
+ We find start and end of phrases, and align lyrics accordingly.
+ Also, lyrics at start of melismata should be left aligned.
+
+ Alignment and melismata
+
+ I've taken [a different] approach:
+ | |
+ | |
+ O O <-- second note throws a melisma score element
+ \____/
+
+ ^ ^
+ | |
+ Lyric (None)
+
+ Lyric_phrasing_engraver keeps track of the current and previous notes and
+ lyrics for each voice, and when it catches a melisma, it adjusts the
+ alignment of the lyrics of the previous note. I hope this isn't
+ unnecessarily convoluted.
+ */
Lyric_phrasing_engraver::Lyric_phrasing_engraver()
{
SCM s = scm_assoc(key, voice_alist_);
if(! (gh_boolean_p(s) && !to_boolean(s))) {
/* match found */
- return unsmob_voice_entry(gh_cdr(s));
+ // ( key . ( (alist_entry . old_entry) . previous_entry) )
+ if(to_boolean(gh_cdadr(s))) { // it's an old entry ... make it a new one
+ SCM val = gh_cons(gh_cons(gh_caadr(s), SCM_BOOL_F), gh_cddr(s));
+ voice_alist_ = scm_assoc_set_x(voice_alist_, gh_car(s), val);
+ return unsmob_voice_entry (gh_caar(val));
+ }
+ else { // the entry is current ... return it.
+ SCM entry_scm = gh_caadr(s);
+ return unsmob_voice_entry(entry_scm);
+ }
}
}
- SCM val = Voice_alist_entry::make_entry ();
+ // ( ( alist_entry . old_entry ) . previous_entry )
+ SCM val = gh_cons(gh_cons(Voice_alist_entry::make_entry (), SCM_BOOL_F),
+ Voice_alist_entry::make_entry ());
+
voice_alist_ = scm_acons(key, val, voice_alist_);
- return unsmob_voice_entry (val);
+ return unsmob_voice_entry (gh_caar(val));
}
void
-Lyric_phrasing_engraver::record_notehead(const String &context_id, Score_element * notehead)
+Lyric_phrasing_engraver::record_notehead(const String &context_id,
+ Score_element * notehead)
{
Voice_alist_entry * v = lookup_context_id(context_id);
v->set_notehead(notehead);
v->add_lyric(lyric);
}
-
-
-
+void
+Lyric_phrasing_engraver::record_melisma(const String &context_id)
+{
+ Voice_alist_entry * v = lookup_context_id(context_id);
+ v->set_melisma();
+}
+
void
Lyric_phrasing_engraver::acknowledge_element(Score_element_info i)
{
record_lyric(trim_suffix(lyric_voice_context_id), h);
return;
}
+ /* finally for a melisma */
+ if(h->has_interface (ly_symbol2scm ("melisma-interface"))) {
+ String voice_context_id = get_context_id(i.origin_trans_l_->daddy_trans_l_, "Voice");
+ record_melisma(voice_context_id);
+ return;
+ }
}
-
String
get_context_id(Translator_group * ancestor, const char *type)
{
/* iterate through entries in voice_alist_
for each, call set_lyric_align(alignment). Issue a warning if this returns false.
*/
- Voice_alist_entry *entry;
String punc;
SCM sp = get_property("phrasingPunctuation");
punc = gh_string_p(sp) ? ly_scm2string(sp) : ".,;:?!\"";
- for(unsigned v=0; v < gh_length(voice_alist_); v++) {
- entry = unsmob_voice_entry(gh_cdr(gh_list_ref(voice_alist_, gh_int2scm(v))));
+ for(SCM v=voice_alist_; gh_pair_p(v); v = gh_cdr(v)) {
+ SCM v_entry = gh_cdar(v);
+ // ((current . oldflag) . previous)
+ Voice_alist_entry *entry = unsmob_voice_entry(gh_caar(v_entry));
if(! entry->set_lyric_align(punc.ch_C(), any_notehead_l_))
warning (_ ("lyrics found without any matching notehead"));
+
+ // is this note melismatic? If so adjust alignment of previous one.
+ if(entry->get_melisma()) {
+ if(entry->lyric_count())
+ warning (_ ("Huh? Melismatic note found to have associated lyrics."));
+ SCM previous_scm = gh_cdr(v_entry);
+ if(previous_scm != SCM_EOL) {
+ Voice_alist_entry *previous = unsmob_voice_entry(previous_scm);
+ if (previous->lyric_count())
+ previous->adjust_melisma_align();
+ }
+ }
}
}
void
Lyric_phrasing_engraver::do_pre_move_processing ()
{
- Voice_alist_entry * entry;
- for(unsigned v=0; v < gh_length(voice_alist_); v++) {
- entry = unsmob_voice_entry(gh_cdr(gh_list_ref(voice_alist_, gh_int2scm(v))));
+ for(SCM v=voice_alist_; gh_pair_p(v); v = gh_cdr(v)) {
+ SCM entry_scm = gh_cdar(v);
+ // ((alist_entry . entry_is_old) . previous_entry)
+ Voice_alist_entry * entry = unsmob_voice_entry(gh_caar(entry_scm));
+
+ // set previous_entry, set entry_is_old, and resave it to alist_
+ // but only change if this current was not old.
+ if(! to_boolean(gh_cdar(entry_scm))) {
+ Voice_alist_entry * previous_entry = unsmob_voice_entry(gh_cdr(entry_scm));
+ previous_entry->copy(entry);
+ entry_scm = gh_cons(gh_cons(gh_caar(entry_scm), SCM_BOOL_T), gh_cdr(entry_scm));
+ voice_alist_ = scm_assoc_set_x(voice_alist_, gh_caar(v), entry_scm);
+ }
entry->next_lyric();
}
any_notehead_l_ = 0;
Voice_alist_entry::Voice_alist_entry()
{
first_in_phrase_b_=true;
+ melisma_b_ = false;
clear();
}
-
-
-
void
Voice_alist_entry::clear()
{
lyric_list_.clear();
longest_lyric_l_=0;
shortest_lyric_l_=0;
+ melisma_b_ = false;
}
+void
+Voice_alist_entry::copy( Voice_alist_entry *from)
+{
+ notehead_l_ = from->notehead_l_;
+ lyric_list_ = from->lyric_list_;
+ longest_lyric_l_ = from->longest_lyric_l_;
+ shortest_lyric_l_ = from->shortest_lyric_l_;
+ melisma_b_ = from->melisma_b_;
+ alignment_i_ = from->alignment_i_;
+ first_in_phrase_b_ = from->first_in_phrase_b_;
+}
+
void
Voice_alist_entry::set_first_in_phrase(bool f)
{
void
Voice_alist_entry::set_notehead(Score_element * notehead)
{
- if(!notehead_l_)
+ if(!notehead_l_) {
/* there should only be a single notehead, so silently ignore any extras */
notehead_l_=notehead;
+ }
}
void
else
longest_lyric_l_ = shortest_lyric_l_ = lyric;
}
-
+
+ void
+Voice_alist_entry::set_melisma()
+{
+ melisma_b_ = true;
+}
+
bool
Voice_alist_entry::set_lyric_align(const char *punc, Score_element *default_notehead_l)
{
- if(lyric_list_.size()<2) {
- /* Only for multi-stanza songs ... if we've only a single lyric (or none at all) we
- do nothing.
- */
- clear();
+ if(lyric_list_.size()==0) {
+ // No lyrics: nothing to do.
return true;
}
Score_element * lyric;
alignment_i_ = appropriate_alignment(punc);
+ // If there was no notehead in the matching voice context, use the first
+ // notehead caught from any voice context (any port in a storm).
+ if(!notehead_l_) {
+ notehead_l_ = default_notehead_l;
+ }
+ Real translation = amount_to_translate();
for(int l = 0; l < lyric_list_.size(); l++) {
/** set the x alignment of each lyric
*/
lyric = lyric_list_[l];
lyric->set_elt_property("self-alignment-X", gh_int2scm(alignment_i_));
- // centre on notehead ... if we have one. If there was no notehead in the matching
- // voice context, use the first notehead caught from any voice context (any port in a storm).
- if(notehead_l_ || default_notehead_l) {
+ // centre on notehead ... if we have one.
+ if(notehead_l_) {
/* set the parent of each lyric to the notehead,
set the offset callback of each lyric to centered_on_parent,
*/
- Score_element * parent_nh = notehead_l_ ? notehead_l_ : default_notehead_l;
- lyric->set_parent(parent_nh, X_AXIS);
+ lyric->set_parent(notehead_l_, X_AXIS);
lyric->add_offset_callback (Side_position::centered_on_parent, X_AXIS);
- /* reference is on the right of the notehead; move it left half way */
- lyric->translate_axis (-(parent_nh->extent(X_AXIS)).center(), X_AXIS);
-
- if(alignment_i_ != CENTER) {
- // right or left align ...
- /* If length of longest lyric < 2 * length of shortest lyric,
- - centre longest lyric on notehead
- Otherwise
- - move so shortest lyric just reaches notehead centre
- */
- // FIXME: do we really know the lyric extent here? Some font sizing comes later?
- Real translate;
- if((longest_lyric_l_->extent(X_AXIS)).length() <
- (shortest_lyric_l_->extent(X_AXIS)).length() * 2 )
- translate = alignment_i_*(longest_lyric_l_->extent(X_AXIS)).length()/2;
- else
- translate = alignment_i_*(shortest_lyric_l_->extent(X_AXIS)).length();
- lyric->translate_axis (translate, X_AXIS);
- }
+ /* reference is on the right of the notehead; move it left half way, then centralise */
+ lyric->translate_axis (translation-(notehead_l_->extent(X_AXIS)).center(), X_AXIS);
}
}
- return (notehead_l_ || default_notehead_l);
+ return (notehead_l_);
+}
+
+Real
+Voice_alist_entry::amount_to_translate()
+{
+ Real translate = 0.0;
+ if(alignment_i_ != CENTER) {
+ // right or left align ...
+ /* If length of longest lyric < 2 * length of shortest lyric,
+ - centre longest lyric on notehead
+ Otherwise
+ - move so shortest lyric just reaches notehead centre
+ */
+ // FIXME: do we really know the lyric extent here? Some font sizing comes later?
+ if((longest_lyric_l_->extent(X_AXIS)).length() <
+ (shortest_lyric_l_->extent(X_AXIS)).length() * 2 )
+ translate = alignment_i_*(longest_lyric_l_->extent(X_AXIS)).length()/2;
+ else
+ translate = alignment_i_*(shortest_lyric_l_->extent(X_AXIS)).length();
+ }
+ return translate;
}
+
/** determine what alignment we want.
Rules: if first_in_phrase_b_ is set, then alignment is LEFT.
otherwise if each syllable ends in punctuation, then alignment is RIGHT
return CENTER;
}
+/** We don't know about the melisma until after the initial alignment work is done, so go
+ back and fix the alignment when we DO know.
+*/
+void
+Voice_alist_entry::adjust_melisma_align()
+{
+ if(notehead_l_) {
+ // undo what we did before ...
+ Real translation = -amount_to_translate();
+ // melisma aligning:
+ switch (alignment_i_) {
+ // case LEFT: // that's all
+ case CENTER: // move right so smallest lyric is left-aligned on notehead
+ translation += (shortest_lyric_l_->extent(X_AXIS)).length()/2;
+ break;
+ case RIGHT: // move right so smallest lyric is left-aligned on notehead
+ translation += (shortest_lyric_l_->extent(X_AXIS)).length();
+ break;
+ }
+ for(int l = 0; l < lyric_list_.size(); l++) {
+ lyric_list_[l]->translate_axis (translation, X_AXIS);
+ }
+ }
+}
+
+
bool
Voice_alist_entry::is_empty()
{
#include "engraver.hh"
#include "musical-request.hh"
+#include "score-element.hh"
/**
Signal existence of melismas.
SCM plain (get_property ("melismaBusy"));
SCM slur (get_property ("slurMelismaBusy"));
SCM tie (get_property ("tieMelismaBusy"));
- return (to_boolean (plain))
- || (to_boolean (slur))
- || (to_boolean (tie));
+ SCM beam (get_property ("beamMelismaBusy"));
+
+ if( (to_boolean (plain))
+ || (to_boolean (slur))
+ || (to_boolean (tie))
+ || (to_boolean (beam))) {
+
+ Score_element * melisma_p = new Score_element (get_property ("basicMelismaProperties"));
+ announce_element (melisma_p, m);
+
+ return true;
+ }
}
return false;
}
(break-align-symbol . Clef_item)
(visibility-lambda . ,begin-of-line-visible)
)
+ basicMelismaProperties = #`(
+ (interfaces . (melisma-interface))
+ )
\accepts "Staff";
\accepts "StaffGroup";
Begin3
Title: LilyPond
-Version: 1.3.75
-Entered-date: 25JUL00
+Version: 1.3.76
+Entered-date: 03AUG00
Description:
Keywords: music notation typesetting midi fonts engraving
Author: hanwen@cs.uu.nl (Han-Wen Nienhuys)
janneke@gnu.org (Jan Nieuwenhuizen)
Maintained-by: hanwen@stack.nl (Han-Wen Nienhuys)
Primary-site: sunsite.unc.edu /pub/Linux/apps/sound/convert
- 1000k lilypond-1.3.75.tar.gz
+ 1000k lilypond-1.3.76.tar.gz
Original-site: ftp.cs.uu.nl /pub/GNU/LilyPond/development/
- 1000k lilypond-1.3.75.tar.gz
+ 1000k lilypond-1.3.76.tar.gz
Copying-policy: GPL
End
Name: lilypond
-Version: 1.3.75
+Version: 1.3.76
Release: 1
Copyright: GPL
Group: Applications/Publishing
-Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.3.75.tar.gz
+Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.3.76.tar.gz
Summary: A program for printing sheet music.
URL: http://www.cs.uu.nl/~hanwen/lilypond
# Icon: lilypond-icon.gif
(define slur-extremity-rules
(list
+
+ ;; (cons (lambda (slur dir) (begin (display "before head") (newline))#f) #f)
+
(cons (lambda (slur dir)
;; urg, code dup
(let* ((note-columns (ly-get-elt-property slur 'note-columns))
(not (= (ly-get-elt-property slur 'direction)
(ly-get-elt-property stem 'direction)))))) 'head)
+ ;; (cons (lambda (slur dir) (begin (display "before stem") (newline))#f) #f)
+
(cons (lambda (slur dir)
;; if attached-to-stem
(and (attached-to-stem slur dir)
#f))))))
'stem)
+ ;;(cons (lambda (slur dir) (begin (display "before loose-end") (newline))#f) #f)
(cons (lambda (slur dir) (not (attached-to-stem slur dir))) 'loose-end)
+ ;; (cons (lambda (slur dir) (begin (display "after loose-end") (newline))#f) #f)
;; default case, attach to head
(cons (lambda (x y) #t) 'head)
system ('lilypond %s %s' % (lilyopts, texfiles))
for e in eps:
- cmd = r"""tex '\nonstopmode \input %s'; dvips -E -o %s %s""" % \
+ if os.environ.has_key('OS') and \
+ os.environ['OS'] == 'Windows_95':
+ cmd = r"""ash -c 'tex " \nonstopmode \input %s " ; dvips -E -o %s %s ' """ % \
+ (e, e + '.eps', e)
+ else:
+ cmd = r"""tex '\nonstopmode \input %s' ; dvips -E -o %s %s""" % \
(e, e + '.eps', e)
system (cmd)
$(outdir)/%.0: %.mf $(outdir)/mfplain.mem
-$(METAPOST) "&$(outdir)/mfplain \mode=lowres; \mag=1.0; nonstopmode; input $<"
-mfplain.mem: $(MFPLAIN_MP)
+$(outdir)/mfplain.mem: $(MFPLAIN_MP)
$(INIMETAPOST) $(INIMETAPOST_FLAGS) $(MFPLAIN_MP) dump
mv mfplain.* $(outdir)