+1.3.91.uu1
+==========
+
+* RPM .spec fixes.
+
+* italiano.ly
+
+* mudela-book updates by Tom Cato Amundsen.
+
+* Allow lyric hara kiri as well.
+
+* Bugfix: left/right mixup in Side_position_interface::aligned_on_self ()
+
+* rest collision of differing rests.
+
+* Cleanup of Sequential_music_iterator, Simple_music_iterator.
+
+* Unfolded_repeat_iterator now signals repeats using \property
+ repeatCommands. You could override this, eg.
+
+ \property Score.repeatCommands = #'((volta "X") start-repeat)
+
+ will print a |: and a volta bracket saying X. See also
+ input/test/manual-volta.ly
+
+* Volta_engraver, Repeat_acknowledge_engraver: new engravers that are
+controlled by repeatCommands; much cleaner than the Repeat_engraver.
+
+* Junked Repeat_engraver.
+
1.3.91.jcn1
===========
-
* Abort all running spanners when part-combiner combines voices.
-1.3.90.jcn1
-===========
+1.3.91
+======
* Use S_ISDIR () and check for stat.h.
STEPMAKE_TEMPLATES=documentation texinfo tex
LOCALSTEPMAKE_TEMPLATES=lilypond mudela
-README_TOP_FILES=NEWS DEDICATION CHANGES TODO
+README_TOP_FILES=NEWS DEDICATION CHANGES
EXTRA_DIST_FILES=
include $(depth)/make/stepmake.make
<tr><td><font size=-1>
<a href="@TOP@Documentation/out-www/NEWS.html">NEWS</a><br>
<a href="@TOP@Documentation/out-www/CHANGES.html">Change Log</a><br>
- <a href="@TOP@Documentation/out-www/faq.html">FAQ</a><br>
+ <a href="http://appel.lilypond.org/wiki/index.php3?LilyPondFaqs">FAQ</a><br>
<a href="@TOP@Documentation/user/out-www/lilypond.html">User manual</a><br>
<a href="@TOP@Documentation/out-www/regression-test.html">Features</a><br>
<a href="http://appel.lilypond.org/lilypond/todo.html">Todo</a><br>
Officially BugFree (tm). This document is intended for finding bugs,
and documenting bugfixes.
+[TODO: revise and completize this. ]
+
+[TODO: should generate out of header fields using ly2dvi?]
+
+
+
@section Notes and rests
Rests. Note that the dot of 8th, 16th and 32nd rests rest should be
@mudelafile{repeat-line-break.ly}
+Auto change piano staff switches voices between up and down staffs
+automatically; rests are switched along with the coming note.
+@mudelafile{auto-change.ly}
@section Lyrics
@mudelafile{non-empty-text.ly}
+
+
+
+@section PianoStaff
+
+
+
@section Global stuff
Breaks can be encouraged and discouraged using @code{\break} and
@mudelafile{break.ly}
-
Markings that are attached to (invisible) barlines are
delicate: the are attached to the rest of the score without the score
knowing it. Consequently, they fall over often.
@chapter INSTALL - compiling and installing GNU LilyPond
-
-@section Abstract
-
-This document explains what you need to install LilyPond, and what you
-should do. If you are going to compile and install LilyPond often,
-e.g. when doing development, you might want to check out the
-@file{buildscripts/set-lily.sh} script. It sets some environment
-variables and symlinks, which comes in handy when you have to compile
-LilyPond more often.
-
@section Obtaining
You can get the latest version of LilyPond at
@itemize @bullet
@item A GNU system: GNU LilyPond is known to run on these GNU systems: Linux
(PPC, intel), FreeBSD, AIX, NeXTStep, IRIX, Digital Unix and
-Solaris.
+ Solaris.
@item Lots of disk space: LilyPond takes between 30 and 100 mb to
compile if you use debugging information. If you are short on
Check out
@uref{ftp://ftp.gnu.org/gnu/make/,ftp://ftp.gnu.org/gnu/make/}.
-@item Flex (version 2.5.4 or newer).
+@item Flex (version 2.5.4a or newer).
Check out @uref{ftp://ftp.gnu.org/gnu/flex/,ftp://ftp.gnu.org/gnu/flex/}.
@item Bison (version 1.25 or newer).
@file{mfplain.mp}, which is needed for producing the scalable font
files.
-If you do not want to use PostScript output, edit @file{mf/GNUmakefile}.
+If you do not want to use PostScript output, edit @file{mf/GNUmakefile},
+removing the line saying @code{PFA_FILES=}
@item kpathsea, a library for searching (TeX) files. @code{kpathsea} is
usually included with your installation of TeX.
-
@end itemize
@section Running
@item GUILE 1.3.4, check out @uref{http://www.gnu.org/programs/guile.html,http://www.gnu.org/software/guile/}
@end itemize
-For running LilyPond successfully you have to help TeX and MetaFont
-find various files. The recommended way of doing so is adjusting the
-environment variables in the start-up scripts of your shell. An
-example is given here for the Bourne shell:
-@example
-export MFINPUTS="/usr/local/share/lilypond/mf:"
-export TEXINPUTS="/usr/local/share/lilypond/tex:/usr/local/share/lilypond/ps:"
-
-@end example
+For running LilyPond successfully you have to help TeX and MetaFont find
+various files. The recommended way of doing so is adjusting the
+environment variables in the start-up scripts of your shell. Appropriate
+Csh and sh scripts are left in @file{buildscripts/out/lilypond-profile}
+and @file{buildscripts/out/lilypond-login} after compilation.
-The empty path component
-represents TeX and MetaFont's default search paths. Scripts with
-the proper paths for the bourne and C-shell respectively are generated in
-@file{buildscripts/out/lilypond-profile} and
-@file{buildscripts/out/lilypond-login} during compilation.
+The empty path component represents TeX and MetaFont's default search
+paths. Scripts with the proper paths for the bourne and C-shell
+respectively are generated in @file{buildscripts/out/lilypond-profile}
+and @file{buildscripts/out/lilypond-login} during compilation.
-LilyPond is a hiddeously big, slow and bloated program. A fast CPU
-and plenty of RAM is recommended for comfortable use.
+LilyPond is a big and slow program. A fast CPU and plenty of RAM is
+recommended for comfortable use.
@section Website
The version of @file{pnmtopng} that is distributed with RedHat 5.1 and
5.2 contains a bug: pnmtopng is dynamically linked to the wrong
-version of libpng, which results in cropped images. Recompile it from
-source, and make sure that the pnmtopng binary is linked statically to
-the libpng that is included in libgr. RedHat 6.0 does not have this
-problem.
-
-@example
- tar xzf libgr-2.0.13.tar.gz
- make
- cd png
- rm libpng.so*
- make pnmtopng
-
-@end example
-
-You can then install the new pnmtopng into @file{/usr/local/bin/}
+version of libpng.
@item @uref{http://pertsserver.cs.uiuc.edu/~hull/bib2html,Bib2html}.
Which, in turn depends on man2html for proper installation.
to install GNU LilyPond, simply type:
@example
-
gunzip -c lilypond-x.y.z | tar xf -
cd lilypond-x.y.z
./configure # fill in your standard prefix with --prefix
make
make install
-
@end example
This will install a number of files, something close to:
Rests are entered like notes, with note name `@code{r}@indexcode{r}',
-or `@code{R}@indexcode{R}'. There is also a note name `@code{s}@indexcode{s}',
-which produces a space of the specified duration.
-`@code{R}' is specifically meant for entering parts: the @code{R} rest
-can expand to fill a score with rests, or it can be printed as a
-single multimeasure rest.
+or `@code{R}@indexcode{R}'. There is also a note name
+`@code{s}@indexcode{s}', which produces a space of the specified
+duration. `@code{R}' is specifically meant for entering parts: the
+@code{R} rest can expand to fill a score with rests, or it can be
+printed as a single multimeasure rest.
+
+You can control the expansion by setting the property
+@code{Score.skipBars}. If this is set to true, Lily will not expand
+empty measures, and the multimeasure rests automatically adds the
+appropriate number.
@cindex lyrics expressions
INSTALL - compiling and installing GNU LilyPond
***********************************************
-Abstract
-========
-
- This document explains what you need to install LilyPond, and what
-you should do. If you are going to compile and install LilyPond often,
-e.g. when doing development, you might want to check out the
-`buildscripts/set-lily.sh' script. It sets some environment variables
-and symlinks, which comes in handy when you have to compile LilyPond
-more often.
-
Obtaining
=========
* A GNU system: GNU LilyPond is known to run on these GNU systems:
Linux (PPC, intel), FreeBSD, AIX, NeXTStep, IRIX, Digital Unix
- and Solaris.
+ and Solaris.
* Lots of disk space: LilyPond takes between 30 and 100 mb to
compile if you use debugging information. If you are short on
* GNU Make. Check out ftp://ftp.gnu.org/gnu/make/
(ftp://ftp.gnu.org/gnu/make/).
- * Flex (version 2.5.4 or newer). Check out
+ * Flex (version 2.5.4a or newer). Check out
ftp://ftp.gnu.org/gnu/flex/ (ftp://ftp.gnu.org/gnu/flex/).
* Bison (version 1.25 or newer). Check out
`mfplain.mp', which is needed for producing the scalable font
files.
- If you do not want to use PostScript output, edit `mf/GNUmakefile'.
+ If you do not want to use PostScript output, edit `mf/GNUmakefile',
+ removing the line saying `PFA_FILES='
* kpathsea, a library for searching (TeX) files. `kpathsea' is
usually included with your installation of TeX.
For running LilyPond successfully you have to help TeX and MetaFont
find various files. The recommended way of doing so is adjusting the
-environment variables in the start-up scripts of your shell. An
-example is given here for the Bourne shell:
- export MFINPUTS="/usr/local/share/lilypond/mf:"
- export TEXINPUTS="/usr/local/share/lilypond/tex:/usr/local/share/lilypond/ps:"
+environment variables in the start-up scripts of your shell. Appropriate
+Csh and sh scripts are left in `buildscripts/out/lilypond-profile' and
+`buildscripts/out/lilypond-login' after compilation.
- The empty path component represents TeX and MetaFont's default
-search paths. Scripts with the proper paths for the bourne and C-shell
+ The empty path component represents TeX and MetaFont's default search
+paths. Scripts with the proper paths for the bourne and C-shell
respectively are generated in `buildscripts/out/lilypond-profile' and
`buildscripts/out/lilypond-login' during compilation.
- LilyPond is a hiddeously big, slow and bloated program. A fast CPU
-and plenty of RAM is recommended for comfortable use.
+ LilyPond is a big and slow program. A fast CPU and plenty of RAM is
+recommended for comfortable use.
Website
=======
The version of `pnmtopng' that is distributed with RedHat 5.1 and
5.2 contains a bug: pnmtopng is dynamically linked to the wrong
- version of libpng, which results in cropped images. Recompile it
- from source, and make sure that the pnmtopng binary is linked
- statically to the libpng that is included in libgr. RedHat 6.0
- does not have this problem.
-
- tar xzf libgr-2.0.13.tar.gz
- make
- cd png
- rm libpng.so*
- make pnmtopng
-
- You can then install the new pnmtopng into `/usr/local/bin/'
+ version of libpng.
* Bib2html (http://pertsserver.cs.uiuc.edu/~hull/bib2html).
Which, in turn depends on man2html for proper installation.
=========================
to install GNU LilyPond, simply type:
-
gunzip -c lilypond-x.y.z | tar xf -
cd lilypond-x.y.z
./configure # fill in your standard prefix with --prefix
* Typography: More elegant slurs, aligned dynamics, text crescendos,
-* Better lyrics placement: Automagical phrasing, melisma alignment,
- stanza numbering.
+* Better lyrics placement: Automatical phrasing, melisma alignment,
+ and stanza numbering.
* Part combining for orchestral scores and hymns: two voices are
- combined automatic into a staff automatically, including Solo/`a2
+ combined into a staff automatically, including Solo/`a2
indications as appropriate.
* Chordnames are now configurable in every respect
-* Included extensive glossary
+* Includes an extensive glossary of musical terms.
* Many bugfixes.
* Finished ouverture Coriolan as full orchestral score example.
-* AsciiScript
+* AsciiScript: ASCII-art output
-* Translations into Japanese and Russian
+* Translations into Japanese, French and Russian
+++ /dev/null
-
-[see http://www.cs.uu.nl/people/hanwen/lily-devel/index.html]
PACKAGE_NAME=LilyPond
MAJOR_VERSION=1
MINOR_VERSION=3
-PATCH_LEVEL=91
-MY_PATCH_LEVEL=jcn1
+PATCH_LEVEL=92
+MY_PATCH_LEVEL=
# use the above to send patches: MY_PATCH_LEVEL is always empty for a
# released version.
+%
+% This is NOT a lilypond input file. It is an ABC file, see
+% http://www.gre.ac.uk/~c.walshaw/abc/
+%
+% LilyPond includes import tools for Finale, Musedata, ABC, MIDI and PMX
+%
X:1
T:Paddy O'Rafferty
C:Trad.
--- /dev/null
+
+\score { \notes {
+ c4
+ \property Score.repeatCommands = #'((volta "93") end-repeat)
+ c4 c4
+ \property Score.repeatCommands = #'((volta #f))
+ c4 c4
+}
+}
rests = \notes {
r r r r r r r r r r r r r r r r
}
+different =< \context Voice = one {
+ \stemup
+ \notes \relative c'' {
+ r8 a e4 a e
+ }
+ }
+ \context Voice = two {
+ \stemdown
+ \notes \relative c'' {
+ r1
+ }} >
scales = \context Staff \notes <
\context Voice=i { \stemup r1 r2 r2 \scale c''1 c'2 a'2 \rests }
[c8 r8 c8 c8]
[c''8 r8 c''8 c''8]
[c'8 r8 r8 c'''8]
-
+ \different
}
}
}
-Real
-Align_interface::center_on_element (Score_element *me, Axis a)
-{
- Score_element *cent = unsmob_element (me->get_elt_property ("group-center-element"));
-
- if (cent)
- {
- Real r = cent->relative_coordinate (me, a);
- return -r;
- }
- return 0;
-}
-
/*
Hairy function to put elements where they should be. Can be tweaked
from the outside by setting minimum-space and extra-space in its
Hara_kiri_engraver::acknowledge_element (Score_element_info i)
{
Axis_group_engraver::acknowledge_element (i);
- if (Rhythmic_head::has_interface (i.elem_l_))
+ if (Rhythmic_head::has_interface (i.elem_l_)
+ || i.elem_l_->has_interface (ly_symbol2scm ("lyric-syllable-interface")))
{
Hara_kiri_group_spanner::add_interesting_item (staffline_p_, i.elem_l_);
}
#include "bar.hh"
#include "score-engraver.hh"
-#include "bar-engraver.hh"
#include "musical-request.hh"
#include "multi-measure-rest.hh"
#include "command-request.hh"
#include "engraver-group-engraver.hh"
#include "warn.hh"
#include "item.hh"
+#include "engraver.hh"
+
+/**
+ generate bars. Either user ("|:"), or default (new measure)
+ */
+class Bar_engraver : public Engraver
+{
+public:
+ Bar_engraver();
+ VIRTUAL_COPY_CONS(Translator);
+ void request_bar (String type_str);
+
+protected:
+ virtual void do_creation_processing ();
+ virtual void do_removal_processing ();
+ virtual void do_process_music();
+ virtual void do_pre_move_processing();
+
+private:
+ void typeset_bar ();
+ void create_bar ();
+
+ Item * bar_p_;
+};
Bar_engraver::Bar_engraver()
{
if (!bar_p_)
{
bar_p_ = new Item (get_property ("basicBarProperties"));
+
+ SCM gl = get_property ("whichBar");
+ if (scm_equal_p (gl, bar_p_->get_elt_property ("glyph")) != SCM_BOOL_T)
+ bar_p_->set_elt_property ("glyph", gl);
+
announce_element (bar_p_, 0);
}
}
{
if (bar_p_)
{
- SCM gl = get_property ("whichBar");
- if (scm_equal_p (gl, bar_p_->get_elt_property ("glyph")) != SCM_BOOL_T)
- bar_p_->set_elt_property ("glyph", gl);
typeset_element (bar_p_);
bar_p_ =0;
}
}
ADD_THIS_TRANSLATOR(Bar_engraver);
-
-
-
Break_align_engraver::add_column (SCM smob)
{
Score_element * e = unsmob_element (smob);
- Break_align_item::add_element (align_l_,e);
+ Break_align_interface::add_element (align_l_,e);
typeset_element (e);
}
if (!align_l_)
{
align_l_ = new Item (get_property ("basicBreakAlignProperties"));
- Break_align_item::set_interface (align_l_);
+ Break_align_interface::set_interface (align_l_);
announce_element (align_l_,0);
SCM edge_sym = ly_symbol2scm ("Left_edge_item");
Item * edge = new Item (get_property ("leftEdgeBasicProperties"));
+ /*
+ We must have left-edge in the middle. Instrument-names
+ are left to left-edge, so they don't enter the staff.
+ */
+ align_l_->set_elt_property ("self-alignment-X", edge->self_scm ());
+
+
/*
If the element is empty, it will be ignored in the break
alignment stuff.
group->set_parent (align_l_, Y_AXIS);
announce_element (group, 0);
column_alist_ = scm_assoc_set_x (column_alist_, align_name, group->self_scm ());
+
}
Axis_group_interface::add_element (group, item_l);
}
/*
- break-align-item.cc -- implement Break_align_item
+ break-align-item.cc -- implement Break_align_interface
source file of the GNU LilyPond music typesetter
#include "group-interface.hh"
#include "align-interface.hh"
-MAKE_SCHEME_CALLBACK(Break_align_item,before_line_breaking);
+MAKE_SCHEME_CALLBACK(Break_align_interface,before_line_breaking);
SCM
-Break_align_item::before_line_breaking (SCM smob)
+Break_align_interface::before_line_breaking (SCM smob)
{
Score_element* me = unsmob_element (smob);
do_alignment (me);
}
Real
-Break_align_item::alignment_callback (Score_element*c, Axis a)
+Break_align_interface::alignment_callback (Score_element*c, Axis a)
{
assert (a == X_AXIS);
Score_element *par = c->parent_l (a);
if (par && !to_boolean (par->get_elt_property ("break-alignment-done")))\
{
par->set_elt_property ("break-alignment-done", SCM_BOOL_T);
- Break_align_item::do_alignment (par);
+ Break_align_interface::do_alignment (par);
}
return 0.0;
}
+Real
+Break_align_interface::self_align_callback (Score_element *me, Axis a)
+{
+ assert (a == X_AXIS);
+
+ Item* item = dynamic_cast<Item*> (me);
+ Direction bsd = item->break_status_dir();
+ if (bsd == LEFT)
+ {
+ me->set_elt_property ("self-alignment-X", gh_int2scm (RIGHT));
+ }
+
+ return Side_position::aligned_on_self (me, a);
+}
+
void
-Break_align_item::add_element (Score_element*me, Score_element *toadd)
+Break_align_interface::add_element (Score_element*me, Score_element *toadd)
{
toadd->add_offset_callback (alignment_callback, X_AXIS);
Axis_group_interface::add_element (me, toadd);
}
void
-Break_align_item::do_alignment (Score_element *me)
+Break_align_interface::do_alignment (Score_element *me)
{
Item * item = dynamic_cast<Item*> (me);
Item *column = item->column_l ();
- if (item->break_status_dir() == LEFT)
- {
- me->set_elt_property ("self-alignment-X", gh_int2scm (RIGHT));
- }
- else
- {
- me->add_offset_callback (Align_interface::center_on_element, X_AXIS);
- }
Real interline= me->paper_l ()->get_var ("staffspace");
Link_array<Score_element> elems;
void
-Break_align_item::set_interface (Score_element*me)
+Break_align_interface::set_interface (Score_element*me)
{
Align_interface::set_interface (me);
Align_interface::set_axis (me,X_AXIS);
- me->add_offset_callback (Side_position::aligned_on_self, X_AXIS);
+ me->add_offset_callback (Break_align_interface::self_align_callback, X_AXIS);
}
*/
+
+/*
+ Folded repeats are a stupid idea at this point, so we refrain from
+ implementing get_music () and skip ().
+*/
+
#include "folded-repeat-iterator.hh"
#include "repeated-music.hh"
#include "music-list.hh"
alignment-done -- boolean to administrate whether we've done the alignment already (to ensure that the process is done only once)
- group-center-element -- element which will be at the center of the group
- after aligning (when using Align_interface::center_on_element)
+ center-element -- element which will be at the center of the group
+ after aligning (when using
+ Align_interface::center_on_element). The center element should
+ have this object as a reference point.
elements -- to be aligned elements
+++ /dev/null
-/*
- bar-engraver.hh -- declare Bar_engraver
-
- source file of the GNU LilyPond music typesetter
-
- (c) 1997--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
-*/
-
-
-#ifndef BAR_ENGRAVER_HH
-#define BAR_ENGRAVER_HH
-
-#include "engraver.hh"
-
-/**
- generate bars. Either user ("|:"), or default (new measure)
- */
-class Bar_engraver : public Engraver
-{
-public:
- Bar_engraver();
- VIRTUAL_COPY_CONS(Translator);
-
- void request_bar (String type_str);
-
-protected:
- virtual void do_creation_processing ();
- virtual void do_removal_processing ();
- virtual void do_process_music();
- virtual void do_pre_move_processing();
-
-
-private:
- void typeset_bar ();
- void create_bar ();
-
- Item * bar_p_;
-};
-
-#endif // BAR_ENGRAVER_HH
break-align-symbol -- the index in the spacing table (symbol) of
the to be aligned item.
-
- TODO: remove this as a class, and make interface.
- */
-
-class Break_align_item
+*/
+class Break_align_interface
{
public:
static SCM before_line_breaking (SCM);
static bool has_interface (Score_element*);
static void add_element (Score_element*me, Score_element*add);
static Real alignment_callback (Score_element*, Axis);
+ static Real self_align_callback (Score_element*, Axis);
};
#endif // BREAK_ALIGN_ITEM_HH
#include "lily-proto.hh"
#include "lily-guile.hh"
+
+
+
/*
+ Move rests in note-columns so that they do not collide.
+
properties:
+ read-only
+
+ maximum-rest-count -- kill off rests so we don't more than this
+ number left.
+
+ minimum-distance -- minimum distance between notes and rests.
+
+ read/write
+
elements -- list of elts (both rests and notes) participating in the
collision.
+
+ sets in elements:
+
+ rest-collision -- pointer to self.
+
+
+
+
*/
class Rest_collision // interface
typedef map<SCM,SCM, SCM_less> Scm_stl_map;
/**
- auto resizing hash table. This should come from GUILE.
+ auto resizing hash table.
1. ALWAYS USE THIS AS VIA A POINTER, i.e.
2. UPON DESTRUCTION, DO
scm_unprotect_object (tab->self_scm_);
+
+
+
+
+ TODO:
+
+ This should come from GUILE. We're typically doing double work,
+ because KEY already is a symbol, and is looked up in a symbol
+ hashtable.
*/
class Scheme_hash_table : private Scm_stl_map
SCM to_alist () const;
DECLARE_SMOBS(Scheme_hash_table,foo);
-
};
#endif /* SCM_HASH_HH */
private:
Moment here_mom_;
-
SCM cursor_;
Music_iterator * iter_p_;
+ void next_element ();
void descend_to_child ();
};
self-alignment-X -- real number: -1 = left aligned, 0 = center, 1
right-aligned in X direction.
+
+ Set to an element pointer, if you want that element to be the center.
self-alignment-Y -- like self-alignment-X but for Y axis
*/
class Unfolded_repeat_iterator : public Music_iterator
{
+ void add_repeat_command (SCM);
+
public:
VIRTUAL_COPY_CONS (Music_iterator);
/**
*/
int done_count_;
+ /*
+ are we now busy doing the body?
- /// unfold everything, or do volta?
- bool full_unfold_b_;
-
- /// are we busy doing the body?
+ */
bool do_main_b_;
/** How far have we progressed into the repeat.
This excludes the elt currently being iterated.
*/
- Moment done_mom_;
+ Moment here_mom_;
int alternative_count_i_;
Music_iterator * current_iter_p_;
~Unfolded_repeat_iterator();
Unfolded_repeat_iterator ();
-
protected:
virtual void construct_children ();
virtual Moment pending_moment () const;
virtual void process (Moment);
virtual Music_iterator *try_music_in_children (Music *) const;
-
+ virtual void skip (Moment);
+ virtual SCM get_music (Moment) const;
+
virtual bool ok () const;
- virtual void next_element ();
+ virtual void next_element (bool side_effect);
};
#endif /* UNFOLDED_REPEAT_ITERATOR_HH */
} else if (gh_number_p (sid)) {
yylval.scm = sid;
return NUMBER_IDENTIFIER;
- } else if (Translator_def* tr = unsmob_translator_def (sid)) {
+ } else if (unsmob_translator_def (sid)) {
yylval.scm = sid;
return TRANSLATOR_IDENTIFIER;
} else if (Music * mus =unsmob_music (sid)) {
/**
The name says it all: make multi measure rests
- */
+
+FIXME? The MM rest engraver must be able to see bar lines, so it won't
+work at Voice level. Not a problem in practice, but aesthetically pleasing?
+
+*/
class Multi_measure_rest_engraver : public Engraver
{
public:
--- /dev/null
+/*
+ repeat-acknowledge-engraver.cc -- implement Repeat_acknowledge_engraver
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+
+ */
+#include "engraver.hh"
+#include "translator-group.hh"
+#include "repeated-music.hh"
+
+
+/*
+ Objective:
+
+ -- set and reset repeatCommands, so Unfolded_repeat_iterator knows
+ where to set variables.
+
+ -- collect information passed by Unfolded_repeat_iterator for
+ Bar_engraver: writes whichBar property. (TODO: check for
+ interactions with timing engraver.)
+
+ */
+class Repeat_acknowledge_engraver : public Engraver
+{
+public:
+ VIRTUAL_COPY_CONS (Translator);
+ Repeat_acknowledge_engraver();
+
+ virtual void do_post_move_processing ();
+ virtual void do_process_music ();
+ virtual void do_creation_processing ();
+};
+
+void
+Repeat_acknowledge_engraver::do_creation_processing ()
+{
+ daddy_trans_l_->set_property ("repeatCommands", SCM_EOL);
+}
+
+
+Repeat_acknowledge_engraver::Repeat_acknowledge_engraver()
+{
+}
+
+void
+Repeat_acknowledge_engraver::do_post_move_processing ()
+{
+ Translator_group * tr = daddy_trans_l_->where_defined (ly_symbol2scm ("repeatCommands"));
+ if (!tr)
+ tr = daddy_trans_l_;
+
+ tr->set_property ("repeatCommands", SCM_EOL);
+}
+
+void
+Repeat_acknowledge_engraver::do_process_music ()
+{
+ SCM cs = get_property ("repeatCommands");
+
+ String s = "";
+ bool start = false;
+ bool end = false;
+ while (gh_pair_p (cs))
+ {
+ SCM command = gh_car (cs);
+ if (command == ly_symbol2scm ("start-repeat"))
+ start = true;
+ else if (command == ly_symbol2scm ("end-repeat"))
+ end = true;
+ cs = gh_cdr (cs);
+ }
+
+ if ( start && end )
+ s = ":|:";
+ else if (start)
+ s = "|:";
+ else if (end)
+ s = ":|";
+
+ if (s != "")
+ {
+ daddy_trans_l_->set_property ("whichBar", ly_str02scm(s.ch_C()));
+ }
+}
+
+
+ADD_THIS_TRANSLATOR(Repeat_acknowledge_engraver);
+++ /dev/null
-/*
- repeat-engraver.cc -- implement Repeat_engraver
-
- source file of the GNU LilyPond music typesetter
-
- (c) 1998--2000 Jan Nieuwenhuizen <janneke@gnu.org>
-*/
-
-#include "engraver.hh"
-#include "cons.hh"
-#include "bar.hh"
-#include "bar-engraver.hh"
-#include "musical-request.hh"
-#include "multi-measure-rest.hh"
-#include "command-request.hh"
-#include "timing-translator.hh"
-#include "engraver-group-engraver.hh"
-#include "repeated-music.hh"
-#include "timing-translator.hh"
-#include "volta-spanner.hh"
-#include "note-column.hh"
-#include "paper-def.hh"
-#include "music-list.hh"
-#include "side-position-interface.hh"
-#include "spanner.hh"
-#include "note-column.hh"
-
-struct Bar_create_event
-{
- Moment when_;
- bool bar_b_;
- bool last_b_;
- String type_;
- Bar_create_event();
- Bar_create_event (Moment w, String s);
- Bar_create_event (Moment w, int i, int j);
-};
-
-int compare (Bar_create_event const & c1, Bar_create_event const &c2)
-{
- return (c1.when_ - c2.when_).sign();
-}
-
-/**
- Generate repeat-bars |: :| for repeated-music
- */
-class Repeat_engraver : public Engraver
-{
-public:
- VIRTUAL_COPY_CONS(Translator);
- Repeat_engraver ();
-protected:
- virtual void acknowledge_element (Score_element_info i);
- virtual void do_removal_processing ();
- virtual bool do_try_music (Music *req_l);
- virtual void do_process_music();
- virtual void do_pre_move_processing();
- virtual void do_post_move_processing ();
- void queue_events ();
-
-private:
- Repeated_music *repeated_music_l_;
- bool done_this_one_b_;
-
- /*
- Royal_brackla_create_queue is only two Whiskies away. :-)
- */
- Cons<Bar_create_event> *create_barmoments_queue_;
-
- Spanner * volta_span_p_;
- Spanner* end_volta_span_p_;
-};
-
-
-
-
-ADD_THIS_TRANSLATOR (Repeat_engraver);
-
-bool
-Repeat_engraver::do_try_music (Music* m)
-{
- if (Repeated_music* r = dynamic_cast<Repeated_music *> (m))
- {
- if (repeated_music_l_)
- return false;
-
- if (r->volta_fold_b_)
- {
- repeated_music_l_ = r;
- }
-
- /*
- We acknowledge other types of unfolded music as well, to
- get auto context selection right.
- */
- if (r->type_ == "volta" || r->type_ == "unfolded")
- return true;
-
- }
- return false;
-}
-
-/**
- Walk through repeat music, and generate events for appropriate times.
-
- UGH. Should use Music_iteration for this.
-
- Should also queue some event to get timing information reset during
- 2nd and following voltas.
-*/
-void
-Repeat_engraver::queue_events ()
-{
- Music_sequence* alt = repeated_music_l_->alternatives ();
- Moment walk_mom = now_mom () + repeated_music_l_->body ()->length_mom ();
-
- SCM novolta = get_property ("noVoltaBraces");
- bool create_volta = !to_boolean (novolta);
-
- Cons_list<Bar_create_event> becel;
- becel.append (new Bar_create_event (now_mom (), "|:"));
-
- if (!alt)
- {
- becel.append (new Bar_create_event (walk_mom, ":|"));
- becel.append (new Bar_create_event (walk_mom, "stop"));
- }
- else
- {
- int last_number = 0;
- int volta_number = repeated_music_l_->repeats_i_ - alt->length_i () + 1;
-
- /*
- all repeat alternatives, and generate events with
- appropriate timestamps. The volta spanner event (a number string)
- happens at the begin of the alt. The :| bar event at the ending.
- */
-
- for (SCM s = repeated_music_l_->alternatives ()->music_list ();
- gh_pair_p (s); s = gh_cdr (s))
- {
- Music *mus =unsmob_music (gh_car (s));
-
- /*
- some idiot might typeset a repeat not starting on a
- barline. Make sure there is one.
-
- (todo: should try to avoid line breaks?)
- */
- if (last_number == 0)
- {
- becel.append (new Bar_create_event (walk_mom, ""));
- }
-
-
- if (create_volta)
- {
- Bar_create_event * c = new Bar_create_event (walk_mom, last_number+ 1,
- volta_number);
-
- if (!gh_pair_p (gh_cdr (s)))
- c->last_b_ = true;
-
- becel.append (c);
- last_number = volta_number;
- volta_number ++;
- SCM l (get_property ("voltaSpannerDuration"));
- if (unsmob_moment(l))
- {
- Moment vSD_mom = *unsmob_moment (l);
- if ( vSD_mom < mus->length_mom() ) // terminate volta early ?
- {
- vSD_mom += walk_mom;
- c->last_b_ = true;
- becel.append (new Bar_create_event (vSD_mom, "stop"));
- }
- }
- }
- walk_mom += mus->length_mom();
-
- if (gh_pair_p (gh_cdr (s)))
- becel.append (new Bar_create_event (walk_mom, ":|"));
- else
- becel.append (new Bar_create_event (walk_mom, "stop"));
- }
- }
-
- /*
- ugh, should merge :| and |: here.
- */
- Cons<Bar_create_event> * last = last_cons (create_barmoments_queue_);
- Cons<Bar_create_event> **tail = last? & last->next_
- : & create_barmoments_queue_;
-
- *tail = becel.head_ ;
-
- becel.head_ = 0;
-}
-
-void
-Repeat_engraver::do_process_music ()
-{
- if (repeated_music_l_ && !done_this_one_b_)
- {
- queue_events ();
- done_this_one_b_ = true;
- }
-
-
- Cons<Bar_create_event> * head = create_barmoments_queue_;
- if (!head)
- return;
-
- /*
- Do all the events that need to be done now.
- */
- while (head && now_mom () == head->car_->when_)
- {
- create_barmoments_queue_ = create_barmoments_queue_->next_;
- head->next_ =0;
- String t = head->car_->type_;
- if (head->car_->bar_b_)
- {
- if (t == "stop" || t == ":|")
- {
- end_volta_span_p_ = volta_span_p_;
- volta_span_p_ =0;
- }
-
- SCM whsym = ly_symbol2scm ("whichBar");
- Translator_group* where = daddy_trans_l_->where_defined (whsym);
- SCM which = where->get_property (whsym);
-
- /*
- Should use symbols for bar glyphs.
- */
- if (t == "stop" && which == SCM_UNDEFINED)
- which = ly_str02scm ("");
- else if (t != "stop")
- {
- SCM l = ly_str02scm (":|");
- SCM r = ly_str02scm ("|:");
-
- if ( (t == "|:" && scm_equal_p (which, l) == SCM_BOOL_T)
- || (t == ":|" && scm_equal_p (which, r)== SCM_BOOL_T))
- t = ":|:";
-
- if (t != "" || !gh_string_p (which))
- which = ly_str02scm (t.ch_C());
- }
- where->set_property (whsym, which);
- }
- else
- {
- assert (!volta_span_p_);
- volta_span_p_ = new Spanner (get_property ("basicVoltaSpannerProperties"));
- Volta_spanner::set_interface (volta_span_p_);
- announce_element (volta_span_p_,0);
- volta_span_p_->set_elt_property ("text",
- ly_str02scm (t.ch_C()));
- volta_span_p_->set_elt_property ("last-volta",
- gh_bool2scm (head->car_->last_b_));
- // voltaSpannerDuration stuff here.
- // other property stuff here.
- }
-
-
- delete head->car_;
- delete head;
-
- head = create_barmoments_queue_;
- }
-
- assert (!head || head->car_->when_ > now_mom ());
-}
-
-
-void
-Repeat_engraver::acknowledge_element (Score_element_info i)
-{
- if (Item* item = dynamic_cast<Item*> (i.elem_l_))
- {
- if (Note_column::has_interface (item))
- {
- if (volta_span_p_)
- Volta_spanner::add_column (volta_span_p_,item);
- if (end_volta_span_p_)
- Volta_spanner::add_column (end_volta_span_p_,item);
- }
- if (Bar::has_interface (item))
- {
- if (volta_span_p_)
- Volta_spanner::add_bar (volta_span_p_, item);
- if (end_volta_span_p_)
- Volta_spanner::add_bar(end_volta_span_p_ , item);
- }
- }
-}
-
-void
-Repeat_engraver::do_removal_processing ()
-{
- if (volta_span_p_)
- {
- typeset_element(volta_span_p_);
- }
- if (end_volta_span_p_)
- {
- typeset_element (end_volta_span_p_);
- }
- // todo: the paranoid may also delete create_barmoments_queue_
-}
-
-void
-Repeat_engraver::do_post_move_processing ()
-{
- for (Cons<Bar_create_event> *p = create_barmoments_queue_;
- p && p->car_->when_ == now_mom (); p = p->next_)
- if (p->car_->type_ == "stop")
- {
- repeated_music_l_ = 0;
- done_this_one_b_ = false;
- }
-}
-
-void
-Repeat_engraver::do_pre_move_processing ()
-{
- if (end_volta_span_p_)
- {
- Side_position::add_staff_support (end_volta_span_p_);
-
- typeset_element (end_volta_span_p_ );
- end_volta_span_p_ =0;
- }
-
-}
-
-
-Repeat_engraver::Repeat_engraver()
-{
- repeated_music_l_ =0;
- end_volta_span_p_ =0;
- volta_span_p_ =0;
- done_this_one_b_ = false;
- create_barmoments_queue_ =0;
-}
-
-/* ************** */
-Bar_create_event::Bar_create_event()
-{
- last_b_ =false;
- bar_b_ = true;
-}
-
-Bar_create_event::Bar_create_event (Moment w, String s)
-{
- last_b_ =false;
- when_ = w;
- type_ = s;
- bar_b_ = true;
-}
-
-Bar_create_event::Bar_create_event (Moment w, int i, int j)
-{
- last_b_ =false;
- when_ = w ;
- bar_b_ = false;
-
- if (i!=j)
- type_ = to_str (i) + ".-" ;
-
- type_ += to_str(j) + ".";
-}
Request_chord_iterator::get_music (Moment) const
{
SCM s = SCM_EOL;
- if (music_l_)
+ if (last_processed_mom_ < Moment (0))
{
Music_sequence * ms = dynamic_cast<Music_sequence*> (music_l_);
void
Request_chord_iterator::process (Moment m)
{
- if (music_l_)
+ if (last_processed_mom_ < Moment (0))
{
for (SCM s = dynamic_cast<Music_sequence *> (music_l_)->music_list ();
gh_pair_p (s); s = gh_cdr (s))
p->set_elt_property ("rest-collision", me->self_scm ());
}
+
+/*
+ Combination of dot-count and duration-log.
+ */
static SCM
head_characteristic (Score_element * col)
{
// meisjes met meisjes
if (!notes.size())
{
-
- /*
- FIXME: col2rhythmic_head and rhythmic_head2mom sucks bigtime.
-
- */
SCM characteristic = head_characteristic (rests[0]);
int i = 1;
for (; i < rests.size (); i++)
display_count = rests.size ();
/*
- UGH. Should get dims from table. Should have minimum dist.
+ Ugh. Should have minimum dist.
+
+ Ugh. What do we do if we have three different rests?
+
*/
- int dy = display_count > 2 ? 6 : 4;
+ int dy = display_count > 2 ? 6 : 4; // FIXME Should get dims from table.
if (display_count > 1)
{
- Note_column::translate_rests (rests[0],dy);
- Note_column::translate_rests (rests[1], -dy);
+ Direction d0 = Note_column::dir (rests[0]);
+ Direction d1 = Note_column::dir (rests[1]);
+
+ if (!d0 && !d1)
+ {
+ d0= UP;
+ d1 = DOWN;
+ }
+ else if (!d0)
+ d0 = - d1;
+ else if (!d1)
+ d1 = -d0;
+
+ Note_column::translate_rests (rests[0],d0 *dy);
+ Note_column::translate_rests (rests[1], d1 *dy);
}
}
// meisjes met jongetjes
#include "music-list.hh"
#include "request-chord-iterator.hh"
+/*
+ Invariant for the data structure.
+
+
+ if (gh_pair_p (cursor_))
+ iter_p_->music_l_ == unsmob_music (gh_car (cursor_))
+ else
+ iter_p_ == 0;
+
+ The length of musiclist from start to up to cursor_ (cursor_ not
+ including), is summed
+
+ here_mom_ = sum (length (musiclist [start ... cursor> )) %)
+
+ */
+
+
Sequential_music_iterator::Sequential_music_iterator ()
{
- cursor_ = 0;
- here_mom_ = 0;
+ cursor_ = SCM_EOL;
+ here_mom_ = Moment (0);
+
iter_p_ =0;
}
Sequential_music_iterator::construct_children()
{
cursor_ = dynamic_cast<Music_sequence const*> (music_l_)->music_list ();
-
- while (gh_pair_p (cursor_ ))
+
+ iter_p_ = gh_pair_p (cursor_) ? get_iterator_p (unsmob_music (gh_car (cursor_))) : 0;
+ while (iter_p_ && !iter_p_->ok ())
{
- iter_p_ = get_iterator_p (unsmob_music (gh_car (cursor_)));
-
- if (iter_p_->ok())
- {
- descend_to_child ();
- return;
- }
-
- delete iter_p_ ;
- iter_p_ =0;
- cursor_ = gh_cdr (cursor_);
+ next_element ();
}
+
+ /*
+ iter_p_->ok () is tautology, but what the heck.
+ */
+ if (iter_p_ && iter_p_->ok())
+ descend_to_child ();
+
+}
+
+
+/*
+ maintain invariants: change cursor, iter and here_mom_ in one fell
+ swoop.
+*/
+void
+Sequential_music_iterator::next_element ()
+{
+ here_mom_ += iter_p_->music_length_mom ();
+ delete iter_p_;
+ cursor_ = gh_cdr (cursor_);
+
+ if (gh_pair_p (cursor_))
+ iter_p_ = get_iterator_p (unsmob_music (gh_car (cursor_)));
+ else
+ iter_p_ = 0;
}
- /*
+
+/*
move to context of child iterator if it is deeper down in the
hierarchy.
*/
void
Sequential_music_iterator::descend_to_child ()
{
-
Translator_group * child_report = child_report = iter_p_->report_to_l ();
if (dynamic_cast<Grace_iterator*> (iter_p_))
child_report = child_report->daddy_trans_l_;
if (until < pending_moment ())
return s;
- SCM curs = cursor_;
- Music_iterator * iter = iter_p_->clone ();
- while (1)
+ Sequential_music_iterator * me =
+ dynamic_cast<Sequential_music_iterator*> (clone ());
+ while (me->ok ())
{
- SCM nm = iter->get_music (until - here_mom_);
+ SCM nm = me->iter_p_->get_music (until - me->here_mom_);
s = gh_append2 (nm, s);
Moment m = 0;
for (SCM i = nm; gh_pair_p(i); i = gh_cdr (i))
m = m >? unsmob_music (gh_car (i))->length_mom ();
- delete iter;
-
- curs = gh_cdr (curs);
-
- if (!gh_pair_p (curs) || m > Moment (0))
- return s;
+ if (m > Moment (0))
+ break ;
else
- {
- iter = get_iterator_p (unsmob_music (gh_car (curs)));
- }
+ me->next_element ();
}
+ delete me;
+
return s;
}
/*
void
Sequential_music_iterator::skip (Moment until)
{
- while (1)
+ while (ok ())
{
Moment l =iter_p_->music_length_mom ();
if (l >= until - here_mom_)
if (iter_p_->ok ())
return ;
-
- here_mom_ = here_mom_ + l;
- delete iter_p_;
- iter_p_ =0;
-
- cursor_ = gh_cdr (cursor_);
- if (!gh_pair_p (cursor_))
- return ;
- else
- iter_p_ = get_iterator_p (unsmob_music (gh_car (cursor_)));
+ next_element ();
}
}
void
Sequential_music_iterator::process (Moment until)
{
- while (1)
+ while (iter_p_)
{
iter_p_->process (until - here_mom_);
if (iter_p_->ok ())
return ;
- here_mom_ += iter_p_->music_length_mom ();
-
descend_to_child ();
- delete iter_p_;
- iter_p_ =0;
-
- cursor_ = gh_cdr (cursor_);
-
- if (!gh_pair_p (cursor_))
- return ;
- else
- {
- delete iter_p_;
- iter_p_ = get_iterator_p (unsmob_music (gh_car (cursor_)));
- }
+ next_element ();
}
-
}
Moment
callback that centers the element on itself
*/
Real
-Side_position::aligned_on_self (Score_element *elm, Axis ax)
+Side_position::aligned_on_self (Score_element *me, Axis ax)
{
String s ("self-alignment-");
s += (ax == X_AXIS) ? "X" : "Y";
- SCM align (elm->get_elt_property (s.ch_C()));
+ SCM align (me->get_elt_property (s.ch_C()));
if (gh_number_p (align))
{
- Interval ext(elm->extent (ax));
+ Interval ext(me->extent (ax));
if (ext.empty_b ())
{
}
else
{
- Real lambda = (0.5 + gh_scm2double (align) / 2.0);
+ Real lambda = (0.5 - gh_scm2double (align) / 2.0);
return - (lambda * ext[LEFT] + (1 - lambda) * ext[RIGHT]);
}
}
- else
+ else if (unsmob_element (align))
+ {
+ return - unsmob_element (align)->relative_coordinate (me, ax);
+ }
return 0.0;
}
Moment
Simple_music_iterator::pending_moment ()const
{
- if (music_l_)
+ if (last_processed_mom_ < Moment (0))
return Moment (0);
else
return music_length_mom ();
void
Simple_music_iterator::process (Moment m)
{
-#if 0
/*
- try_music () causes trouble for base classes
- */
- if (music_l_)
- {
- bool b = try_music (music_l_);
- if (!b)
- music_l_->origin ()->warning (_f ("Junking music: `%s'",
- classname (music_l_)));
- }
-#endif
+ don't do try_music (), since it would make the function useless for
+ base classes */
+
skip (m);
}
void
Stem_tremolo::set_interface (Score_element *me)
{
+ me->set_interface (ly_symbol2scm ("stem-tremolo"));
+}
+
+bool
+Stem_tremolo::has_interface (Score_element *me)
+{
+ return me->has_interface (ly_symbol2scm ("stem-tremolo"));
}
(c) 1997--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
*/
+#include <iostream.h>
#include "translator-group.hh"
#include "command-request.hh"
virtual bool do_try_music (Music * );
virtual void do_post_move_processing ();
virtual void do_process_music ();
+ virtual void do_pre_move_processing ();
public:
- String which_bar ();
VIRTUAL_COPY_CONS(Translator);
};
Timing_translator::do_post_move_processing ();
SCM nonauto = get_property ("barNonAuto");
- SCM which = now_mom () ? SCM_UNDEFINED : ly_str02scm ("|");
+
+ SCM which = get_property ("whichBar");
+ if (!gh_string_p (which))
+ which = now_mom () ? SCM_EOL : ly_str02scm ("|");
- if (which == SCM_UNDEFINED && !to_boolean (nonauto))
+ if (!gh_string_p (which) && !to_boolean (nonauto))
{
SCM always = get_property ("barAlways");
if (!measure_position ()
daddy_trans_l_->set_property ("whichBar", which);
}
+void
+Timing_engraver::do_pre_move_processing ()
+{
+ Timing_translator::do_pre_move_processing ();
+ daddy_trans_l_->set_property ("whichBar", SCM_EOL);
+}
+
bool
Timing_engraver::do_try_music (Music*m)
{
*/
void
-Unfolded_repeat_iterator::next_element ()
+Unfolded_repeat_iterator::next_element (bool side_effect)
{
- Repeated_music * mus =dynamic_cast<Repeated_music *> (music_l_);
+ Repeated_music * repmus =dynamic_cast<Repeated_music *> (music_l_);
delete current_iter_p_;
current_iter_p_ =0;
-
+ bool do_repcommands = side_effect && repmus->volta_fold_b_;
+
if (do_main_b_)
{
- done_mom_ += mus->body ()->length_mom ();
+ /*
+ we were busy doing the main body, so
+
+ - go to alternative if we're a volta
+
+ - do something intelligent when we're fully unfolding (fixcomment)
+ */
+
+ here_mom_ += repmus->body ()->length_mom ();
- if (!mus->volta_fold_b_)
+ if (!repmus->volta_fold_b_)
done_count_ ++;
if (gh_pair_p (alternative_cons_))
{
current_iter_p_ = get_iterator_p (unsmob_music (gh_car (alternative_cons_)));
do_main_b_ = false;
+
+ if (repmus->volta_fold_b_)
+ {
+ String repstr = to_str (done_count_ + 1);
+ if (do_repcommands)
+ add_repeat_command (gh_list (ly_symbol2scm ("volta"),
+ gh_str02scm (repstr.ch_C()), SCM_UNDEFINED));
+ }
}
- else if (done_count_ < mus->repeats_i_ && !mus->volta_fold_b_)
+ else if (done_count_ < repmus->repeats_i_ && !repmus->volta_fold_b_)
{
- current_iter_p_ = get_iterator_p (mus->body ());
+ current_iter_p_ = get_iterator_p (repmus->body ());
do_main_b_ = true;
}
}
we're not in the main part. So we're either in an alternative, or
we just finished.
*/
+
+ /*
+ we're in the alternatives. We move the pointer to the
+ next alternative.
+ */
if (alternative_cons_)
{
- done_mom_ += unsmob_music (gh_car (alternative_cons_))->length_mom ();
+ here_mom_ += unsmob_music (gh_car (alternative_cons_))->length_mom ();
- if (mus->volta_fold_b_ ||
- mus->repeats_i_ - done_count_ < alternative_count_i_)
+ if (repmus->volta_fold_b_ ||
+ repmus->repeats_i_ - done_count_ < alternative_count_i_)
alternative_cons_ = gh_cdr (alternative_cons_);
+ if (do_repcommands)
+ add_repeat_command (gh_list (ly_symbol2scm ("volta"), SCM_BOOL_F, SCM_UNDEFINED));
+
+
+
/*
we've done the main body as well, but didn't go over the other
increment. */
- if (mus->volta_fold_b_)
+ if (repmus->volta_fold_b_)
done_count_ ++;
}
+
+ /*
+ We still have alternatives left, so
+
+ if we're volta: traverse them
+
+ if we're full unfold: go back to main body.
+ */
- if (done_count_ < mus->repeats_i_ && gh_pair_p (alternative_cons_))
+ if (done_count_ < repmus->repeats_i_ && gh_pair_p (alternative_cons_))
{
- if (mus->volta_fold_b_)
+ if (do_repcommands)
+ {
+ String repstr = to_str (done_count_ + 1);
+ add_repeat_command (gh_list (ly_symbol2scm ("volta"),
+ gh_str02scm (repstr.ch_C()), SCM_UNDEFINED));
+ add_repeat_command (ly_symbol2scm ("end-repeat"));
+ }
+
+
+ if (repmus->volta_fold_b_)
current_iter_p_ = get_iterator_p (unsmob_music (gh_car (alternative_cons_)));
else
{
- current_iter_p_ = get_iterator_p (mus->body ());
+ current_iter_p_ = get_iterator_p (repmus->body ());
do_main_b_ = true;
}
}
Moment
Unfolded_repeat_iterator::pending_moment () const
{
- return done_mom_ + current_iter_p_->pending_moment ();
+ return here_mom_ + current_iter_p_->pending_moment ();
}
void
}
}
+void
+Unfolded_repeat_iterator::add_repeat_command (SCM what)
+{
+ SCM reps = ly_symbol2scm ("repeatCommands");
+ SCM current_reps = report_to_l ()->get_property(reps);
+
+ Translator_group * where = report_to_l ()->where_defined (reps);
+ if (where
+ && current_reps == SCM_EOL || gh_pair_p (current_reps))
+ {
+ current_reps = gh_cons (what, current_reps);
+ where->set_property (reps, current_reps);
+ }
+}
+
void
Unfolded_repeat_iterator::process (Moment m)
{
if (!m)
{
- Music_iterator *yeah = try_music (music_l_);
- if (yeah)
- set_translator (yeah->report_to_l ());
- else
- music_l_->origin ()->warning ( _("no one to print a volta bracket"));
+ if (dynamic_cast<Repeated_music*> (music_l_)->volta_fold_b_)
+ add_repeat_command (ly_symbol2scm ("start-repeat"));
}
while (1)
{
while (!current_iter_p_->ok ())
{
- next_element();
+ next_element(true);
if (!current_iter_p_)
return;
}
- if (m - done_mom_ >= current_iter_p_->pending_moment ())
- current_iter_p_->process (m - done_mom_);
+ if (m - here_mom_ >= current_iter_p_->pending_moment ())
+ current_iter_p_->process (m - here_mom_);
else
return;
}
}
+void
+Unfolded_repeat_iterator::skip (Moment until)
+{
+ while (current_iter_p_)
+ {
+ Moment l =current_iter_p_->music_length_mom ();
+ if (l >= until - here_mom_)
+ current_iter_p_->skip (until - here_mom_);
+
+ if (current_iter_p_->ok ())
+ return ;
+
+ next_element (false);
+ }
+}
+
+SCM
+Unfolded_repeat_iterator::get_music (Moment until)const
+{
+ SCM s = SCM_EOL;
+ if (until < pending_moment ())
+ return s;
+
+
+ Unfolded_repeat_iterator * me
+ = dynamic_cast<Unfolded_repeat_iterator*> (this->clone ());
+
+ while (me->ok ())
+ {
+ SCM nm = me->current_iter_p_->get_music (until -
+ me->here_mom_);
+
+ s = gh_append2 (nm, s);
+
+ Moment m = 0;
+ for (SCM i = nm; gh_pair_p(i); i = gh_cdr (i))
+ m = m >? unsmob_music (gh_car (i))->length_mom ();
+
+ if (m > Moment (0))
+ break ;
+ else
+ me->next_element (false);
+ }
+
+ delete me;
+
+ return s;
+}
+
Music_iterator*
Unfolded_repeat_iterator::try_music_in_children (Music * m) const
--- /dev/null
+/*
+ volta-engraver.cc -- implement Volta_engraver
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+
+ */
+
+#include "engraver.hh"
+#include "translator-group.hh"
+#include "volta-spanner.hh"
+#include "item.hh"
+#include "note-column.hh"
+#include "bar.hh"
+#include "side-position-interface.hh"
+
+/*
+ Create Volta spanners, by reading repeatCommands property, usually
+ set by Unfolded_repeat_iterator.
+ */
+class Volta_engraver : public Engraver
+{
+public:
+ Volta_engraver();
+ VIRTUAL_COPY_CONS(Translator);
+protected:
+
+ virtual void acknowledge_element (Score_element_info);
+ virtual void do_removal_processing ();
+ virtual void do_pre_move_processing ();
+ virtual void do_process_music ();
+
+ Moment started_mom_;
+ Spanner * volta_span_p_;
+ Spanner* end_volta_span_p_;
+};
+
+ADD_THIS_TRANSLATOR(Volta_engraver);
+
+Volta_engraver::Volta_engraver ()
+{
+ volta_span_p_ = 0;
+ end_volta_span_p_ = 0;
+}
+
+void
+Volta_engraver::do_process_music ()
+{
+ SCM cs = get_property ("repeatCommands");
+
+ SCM str = SCM_EOL;
+ bool end = false;
+ while (gh_pair_p (cs))
+ {
+ SCM c = gh_car (cs);
+
+ if (gh_pair_p (c) && gh_car (c) == ly_symbol2scm ("volta"))
+ {
+ if (gh_cadr (c) == SCM_BOOL_F)
+ end = true;
+ else
+ str = gh_cadr (c);
+ }
+
+ cs = gh_cdr (cs);
+ }
+
+ SCM l (get_property ("voltaSpannerDuration"));
+ Moment now = now_mom ();
+
+ bool early_stop = volta_span_p_ && unsmob_moment (l)
+ &&*unsmob_moment (l) <= now - started_mom_;
+
+ if (end || early_stop)
+ {
+ end_volta_span_p_ = volta_span_p_;
+ volta_span_p_ =0;
+
+ /*
+ maybe do typeset_element () directly?
+ */
+
+ if (!gh_string_p (str))
+ end_volta_span_p_->set_elt_property ("last-volta", SCM_BOOL_T);
+ }
+
+ if (gh_string_p (str))
+ {
+ started_mom_ = now;
+ if (volta_span_p_)
+ {
+ warning (_ ("Already have a volta spanner. Stopping that one prematurely."));
+
+ if (end_volta_span_p_)
+ {
+ warning (_("Also have a stopped spanner. Giving up."));
+
+ return ;
+
+ }
+
+
+ end_volta_span_p_ = volta_span_p_;
+ volta_span_p_ = 0;
+ }
+
+ volta_span_p_ = new Spanner (get_property ("basicVoltaSpannerProperties"));
+ Volta_spanner::set_interface (volta_span_p_);
+ announce_element (volta_span_p_,0);
+ volta_span_p_->set_elt_property ("text", str);
+ }
+}
+
+void
+Volta_engraver::acknowledge_element (Score_element_info i)
+{
+ if (Item* item = dynamic_cast<Item*> (i.elem_l_))
+ {
+ if (Note_column::has_interface (item))
+ {
+ if (volta_span_p_)
+ Volta_spanner::add_column (volta_span_p_,item);
+ if (end_volta_span_p_)
+ Volta_spanner::add_column (end_volta_span_p_,item);
+ }
+ if (Bar::has_interface (item))
+ {
+ if (volta_span_p_)
+ Volta_spanner::add_bar (volta_span_p_, item);
+ if (end_volta_span_p_)
+ Volta_spanner::add_bar(end_volta_span_p_ , item);
+ }
+ }
+}
+
+void
+Volta_engraver::do_removal_processing ()
+{
+ if (volta_span_p_)
+ {
+ typeset_element(volta_span_p_);
+ }
+ if (end_volta_span_p_)
+ {
+ typeset_element (end_volta_span_p_);
+ }
+}
+
+void
+Volta_engraver::do_pre_move_processing ()
+{
+ if (end_volta_span_p_)
+ {
+ Side_position::add_staff_support (end_volta_span_p_);
+
+ typeset_element (end_volta_span_p_ );
+ end_volta_span_p_ =0;
+ }
+}
% with empty ones.
- \consists "Repeat_engraver";
+% \consists "Repeat_engraver";
+ \consists "Volta_engraver";
\consists "Separating_line_group_engraver";
basicVoltaSpannerProperties \push #'padding = #5 % urg, in \pt
basicStaffSymbolProperties \push #'line-count = #1
- \consists "Repeat_engraver";
+% \consists "Repeat_engraver";
+ \consists "Volta_engraver";
\consists "Bar_engraver";
\consists "Time_signature_engraver";
\consists "Staff_symbol_engraver";
\name Score;
+ \consists "Repeat_acknowledge_engraver";
\consists "Timing_engraver";
\consists "Output_property_engraver";
\consists "System_start_delimiter_engraver";
\consists "Mark_engraver";
\consists "Break_align_engraver";
\consists "Spacing_engraver";
-
\consists "Vertical_align_engraver";
\consists "Lyric_phrasing_engraver";
% contributed by Paolo Zuliani <zuliap@easynet.it>
-\notenames {
+\notenames #'
(dobb . ( -1 0 -2 ))
(dob . ( -1 0 -1 ))
(do . ( -1 0 0 ))
(si . ( -1 6 0 ))
(sid . ( -1 6 1 ))
(sidd . ( -1 6 2 ))
-}
+)
-\version "1.3.59";
+\version "1.3.90";
common dutch names for notes. es means flat, is means sharp
%}
-\notenames
- #'((ceses . (-1 0 -2 ))
+\notenames #'(
+ (ceses . (-1 0 -2 ))
(ces . ( -1 0 -1 ))
(c . ( -1 0 0 ))
(cis . ( -1 0 1 ))
%}
+
+papersizename = \papersize ;
+
paperfile = \papersize + ".ly";
% paperfile = "a4.ly";
\include \paperfile;
Name: lilypond
Version: @TOPLEVEL_VERSION@
Release: 1
-Copyright: GPL
+License: GPL
Group: Applications/Publishing
Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-@TOPLEVEL_VERSION@.tar.gz
Summary: A program for printing sheet music.
%build
-%{configure} --disable-checking --disable-debugging --enable-printing --prefix=%{_prefix} --disable-optimise --enable-shared
+#
-make all
+# DO NOT use % { configure } , it hardcodes all paths, runs libtool,
+# so we can't do make prefix=/tmp/ install.
+
+# In fact, do not take out the spaces between % and { , because RPM will gladly
+# do a substitution anyway.
-ln -s %{_prefix}/share/texmf/fonts/tfm/public/cm/ tfm
+./configure --disable-checking --disable-debugging --enable-printing --prefix=%{_prefix} --disable-optimise --enable-shared
+
+make all
# urg
# %build documentation
# line 42: second %build
# ok, now make sure that lilypond package will succeed,
# even if documentation fails to build
+
make -C Documentation || true
make htmldoc || true
%ifnos cygwin
%{_prefix}/bin/abc2ly
-%{_prefix}/bin/etf2ly
-%{_prefix}/bin/musedata2ly
-%{_prefix}/bin/pmx2ly
+%{_prefix}/bin/as2text
%{_prefix}/bin/convert-mudela
-%{_prefix}/bin/mudela-book
-%{_prefix}/bin/ly2dvi
+%{_prefix}/bin/etf2ly
%{_prefix}/bin/lilypond
+%{_prefix}/bin/ly2dvi
%{_prefix}/bin/midi2ly
+%{_prefix}/bin/mudela-book
+%{_prefix}/bin/musedata2ly
+%{_prefix}/bin/pmx2ly
%else
%{_prefix}/bin
%endif
-%{_prefix}/man/man1/midi2ly.1
-%{_prefix}/man/man1/lilypond.1
-%{_prefix}/man/man1/mudela-book.1
-%{_prefix}/man/man1/ly2dvi.1
-%{_prefix}/man/man1/convert-mudela.1
+%{_prefix}/man/man1/abc2ly.1.gz
+%{_prefix}/man/man1/as2text.1.gz
+%{_prefix}/man/man1/convert-mudela.1.gz
+%{_prefix}/man/man1/etf2ly.1.gz
+%{_prefix}/man/man1/lilypond.1.gz
+%{_prefix}/man/man1/ly2dvi.1.gz
+%{_prefix}/man/man1/midi2ly.1.gz
+%{_prefix}/man/man1/mudela-book.1.gz
+%{_prefix}/man/man1/musedata2ly.1.gz
+%{_prefix}/man/man1/pmx2ly.1.gz
+
%{_prefix}/share/lilypond/
%{_prefix}/share/locale/*/LC_MESSAGES/lilypond.mo
# urg?
Begin3
Title: LilyPond
-Version: 1.3.91
-Entered-date: 28SEP00
+Version: 1.3.92
+Entered-date: 01OCT00
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.91.tar.gz
+ 1000k lilypond-1.3.92.tar.gz
Original-site: ftp.cs.uu.nl /pub/GNU/LilyPond/development/
- 1000k lilypond-1.3.91.tar.gz
+ 1000k lilypond-1.3.92.tar.gz
Copying-policy: GPL
End
Name: lilypond
-Version: 1.3.91
+Version: 1.3.92
Release: 1
-Copyright: GPL
+License: GPL
Group: Applications/Publishing
-Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.3.91.tar.gz
+Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.3.92.tar.gz
Summary: A program for printing sheet music.
URL: http://www.cs.uu.nl/~hanwen/lilypond
# Icon: lilypond-icon.gif
%build
-%{configure} --disable-checking --disable-debugging --enable-printing --prefix=%{_prefix} --disable-optimise --enable-shared
+#
-make all
+# DO NOT use % { configure } , it hardcodes all paths, runs libtool,
+# so we can't do make prefix=/tmp/ install.
+
+# In fact, do not take out the spaces between % and { , because RPM will gladly
+# do a substitution anyway.
-ln -s %{_prefix}/share/texmf/fonts/tfm/public/cm/ tfm
+./configure --disable-checking --disable-debugging --enable-printing --prefix=%{_prefix} --disable-optimise --enable-shared
+
+make all
# urg
# %build documentation
# line 42: second %build
# ok, now make sure that lilypond package will succeed,
# even if documentation fails to build
+
make -C Documentation || true
make htmldoc || true
%ifnos cygwin
%{_prefix}/bin/abc2ly
-%{_prefix}/bin/etf2ly
-%{_prefix}/bin/musedata2ly
-%{_prefix}/bin/pmx2ly
+%{_prefix}/bin/as2text
%{_prefix}/bin/convert-mudela
-%{_prefix}/bin/mudela-book
-%{_prefix}/bin/ly2dvi
+%{_prefix}/bin/etf2ly
%{_prefix}/bin/lilypond
+%{_prefix}/bin/ly2dvi
%{_prefix}/bin/midi2ly
+%{_prefix}/bin/mudela-book
+%{_prefix}/bin/musedata2ly
+%{_prefix}/bin/pmx2ly
%else
%{_prefix}/bin
%endif
-%{_prefix}/man/man1/midi2ly.1
-%{_prefix}/man/man1/lilypond.1
-%{_prefix}/man/man1/mudela-book.1
-%{_prefix}/man/man1/ly2dvi.1
-%{_prefix}/man/man1/convert-mudela.1
+%{_prefix}/man/man1/abc2ly.1.gz
+%{_prefix}/man/man1/as2text.1.gz
+%{_prefix}/man/man1/convert-mudela.1.gz
+%{_prefix}/man/man1/etf2ly.1.gz
+%{_prefix}/man/man1/lilypond.1.gz
+%{_prefix}/man/man1/ly2dvi.1.gz
+%{_prefix}/man/man1/midi2ly.1.gz
+%{_prefix}/man/man1/mudela-book.1.gz
+%{_prefix}/man/man1/musedata2ly.1.gz
+%{_prefix}/man/man1/pmx2ly.1.gz
+
%{_prefix}/share/lilypond/
%{_prefix}/share/locale/*/LC_MESSAGES/lilypond.mo
# urg?
#
SCRIPTS = configure aclocal.m4
-README_FILES = DEDICATION COPYING NEWS TODO CHANGES ROADMAP
+README_FILES = DEDICATION COPYING NEWS CHANGES ROADMAP
README_TXT_FILES = AUTHORS.txt README.txt INSTALL.txt
IN_FILES := $(wildcard *.in)
EXTRA_DIST_FILES = dstreamrc lilypond-mode.el vimrc VERSION $(README_FILES) $(SCRIPTS) $(IN_FILES)
MODULE_NAME = midi2ly
SUBDIRS = include
-EXTRA_DIST_FILES += TODO
MODULE_LIBS=$(depth)/flower
HELP2MAN_EXECS = midi2ly
STEPMAKE_TEMPLATES=c++ executable po help2man
+++ /dev/null
-# midi2ly/TODO
-
-Most of the items are marked in the code as well, with full explanation.
-grep for TODO and ugh/ugr
-
-
-IMPORTANT
-
- * if multiple channels per track: output each to separate voice
-
- * get rid of (last few?) midi-specifics in mudela-*
-
- * find / remove trend (tempo) of mudela columns
-
- * get rid of Duration_* statics
-
- * junk one in list vs. array
-
- * add midi2ly example output (.midi.ly and .gif) to website
-
- * important? lily is important, go work on lily!
-
- * faq about midi2ly midi t1. ?
-
-PROJECTS
-
- * write something interesting in midi2ly manual page
-
- * check/use type 0 / 1 / 2 of midi file
-
- * create Indentable_stream (see Tex_stream) as base for Lily_stream
-
- * use dynamic info
-
- * use aftertouch info (to guess slurs/ties, scripts (staccato?))
-
- * lyric events
-
- * parse all midi events
-
- * handle time based midi files
-
- * use dstream feature from lily
-
- * midi esp.: use I32 iso int where 32 bits are needed (or assumed...)
-
- * read unsigned words as U16 (not as I16)
-
- * check use of integral and unsigned in lexer
-
- * get rid of ugly statics in Duration_convert
-
- * change option double-dots to max-dots
-
- * set Key, Meter, ... command line options
-
-BUGS
-
- * output of 0 duration c'0
-
- * array memleaks(?): use Link_array / create Pointer_array?
-
- * fix "#undef MEVENT_LIST" source tree: Array<Midi_event*>
-
- * split notes that cross bar limit
-
-FUTURE
-
- * guess plets (i.e.: only use plet-duration *2/3 if there's a
- whole plet)
-
- * merge midi-events with lily's midi-items?
-
- * guess beams
-
- * guess / follow tempo changes
-
- * check out NIFF / analogies?
-
- * steal good ideas of other gpl midi parsers
-
- * lily: add mudela info into midi as specials
- midi2ly: use special info
-
# bin/Makefile
depth = ..
-SEXECUTABLES=convert-mudela mudela-book ly2dvi abc2ly as2text
+SEXECUTABLES=convert-mudela mudela-book ly2dvi abc2ly as2text etf2ly musedata2ly pmx2ly
STEPMAKE_TEMPLATES=script help2man
HELP2MAN_EXECS = $(SEXECUTABLES)
def calculate (self):
fs = []
-
if len (self.finale) < 2:
fs = self.finale[0]
fs = map (string.atoi, list (fs))
self.clef = fs[1]
self.frames = [fs[0]]
else:
- fs = self.finale[0:2]
+ fs = self.finale[0] + self.finale[1]
fs = map (string.atoi, list (fs))
self.clef = fs[0]