nesting by initting measurePosition.
* lily/timing-translator.cc (initialize): do no init
measurePosition
* lily/include/music-output-def.hh (class Music_output_def): add
input_origin_ field.
* Documentation/user/changing-defaults.itely (Changing context
properties on the fly): new node.
* lily/include/ly-smobs.icc (free_smob): remove smobbed_self()
function. Only have smobbed_copy (), and do not provide
smobbed_copy() for non-simple smobs. Changes throughout.
+2004-03-18 Han-Wen Nienhuys <hanwen@xs4all.nl>
+
+ * lily/global-context.cc (run_iterator_on_me): fix grace note
+ nesting by initting measurePosition.
+
+ * lily/timing-translator.cc (initialize): do no init
+ measurePosition
+
+ * lily/include/music-output-def.hh (class Music_output_def): add
+ input_origin_ field.
+
+ * Documentation/user/changing-defaults.itely (Changing context
+ properties on the fly): new node.
+
+ * lily/include/ly-smobs.icc (free_smob): remove smobbed_self()
+ function. Only have smobbed_copy (), and do not provide
+ smobbed_copy() for non-simple smobs. Changes throughout.
+
+2004-03-17 Han-Wen Nienhuys <hanwen@xs4all.nl>
+
+ * lily/auto-change-iterator.cc (class Auto_change_iterator): add
+ start_moment_. Fix by Doug A. Linhardt.
+
2004-03-16 Han-Wen Nienhuys <hanwen@xs4all.nl>
+ * lily/accidental-engraver.cc (acknowledge_grob): don't suppress
+ accidentals for harmonic notes.
+
+ * lily/note-collision.cc (check_meshing_chords): don't merge heads
+ fo different style. (Thanks to Doug Linhardt).
+
* Documentation/user/changing-defaults.itely (Scheme tutorial):
new node.
@itemize @bullet
@item Output: changing the appearance of individual
- objects
-@item Context: changing the translation from music events to
- notation
+ objects. For example, changing stem directions, or the location of
+ subscripts.
+
+@item Context: changing aspects of the translation from music events to
+ notation. For example, giving each staff a separate time signature.
+
@item Global layout: changing the appearance of the spacing, line
breaks and page dimensions.
@end itemize
discusses these.
Internally, LilyPond uses Scheme (a LISP dialect) to provide
-infrastructure. Since overriding layout decisions in effect
-accesses the program internals, it is necessary to learn a (very
-small) subset of Scheme. That is why this chapter starts with
-a short tutorial on entering numbers, lists, strings and symbols in
-Scheme.
+infrastructure. Overriding layout decisions in effect accesses the
+program internals, so it is necessary to learn a (very small) subset
+of Scheme. That is why this chapter starts with a short tutorial on
+entering numbers, lists, strings and symbols in Scheme.
@menu
* Scheme tutorial::
-* Setting variables::
+* Context ::
* Fine tuning layout::
* Tuning output::
* Text markup::
@code{twentyFour}.
This syntax will be used very frequently, since many of the layout
-tweaks involve assigning (Scheme) values to variables, for example
+tweaks involve assigning (Scheme) values to internal variables, for
+example
@example
- \override Stem #'thickness = #2.5
+ \override Stem #'thickness = #2.6
@end example
-This instruction adjusts the appearance of stems. The value @code{2.5}
+This instruction adjusts the appearance of stems. The value @code{2.6}
is put into a the @code{thickness} variable of a @code{Stem}
object. This makes stems almost twice as thick as their normal size.
-
+To distinguish between variables defined in input files (like
+@code{twentyFour} in the example above), and internal variables, we
+will call the latter ``properties.'' So, the stem object has a
+@code{thickness} property.
+
Two-dimensional offsets (X and Y coordinates) as well as object sizes
(intervals with a left and right point) are entered as @code{pairs}. A
pair@footnote{In Scheme terminology, the pair is called @code{cons},
#'("blah-blah" . 3.14159265)
@end example
-A list is entered by enclosing its elements in parentheses, and
-adding a quote. . For example,
+A list is entered by enclosing its elements in parentheses, and adding
+a quote. For example,
@example
#'(1 2 3)
#'(1 2 "string" #f)
calculations, do not use a quote.
Inside a quoted list or pair, there is no need to quote anymore. The
-following is a pair and a list of symbols respectively.
+following is a pair of symbols, a list of symbols and a list of lists
+respectively,
+
@example
#'(stem . head)
#'(staff clef key-signature)
+ #'((1) (2))
@end example
+@node Context
+@section Context
+
+When music is printed, a lot of things notation elements must be added
+to the input, which is often bare bones. For example, compare the
+input and output of the following example
+
+@lilypond[verbatim,relative=2]
+ cis4 cis2. g4
+@end lilypond
+
+The input is rather sparse, but in the output, bar lines, accidentals,
+clef and time signature are added. LilyPond @emph{interprets} the
+input. During this step, the musical information is inspected in time
+order, similar to reading a score from left to right. While reading,
+the program remembers where measure boundaries are, and what pitches
+need explicit accidentals.
+
+This information can be present on several levels. For example, the
+effect of an accidental is limited to a single stave, while a bar line
+must be synchronized across the entire score. To match this
+hierarchy, LilyPond's interpretation step is hierarchical. Properties
+are maintained `interpretation contexts', like Voice, Staff and Score,
+and each context can have different @emph{properties}, variables that
+are contained in a context.
+
@menu
-* Inline Scheme::
+* Changing context properties on the fly ::
+* context property defaults ::
+* which properties to change::
@end menu
-@node Inline Scheme
-@subsection Inline Scheme
+@node Changing context properties on the fly
+@subsection Changing context properties on the fly
-Scheme expressions can be entered in the input file by entering a
-hash-sign (@code{#}). The expression following the hash-sign is
-evaluated as Scheme. For example, the boolean value @var{true} is
-@code{#t} in Scheme, so for LilyPond @var{true} looks like @code{##t},
-and can be used in property assignments:
-@example
- \set Staff.autoBeaming = ##f
-@end example
+Such variables can be changed during the interpretation step.
+This is achieved by inserting the @code{\set} command in the music,
+@quotation
+ @code{\set }[@var{context}]@code{.}@var{prop}@code{ = #}@var{value}
+@end quotation
-@node Setting variables
-@section Setting variables
+For example,
+@lilypond[verbatim,relative=2]
+ R1*2
+ \set Score.skipBars = ##t
+ R1*2
+@end lilypond
-When the music is converted from notes to print it is interpreted
-in left-to-right order. This is similar to what happens when we read
-music. During this step context-sensitive information such as the
-accidentals to print, and where bar lines must be placed, are stored in
-variables. These variables are called @emph{context properties}.
-The properties can also be manipulated from input files. Consider this input:
-@example
-\set Staff.autoBeaming = ##f
-@end example
+This command skips measures that have no notes. The result is that
+multi rests are condensed. The value assigned is a Scheme object. In
+this case, it is @code{#t}, the boolean True value.
-@noindent
-It sets the property named @code{autoBeaming} in the current staff at
-this point in the music to @code{##f}, which means `false'. This
-property controls whether beams are printed automatically:
-@c
-@lilypond[relative=1,fragment,verbatim]
+If the @var{context} argument is left out, then the current
+bottom-most context (typically ChordNames, Voice or Lyrics) is used.
+In this example,
+
+@lilypond[verbatim,relative=2]
+ c8 c c c
+ \set autoBeaming = ##f
c8 c c c
- \set Staff.autoBeaming = ##f
- c8 c c c
@end lilypond
@noindent
-LilyPond includes a built-in programming language, namely, a dialect
-of Scheme. The argument to @code{\set}, @code{##f}, is an
-expression in that language. The first hash-mark signals that a piece
-of Scheme code follows. The second hash character is part of the
-boolean value true (@code{#t}). Values of other types may be
-entered as follows:
-@itemize @bullet
-@item a string, enclosed in double quotes, for example,
-@example
- \set Staff.instrument = #"French Horn"
-@end example
-@item a boolean: either @code{#t} or @code{#f}, for true and false
-respectively, e.g.
-@example
- \set autoBeaming = ##f
- \set Score.skipBars = ##t
-@end example
+the @var{context} argument to @code{\set} is left out, and the current
+@internalsref{Voice} is used. Contexts are hierarchical, so if a
+bigger context was specified, for example @code{Staff}, then the
+change would apply to all Voices in the current stave.
-@item a number, such as
-@example
- \set Score.currentBarNumber = #20
-@end example
+There is also an @code{\unset} command,
+@quotation
+ @code{\set }[@var{context}]@code{.}@var{prop}
+@end quotation
+
+@noindent
+which removes the definition of @var{prop}. This command only removes
+definitions set in
+@var{context}. in
-@item a symbol, which is introduced by a quote character, as in
@example
- \set Staff.crescendoSpanner = #'dashed-line
+ \set staff.autobeaming = ##f
+ \unset voice.autobeaming
@end example
-@item a pair, which is also introduced by a quote character, like in
-the following statements, which set properties to the pairs (-7.5, 6)
-and (3, 4) respectively:
+@noindent
+the current voice does not have the property, and the definition at
+staff level remains intact.
-@example
- \set Staff.minimumVerticalExtent = #'(-7.5 . 6)
- \set Staff.timeSignatureFraction = #'(3 . 4)
-@end example
+@node context property defaults
+@subsection context property defaults
-@item a list, which is also introduced by a quote character. In the
-following example, the @code{breakAlignOrder} property is set to a
-list of symbols:
-@example
- \set Score.breakAlignOrder =
- #'(left-edge time-signature key-signatures)
-@end example
-@end itemize
+@node which properties to change
+@subsection which properties to change
+
There are many different properties. Not all of them are listed in
this manual. However, the program reference lists them all in the
David Bobroff
Darius
Delma Avers
+Doug Linhardt
Edward Sanford Sutton
Eric Wurbel
Erik Sandberg
MAJOR_VERSION=2
MINOR_VERSION=1
PATCH_LEVEL=31
-MY_PATCH_LEVEL=
+MY_PATCH_LEVEL=hwn1
\score {
\context Staff \notes \relative c' {
- \repeat unfold 35 { a b c d \break }
+ \repeat unfold 135 { a b c d \break }
c1
}
}
if (note
&& note->is_mus_type ("note-event")
&& Rhythmic_head::has_interface (info.grob_)
- && !gh_equal_p (info.grob_->get_property ("style"), ly_symbol2scm ("harmonic"))
+#if 0
+ /*
+ todo: make tunable.
+ */
+ && !gh_equal_p (info.grob_->get_property ("style"),
+ ly_symbol2scm ("harmonic"))
+#endif
)
{
Accidental_entry entry ;
SCM split_list_;
Direction where_dir_;
void change_to (Music_iterator* , SCM, String);
+ Moment start_moment_;
};
for (; gh_pair_p (split_list_); split_list_ = gh_cdr (split_list_))
{
splitm = unsmob_moment (gh_caar (split_list_));
- if (*splitm > now)
+ if ((*splitm + start_moment_) > now)
break ;
+ *splitm += start_moment_;
SCM tag = gh_cdar (split_list_);
Direction d = to_dir (tag);
{
Music_wrapper_iterator::construct_children ();
split_list_ = get_music ()->get_property ("split-list");
+ start_moment_ = get_outlet ()->now_mom ();
}
IMPLEMENT_CTOR_CALLBACK (Auto_change_iterator);
return gh_cons (gh_int2scm (r.num ()), gh_int2scm (r.den ()));
}
-SCM
-Duration::smobbed_copy () const
-{
- Duration *p = new Duration (*this);
- return p->smobbed_self ();
-}
-
int
Duration::duration_log () const
{
if (w.main_part_.is_infinity ())
break ;
+ if (first)
+ {
+ /*
+ Need this to get grace notes at start of a piece correct.
+ */
+ first = false;
+ set_property ("measurePosition", w.smobbed_copy ());
+ }
+
+
prepare (w);
if (iter->ok ())
}
one_time_step ();
- first = false;
}
}
static int compare (Duration const&, Duration const&);
- SCM smobbed_copy () const;
DECLARE_SCHEME_CALLBACK (less_p, (SCM a, SCM b));
DECLARE_SIMPLE_SMOBS (Duration,);
-#define IMPLEMENT_SIMPLE_SMOBS(CL) \
+#define IMPLEMENT_BASE_SMOBS(CL) \
scm_t_bits CL::smob_tag_; \
SCM \
CL::smob_p (SCM s) \
scm_set_smob_print (smob_tag_, CL::print_smob); \
scm_set_smob_equalp (smob_tag_, CL::equal_p); \
} \
-SCM CL::smobbed_self () const \
-{ \
- SCM s; \
- s = gh_cons (SCM_PACK (CL::smob_tag_), SCM_PACK (this)); \
- scm_gc_register_collectable_memory ((CL*)this, sizeof (CL), #CL " smob"); \
- \
- return s; \
-} \
size_t \
CL::free_smob (SCM ses) \
{ \
}\
ADD_SCM_INIT_FUNC (CL, CL::init_smobs)
+
+#define IMPLEMENT_SIMPLE_SMOBS(CL) \
+IMPLEMENT_BASE_SMOBS(CL);\
+SCM CL::smobbed_copy () const \
+{ \
+ CL * ptr = new CL (*this);\
+ SCM s; \
+ s = gh_cons (SCM_PACK (CL::smob_tag_), SCM_PACK (ptr)); \
+ scm_gc_register_collectable_memory ((CL*)this, sizeof (CL), #CL " smob"); \
+ \
+ return s; \
+} \
+
+
#define IMPLEMENT_SMOBS(CL) \
-IMPLEMENT_SIMPLE_SMOBS (CL) \
+IMPLEMENT_BASE_SMOBS (CL) \
SCM \
CL::smobify_self () \
{ \
/*
Deliver a copy of THIS as a smobified SCM
*/
- SCM smobbed_copy () const;
String to_string () const;
static int compare (Moment const&, Moment const&);
#include "lily-guile.hh"
#include "virtual-methods.hh"
#include "smobs.hh"
+#include "input.hh"
/**
Definition of how to output lilypond.
*/
-class Music_output_def
+class Music_output_def
{
public:
Scheme_hash_table * translator_tab_;
-
+ Input input_origin_;
+
SCM scope_;
SCM scaled_fonts_;
/* JUNKME */
Real get_realvar (SCM symbol) const;
- SCM smobbed_copy () const;
-
friend int yyparse (void*);
};
SCM stencils_;
Offset dim_;
bool is_title_;
- DECLARE_SIMPLE_SMOBS (Paper_line,);
+ DECLARE_SMOBS (Paper_line,);
public:
Paper_line (Offset, SCM, bool = true);
Offset dim () const;
- SCM smobbed_copy () const;
SCM stencils () const;
bool is_title () const;
};
int quartertone_pitch () const;
String to_string () const;
- SCM smobbed_copy () const;
DECLARE_SCHEME_CALLBACK (less_p, (SCM a, SCM b));
DECLARE_SIMPLE_SMOBS (Pitch,);
};
*/
#define DECLARE_SIMPLE_SMOBS(CL,dummy) \
-protected: \
+public: \
+ SCM smobbed_copy () const; \
+DECLARE_BASE_SMOBS(CL)
+
+
+#define DECLARE_BASE_SMOBS(CL) \
friend class Non_existant_class ; \
- SCM smobbed_self () const; \
private:\
static scm_t_bits smob_tag_; \
static SCM mark_smob (SCM); \
#define DECLARE_SMOBS(CL,dummy) \
- DECLARE_SIMPLE_SMOBS (CL,dammy) \
+ DECLARE_BASE_SMOBS (CL) \
protected:\
virtual ~CL ();\
SCM unprotected_smobify_self ();\
DECLARE_SIMPLE_SMOBS(Spring_smob,dummy);
public:
- SCM smobbed_copy () const;
Spring_smob();
};
DECLARE_UNSMOB(Spring_smob, spring);
Stencil ();
Offset origin () const;
- SCM smobbed_copy () const;
SCM get_expr () const;
/**
}
-SCM
-Moment::smobbed_copy () const
-{
- Moment * m = new Moment (*this);
- return m->smobbed_self ();
-}
int
// FIXME: what's this?
bool merge_possible = (ups[0] >= dps[0]) && (ups.top () >= dps.top ());
+
+
+ /* Do not merge notes typeset in different style. */
+ if ( !gh_equal_p (nu->get_property ("style"),
+ nd->get_property ("style") ) )
+ merge_possible = false;
+
int upball_type = Note_head::get_balltype (nu);
int dnball_type = Note_head::get_balltype (nd);
z = scm_permanent_object (ly_offset2scm (Offset (0, 0)));
Offset dim = Offset (stil->extent (X_AXIS).length (),
stil->extent (Y_AXIS).length ());
- Paper_line pl (dim, scm_cons (stil->smobbed_copy (), SCM_EOL), is_title);
- return pl.smobbed_copy ();
+ Paper_line * pl = new Paper_line (dim, scm_cons (stil->smobbed_copy (), SCM_EOL), is_title);
+ return pl->self_scm ();
}
/* Simplistic page interface */
SCM make_header = scm_primitive_eval (ly_symbol2scm ("make-header"));
SCM make_footer = scm_primitive_eval (ly_symbol2scm ("make-footer"));
- header_ = scm_call_2 (make_header, paper_->smobbed_copy (),
+ header_ = scm_call_2 (make_header, paper_->self_scm (),
scm_int2num (number_));
// FIXME: why does this (generates Stencil) not trigger font load?
if (get_header ())
get_header ()->align_to (Y_AXIS, UP);
- footer_ = scm_call_2 (make_footer, paper_->smobbed_copy (),
+ footer_ = scm_call_2 (make_footer, paper_->self_scm (),
scm_int2num (number_));
if (get_footer ())
get_footer ()->align_to (Y_AXIS, UP);
SCM scopes = get_scopes (0);
SCM make_tagline = scm_primitive_eval (ly_symbol2scm ("make-tagline"));
- tagline_ = scm_call_2 (make_tagline, paper->smobbed_copy (), scopes);
+ tagline_ = scm_call_2 (make_tagline, paper->self_scm (), scopes);
Real tag_height = 0;
if (Stencil *s = unsmob_stencil (tagline_))
tag_height = s->extent (Y_AXIS).length ();
height_ += tag_height;
SCM make_copyright = scm_primitive_eval (ly_symbol2scm ("make-copyright"));
- copyright_ = scm_call_2 (make_copyright, paper->smobbed_copy (), scopes);
+ copyright_ = scm_call_2 (make_copyright, paper->self_scm (), scopes);
Real copy_height = 0;
if (Stencil *s = unsmob_stencil (copyright_))
copy_height = s->extent (Y_AXIS).length ();
{
return dynamic_cast<Paper_def*> (unsmob_music_output_def (x));
}
-
-SCM
-Paper_def::smobbed_copy () const
-{
- Paper_def *p = new Paper_def (*this);
- return p->smobbed_self ();
-}
dim_ = o;
stencils_ = stencils;
is_title_ = is_title;
+ smobify_self ();
}
Offset
return 1;
}
-SCM
-Paper_line::smobbed_copy () const
+Paper_line::~Paper_line ()
{
- Paper_line *line = new Paper_line (*this);
- return line->smobbed_self ();
}
-IMPLEMENT_SIMPLE_SMOBS (Paper_line);
+IMPLEMENT_SMOBS (Paper_line);
IMPLEMENT_TYPE_P (Paper_line, "ly:paper-line?");
IMPLEMENT_DEFAULT_EQUAL_P (Paper_line);
music_output_def_body:
- music_output_def_head '{' {
+ music_output_def_head '{' {
+ $$ = $1;
+ $$->input_origin_. set_spot (THIS->here_input ());
}
| music_output_def_head '{' MUSIC_OUTPUT_DEF_IDENTIFIER {
scm_gc_unprotect_object ($1->self_scm ());
Music_output_def * o = unsmob_music_output_def ($3);
+ o->input_origin_.set_spot (THIS->here_input ());
$$ = o;
THIS->lexer_->remove_scope ();
THIS->lexer_->add_scope (o->scope_);
return interval (*r, *p).smobbed_copy ();
}
-SCM
-Pitch::smobbed_copy ()const
-{
- Pitch *p = new Pitch (*this);
- return p->smobbed_self ();
-}
int
Pitch::get_octave ()const
return a==b? SCM_BOOL_T : SCM_BOOL_F;
}
-SCM
-Spring_smob::smobbed_copy ()const
-{
- Spring_smob * p = new Spring_smob (*this);
- return p->smobbed_self ();
-}
#include "ly-smobs.icc"
-SCM
-Stencil::smobbed_copy () const
-{
- Stencil *s = new Stencil (*this);
- return s->smobbed_self ();
-}
Offset
Stencil::origin () const
Interval x (extent (this, X_AXIS));
Interval y (extent (this, Y_AXIS));
- Paper_line pl (Offset (x.length (), y.length ()), stencils);
- return pl.smobbed_copy ();
+ Paper_line *pl = new Paper_line (Offset (x.length (), y.length ()), stencils);
+ return pl->self_scm ();
}
Link_array<Item>
daddy_context_->set_property ("timeSignatureFraction",
gh_cons (gh_int2scm (4), gh_int2scm (4)));
- daddy_context_->set_property ("measurePosition", Moment (Rational (0)).smobbed_copy ());
+ /*
+ Do not init measurePosition; this should be done from global
+ context.
+ */
daddy_context_->set_property ("measureLength", Moment (Rational (1)).smobbed_copy ());
daddy_context_->set_property ("beatLength", Moment (Rational (1,4)).smobbed_copy ());
}
;;; Library functions
-
+(set-debug-cell-accesses! #t)
(use-modules (ice-9 regex)
(ice-9 safe)
(oop goops)
(scm output-sodipodi)
(scm output-pdftex))
+
+(define output-tex-module
+ (make-module 1021 (list (resolve-interface '(scm new-output-tex)))))
+
+(define (new-tex-output-expression expr port)
+ (display (eval expr output-tex-module) port))
+
(define output-alist
`(
("tex" . ("TeX output. The default output form." ,tex-output-expression))
+ ("safetex" . ("TeX output. The default output form." ,new-tex-output-expression))
("scm" . ("Scheme dump: debug scheme stencil expressions" ,write))
("sketch" . ("Bare bones Sketch output." ,sketch-output-expression))
("sodipodi" . ("Bare bones Sodipodi output." ,sodipodi-output-expression))
(display (eval expr output-ps) port))
;;; Output interface entry
+
(define-public (tex-output-expression expr port)
(display (eval expr this-module) port ))