\mudelafile{number-staff-lines.fly}
+\section{Spacing}
+
+In a limited number of cases, LilyPond corrects for optical spacing
+effects. In this example, space for opposite pointed stems is adjusted
+
+\mudelafile{stem-spacing.sly}
+
\section{Global stuff}
Markings that are attached to (invisible) barlines are
It is possible to create beams and slurs that cross staffs by switching the
context:
mudela(fragment,verbatim,center)(
-<
+\context PianoStaff <
\context Staff=one \notes\relative c'{
\stemup
[c8 c \translator Staff=two \stemup c c]
\translator Staff=one
d4( \translator Staff=two )a4
}
-\context Staff=two \notes{ \clef bass;}
+\context Staff=two \notes{ \clef bass; s1}
>
)
Mutopia is an archive of public domain music, free for all to
download, modify and redistribute. It should be based on free
-software. It is similar in spirit to the gutenberg archive.
+software. It is similar in spirit to the Gutenberg archive.
- setup submission guidelines,
-- acquire mutopia.org domain.
-
-- setup FTP server
-
-- cooperate with ABC folks, ftp.gmd.de
+- setup FTP/Web server
WHO DO WE NEED
-Volunteers that want to setup and maintain a website and FTP site.
-
-Volunteers with enough legal knowledge to write submission guidelines.
+Volunteers that want to setup, host and maintain a website and FTP
+site.
-A project leader.
+Volunteers to write submission guidelines, and copyright FAQs.
Signed
-Han-Wen Nienhys
+Han-Wen Nienhuys
Jan Nieuwenhuizen
[other bigwigs?]
Grep for TODO and ugh/ugr/urg.
.* BUGS
-. * junk separate mudela versioning.
-. * petite-ouverture time sig size.
+. * junk separate mudela versioning.
+. * indent = 0.0 with linewidth=-1.0
. * PostScript
. * header for PS enteredby = "bla <bla@bar.com>"
. * ps/lily.ps see comments.
. * fix MIDI
. * \shape 1st dim skipped?
. * turn slope-damping on/off
-. * tremolo stuff: tremolo over whole note.
. * We need feta-din*.mf files for more sizes than 10.
. * fix dynamics decently, ie. use kerning & ligatures.
. * dots & rest collisions?
note + circle = note + 1/4 of its length
-5 the circle is like a dot that's not filled in. for example, on
+ the circle is like a dot that's not filled in. for example, on
page three, the c-sharp on the second line should be a quarter with
a circle, not a quarter tied to a sixteenth. is this at all
possible with lily?
. * repeat engraver, gallina.ly
. * Matanya's tips:
-. * spacing for prefatory matter
. * accidentals closer to note head
. * to space the staffs/staffgroups contained in the score.
. * heavier beams?
. * Slur
. * Rhythmic_grouping
. * Duration
-. * Collision
-. * Rest_collision
-. * clef grav prop's
+. * clef engraver
. * parser
.* TODO before 1.2
. * Morally pure LilyPond.
-. * Remove mutopia ramblings.
. * Remove non-free software links.
. * Remove meta article LilyPond.
. * break priority setting from SCM.
. * add new glyphs to font.ly
. * formatting of input stuff.
. * \notes{ a \< b \cr } vs \notes{ a \< b \! }
-. * 'hinterfleisch' before bar (e.g. wtk1-fugue2)?
-. * Summary of minor spelling irregularities:
-. * capitalization/use of underscores in property names
-. * fix SkipBars -> skipBars
. * broken scripts:
lbheel = \script { "bheel" 0 0 -1 0 0 }
rbheel = \script { "bheel" 0 0 1 0 0 }
.* 3RD PARTY BUGS
. * GNU diff 2.7: diff -rN does not see a new directory with empty file
+. * mf-to-table -> add space before ; in AFM output. (-> check AFM
+ spec. Is this a bug in afm2tfm?)
. * check out GCC signatures?
. * glibc 2.0:
f = fopen ("/dev/null", "r")
piece = "1. Overture";
}
-\version "1.0.20";
+\version "1.0.21";
global=\notes{
\time 2/2;
--- /dev/null
+
+\score { \context Staff \notes { c1 \nobreak c1 }}
-\version "1.0.20";
+\version "1.0.21";
one = \notes\relative c{
c'' d e f
}
}
-\version "1.0.20";
+\version "1.0.21";
-\version "1.0.20";
+\version "1.0.21";
blah = \notes {
Tested Features: example file with comments
%}
-\version "1.0.20";
+\version "1.0.21";
% the % is a comment.
-\version "1.0.20";
+\version "1.0.21";
part = \notes {
c-1 c c c
r1*3
% \lbheel \lbheel \lfheel \lftoe
% \rbheel \rbtoe \rfheel \rftoe
-\version "1.0.20";
+\version "1.0.21";
\score{
\notes {
* organ staff...
%}
-\version "1.0.20";
+\version "1.0.21";
\VoiceContext
\name "VoiceThree";
verticalDirection = "1";
- hshift = "1";
+ horizontalNoteShift = "1";
}
\translator {
\VoiceContext
\name "VoiceFour";
verticalDirection = "-1";
- hshift = "1";
+ horizontalNoteShift = "1";
}
\translator {
\StaffContext
-\version "1.0.20";
+\version "1.0.21";
ritme = \notes\transpose c'' {
\time 4/4;
% scales with accents.
%
-\version "1.0.20";
+\version "1.0.21";
blah = \notes {
\time 6/8;
\transpose c {
-\version "1.0.20";
+\version "1.0.21";
blah = \notes{ \transpose c'' {
}
-\version "1.0.20";
+\version "1.0.21";
}
}
-\version "1.0.20";
+\version "1.0.21";
}}
-\version "1.0.20";
+\version "1.0.21";
-\version "1.0.20";
+\version "1.0.21";
onestaff = \context Staff = foo\notes {
\property Staff.instr = instr
-\version "1.0.20";
+\version "1.0.21";
\score{
\notes\transpose c'{
}
}
-\version "1.0.20";
+\version "1.0.21";
}
}
-\version "1.0.20";
+\version "1.0.21";
-\version "1.0.20";
+\version "1.0.21";
\score{
\notes\transpose c''{
TestedFeatures = "beams and beamflags";
}
-\version "1.0.20";
+\version "1.0.21";
\score{
<
"(Feta definitively is not an abbreviation of Font-En-TjA)";
}
-\version "1.0.20";
+\version "1.0.21";
shortlong = \notes{
c4()c( c c |
>
}
-\version "1.0.20";
+\version "1.0.21";
}
-\version "1.0.20";
+\version "1.0.21";
-\version "1.0.20";
+\version "1.0.21";
%{
Would this be acceptable/good enough/convenient for entry?
-\version "1.0.20";
+\version "1.0.21";
\score {
\notes{
copyright = "public domain";
Tested = "test the Collision resolution ";
}
-\version "1.0.20";
+\version "1.0.21";
twovoice = \context Staff \notes <
\context Voice=i { \stemdown c4 d e f g2~ g4 a [c8 d e f] c2| }
threevoice = \context Staff \notes <
\context Voice=i { \stemup g4 f e f g a g2 }
- \context Voice=ii { \stemup \property Voice.hshift = 1 e2 e2 e2 e2 }
+ \context Voice=ii { \stemup \property Voice.horizontalNoteShift = 1 e2 e2 e2 e2 }
\context Voice=iii { \stemdown c4 d e d c d es }
>
-\version "1.0.20";
+\version "1.0.21";
\score {
\include "paper20.ly"
-\version "1.0.20";
+\version "1.0.21";
oden = \lyrics{
O8 |
-\version "1.0.20";
+\version "1.0.21";
\score{
\notes{
>
}
-\version "1.0.20";
+\version "1.0.21";
}
-\version "1.0.20";
+\version "1.0.21";
-\version "1.0.20";
+\version "1.0.21";
\score{
\notes \relative c {
% "(Feta definitively is not an abbreviation of Font-En-TjA)";
}
-\version "1.0.20";
+\version "1.0.21";
\include "font-body.ly"
\score{
% "(Feta definitively is not an abbreviation of Font-En-TjA)";
}
-\version "1.0.20";
+\version "1.0.21";
\include "paper16.ly"
\include "font-body.ly"
gourlay_maxmeasures =5.;
}
}
-\version "1.0.20";
+\version "1.0.21";
TestedFeatures = "This file tests some nasty Gourlay spacings";
}
-\version "1.0.20";
+\version "1.0.21";
%{
-\version "1.0.20";
+\version "1.0.21";
\score{
<
-\version "1.0.20";
+\version "1.0.21";
toeter_i = \notes\relative c <{
\property Staff.instrument = "Toeters"
/Mats B
%}
-\version "1.0.20";
+\version "1.0.21";
incipit = \notes\relative c'{
<b1 fis' b d>
-\version "1.0.20";
+\version "1.0.21";
%{
test key itemv breaking
-\version "1.0.20";
+\version "1.0.21";
\score{
\notes\relative c'{
[c16 \stemdown c'' \stemboth c,, d]
-\version "1.0.20";
+\version "1.0.21";
global = \notes {
s1 | \mark "A";
>
\paper { Gourlay_maxmeaures = 2.; }
}
-\version "1.0.20";
+\version "1.0.21";
-\version "1.0.20";
+\version "1.0.21";
voice_one = \notes\transpose c''{ \stemup
R1 * 2 | f'4-. r r2 | R1 * 3 |
}
}
-\version "1.0.20";
+\version "1.0.21";
-\version "1.0.20";
+\version "1.0.21";
\score{
\notes \transpose c''{
-\version "1.0.20";
+\version "1.0.21";
m = \notes \relative c''{
c1 | c2 c | c c | c c | c c | c c | c c | c c |
-\version "1.0.20";
+\version "1.0.21";
\score {
}
}
-\version "1.0.20";
+\version "1.0.21";
-\version "1.0.20";
+\version "1.0.21";
onestaff = \context Staff = foo\notes {
\property Staff.instr = instr
"(Feta definitively is not an abbreviation of Font-En-TjA)";
}
-\version "1.0.20";
+\version "1.0.21";
shortlong = \notes{
c4()c( c c |
}
under = \notes\transpose c'{
-
\stemdown
f'( \stemboth d d \stemdown )f'
f'( \stemboth c c \stemdown )f'
}
eccentric = \notes\transpose c'{
-
\stemup
\times 4/7 { f( a' f f f f )f } |
\times 4/7 { f( f f f f a' )f } |
-\version "1.0.20";
+\version "1.0.21";
% bug
% excentric slur can't handle this ...
% test damping
-\version "1.0.20";
+\version "1.0.21";
\score{
\notes\relative c'{
}
}
-\version "1.0.20";
+\version "1.0.21";
-\version "1.0.20";
+\version "1.0.21";
% urg, the direction of the slur gets swapped!
\score{
-\version "1.0.20";
+\version "1.0.21";
\score{
\notes\transpose c'{
}
}
-\version "1.0.20";
+\version "1.0.21";
TestedFeatures = "This file tests various spacings";
}
-\version "1.0.20";
+\version "1.0.21";
multipart = \notes \relative c'{
\context StaffGroup <
-\version "1.0.20";
+\version "1.0.21";
nt = \notes { c1 \break c1 c1 }
stuff = \notes \relative c'' <
\context Staff = stone { \nt }
-\version "1.0.20";
+\version "1.0.21";
\score {
}
-\version "1.0.20";
+\version "1.0.21";
>
\paper { linewidth = -1.; }
}
-\version "1.0.20";
+\version "1.0.21";
--- /dev/null
+
+\time 12/4; c''4 c c c a f' f, a
-\version "1.0.20";
+\version "1.0.21";
\score{
\notes \transpose c'''{
\stemup
}
-\version "1.0.20";
+\version "1.0.21";
beamintervals = \notes{
\time 7/4;
instrument= "Violoncello";
}
-\version "1.0.20";
+\version "1.0.21";
% this is an example of extreme dynamics
% the thumb-script is used in cello music to indicate a note that should
% be played with your thumb.
-\version "1.0.20";
+\version "1.0.21";
\score { \notes \relative c'' {
[<a8_\thumb a'8-3(> <)b_\thumb b'-3>
-\version "1.0.20";
+\version "1.0.21";
% middle tie is wrong
-\version "1.0.20";
+\version "1.0.21";
tie = \notes\transpose c''{
instrument= "Instrument";
}
-\version "1.0.20";
+\version "1.0.21";
\score{
\notes
}
-\version "1.0.20";
+\version "1.0.21";
vOne = \notes \relative c''{
\clef"violin";
}
}
-\version "1.0.20";
+\version "1.0.21";
{\voicetwo c}>
-\version "1.0.20";
+\version "1.0.21";
-\version "1.0.20";
+\version "1.0.21";
\score {
\notes <
}
}
-\version "1.0.20";
+\version "1.0.21";
}
}
-\version "1.0.20";
+\version "1.0.21";
"(Feta definitively is not an abbreviation of Font-En-TjA)";
}
-\version "1.0.20";
+\version "1.0.21";
\score{
\notes{
Molecule*
Bar::do_brew_molecule_p () const
{
- Molecule *output = new Molecule (lookup_l ()->bar (type_str_, get_bar_size ()));
+ Molecule *output = new Molecule (lookup_l ()->bar (type_str_, get_bar_size (), paper_l ()));
return output;
}
Array<Column_x_positions> h= do_solve ();
if (approx_stats_.count_i_)
- *mlog << '\n' << _f ("approximated: %s", approx_stats_.str ()) << endl;
+ *mlog << '\n' << _f ("approximated %s", approx_stats_.str ()) << endl;
if (exact_stats_.count_i_)
- *mlog << _f ("calculated exactly: %s", exact_stats_.str ()) << endl;
- *mlog << _f ("time: %.2f seconds", timer.read ()) << endl;
+ *mlog << _f ("calculated %s exactly", exact_stats_.str ()) << endl;
+ *mlog << _f ("elapsed time %.2f seconds", timer.read ()) << endl;
return h;
}
add_element (ncol_l);
add_dependency (ncol_l);
}
-/**
- should derive of Array.
- */
-static
-int idx (int dir, bool h_shift_b)
-{
- assert (abs (dir) == 1);
- int j = dir > 0 ? 0 : 3;
- if (h_shift_b)
- j += dir;
- return j;
-}
+
/** This complicated routine moves note columns around horizontally to
ensure that notes don't clash.
This should be done better, probably.
- This routine is dedicated to Stine Randmael :-)
-
+ TODO: forced hshift
+
*/
void
Collision::do_pre_processing()
{
- if (clash_l_arr_.size() <= 1)
- return;
-
- /*
- [stem up, stem up shifted, stem down shifted, stem down]
- */
- Array<Note_column*> clash_group_arr_a[4]; // TODO: use drul.
-
+ Drul_array<Link_array<Note_column> > clash_groups;
+ Drul_array<Array<int> > shifts;
+
for (int i=0; i < clash_l_arr_.size(); i++)
{
- Note_column* c_l = clash_l_arr_[i];
- Direction d = c_l->dir ();
- if (!d)
- {
- warning (_ ("No stem direction set. Ignoring column in clash."));
- continue;
- }
-
- SCM shift = c_l->remove_elt_property (horizontal_shift_scm_sym);
- bool shift_b = (shift != SCM_BOOL_F);
- clash_group_arr_a[idx (d, shift_b)].push (c_l);
+ clash_groups[clash_l_arr_[i]->dir ()].push (clash_l_arr_[i]);
}
-
- for (int j=0; j < 4; j++)
- {
- if (clash_group_arr_a[j].size() > 1)
- {
- warning (_ ("Too many clashing notecolumns. Ignoring them."));
- return;
- }
- }
+
Direction d = UP;
do
{
- if (!clash_group_arr_a[idx (d, false)].size())
- {
- clash_group_arr_a[idx (d, false)] = clash_group_arr_a[idx (d, true)];
- clash_group_arr_a[idx (d, true)].clear();
- }
- }
- while (flip (&d) != UP);
-
+ Array<int> & shift (shifts[d]);
+ Link_array<Note_column> & clashes (clash_groups[d]);
- Interval_t<int> y_extent[4];
- Note_column * col_l_a[4];
- Real x_off [4];
+ clashes.sort (Note_column::shift_compare);
- for (int j =0 ; j < 4; j++)
- {
- if (clash_group_arr_a[j].size())
- col_l_a[j] = clash_group_arr_a[j][0];
- else
- col_l_a[j] = 0;
+ for (int i=0; i < clashes.size (); i++)
+ {
+ SCM sh
+ = clashes[i]->remove_elt_property (horizontal_shift_scm_sym);
- if (col_l_a[j])
+ if (sh == SCM_BOOL_F)
+ shift.push (0);
+ else
+ shift.push (gh_scm2int (SCM_CDR (sh)));
+ }
+
+ for (int i=1; i < shift.size (); i++)
{
- y_extent[j] = col_l_a[j]->head_positions_interval();
+ if (shift[i-1] == shift[i])
+ {
+ warning (_ ("Too many clashing notecolumns. Ignoring them."));
+ return;
+ }
}
-
-
- x_off [j] = 0.0;
}
+ while ((flip (&d))!= UP);
+ Drul_array< Array < Slice > > extents;
+ Drul_array< Array < Real > > offsets;
+ d = UP;
do
{
- x_off[idx (d, true)] = d*0.5;
+ for (int i=0; i < clash_groups[d].size (); i++)
+ {
+ Slice s(clash_groups[d][i]->head_positions_interval ());
+ s[LEFT] --;
+ s[RIGHT]++;
+ extents[d].push (s);
+ offsets[d].push (d * 0.5 * i);
+ }
}
- while (flip (&d) != UP);
-
-
- // y_extent: smallest y-pos noteball interval containing all balls
- // 4 (0..3) groups: stem up/down; shift on/off;
- Interval_t<int> middle (y_extent[idx (-1,0)][BIGGER],
- y_extent[idx (1,0)][SMALLER]);
- Interval_t<int> open_middle (y_extent[idx (-1,0)][BIGGER]+1, y_extent[idx (1,0)][SMALLER]-1);
+ while ((flip (&d))!= UP);
+
do
{
- if (!open_middle.contains_b (y_extent[idx (d,true)]))
- x_off[idx (d, true)] = d *1.0 ;
- } while ((d *= -1) != 1);
-
+ for (int i=1; i < clash_groups[d].size (); i++)
+ {
+ Slice prev =extents[d][i-1];
+ prev.intersect (extents[d][i]);
+ if (prev.length ()> 0 ||
+ (extents[-d].size () && d * (extents[d][i][-d] - extents[-d][0][d]) < 0))
+ for (int j = i; j < clash_groups[d].size (); j++)
+ offsets[d][j] += d * 0.5;
+ }
+ }
+ while ((flip (&d))!= UP);
- if (!middle.empty_b()
- && middle.length() < 2 && col_l_a[idx (1,0)] && col_l_a[idx (-1,0)])
+ /*
+ if the up and down version are close, and can not be merged, move
+ all of them again. */
+ if (extents[UP].size () && extents[DOWN].size ())
{
- // reproduction of bugfix at 3am ?
- Note_head * nu_l= col_l_a[idx (1,0)]->head_l_arr_[0];
- Note_head * nd_l = col_l_a[idx (-1,0)]->head_l_arr_.top();
- if (! (nu_l->balltype_i_ == nd_l->balltype_i_
- && nu_l->dots_i_ == nd_l->dots_i_ && middle.length() == 0))
- {
+ Note_column *cu_l =clash_groups[UP][0];
+ Note_column *cd_l =clash_groups[DOWN][0];
+ Note_head * nu_l= cu_l->head_l_arr_[0];
+ Note_head * nd_l = cd_l->head_l_arr_.top();
+ int downpos = cd_l->head_positions_interval ()[SMALLER];
+ int uppos = cu_l->head_positions_interval ()[BIGGER];
+
+ bool merge =
+ downpos == uppos
+ && nu_l->balltype_i_ == nd_l->balltype_i_
+ && nu_l->dots_i_ == nd_l->dots_i_;
+
+ /*
+ notes are close, but can not be merged. Shift
+ */
+ if (abs(uppos - downpos) < 2 && !merge)
do
- {
- x_off[idx (d, false)] -= d*0.5;
- x_off[idx (d, true)] -= d*0.5;
- }
- while (flip (&d) != UP);
- }
+ {
+ for (int i=0; i < clash_groups[d].size (); i++)
+ {
+ offsets[d][i] -= d * 0.5;
+ }
+ }
+ while ((flip (&d))!= UP);
}
Real wid_f = paper_l ()->note_width ();
- for (int j=0; j < 4; j++)
+ do
{
- if (col_l_a[j])
+ for (int i=0; i < clash_groups[d].size (); i++)
{
- Offset o (x_off[j] * wid_f, 0);
- col_l_a[j]->translate (o);
+ clash_groups[d][i]->translate_axis (offsets[d][i]*wid_f, X_AXIS);
}
}
+ while (flip (&d) != UP);
}
-
-
void
Collision::do_substitute_element_pointer (Score_element*o_l,Score_element*n_l)
{
bool continued = broken[Direction (-grow_dir_)];
- return Molecule (lookup_l ()->hairpin (w_dim, grow_dir_ < 0, continued));
+ Real height = paper_l()->staffheight_f () / 6;
+
+ return Molecule (lookup_l ()->hairpin (w_dim, height, grow_dir_ < 0, continued));
}
Molecule*
#include "g-script.hh"
#include "lookup.hh"
#include "g-staff-side.hh"
+#include "paper-def.hh"
G_script::G_script ()
{
}
else if (key == ly_symbol ("accordion"))
{
- return lookup_l ()->accordion (SCM_CDR(s));
+ return lookup_l ()->accordion (SCM_CDR(s), paper_l()->get_realvar(interline_scm_sym));
}
else assert (false);
Molecule*
G_text_item::do_brew_molecule_p () const
{
- Molecule a= paper_l ()->lookup_l(0)->text (style_str_,text_str_);
+ Molecule a= paper_l ()->lookup_l(0)->text (style_str_,text_str_, paper_l ());
return new Molecule (a);
}
#include "box.hh"
/** handy interface to symbol table
+ TODO: move this into GUILE?
*/
class Lookup
{
Lookup ();
Lookup (Lookup const&);
- Molecule simple_bar (String s, Real w) const;
+ Molecule simple_bar (String s, Real w, Paper_def*) const;
Molecule accidental (int, bool cautionary) const;
Molecule afm_find (String, bool warn=true) const;
Molecule notehead (int, String) const;
- Molecule bar (String, Real height) const;
+ Molecule bar (String, Real height, Paper_def*) const;
Molecule beam (Real, Real, Real) const;
Molecule clef (String) const;
Molecule dashed_slur (Array<Offset> controls, Real thick, Real dash) const;
Molecule fill (Box b) const;
Molecule filledbox (Box b) const;
Molecule flag (int, Direction) const;
- Molecule hairpin (Real width, bool decresc, bool continued) const;
- Molecule plet (Real dy, Real dx, Direction dir) const;
+ Molecule hairpin (Real width, Real height, bool decresc, bool continued) const;
+ Molecule tuplet_bracket (Real dy, Real dx, Real thick,Real interline, Direction dir) const;
Molecule rest (int, bool outside, String) const;
- Molecule accordion (SCM arg) const;
- Molecule stem (Real y1_pos, Real y2_pos) const;
+ Molecule accordion (SCM arg, Real interline_f) const;
Molecule slur (Array<Offset> controls) const;
- Molecule text (String style, String text) const;
+ Molecule text (String style, String text, Paper_def*) const;
Molecule staff_brace (Real dy) const;
Molecule staff_bracket (Real dy) const;
- Molecule volta (Real w, bool last_b) const;
- Molecule special_time_signature (String, int,int) const;
- Molecule time_signature (int n,int d) const;
-
- Paper_def * paper_l_;
+ Molecule volta (Real w, Real h, Real il, bool last_b) const;
+ Molecule special_time_signature (String, int,int, Paper_def*) const;
+ Molecule time_signature (int n,int d, Paper_def*) const;
String font_name_;
Adobe_font_metric * afm_l_;
DECLARE_LY_SYMBOL(extremal);
DECLARE_LY_SYMBOL(extra_space);
DECLARE_LY_SYMBOL(dir_forced);
+DECLARE_LY_SYMBOL(dir_list);
DECLARE_LY_SYMBOL(extender_height);
DECLARE_LY_SYMBOL(filledbox);
DECLARE_LY_SYMBOL(fontsize);
DECLARE_LY_SYMBOL(tuplet_visibility);
DECLARE_LY_SYMBOL(visibility_lambda);
DECLARE_LY_SYMBOL(volta);
+DECLARE_LY_SYMBOL(void);
DECLARE_LY_SYMBOL(volta_thick);
virtual void do_print () const;
virtual void do_substitute_element_pointer (Score_element*,Score_element*);
public:
+
+ static int shift_compare (Note_column *const &, Note_column*const&);
+
/** The relative position of the "voice" containing this
chord. Normally this would be the same as the stem direction,
#include "parray.hh"
#include "lily-proto.hh"
#include "music-output.hh"
+#include "lily-guile.hh"
/** all stuff which goes onto paper. notes, signs, symbols in a score
#Paper_score# contains the items, the columns.
/// other elements
Link_array<Score_element> elem_p_arr_;
-
- Link_array<Score_element> to_delete_arr_;
Link_array<Score_element> break_helpers_arr_;
+ SCM protected_scms_;
public:
Paper_def *paper_l_;
/// add a Spanner
void typeset_unbroken_spanner (Spanner*);
- void schedule_for_delete (Score_element*);
virtual ~Paper_score();
protected:
-
-
/* MAIN ROUTINES */
virtual void process();
private:
-
-
- Link_array<Score_element> remove_line (Line_of_score*);
- Link_array<Score_element> remove_break_helpers ();
-
/// before calc_breaking
void preprocess();
#include "virtual-methods.hh"
#include "directed-graph.hh"
#include "graphical-element.hh"
-#include "protected-scm.hh"
#include "lily-guile.hh"
*/
class Score_element : public virtual Graphical_element {
- Protected_scm element_property_alist_;
+
+ friend class Paper_score;
+ /**
+ properties specific for this element. Destructor will not call
+ scm_unprotect, so as to allow more flexible GC arrangements. The
+ real alist is in (cdr element_property_alist_), to reduce the
+ need for more scm_protect calls.
+
+ */
+ SCM element_property_alist_;
Link_array<Score_element> dependency_arr_;
/**
The lookup, determined by the font size. Cache this value.
int col_count () const;
protected:
virtual Array<Spring> get_springs () const;
-
+
+ Real stem_dir_correction (Score_column*,Score_column*) const;
+ Real default_bar_spacing (Score_column*,Score_column*,Moment) const;
+ Real note_spacing (Score_column*,Score_column*,Moment) const;
};
#endif /* SPACING_SPANNER_HH */
virtual void do_pre_processing();
virtual Interval do_width() const;
virtual Molecule* do_brew_molecule_p() const;
+
+ void set_spacing_hints () ;
};
#endif
}
else if (measures_i_ > 1)
{
- Molecule s ( lookup_l ()->text ("number", to_str (measures_i_)));
+ Molecule s ( lookup_l ()->text ("number", to_str (measures_i_), paper_l ()));
s.translate_axis (3.0 * interline_f, Y_AXIS);
mol_p->add_molecule (s);
return rest_l_arr_.size ();
}
+int
+Note_column::shift_compare (Note_column *const &p1, Note_column*const&p2)
+{
+ SCM s1 = p1->get_elt_property (horizontal_shift_scm_sym);
+ SCM s2 = p2->get_elt_property (horizontal_shift_scm_sym);
+
+ int h1 = (s1 == SCM_BOOL_F) ? 0 : gh_scm2int (SCM_CDR(s1));
+ int h2 = (s2 == SCM_BOOL_F) ? 0 : gh_scm2int (SCM_CDR(s2));
+ return h1 - h2;
+}
+
Note_column::Note_column()
{
set_axes (X_AXIS,X_AXIS);
head_l_arr_.sort (Note_head::compare);
}
-Interval_t<int>
+Slice
Note_column::head_positions_interval() const
{
- ((Note_column*)this)->sort();
- Interval_t<int> iv;
+ Slice iv;
iv.set_empty ();
-
- if (head_l_arr_.size ())
- iv = Interval_t<int>(head_l_arr_[0]->position_i_,
- head_l_arr_.top()->position_i_);
-
+ for (int i=0; i <head_l_arr_.size ();i ++)
+ {
+ int j = head_l_arr_[i]->position_i_;
+ iv.unite (Slice (j,j));
+ }
return iv;
}
Paper_score::Paper_score ()
{
+ protected_scms_ = scm_protect_object (gh_cons (SCM_BOOL_T, SCM_EOL));
paper_l_ =0;
outputter_l_ =0;
Line_of_score * line_p = new Line_of_score;
delete span_p_arr_[i];
for (int i=elem_p_arr_.size (); --i >=0 ; )
delete elem_p_arr_[i];
+
+ scm_unprotect_object (protected_scms_);
}
void
elem_p_arr_.push (elem_p);
elem_p->pscore_l_ = this;
-
+ // take over protection.
+ SCM_CDR(protected_scms_) = gh_cons (elem_p->element_property_alist_,
+ SCM_CDR (protected_scms_));
+ scm_unprotect_object (elem_p->element_property_alist_);
+
SCM p = elem_p->remove_elt_property (break_helper_only_scm_sym);
if (p != SCM_BOOL_F)
break_helpers_arr_.push (elem_p);
-/*
- not clean. Should update elem_p_arr_ and span_p_arr_. That would
- also repair the stats.
-
- This may be done efficiently by first sorting the arrays. */
-void
-delete_array_contents (Link_array<Score_element> &to_remove, Dictionary<int> &type_stats)
-{
- for (int i=0; i < to_remove.size (); i++)
- {
- Score_element * e = to_remove[i];
- String nm = e->name();
- if (type_stats.elem_b (nm))
- type_stats[nm] ++;
- else
- type_stats[nm] = 1;
-
- if (dynamic_cast<Item*> (e))
- type_stats["Item"] ++;
- else if (dynamic_cast<Spanner*>(e))
- type_stats["Spanner"] ++;
- type_stats["Total"] ++;
- /*
- */
-
- // delete e; //TODO!
- }
-
- to_remove.clear ();
- to_remove.tighten_maxsize ();
-}
-
-void
-Paper_score::schedule_for_delete (Score_element*e)
-{
- to_delete_arr_.push (e);
-}
-
void
Paper_score::process ()
{
Array<Column_x_positions> breaking = calc_breaking ();
- delete_array_contents (break_helpers_arr_, type_stats);
-
Paper_stream* paper_stream_p = paper_l_->paper_stream_p ();
outputter_l_ = paper_l_->paper_outputter_p (paper_stream_p, header_l_, origin_str_);
*mlog << '(' << elem_p_arr_.size () + span_p_arr_.size () << ')';
*mlog << ']' << flush;
-
- delete_array_contents (to_delete_arr_, type_stats);
}
// huh?
for (Hash_table_iter<int, Lookup*> ai(*s.lookup_p_tab_p_); ai.ok (); ai++)
{
Lookup * l = new Lookup (*ai.val ());
- l->paper_l_ = this;
set_lookup (ai.key(), l);
}
}
{
delete lookup_p_tab_p_->elem (i);
}
- l ->paper_l_ = this;
(*lookup_p_tab_p_)[i] = l;
}
// mmm
Mudela_version oldest_version ("1.0.20");
-Mudela_version version ("1.0.20");
+Mudela_version version ("1.0.21");
void
print_mudela_versions (ostream &os)
{
if (ncol_p_)
{
+ Scalar sh = get_property ("horizontalNoteShift", 0);
// egcs
- if (get_property ("hshift", 0).operator bool ())
+ if (sh.to_bool () && sh.isnum_b ())
{
- ncol_p_->set_elt_property (horizontal_shift_scm_sym, SCM_BOOL_T);
+ ncol_p_->set_elt_property (horizontal_shift_scm_sym,
+ gh_int2scm (int (sh)));
}
typeset_element (ncol_p_);
lookup_l_ =0;
status_i_ = 0;
original_l_ = 0;
- element_property_alist_ = SCM_EOL;
+ element_property_alist_ = scm_protect_object (gh_cons (gh_cons (void_scm_sym, SCM_BOOL_T) , SCM_EOL));
}
Score_element::Score_element (Score_element const&s)
{
used_b_ = true;
original_l_ =(Score_element*) &s;
- element_property_alist_ = scm_list_copy (s.element_property_alist_);
+ element_property_alist_ = scm_protect_object (scm_list_copy (s.element_property_alist_));
dependency_arr_ = s.dependency_arr_;
output_p_ =0;
status_i_ = s.status_i_;
Score_element::remove_elt_property (SCM key)
{
SCM s = get_elt_property (key);
- element_property_alist_ = scm_assq_remove_x (element_property_alist_, key);
+ SCM_CDR(element_property_alist_) = scm_assq_remove_x (SCM_CDR (element_property_alist_), key);
return s;
}
void
Score_element::set_elt_property (SCM s, SCM v)
{
- element_property_alist_ =
- scm_assoc_set_x (element_property_alist_, s, v);
+ SCM_CDR(element_property_alist_) =
+ scm_assoc_set_x (SCM_CDR (element_property_alist_), s, v);
}
Interval
pscore_l_->outputter_l_->output_molecule (output_p_,
o,
classname(this));
-
- pscore_l_->schedule_for_delete (this);
}
/*
e->used_b_ = true;
}
else
- warning("Null dependency added");
-
+ programming_error ("Null dependency added");
}
+
void
Score_element::substitute_dependency (Score_element* old, Score_element* new_l)
{
{
if (Break_req* b = dynamic_cast<Break_req *> (r))
{
+ gotcha = true;
if (b->penalty_i_ <= Break_req::DISALLOW)
break_penalty_i_ = b->penalty_i_;
else if (b->penalty_i_ >= Break_req::FORCE)
- {
- command_column_l_->break_penalty_i_ = b->penalty_i_;
- gotcha = true;
- }
+ command_column_l_->break_penalty_i_ = b->penalty_i_;
}
}
return gotcha;
generate springs between columns.
- TODO
-
- * Spacing should take optical effects into account
-
The algorithm is partly taken from :
John S. Gourlay. ``Spacing a Line of Music,'' Technical Report
Array<Spring> meas_springs;
- /*
- UGR GUR URG. duplicate code for spacing generation.
- */
for (int i= col1; i < col2; i++)
{
- SCM hint = scol (i)->get_elt_property (extra_space_scm_sym);
- if (hint != SCM_BOOL_F)
- {
- hint = SCM_CDR (hint);
-
- Spring s;
- s.item_l_drul_[LEFT] = scol (i);
- s.item_l_drul_[RIGHT] = scol (i+1);
- Real unbroken_dist = gh_scm2double (SCM_CDR(hint));
+ Item * l = scol(i);
+ Item * r = scol(i+1);
+ Item * lb = l->find_prebroken_piece (RIGHT);
+ Item * rb = r->find_prebroken_piece (LEFT);
- s.distance_f_ = unbroken_dist;
- s.strength_f_ = 2.0;
-
+ Item* combinations[4][2]={{l,r}, {lb,r}, {l,rb},{lb,rb}};
- meas_springs.push (s);
+ for (int i=0; i < 4; i++)
+ {
+ Score_column * lc = dynamic_cast<Score_column*> (combinations[i][0]);
+ Score_column *rc = dynamic_cast<Score_column*> (combinations[i][1]);
+ if (!lc || !rc)
+ continue;
+ Spring s;
+ s.item_l_drul_[LEFT] = lc;
+ s.item_l_drul_[RIGHT] = rc;
- Item * l = scol(i)->find_prebroken_piece (RIGHT);
- Item * r = scol(i+1)->find_prebroken_piece (LEFT);
- if (l)
+ SCM hint = lc->get_elt_property (extra_space_scm_sym);
+ SCM next_hint = rc->get_elt_property (extra_space_scm_sym);
+
+ if (hint != SCM_BOOL_F)
{
- Spring s;
- s.item_l_drul_[LEFT] = l;
- s.item_l_drul_[RIGHT] = scol (i+1);
- hint = l->get_elt_property (extra_space_scm_sym);
-
- if (hint == SCM_BOOL_F)
- {
- programming_error ("No postbreak breakable spacing hint set.");
- s.distance_f_= unbroken_dist;
- }
- else
- s.distance_f_ = gh_scm2double (SCM_CDDR(hint));
-
- /*
- space around barlines should not stretch very much.
- */
+ hint = SCM_CDDR (hint);
+
+ s.distance_f_ = gh_scm2double (hint);
+ if (!lc->musical_b ())
s.strength_f_ = 2.0;
- meas_springs.push (s);
}
-
- if (r)
+ else if (!lc->musical_b() && i+1 < col_count())
{
- Spring s;
- s.item_l_drul_[LEFT] = scol (i);
- s.item_l_drul_[RIGHT] = r;
- s.distance_f_ = unbroken_dist;
-
- /*
- space around barlines should not stretch very much.
- */
+ s.distance_f_ = default_bar_spacing (lc,rc,shortest);
s.strength_f_ = 2.0;
- meas_springs.push (s);
}
-
- if (l&&r)
+ else if (lc->musical_b())
{
- Spring s;
- s.item_l_drul_[LEFT] = l;
- s.item_l_drul_[RIGHT] = r;
+ s.distance_f_ = note_spacing (lc, rc, shortest);
- hint = l->get_elt_property (extra_space_scm_sym);
- if (hint == SCM_BOOL_F)
- {
- programming_error ("No postbreak breakable spacing hint set.");
- s.distance_f_= unbroken_dist;
- }
- else
- s.distance_f_ = gh_scm2double (SCM_CDDR(hint));
-
- /*
- space around barlines should not stretch very much.
- */
- s.strength_f_ = 2.0;
- meas_springs.push (s);
- }
- }
- else if (!scol (i)->musical_b() && i+1 < col_count())
- {
- Real symbol_distance = scol (i)->extent (X_AXIS)[RIGHT] ;
- Real durational_distance = 0;
- Moment delta_t = scol (i+1)->when_mom () - scol (i)->when_mom () ;
- /*
- ugh should use shortest_playing distance
- */
- if (delta_t)
- {
- Real k= paper_l()->arithmetic_constant (shortest);
- durational_distance = paper_l()->length_mom_to_dist (delta_t,k);
}
- symbol_distance += -scol (i+1)->extent(X_AXIS)[LEFT];
-
- Spring s ;
- s.item_l_drul_[LEFT] = scol (i);
- s.item_l_drul_[RIGHT] = scol (i+1);
- s.distance_f_ = symbol_distance >? durational_distance;
- meas_springs.push (s);
-
- Item *l = s.item_l_drul_[LEFT]->find_prebroken_piece (RIGHT);
- Item *r = s.item_l_drul_[RIGHT]->find_prebroken_piece (LEFT);
- Spring sp_orig (s);
- if (l)
+ if (next_hint != SCM_BOOL_F)
{
- s = sp_orig;
- s.item_l_drul_[LEFT] =l ;
- meas_springs.push (s);
+ next_hint = SCM_CADR(next_hint);
+ s.distance_f_ += gh_scm2double (next_hint);
}
-
- if (l && r)
+ else
{
- s = sp_orig;
- s.item_l_drul_[RIGHT] = r;
- s.item_l_drul_[LEFT] = l;
- meas_springs.push (s);
+ Interval ext (rc->extent (X_AXIS));
+ Real correction = ext.empty_b() ? 0.0 : - ext [LEFT];
+
+ /*
+ don't want to create too much extra space for accidentals
+ */
+ if (lc->musical_b () && rc->musical_b ())
+ correction /= 2.0;
+
+ s.distance_f_ += correction;
}
+ meas_springs.push (s);
}
}
- for (int i=col1; i < col2; i++)
+ return meas_springs;
+}
+
+/**
+ Do something if breakable column has no spacing hints set.
+ */
+Real
+Spacing_spanner::default_bar_spacing (Score_column *lc, Score_column *rc, Moment shortest) const
+{
+ Real symbol_distance = lc->extent (X_AXIS)[RIGHT] ;
+ Real durational_distance = 0;
+ Moment delta_t = rc->when_mom () - lc->when_mom () ;
+
+ /*
+ ugh should use shortest_playing distance
+ */
+ if (delta_t)
{
- if (scol (i)->musical_b())
- {
- Moment shortest_playing_len = scol(i)->shortest_playing_mom_;
- if (! shortest_playing_len)
- {
- warning (_f ("can't find a ruling note at %s",
- scol (i)->when_mom ().str ()));
- shortest_playing_len = 1;
- }
- if (! shortest)
- {
- warning (_f ("no minimum in measure at %s",
- scol (i)->when_mom ().str ()));
- shortest = 1;
- }
- Moment delta_t = scol (i+1)->when_mom () - scol (i)->when_mom ();
- Real k= paper_l()->arithmetic_constant(shortest);
- Real dist = paper_l()->length_mom_to_dist (shortest_playing_len, k);
- dist *= (double)(delta_t / shortest_playing_len);
+ Real k= paper_l()->arithmetic_constant (shortest);
+ durational_distance = paper_l()->length_mom_to_dist (delta_t,k);
+ }
+ return symbol_distance >? durational_distance;
+}
- Spring sp;
- sp.distance_f_ = dist;
- sp.item_l_drul_[LEFT] = scol (i);
- sp.item_l_drul_[RIGHT] = scol (i+1);
- meas_springs.push (sp);
+Real
+Spacing_spanner::note_spacing (Score_column *lc, Score_column *rc, Moment shortest) const
+{
+ Moment shortest_playing_len = lc->shortest_playing_mom_;
+ if (! shortest_playing_len)
+ {
+ warning (_f ("can't find a ruling note at %s",
+ lc->when_mom ().str ()));
+ shortest_playing_len = 1;
+ }
+ if (! shortest)
+ {
+ warning (_f ("no minimum in measure at %s",
+ lc->when_mom ().str ()));
+ shortest = 1;
+ }
+ Moment delta_t = rc->when_mom () - lc->when_mom ();
+ Real k= paper_l()->arithmetic_constant(shortest);
+ Real dist = paper_l()->length_mom_to_dist (shortest_playing_len, k);
+ dist *= (double)(delta_t / shortest_playing_len);
- /*
- UGH. TODO: more
- advanced spacing here.
- */
- Spring sp_orig (sp);
+ dist += stem_dir_correction (lc,rc);
+ return dist;
+}
- Item *r = sp.item_l_drul_[RIGHT]->find_prebroken_piece (LEFT);
-
- if (r)
- {
- sp = sp_orig;
- sp.item_l_drul_[RIGHT] =r ;
- meas_springs.push (sp);
- }
- }
+
+/**
+ Correct for optical illusions. See [Wanske] p. 138. The combination
+ up-stem + down-stem should get extra space, the combination
+ down-stem + up-stem less.
+
+ This should be more advanced, since relative heights of the note
+ heads also influence required correction.
+
+ Also might not work correctly ico. multi voices or staff changing voices
+
+ TODO: lookup correction distances? More advanced correction?
+ Possibly turn this off?
+
+ This routine reads the DIR_LIST property of both its L and R arguments.
+*/
+Real
+Spacing_spanner::stem_dir_correction (Score_column*l, Score_column*r) const
+{
+ SCM dl = l->get_elt_property (dir_list_scm_sym);
+ SCM dr = r->get_elt_property (dir_list_scm_sym);
+ if (dl == SCM_BOOL_F || dr == SCM_BOOL_F)
+ return 0.0;
+
+ dl = SCM_CDR (dl);
+ dr = SCM_CDR (dr);
+
+ if (scm_ilength (dl) != 1 && scm_ilength (dr) != 1)
+ return 0.;
+
+ dl = SCM_CAR(dl);
+ dr = SCM_CAR(dr);
+
+ assert (gh_number_p (dl) && gh_number_p(dr));
+ int d1 = gh_scm2int (dl);
+ int d2 = gh_scm2int (dr);
+
+ if (d1 == d2)
+ return 0.0;
+
+ bool err = false;
+ Real correction = 0.0;
+ Real ssc = paper_l ()->get_realvar(ly_symbol ("stemSpacingCorrection"));
+
+
+ if (d1 && d2)
+ {
+ if (d1 == 1 && d2 == -1)
+ correction = ssc;
+ else if (d1 == -1 && d2 == 1)
+ correction = -ssc;
+ else
+ err = true;
}
- return meas_springs;
+
+ else
+ err = true;
+
+ if (err)
+ programming_error ("Stem directions not set correctly for optical correction");
+ return correction;
}
+
Array<Spring>
Spacing_spanner::get_springs () const
for (int i=1; i < col_count (); i++)
{
if (scol (i)->breakable_b ())
- {
- springs.concat (do_measure (last_break, i));
- last_break = i;
- }
+ {
+ springs.concat (do_measure (last_break, i));
+ last_break = i;
+ }
}
return springs;
}
+
+
Interval
Span_bar::do_width () const
{
- Molecule m = lookup_l ()->bar (type_str_, 40 PT);
+ Molecule m = lookup_l ()->bar (type_str_, 40 PT, paper_l ());
return m.extent (X_AXIS);
}
Molecule*output = new Molecule;
if (!iv.empty_b())
{
- output->add_molecule (lookup_l ()->bar (type_str_, iv.length ()));
+ output->add_molecule (lookup_l ()->bar (type_str_, iv.length (), paper_l ()));
output->translate_axis (iv.center (), Y_AXIS);
}
else
if (cols_[idx].pcol_l_ != cr.other_l_)
continue;
-
- connect (idx, this_rank, cr.distance_f_,
- cr.strength_f_ / cr.distance_f_);
+ Real d = cr.distance_f_;
+ if (fabs (d) < EPS)
+ {
+ connect (idx, this_rank, 0.0, 10); // large strength.
+ programming_error ("requesting zero distance.");
+ }
+ else
+ connect (idx, this_rank, cr.distance_f_,
+ cr.strength_f_ / cr.distance_f_);
}
cols_.push (c);
set_elt_property (transparent_scm_sym, SCM_BOOL_T);
}
set_empty (invisible_b ());
+ set_spacing_hints ();
+}
+
+
+
+/**
+ set stem directions for hinting the optical spacing correction.
+
+ Modifies DIR_LIST property of the Stem's Score_column
+
+ TODO: more advanced: supply height of noteheads as well, for more advanced spacing possibilities
+ */
+void
+Stem::set_spacing_hints ()
+{
+ if (!invisible_b ())
+ {
+ SCM scmdir = gh_int2scm (dir_);
+ SCM dirlist = column_l ()->get_elt_property (dir_list_scm_sym);
+ if (dirlist == SCM_BOOL_F)
+ dirlist = SCM_EOL;
+ else
+ dirlist = SCM_CDR (dirlist);
+
+ if (scm_sloppy_memq (scmdir, dirlist) == SCM_EOL)
+ {
+ dirlist = gh_cons (scmdir, dirlist);
+ column_l ()->set_elt_property (dir_list_scm_sym, dirlist);
+ }
+ }
}
if (!invisible_b ())
{
- Molecule ss =lookup_l ()->stem (stem_y[DOWN]*dy,
- stem_y[UP]*dy);
+ Real stem_width = paper_l ()->get_var ("stemthickness");
+ Molecule ss =lookup_l ()->filledbox (Box (Interval (-stem_width/2, stem_width/2),
+ Interval (stem_y[DOWN]*dy, stem_y[UP]*dy)));
mol_p->add_molecule (ss);
}
if (time_sig_type_str_[0]=='1')
{
Array<int> tmparr = args_;
- return new Molecule( lookup_l ()->time_signature (args_[0], 0));
+ return new Molecule( lookup_l ()->time_signature (args_[0], 0, paper_l ()));
}
else
{
- return new Molecule( lookup_l ()-> special_time_signature (time_sig_type_str_ ,args_[0], args_[1]));
+ return new Molecule( lookup_l ()-> special_time_signature (time_sig_type_str_ ,args_[0], args_[1], paper_l ()));
}
}
else
- return new Molecule(lookup_l ()->time_signature (args_[0], args_[1]));
+ return new Molecule(lookup_l ()->time_signature (args_[0], args_[1],paper_l ()));
}
#include "tuplet-spanner.hh"
#include "stem.hh"
#include "note-column.hh"
+#include "dimensions.hh"
+
Tuplet_spanner::Tuplet_spanner ()
{
Real ncw = column_arr_.top ()->extent (X_AXIS).length ();
Real w = extent (X_AXIS).length () + ncw;
Molecule num (lookup_l ()->text ("italic",
- number_str_));
+ number_str_, paper_l ()));
num.align_to (X_AXIS, CENTER);
num.translate_axis (w/2, X_AXIS);
Real interline = paper_l ()->get_realvar (interline_scm_sym);
num.translate_axis (dir_ * interline, Y_AXIS);
num.translate_axis (dy/2, Y_AXIS);
-
- /* if (beam_l_arr_.size () == 1 && !bracket_visibility)
- {
- num.translate_axis (dir_ * interline, Y_AXIS);
- }
- */
+ Real thick = paper_l ()->get_realvar (tuplet_thick_scm_sym);
if (bracket_visibility)
{
- mol_p->add_molecule (lookup_l ()->plet (dy, w, dir_));
+ mol_p->add_molecule (lookup_l ()->tuplet_bracket (dy, w, thick, interline, dir_));
}
if (number_visibility)
if (!column_arr_.size ())
return mol_p;
-
- Real internote_f = paper_l ()->get_realvar (interline_scm_sym)/2.0;
+ Real interline_f = paper_l ()->get_realvar (interline_scm_sym);
+ Real internote_f = interline_f/2;
+ Real t = paper_l ()->get_realvar (volta_thick_scm_sym);
Real dx = internote_f;
Real w = extent (X_AXIS).length () - dx;
- Molecule volta (lookup_l ()->volta (w, last_b_));
+ Molecule volta (lookup_l ()->volta (w, t, interline_f, last_b_));
Real h = volta.dim_.y ().length ();
-
- Molecule num (lookup_l ()->text ("volta", number_str_));
+ Molecule num (lookup_l ()->text ("volta", number_str_, paper_l ()));
Real dy = column_arr_.top ()->extent (Y_AXIS) [UP] >
column_arr_[0]->extent (Y_AXIS) [UP];
dy += 2 * h;
dy = dy >? note_column_arr_[i]->extent (Y_AXIS)[BIGGER];
dy -= h;
- Molecule two (lookup_l ()->text ("number", "2"));
+ Molecule two (lookup_l ()->text ("number", "2", paper_l ()));
Real gap = two.dim_.x ().length () / 2;
Offset off (num.dim_.x ().length () + gap,
h / internote_f - gap);
% Toplevel initialisation file.
-\version "1.0.20";
+\version "1.0.21";
\include "declarations.ly"
% Toplevel initialisation file.
-\version "1.0.20";
+\version "1.0.21";
\include "declarations.ly";
% Toplevel initialisation file.
-\version "1.0.20";
+\version "1.0.21";
\include "declarations.ly"
% Toplevel initialisation file.
-\version "1.0.20";
+\version "1.0.21";
\include "declarations.ly"
% Toplevel initialisation file.
-\version "1.0.20";
+\version "1.0.21";
\include "declarations.ly"
% Toplevel initialisation file.
-\version "1.0.20";
+\version "1.0.21";
\include "declarations.ly"
% Toplevel initialisation file.
-\version "1.0.20";
+\version "1.0.21";
\include "declarations.ly";
% Toplevel initialisation file.
-\version "1.0.20";
+\version "1.0.21";
\include "declarations.ly"
\maininput
}
\paper {
- linewidth=-1.0;
- indent = 0.0;
+ linewidth=-1.0;
+ % indent = 0.0;
}
\midi{ }
}
-\version "1.0.20";
+\version "1.0.21";
paper_sixteen = \paper {
staffheight = 16.0\pt;
% paper20.ly
-\version "1.0.20";
+\version "1.0.21";
paper_twenty = \paper {
staffheight = 20.0\pt;
restcollision_minimum_dist = 3.0;
restcollision_minimum_beamdist = 1.5;
-postBreakPadding = 1.0*\interline;
+% deprecated!
+postBreakPadding = 0.0;
+
+stemSpacingCorrection = 0.5*\interline;
\include "engraver.ly";
+
\property Voice.slurVerticalDirection = \down
}
-shifton = \property Voice.hshift = 1
-shiftoff = \property Voice.hshift = 0
+shifton = \property Voice.horizontalNoteShift = 1
+shiftoff = \property Voice.horizontalNoteShift = 0
onevoice = {
\stemboth \shiftoff
\shifton
}
-onestaff =
- \translator Staff=one
-
-
-staffone = {
- \translator Staff=one
- \property Staff.verticalDirection = \center
- \property Staff.hshift = 0
-}
-
-stafftwo = {
- \translator Staff=two
- \property Staff.verticalDirection = \center
- \property Staff.hshift = 0
-}
-
-staffthree = {
- \translator Staff=three
- \property Staff.verticalDirection = \center
- \property Staff.hshift = 0
-}
-
-stafffour = {
- \translator Staff=four
- \property Staff.verticalDirection = \center
- \property Staff.hshift = 0
-}
% ugh, cluttering global namespace...
copyright = "public domain";
}
-\version "1.0.20";
+\version "1.0.21";
\include "global.ly"
\include "violoncello.ly"
copyright = "public domain";
}
-\version "1.0.20";
+\version "1.0.21";
\include "global.ly"
\include "clarinetti.ly"
}
-\version "1.0.20";
+\version "1.0.21";
\include "clarinetto-1.ly"
\include "clarinetto-2.ly"
}
-\version "1.0.20";
+\version "1.0.21";
clarinetto1 = \notes \relative c {
R1 *2 | d''4-.\ff r r2 | R1 *3 | e4-. r r2 | R1 *3 |
}
-\version "1.0.20";
+\version "1.0.21";
clarinetto2 = \notes \relative c {
R1*2 bes''4-.\ff r r2 | R1*3 | cis4-. r r2 | R1 *3 |
copyright = "public domain";
}
-\version "1.0.20";
+\version "1.0.21";
\include "global.ly"
\include "contrabasso.ly"
copyright = "public domain";
}
-\version "1.0.20";
+\version "1.0.21";
contrabasso = \notes \relative c {
% \translator Staff=violoncello
copyright = "public domain";
}
-\version "1.0.20";
+\version "1.0.21";
\include "global.ly"
\include "corni.ly"
}
-\version "1.0.20";
+\version "1.0.21";
\include "corno-1.ly"
\include "corno-2.ly"
copyright = "public domain";
}
-\version "1.0.20";
+\version "1.0.21";
corno1 = \notes \relative c {
R1 *2 | f''4-.\ff r r2 | R1 *3 | f4-. r r2 | R1 *3 |
copyright = "public domain";
}
-\version "1.0.20";
+\version "1.0.21";
corno2 = \notes \relative c {
R1 *2 | d''4-.\ff r r2 | R1 *3 | d4-. r r2 | R1 *3 |
}
-\version "1.0.20";
+\version "1.0.21";
\include "global.ly"
\include "fagotti.ly"
}
-\version "1.0.20";
+\version "1.0.21";
\include "fagotto-1.ly"
\include "fagotto-2.ly"
}
-\version "1.0.20";
+\version "1.0.21";
fagotto1 = \notes \relative c {
R1 *2 | as'4-.\ff r r2 | R1 *3 | as4-. r r2 | R1 *3 |
copyright = "public domain";
}
-\version "1.0.20";
+\version "1.0.21";
fagotto2 = \notes \relative c {
R1 *2 | f4-.\ff r r2 | R1 *3 | f4-. r r2 | R1 *3 |
}
-\version "1.0.20";
+\version "1.0.21";
\include "global.ly"
\include "flauti.ly"
}
-\version "1.0.20";
+\version "1.0.21";
\include "flauto-1.ly"
\include "flauto-2.ly"
copyright = "public domain";
}
-\version "1.0.20";
+\version "1.0.21";
flauto1 = \notes \relative c {
R1 *2 | c'''4-.\ff r r2 | R1 *3 | d4-. r r2 | R1 *3 |
copyright = "public domain";
}
-\version "1.0.20";
+\version "1.0.21";
flauto2 = \notes \relative c {
R1 *2 | as'''4-.\ff r r2 | R1 *3 | b4-. r r2 | R1 *3 |
}
-\version "1.0.20";
+\version "1.0.21";
global = \notes {
\time 4/4;
copyright = "public domain";
}
-\version "1.0.20";
+\version "1.0.21";
oboe1 = \notes \relative c'' {
R1 *2 | as'4-.\ff r r2 | R1 *3 | as4-. r r2 | R1 *3 |
}
-\version "1.0.20";
+\version "1.0.21";
oboe2 = \notes \relative c{
R1 *2| f''4-.\ff r r2 | R1 *3 | f4-. r r2 | R1 *3 |
}
-\version "1.0.20";
+\version "1.0.21";
\include "global.ly"
\include "oboi.ly"
}
-\version "1.0.20";
+\version "1.0.21";
\include "oboe-1.ly"
\include "oboe-2.ly"
}
-\version "1.0.20";
+\version "1.0.21";
timpani = \notes \relative c {
R1 *2 | c4-.\ff r r2 | R1 *3 | c4-. r r2 | R1 *3 |
}
-\version "1.0.20";
+\version "1.0.21";
\include "global.ly"
\include "trombe.ly"
}
-\version "1.0.20";
+\version "1.0.21";
\include "trombo-1.ly"
\include "trombo-2.ly"
copyright = "public domain";
}
-\version "1.0.20";
+\version "1.0.21";
trombo1 = \notes \relative c {
R1 *2 | c''4-.\ff r r2 | R1 *3 | c4-. r r2 | R1 *3 |
copyright = "public domain";
}
-\version "1.0.20";
+\version "1.0.21";
trombo2 = \notes \relative c {
R1 *2 | c'4-.\ff r r2 | R1 *3 | c4-. r r2 | R1 *3 |
copyright = "public domain";
}
-\version "1.0.20";
+\version "1.0.21";
viola1 = \notes \relative c {
\context Voice=one
copyright = "public domain";
}
-\version "1.0.20";
+\version "1.0.21";
viola2 = \notes \relative c {
% starts on (actualy, most part is on) same staff as viola1
copyright = "public domain";
}
-\version "1.0.20";
+\version "1.0.21";
\include "global.ly"
\include "viola-1.ly"
copyright = "public domain";
}
-\version "1.0.20";
+\version "1.0.21";
\include "global.ly"
\include "violino-1.ly"
copyright = "public domain";
}
-\version "1.0.20";
+\version "1.0.21";
violino1 = \notes \relative c {
c'1\ff ~ | c | <f4-. c'-. as'-.> r r2 | R1 |
copyright = "public domain";
}
-\version "1.0.20";
+\version "1.0.21";
\include "global.ly"
\include "violino-2.ly"
copyright = "public domain";
}
-\version "1.0.20";
+\version "1.0.21";
violino2 = \notes \relative c {
c'1\ff ~ | c | <f4-. c'-. as'-.> r r2 | R1 |
copyright = "public domain";
}
-\version "1.0.20";
+\version "1.0.21";
\include "global.ly"
\include "violoncello.ly"
}
-\version "1.0.20";
+\version "1.0.21";
violoncello = \notes \relative c {
c1\ff ~ | c | f,4-. r r2 | r1 | c'1\ff ~ | c | f,4-. r r2 |
----------------------------------------------------
-\version "1.0.20";
+\version "1.0.21";
\paper{barsize=50.0; \translator {\StaffContext \consists
Bar_number_engraver;}}
}
-\version "1.0.20";
+\version "1.0.21";
Bar_number_engraver;}}
}
-\version "1.0.20";
+\version "1.0.21";
}
-\version "1.0.20";
+\version "1.0.21";
\paper{barsize=50.0; \translator {\StaffContext \consists
Bar_number_engraver;}}
}
-\version "1.0.20";
+\version "1.0.21";
under the Gnu Public Licence.
%}
-\version "1.0.20";
+\version "1.0.21";
$voice_one = \notes \relative c' {
a'2 bes4. [c16 bes] | a4 d ~ d c ~ | c b ~ [b8 a] a4 ~|
Tested Features: cross staff beams and slurs, grace notes, no bars
%}
-\version "1.0.20";
+\version "1.0.21";
\include "nederlands.ly"
Tested Features:
%}
-\version "1.0.20";
+\version "1.0.21";
\include "nederlands.ly"
copyright = "public domain";
}
-\version "1.0.20";
+\version "1.0.21";
\include "standchen.ly"
description = "A schubert song in 20 pt";
}
-\version "1.0.20";
+\version "1.0.21";
% fool make-website
% \include "standchen.ly";
include $(depth)/make/stepmake.make
-EXTRA_DIST_FILES += TODO
+EXTRA_DIST_FILES +=
title = "Diademata";
metre = "6 6. 8 6. D";
}
-\version "1.0.20";
+\version "1.0.21";
sop=\notes \transpose c''{
ees2 | ees4 ees4 g2 g2 | c'1. \bar "||";
metre = "10 10 . 11 11";
}
-\version "1.0.20";
+\version "1.0.21";
sop = \notes \transpose c''{
f4 | d' bes c' | f2 \bar "||";
metre = "10 11. 11 11. and refrain";
}
-\version "1.0.20";
+\version "1.0.21";
sop=\notes \relative c'' {
b2 gis4. a8 |b2 e,2 |
metre = "8 7 8 7 D";
}
-\version "1.0.20";
+\version "1.0.21";
sop=\notes \relative c'' {
b4 b c d | d c b a | g g a b | b4. a8 a2 \bar "||";
}
-\version "1.0.20";
+\version "1.0.21";
global=\notes {
\time 6/4;
piece = "Allemande";
}
-\version "1.0.20";
+\version "1.0.21";
global = \notes{
\time 4/4;
%%
%% Noe liknende skjer også i mellom andre og tredje stemme i takt 28
-\version "1.0.20";
+\version "1.0.21";
global = \notes{
\time 2/4;
% ???
% What have i misunderstood? I want the note_head not to collide with
% i hotehead i vOne
- \property Voice.hshift = -1
+ \property Voice.horizontalNoteShift = -1
d
- \property Voice.hshift = 0
+ \property Voice.horizontalNoteShift = 0
c4 b8 |
}
vThree = \context Voice = voiceThree \notes\relative c{
copyright = "Public Domain";
}
-\version "1.0.20";
+\version "1.0.21";
global = \notes {
\time 4/4;
bes4 r16 [bes,16 bes. c32] [des8. des16]
\context Staff <
{ \stemup e4 }
- { \stemup \property Voice.hshift = 1 [des16 c32 bes c16. g32] }
+ { \stemup \property Voice.horizontalNoteShift = 1 [des16 c32 bes c16. g32] }
>
%4
f4 \stemboth r16 [f g. as32] \stemup d,4 r16 [d g. es32] |
<[es8. c> <es16 c>]
\context Staff <
{ \stemup fis4 }
- { \stemup \property Voice.hshift = 1 [es16 d32 c d16. a32] }
+ { \stemup \property Voice.horizontalNoteShift = 1 [es16 d32 c d16. a32] }
> g2
}
c4 r c r | r c c r | c r r c | c r r16 [c c. bes32] bes4 |
r16 [bes bes. as32] as4_"tr" g r16 [d' d. es32] |
\context Staff <
- { \stemdown \property Voice.hshift = 1 [f8. f16] [b,8. b16] g4 r | }
+ { \stemdown \property Voice.horizontalNoteShift = 1 [f8. f16] [b,8. b16] g4 r | }
{ \stemdown s4 g}
>
r g g2
dotted slurs
%}
-\version "1.0.16";
+\version "1.0.21";
\include "allemande-urtext.ly";
\time 4/4;
\key f;
\clef bass;
- \repeat 2 {
+ \repeat "semi" 2 {
\partial 16;
s16
s1*11 |
s2 s4 s8
\partial 16*15;
s16
- } \repeat 2 {
+ } \repeat "semi" 2 {
% urg
s32 \partial 16; s32
s1*11
\paper{
\include "scs-paper.ly";
gourlay_maxmeasures = 3.0;
+
}
\midi{ \tempo 4 = 45; }
\header{ piece = "Allemande"; }
d = { \slurdotted }
comma = "\\sethuge\\ \\ ,"
+phrasingcomma = { } % { \bar "empty"; \mark "'"; \nobreak }
+
allemande_a = \context Staff \notes \relative c {
\context Voice=i
\stemup
\n a()f' g,()f e g'( a )bes |
% :-(
% bes( a g )f^\comma
- bes( a g )f^"\\sethuge{\\ \\ '}"
+ bes( a g )f \phrasingcomma
a()e f()d bes d(f)a d()a bes()g |
%21
a,(\n)g'(\n cis())d e()g, a()e f()d bes()d \d gis, f'(e)d |
% \n d( cis b )a^\comma c(a)fis d' c a( b )d
- \n d( cis b )a^"\\sethuge\\ \\ ,"
+ \n d( cis b )a \phrasingcomma %^"\\sethuge\\ \\ ,"
c(a)fis d' c a( b )d
f!(d )gis, d' |
%23
>
-\version "1.0.20";
+\version "1.0.21";
\$courante_b
>
-\version "1.0.20";
+\version "1.0.21";
\$gigue_b
>
-\version "1.0.20";
+\version "1.0.21";
dotted slurs
%}
-\version "1.0.16";
+\version "1.0.21";
\include "menuetto-urtext.ly";
\time 3/4;
\key f;
\clef bass;
- \repeat 2 {
+ \repeat "semi" 2 {
\skip 2.*8;
- } \repeat 2 {
+ }
+ \repeat "semi" 2 {
\skip 2.*1;
\slurdotted
\skip 2.*14;
\time 3/4;
\key D;
\clef bass;
- \repeat 2 {
+ \repeat "semi" 2 {
\skip 2.*8;
- } \repeat 2 {
+ }
+ \repeat "semi" 2 {
\skip 2.*1;
\slurdotted
\skip 2.*14;
\paper{
\include "scs-paper.ly";
gourlay_maxmeasures = 7.0;
+
\translator{
\VoiceContext
beamAutoEnd_8 = "3/4";
<a2\f e'> d8( e16 )f |
\slurdotted
e8( d cis )e a,()g |
- a4 ~ d cis |
+ a4 () d cis |
g'8( f e )f d() c |
%13
bes2 c4 |
% <bes,4 g' d'> <c, g' c> < d,8 bes'(> )a |
<d'4 g, bes,> <c g c,> bes8()a |
c8( bes a )bes g()bes |
- d4 ~ cis d |
+ d4 () cis d |
g,8 f g e f4 |
g,8 g' <{e4.^\trill d8 } a4.> ~ |
<d2. a d,> |
g8 \skip 8*5; |
f2 e4
d8 \skip 8*5; |
- g4 ~ f e
+ g4 () f e
f8 \skip 8*5; |
\skip 2.*3; |
es8 \skip 8*3; d4 |
>
menuetto_i = \context Staff \notes<
- { \$menuetto_i_a_voice_urg_urg }
- { \$menuetto_i_b_voice_urg_urg }
+ \repeat "semi" 2 { \$menuetto_i_a_voice_urg_urg }
+ \repeat "semi" 2 { \$menuetto_i_b_voice_urg_urg }
>
menuetto_ii = \context Staff\notes \relative c {
d2.
}
-\version "1.0.20";
+\version "1.0.21";
dotted slurs
%}
-\version "1.0.20";
+\version "1.0.21";
\include "prelude-urtext.ly";
\$prelude_b
>
-\version "1.0.20";
+\version "1.0.21";
dotted slurs
%}
-\version "1.0.20";
+\version "1.0.21";
\include "prelude-urtext.ly";
\$sarabande_b
>
-\version "1.0.20";
+\version "1.0.21";
\clef alto;
\$global_i
>
-\version "1.0.20";
+\version "1.0.21";
}
}
-\version "1.0.20";
+\version "1.0.21";
}
}
-\version "1.0.20";
+\version "1.0.21";
\clef bass;
\$global_i
>
-\version "1.0.20";
+\version "1.0.21";
%{
%}
-\version "1.0.20";
+\version "1.0.21";
global =
* auto beaming
%}
-\version "1.0.20";
+\version "1.0.21";
\include "nederlands.ly" % for correct parsing of note names
copyright = "Public Domain";
}
-\version "1.0.20";
+\version "1.0.21";
global =
\notes {
-\version "1.0.20";
+\version "1.0.21";
corI=\notes\relative c'' {
\key c;
-\version "1.0.20";
+\version "1.0.21";
viI=\notes\relative c'' {
-\version "1.0.20";
+\version "1.0.21";
oboe=\notes\relative c'' {
\clef "treble";
Ugh.. Wish we had grace notes.... It adds another dimension to this
piece of music. %}
-\version "1.0.20";
+\version "1.0.21";
cad = \notes \relative c' {
}
-\version "1.0.20";
+\version "1.0.21";
allegro =
\notes
definition below. --MB
%}
-\version "1.0.18";
+\version "1.0.21";
global = \notes {
\property StaffGroup.timeSignatureStyle = "old"
#
program_name = 'abc-to-ly'
-version = '0.1'
+version = '@TOPLEVEL_VERSION@'
import __main__
import getopt
import sys
default_len = 4
global_key = [0] * 7 # UGH
DIGITS='0123456789'
+HSPACE=' \t'
def gcd (a, b):
while a % b:
return key_table
+tup_lookup = {
+ '3' : '2/3',
+ '4' : '4/3',
+ '6' : '4/6',
+ }
+
+
+def try_parse_tuplet_begin (str, state):
+ if str and str[0] in DIGITS:
+ dig = str[0]
+ str = str[1:]
+ state.parsing_tuplet = 1
+
+ print '\\times %s {' % tup_lookup[dig]
+ return str
+
+def try_parse_group_end (str, state):
+ if str and str[0] in HSPACE:
+ str = str[1:]
+ if state.parsing_tuplet:
+ state.parsing_tuplet = 0
+ print '}'
+ return str
+
def try_parse_header_line (ln):
m = re.match ('^(.): *(.*)$', ln)
if g == 'T':
header['title'] = a
if g == 'M':
+ if a == 'C':
+ a = '4/4'
global_voice_stuff.append ('\\time %s;' % a)
if g == 'K':
__main__.global_key =compute_key (a)# ugh.
def parse_num (str):
durstr = ''
- while str[0] in DIGITS:
+ while str and str[0] in DIGITS:
durstr = durstr + str[0]
str = str[1:]
def __init__ (self):
self.next_dots = 0
self.next_den = 1
+ self.parsing_tuplet = 0
# WAT IS ABC EEN ONTZETTENDE PROGRAMMEERPOEP !
mud = ''
slur_begin =0
- if str[0] == '(':
+ if not str:
+ return str
+
+ if str[0] == '(':
slur_begin = 1
str = str[1:]
return str
+
+def try_parse_guitar_chord (str):
+ if str and str[0] == '"':
+ str = str[1:]
+ gc = ''
+ while str and str[0] != '"':
+ gc = gc + str[0]
+ str = str[1:]
+
+ if str:
+ str = str[1:]
+
+ print "guitar chord: %s\n" % gc
+
+ return str
+
def try_parse_escape (str):
- if str [0] != '\\':
+ if not str or str [0] != '\\':
return str
str = str[1:]
- if str[0] == 'K':
- compute_key ()
+ if str and str[0] == 'K':
+ key_table = compute_key ()
return str
def try_parse_bar (str):
- if str[0] == '|':
+ if str and str[0] == '|':
+ bs = ''
str = str[1:]
+ if str:
+ if str[0] == ']':
+ bs = '|.'
+ if str[0] == '|':
+ bs = '||'
+
+ if bs:
+ print '\\bar "%s";' % bs
return str
+def try_parse_chord_delims (str):
+ if str and str[0] == '[':
+ str = str[1:]
+ print '<'
+
+ if str and str[0] == ']':
+ str = str[1:]
+ print '>'
+
+ return str
+# Try nibbling characters off until the line doesn't change.
def try_parse_body_line (ln, state):
prev_ln = ''
- while ln and ln != prev_ln:
+ while ln != prev_ln:
prev_ln = ln
+ ln = try_parse_chord_delims (ln)
ln = try_parse_note (ln, state)
ln = try_parse_bar (ln)
- ln = junk_space (ln)
ln = try_parse_escape (ln)
+ ln = try_parse_guitar_chord (ln)
+ ln = try_parse_tuplet_begin (ln, state)
+ ln = try_parse_group_end (ln, state)
+ ln = junk_space (ln)
+
if ln:
- print 'Huh %s' % ln
+ print 'Huh? Don\'t understand `%s\'' % ln
def identify():
- print '%s %s' % (program_name, version)
+ print '%s from LilyPond %s' % (program_name, version)
def help ():
print r"""
This is a disfunctional ABC to mudela convertor. It only gulps input, and
-says huh when confused. Does not do chords. Go ahead and fix me.
+says huh when confused. Go ahead and fix me.
+
+Usage: abc-2-ly INPUTFILE
-h, --help this help.
"""