+2002-08-02 Han-Wen <hanwen@cs.uu.nl>
+
+ * scripts/lilypond-book.py: make URL for printfilename option.
+
+ * lily/beam.cc (position_with_maximal_common_beams): fix kneed
+ beamlets. This fixes input/bugs/knee
+
+ * ly/engraver-init.ly (HaraKiriStaffContext): switch off auto knee
+ for hara kiri staffs.
+
+ * lily/slur-engraver.cc (try_music): remove nested slur
+ functionality. This fixes spurious warnings with the partcombiner.
+
2002-08-01 Han-Wen Nienhuys <hanwen@cs.uu.nl>
* lily/parse-scm.cc (protected_ly_parse_scm): guile 1.4 compatibility.
editor to enter it, you can put it in mail or embed it in an article like
this:
@quotation
-@lilypond[fragment,verbatim, relative 1]
+@lilypond[fragment,verbatim,relative 1]
\key c \minor r8 c16 b c8 g as c16 b c8 d | g,4
@end lilypond
@end quotation
-
-test1
-
-
LilyPond development is hosted at http://savannah.gnu.org/projects/lilypond
-Here is an attempt at a simple explanation of the directory layout for
-LilyPond's source files.
+Here is a simple explanation of the directory layout for LilyPond's
+source files.
Documentation/
bibliography/ .bib files with references to books and articles
windows/ building on windows
pictures/ .xpms of the logo
- programmer/ programmers documentation, including a test document
- topdocs/ sources for the toplevel files (README.txt, INSTALL.txt, etc.)
+ topdocs/ sources for the toplevel files
+ (README.txt, INSTALL.txt, etc.)
user/ User manuals
buildscripts/ Scripts used during the build process
debian/ Files for building .deb packages
include/
input/ Various input files
test/ Test features: one file per feature
+ mutopia/ Real examples of music.
bugs/ Show bugs
no-notation/ Examples or bugs that do not produce output
regression/ Various features for regression test
lily/ Source code for LilyPond
include/
ly/ Standard include files.
- make/ LilyPond specific Make subroutine files
+ make/ LilyPond specific make subroutine files, spec
+ files.
mf/ MetaFont sources for the feta font
- midi2ly/ midi2ly source code
- include/
- mutopia/ Larger examples with full music pieces.
- E.Satie/
- F.Schubert/
- J.S.Bach/
+ python/ python MIDI module
po/ translations
- ports/ access to mutopia archive
ps/ postscript library files
tex/ TeX library files
scm/ Scheme initialisation and subroutine files
- scripts/ User scripts
+ scripts/ End-user scripts
stepmake/ Generic make subroutine files
def name2line (n):
# UGR
- if string.find (n, '+') >= 0:
- s = "@lilypondfile[printfilename]{%s}" % n
- else:
- s = "@lilypondfile[printfilename,verbatim]{%s}" % n
+ s = "@lilypondfile[printfilename]{%s}" % n
return s
s = s + string.join (map (lambda x: name2line (x), files), "\n")
+++ /dev/null
-\header{
-texidoc = "@section Grace notes"
-foollilypondbook = "
-\score
-"
-}
-
-\score {
- \context Lyrics \lyrics { "." }
-}
+++ /dev/null
-
-%
-% Autoknee-ing triggers hara-kiri too early.
-%
-
-\score { \notes \transpose c'''
- \context PianoStaff <
- \context Staff = up { c4 c c c \break c c c c }
- \context Staff = mid { c4 c c c \break s1 }
- \context Staff = down { c8 \translator Staff=mid c \translator
-Staff=down c c c4 c c c c c }
- >
- \paper {
- \translator {
- \HaraKiriStaffContext
-% Beam \revert #'auto-knee-gap
- }
- }
-}
-
\header {
-texidoc="
-gives
-
-@example
- | |
- | |
- +-- | --+
- +----+----+
- |
- |
-
-instead of the desired
-
- | |
- | |
- | --+
- +----+----+
- +--
- |
- |
-
-@end example
+texidoc=" Funky kneed beams with beamlets also work. The beamlets
+should be pointing to the note head.
"
}
\score {
\notes\relative c' {
+ c16 c''8 c,,16
c16 c''8 c16
+ c16 c,,8 c16
- % it's very helpful to have this one too,
- % because a fix is likely to break
-
- c,, c'' c,, cc
}
\paper { linewidth = -1 }
}
-
\ No newline at end of file
+
+++ /dev/null
-% \mark NUMBER should work.
-\score {
- \notes { c1 \mark 12 c1 }
- \paper { linewidth = -1. }
- }
+++ /dev/null
-
-\header{
- texidoc="This gives two unexpected warnings."
-}
-
-\score {
- \context StaffGroup = group <
- \context Staff = instrument <
- \context Voice=one \partcombine Voice
- \context Thread=one \notes \relative c'' {
- c4 ()d e f \grace f16 g1
- }
- \context Thread=two \notes \relative c' {
- c4 () d e2 g1
- }
- >
- >
-}
+++ /dev/null
-\version "1.5.68"
-\header{
-texidoc=" should start with |:"
-}
-
-\score { \context Staff \notes \repeat volta 3 c1 \alternative { d1 e1 }}
+++ /dev/null
-\version "1.5.68"
-
-\header{
-texidoc="separate staff-size is clumsy with \override.
-Also, it doesn't seem to work anymore."
-}
-
-\score {
- \notes \relative c' < \context Voice {
- \property Staff.staffSpace = #10
- \property Staff.fontSize = #-1
- \property Voice.fontSize = #-1
-
- \property Voice . dynamicDirection = \up \stemDown
-%\key gis \major
- c8 d [e f g a] b c \ff
- }
-
-\context Staff = VB { \property Voice . dynamicDirection = \down c,,4 \ff c c c }
-
->
-\paper { linewidth = -1. }
-}
-
+++ /dev/null
-\version "1.5.68"
-\header{
-
- texidoc= "The 8th notes should have regular spacing. (TODO: check
- with printed ed.) "
-
-
-}
-\score {
-\notes \relative c' <
-\context Staff = SA { c4. c8 \times 2/3 { [c8 c c] } }
-\context Staff = SB { [c8 c c c c c] }
->
-
-\paper { linewidth = -1. }
-}
+++ /dev/null
-\version "1.5.68"
-\header{
-texidoc="Ugly slur"
-}
-
-
-\score{
- \notes\relative c''{
- a'( a a [a8...] b,32\break
- c4 \clef bass c,,, c )c
- }
- \paper{
- indent=0.0\mm
- linewidth=40.0\mm
- }
-}
-
-\version "1.5.68"
+
+\header { texidoc = "Setting staff sizes is a little clumsy. There
+are two options: using StaffContainer and override/revert, or
+\outputproperty. Both methods are shown in this example."
+}
+
+\version "1.5.70"
\score {
\notes \relative c' < \context StaffContainer = SA{
\property StaffContainer.StaffSymbol \set #'staff-space = #(/ 16 20)
c8 d [e f g a] b c \ff
}
-\context StaffContainer = SB { \dynamicDown c,,4 \ff c c c }
-
+\context Staff = SB { \dynamicDown c,,4 \ff c c c }
+\context Staff = SC {
+ \context Staff \outputproperty #(make-type-checker 'staff-symbol-interface)
+ #'staff-space = #0.8
+ \property Staff.fontSize = #-1
+ \clef bass
+ c8 c c c c c c c
+}
>
\paper { linewidth = -1. }
}
}
+/*
+ We want a maximal number of shared beams, but if there is choice, we
+ take the one that is closest to the end of the stem. This is for situations like
+
+ x
+ |
+ |
+ |===|
+ |=
+ |
+ x
+
+
+ */
+int
+position_with_maximal_common_beams (SCM left_beaming, SCM right_beaming,
+ Direction left_dir,
+ Direction right_dir)
+{
+ Slice lslice = int_list_to_slice (gh_cdr (left_beaming));
+
+ int best_count = 0;
+ int best_start = 0;
+ for (int i = lslice[-left_dir];
+ (i - lslice[left_dir])* left_dir <= 0 ; i+= left_dir)
+ {
+ int count =0;
+ for ( SCM s = gh_car (right_beaming); gh_pair_p (s); s = gh_cdr (s))
+ {
+ int k = - right_dir * gh_scm2int (gh_car (s)) + i;
+ if (scm_memq (gh_int2scm (k), left_beaming) != SCM_BOOL_F)
+ count ++;
+ }
+
+ if (count >= best_count)
+ {
+ best_count = count;
+ best_start = i;
+ }
+ }
+
+ return best_start;
+}
void
Beam::connect_beams (Grob *me)
Slice last_int;
last_int.set_empty();
+ SCM last_beaming = SCM_EOL;
+ Direction last_dir = CENTER;
for (int i = 0; i< stems.size(); i++)
{
Grob *this_stem = stems[i];
Direction this_dir = Directional_element_interface::get(this_stem);
if (i > 0)
{
- int start_point = last_int [this_dir];
+ int start_point = position_with_maximal_common_beams
+ (last_beaming, this_beaming,
+ last_dir, this_dir);
Direction d = LEFT;
Slice new_slice ;
new_slice.add_point (new_beam_pos);
gh_set_car_x (s, gh_int2scm (new_beam_pos));
}
+
+
}
while (flip (&d) != LEFT);
gh_set_car_x (s, gh_int2scm (np));
last_int.add_point (np);
}
+
}
if (i == stems.size () -1)
{
gh_set_cdr_x ( this_beaming, SCM_EOL);
}
+ last_beaming = this_beaming;
+ last_dir = this_dir;
}
}
return SCM_UNSPECIFIED;
}
+/*
+ Report slice containing the numbers that are both in (car BEAMING)
+ and (cdr BEAMING)
+ */
Slice
where_are_the_whole_beams(SCM beaming)
{
#include "engraver.hh"
#include "spanner.hh"
+/*
+ TODO: junk nested slur functionality.
+ */
class Slur_engraver : public Engraver
{
- Link_array<Span_req> requestses_;
+ Link_array<Span_req> requests_;
Link_array<Span_req> new_slur_reqs_;
- Link_array<Grob> slur_l_stack_;
+ Link_array<Grob> slur_stack_;
Link_array<Grob> end_slurs_;
Moment last_start_;
String t = ly_scm2string (sl->get_mus_property ("span-type"));
if (t == "abort")
{
- for (int i = 0; i < slur_l_stack_.size (); i++)
+ for (int i = 0; i < slur_stack_.size (); i++)
{
- slur_l_stack_[i]->suicide ();
+ slur_stack_[i]->suicide ();
}
- slur_l_stack_.clear ();
+ slur_stack_.clear ();
for (int i = 0; i < end_slurs_.size (); i++)
{
end_slurs_[i]->suicide ();
}
end_slurs_.clear ();
- requestses_.clear ();
+ requests_.clear ();
new_slur_reqs_.clear ();
}
else if (t == "slur")
{
new_slur_reqs_.push (sl);
last_start_ = now_mom ();
- return true;
}
+
+ /*
+ But we swallow other slur requests.
+ */
+
+ return true;
+
}
- else
+ else if (sl->get_span_dir () == STOP)
{
+ /*
+ Swallow other requests.
+ */
+ for (int j = new_slur_reqs_.size(); j--;)
+ if (new_slur_reqs_[j]->get_span_dir() == STOP)
+ return true;
+
new_slur_reqs_.push (sl);
return true;
}
if (Note_column::has_interface (info.grob_))
{
Grob *e =info.grob_;
- for (int i = 0; i < slur_l_stack_.size (); i++)
- Slur::add_column (slur_l_stack_[i], e);
+ for (int i = 0; i < slur_stack_.size (); i++)
+ Slur::add_column (slur_stack_[i], e);
for (int i = 0; i < end_slurs_.size (); i++)
Slur::add_column (end_slurs_[i], e);
}
void
Slur_engraver::finalize ()
{
- for (int i = 0; i < slur_l_stack_.size (); i++)
+ for (int i = 0; i < slur_stack_.size (); i++)
{
#if 0
- typeset_grob (slur_l_stack_[i]);
+ typeset_grob (slur_stack_[i]);
#else
/*
Let's not typeset unterminated stuff
*/
- slur_l_stack_[i]->suicide ();
+ slur_stack_[i]->suicide ();
#endif
}
- slur_l_stack_.clear ();
+ slur_stack_.clear ();
- for (int i=0; i < requestses_.size (); i++)
+ for (int i=0; i < requests_.size (); i++)
{
- requestses_[i]->origin ()->warning (_ ("unterminated slur"));
+ requests_[i]->origin ()->warning (_ ("unterminated slur"));
}
}
// end slur: move the slur to other array
if (slur_req->get_span_dir () == STOP)
{
- if (slur_l_stack_.empty ())
+ if (slur_stack_.empty ())
/* How to shut up this warning, when Voice_devnull_engraver has
eaten start request? */
slur_req->origin ()->warning (_f ("can't find start of slur"));
else
{
- Grob* slur = slur_l_stack_.pop ();
+ Grob* slur = slur_stack_.pop ();
end_slurs_.push (slur);
- requestses_.pop ();
+ requests_.pop ();
}
}
else if (slur_req->get_span_dir () == START)
Grob* slur = new Spanner (get_property ("Slur"));
Slur::set_interface (slur); // cannot remove yet!
start_slurs.push (slur);
- requestses_.push (slur_req);
+ requests_.push (slur_req);
announce_grob (slur, slur_req->self_scm ());
}
}
for (int i=0; i < start_slurs.size (); i++)
- slur_l_stack_.push (start_slurs[i]);
+ slur_stack_.push (start_slurs[i]);
new_slur_reqs_.clear ();
}
SCM m = get_property ("automaticMelismata");
if (to_boolean (m))
{
- set_melisma (slur_l_stack_.size ());
+ set_melisma (slur_stack_.size ());
}
}
\consistsend "Hara_kiri_engraver"
\consists "Instrument_name_engraver"
\accepts "Voice"
+
+ % hara kiri & auto knee don't work together.
+ Beam \override #'auto-knee-gap = #'()
}
+
%{
The HaraKiriStaffContexts doesn't override \name,
so it is still named `Staff'.
%s
</lilypond>''',
'output-filename' : r'''
-
-<pre>%s</pre>:''',
+<!-- %s >
+<a href="%s">
+<pre>%s</pre></a>:''',
'output-lilypond-fragment': '''<lilypond%s>
\context Staff\context Voice{ %s }
</lilypond>''',
>
\end{lilypond}''',
'output-filename' : r'''
-
-\verb+%s+:''',
+\verb+%s+:
+%% %s
+%% %s
+''',
'output-lilypond': r'''\begin[%s]{lilypond}
%s
\end{lilypond}
@end lilypond
''',
'output-filename' : r'''
-
-@file{%s}:''',
+@ifnothtml
+@file{%s}:
+@end ifnothtml
+@ifhtml
+@uref{%s,@file{%s}}
+@end ifhtml
+''',
'output-lilypond-fragment': '''@lilypond[%s]
\context Staff\context Voice{ %s }
@end lilypond ''',
for o in opts:
m= re.match ("filename=(.*)", o)
if m:
- newbody = newbody + get_output ("output-filename") % m.group(1)
+ newbody = newbody + get_output ("output-filename") % (m.group(1), basename + '.ly', m.group(1))
break