<a\f c( e>1 <a c) e>\f <a\< c e>( <a\! c e>) <a c e>\< <a c e> <a c e>\!
@end lilypond
+@cindex chords, empty
+@cindex placeholder events
+
+A chord acts merely as a container for its notes, its articulations and
+other attached elements. Consequently, a chord without notes inside
+does not actually have a duration. Any attached articulations will
+happen at the same musical time as the next following note or chord and
+be combined with them (for more complex possibilities of combining such
+elements, see @ref{Simultaneous expressions}):
+
+@lilypond[verbatim,quote,relative=2]
+\grace { g8[( a b] }
+<> ) \p \< -. -\markup \italic "sempre staccato"
+\repeat unfold 4 { c4 e } c1\f
+@end lilypond
+
@cindex relative pitch, chords
@cindex chords, relative pitch
@end lilypond
This can be useful if the simultaneous sections have identical
-rhythms, but attempts to attach notes with different durations
-to the same stem will cause errors.
+rhythms, but attempts to attach notes with different durations to
+the same stem will cause errors. Notes, articulations, and property
+changes in a @emph{single} @samp{Voice} are collected and engraved in
+musical order:
+
+@lilypond[quote,verbatim,relative=2]
+<a c>4-. <>-. << c a >> << { c-. <c a> } { a s-. } >>
+@end lilypond
+
+Multiple stems or beams or different note durations or properties at
+the same musical time require the use of multiple voices.
The following example shows how simultaneous expressions can
generate multiple staves implicitly:
<< { a4 b g2 } { d4 g2 c,4 } >>
@end lilypond
-Here different rhythms cause no problems.
+Here different rhythms cause no problems because they are
+interpreted in different voices.
@cindex collisions, clashing note columns
@cindex collisions, ignoring
Grob *e = info.grob ();
SCM avoid = e->get_property ("avoid-slur");
+ Grob *slur;
+ if (end_slurs.size () && !slurs.size ())
+ slur = end_slurs[0];
+ else
+ slur = slurs[0];
+
if (Tie::has_interface (e)
|| avoid == ly_symbol2scm ("inside"))
{
add_extra_encompass (slurs[i], e);
for (vsize i = end_slurs.size (); i--;)
add_extra_encompass (end_slurs[i], e);
+ if (slur)
+ e->set_object ("slur", slur->self_scm ());
}
else if (avoid == ly_symbol2scm ("outside")
|| avoid == ly_symbol2scm ("around"))
{
- Grob *slur;
- if (end_slurs.size () && !slurs.size ())
- slur = end_slurs[0];
- else
- slur = slurs[0];
-
if (slur)
{
chain_offset_callback (e, outside_slur_callback_proc, Y_AXIS);
// assume that if a script is avoiding slurs, it should not get placed
// under a tuplet bracket
- SCM avoid = scripts[i]->get_property ("avoid-slur");
- if (unsmob_grob (scripts[i]->get_object ("slur"))
- && (avoid == ly_symbol2scm ("outside")
- || avoid == ly_symbol2scm ("around")))
+ if (unsmob_grob (scripts[i]->get_object ("slur")))
continue;
Interval script_x (scripts[i]->extent (commonx, X_AXIS));