line-break-system-details from left bound to determine extents.
* Documentation/user/programming-interface.itely (Using LilyPond
syntax inside Scheme): change applyxxx -> applyXxx.
* ly/music-functions-init.ly: add outputProperty music function.
* lily/parser.yy (Generic_prefix_music_scm): add scm-scm-scm signature.
* lily/grob-scheme.cc (LY_DEFINE): add ! to ly:grob-suicide! name.
* python/convertrules.py (conv): rule
* ly/music-functions-init.ly: applyxxx -> applyXxx
* ly/engraver-init.ly (AncientRemoveEmptyStaffContext): alias
TabVoice to Voice.
+2005-09-27 Han-Wen Nienhuys <hanwen@xs4all.nl>
+
+ * lily/paper-system.cc (read_left_bound): new function. Read
+ line-break-system-details from left bound to determine extents.
+
+ * Documentation/user/programming-interface.itely (Using LilyPond
+ syntax inside Scheme): change applyxxx -> applyXxx.
+
+ * ly/music-functions-init.ly: add outputProperty music function.
+
+ * lily/parser.yy (Generic_prefix_music_scm): add scm-scm-scm signature.
+
+ * lily/grob-scheme.cc (LY_DEFINE): add ! to ly:grob-suicide! name.
+
+ * python/convertrules.py (conv): rule
+
+ * ly/music-functions-init.ly: applyxxx -> applyXxx
+
+ * ly/engraver-init.ly (AncientRemoveEmptyStaffContext): alias
+ TabVoice to Voice.
+
2005-09-26 Han-Wen Nienhuys <hanwen@xs4all.nl>
* flower/include/real.hh: include <math.h> iso. <cmath>
@lilypond[quote,verbatim,fragment,raggedright,relative=2]
\context Voice {
- \applyoutput
+ \applyOutput
#(add-balloon-text 'NoteHead "heads, or tails?"
'(1 . -3))
c8
@cindex automatic beams, tuning
@cindex tuning automatic beaming
-@c [TODO: use \applycontext]
+@c [TODO: use \applyContext]
In normal time signatures, automatic beams can start on any note but can
only end in a few positions within the measure: beams can end on a beat,
\magnify isn't changed to \fontsize.
- \magnify #m => \fontsize #f, where f = 6ln(m)/ln(2)
remove-tag isn't changed.
- - \applymusic #(remove-tag '. . .) => \keepWithTag #'. . .
+ - \applyMusic #(remove-tag '. . .) => \keepWithTag #'. . .
firstpagenumber isn't changed.
- firstpagenumber no => printfirstpagenumber = ##f
Line breaks in header strings aren't converted.
Such syntax can also be defined as user code. To do this, it is
necessary to create a @emph{music function}. This is a specially marked
-Scheme function. For example, the music function @code{\applymusic} applies
+Scheme function. For example, the music function @code{\applyMusic} applies
a user-defined function to a music expression. Its syntax is
@example
-\applymusic #@var{func} @var{music}
+\applyMusic #@var{func} @var{music}
@end example
A music function is created with @code{ly:make-music-function},
(ly:make-music-function
@end example
-@code{\applymusic} takes a Scheme function and a Music expression as
+@code{\applyMusic} takes a Scheme function and a Music expression as
arguments. This is encoded in its parameter list,
@example
@end example
The above Scheme code only defines the functionality. The tag
-@code{\applymusic} is selected by defining
+@code{\applyMusic} is selected by defining
@example
-applymusic = #(ly:make-music-function
+applyMusic = #(ly:make-music-function
(list procedure? ly:music?)
(lambda (parser location func music)
(func music)))
functions:
@example
-applymusic = #(def-music-function (parser location func music)
+applyMusic = #(def-music-function (parser location func music)
(procedure? ly:music?)
(func music))
@end example
-Examples of the use of @code{\applymusic} are in the next section.
+Examples of the use of @code{\applyMusic} are in the next section.
@seealso
@file{ly/@/music@/-functions@/-init@/.ly}.
@subsection Manipulating music expressions
Music objects and their properties can be accessed and manipulated
-directly, through the @code{\applymusic} mechanism.
-The syntax for @code{\applymusic} is
+directly, through the @code{\applyMusic} mechanism.
+The syntax for @code{\applyMusic} is
@example
-\applymusic #@var{func} @var{music}
+\applyMusic #@var{func} @var{music}
@end example
@noindent
(reverse (ly:music-property m 'elements)))
m)
-\applymusic #rev-music-1 { c'4 d'4 }
+\applyMusic #rev-music-1 { c'4 d'4 }
@end lilypond
The use of such a function is very limited. The effect of this
multiple children. The following function application has no effect
@example
-\applymusic #rev-music-1 \grace @{ c4 d4 @}
+\applyMusic #rev-music-1 \grace @{ c4 d4 @}
@end example
@noindent
In this case, @code{\grace} is stored as @internalsref{GraceMusic}, which
has no @code{elements}, only a single @code{element}. Every generally
-applicable function for @code{\applymusic} must -- like music expressions
+applicable function for @code{\applyMusic} must -- like music expressions
themselves -- be recursive.
The following example is such a recursive function: It first extracts
\context Voice = "2" @{ \voiceTwo b @} >>
@end example
-Other applications of @code{\applymusic} are writing out repeats
+Other applications of @code{\applyMusic} are writing out repeats
automatically (@inputfileref{input/@/test,unfold@/-all@/-repeats@/.ly}),
saving keystrokes (@inputfileref{input/@/test,music@/-box@/.ly}) and
exporting LilyPond input to other formats
{
c'^"1"
- \applymusic #(with-padding 3) { c'^"2" c'^"3" }
+ \applyMusic #(with-padding 3) { c'^"2" c'^"3" }
c'^"4"
}
@end lilypond
@subsection Context evaluation
@cindex calling code during interpreting
-@cindex @code{\applycontext}
+@cindex @code{\applyContext}
Contexts can be modified during interpretation with Scheme code. The
syntax for this is
@example
-\applycontext @var{function}
+\applyContext @var{function}
@end example
@var{function} should be a Scheme function taking a single argument,
current bar number on the standard output during the compile:
@example
-\applycontext
+\applyContext
#(lambda (x)
(format #t "\nWe were called in barnumber ~a.\n"
(ly:context-property x 'currentBarNumber)))
return s;
}
-LY_DEFINE (ly_grob_suicide, "ly:grob-suicide",
+LY_DEFINE (ly_grob_suicide_x, "ly:grob-suicide!",
1, 0, 0, (SCM g),
"Kill @var{g}.")
{
int number_;
Paper_system (Stencil, bool);
-
+ void read_left_bound (Item*);
Stencil to_stencil () const;
SCM stencils () const;
bool is_title () const;
Real break_before_penalty () const;
+ Interval staff_refpoints () const;
};
DECLARE_UNSMOB (Paper_system, paper_system);
else if (tag == ly_symbol2scm ("scheme0-scheme1-scheme2"))
return MARKUP_HEAD_SCM0_SCM1_SCM2;
else {
- programming_error ("no parser tag defined for this signature");
+ programming_error ("no parser tag defined for this markup signature");
ly_display_scm (s);
assert(false);
}
{
return MUSIC_FUNCTION_SCM_SCM_MUSIC;
}
+ else if (type == ly_symbol2scm ("scm-scm-scm"))
+ {
+ return MUSIC_FUNCTION_SCM_SCM_SCM;
+ }
else if (type == ly_symbol2scm ("markup"))
{
return MUSIC_FUNCTION_MARKUP;
Paper_system *ps = new Paper_system (*unsmob_stencil (t), true);
systems_ = scm_cons (ps->self_scm (), systems_);
ps->unprotect ();
+
// FIXME: figure out penalty.
//set_system_penalty (ps, scores_[i].header_);
}
"Score_engraver::forbid_breaks to stop linebreaks. In practice, this "
"means that you can make a breakpoint by creating a barline (assuming "
"that there are no beams or notes that prevent a breakpoint.) ",
- /* create */ "PaperColumn NonMusicalPaperColumn",
+
+ /* create */
+ "PaperColumn "
+ "NonMusicalPaperColumn",
+
/* accept */ "break-event",
/* read */ "",
- /* write */ "currentCommandColumn currentMusicalColumn");
+ /* write */
+ "currentCommandColumn "
+ "currentMusicalColumn");
return new Paper_column (*this, count);
}
-ADD_INTERFACE (Paper_column, "paper-column-interface",
- "@code{Paper_column} objects form the top-most X-parents for items."
- " The are two types of columns: musical columns, where are attached to, and "
- " non-musical columns, where bar-lines, clefs etc. are attached to. "
- " The spacing engine determines the X-positions of these objects."
-
- "\n\n"
- "They are\n"
- " numbered, the first (leftmost) is column 0. Numbering happens before\n"
- " line-breaking, and columns are not renumbered after line breaking.\n"
- " Since many columns go unused, you should only use the rank field to\n"
- " get ordering information. Two adjacent columns may have\n"
- " non-adjacent numbers.\n",
-
-
- "between-cols "
- "bounded-by-me "
- "page-penalty "
- "shortest-playing-duration "
- "shortest-starter-duration "
- "used "
- "when ");
-
void
Paper_column::do_break_processing ()
{
return SCM_UNSPECIFIED;
}
+
+
+ADD_INTERFACE (Paper_column,
+
+ "paper-column-interface",
+ "@code{Paper_column} objects form the top-most X-parents for items."
+ " The are two types of columns: musical columns, where are attached to, and "
+ " non-musical columns, where bar-lines, clefs etc. are attached to. "
+ " The spacing engine determines the X-positions of these objects."
+
+ "\n\n"
+ "They are\n"
+ " numbered, the first (leftmost) is column 0. Numbering happens before\n"
+ " line-breaking, and columns are not renumbered after line breaking.\n"
+ " Since many columns go unused, you should only use the rank field to\n"
+ " get ordering information. Two adjacent columns may have\n"
+ " non-adjacent numbers.\n",
+
+
+ /* properties */
+ "between-cols "
+ "bounded-by-me "
+ "line-break-system-details "
+ "page-penalty "
+ "shortest-playing-duration "
+ "shortest-starter-duration "
+ "used "
+ "when ");
+
{
Paper_system *ps = unsmob_paper_system (system);
SCM_ASSERT_TYPE (ps, system, SCM_ARG1, __FUNCTION__, "paper-system");
- return ly_interval2scm (ps->staff_refpoints_);
+ return ly_interval2scm (ps->staff_refpoints ());
}
*/
#include "paper-system.hh"
-
-#include "virtual-methods.hh"
+#include "item.hh"
#include "ly-smobs.icc"
{
return stencil_;
}
+
+void
+Paper_system::read_left_bound (Item *left)
+{
+ break_before_penalty_
+ = robust_scm2double (left->get_property ("page-penalty"), 0.0);
+
+ SCM details
+ = left->get_property ("line-break-system-details");
+
+ SCM yext
+ = scm_assoc (ly_symbol2scm ("Y-extent"), details);
+
+ SCM staff_ext
+ = scm_assoc (ly_symbol2scm ("refpoint-Y-extent"), details);
+
+ if (scm_is_pair (yext)
+ && is_number_pair (scm_cdr (yext)))
+ {
+ Box b = stencil_.extent_box();
+ b[Y_AXIS] = ly_scm2interval (scm_cdr (yext));
+
+ stencil_ = Stencil (b, stencil_.expr ());
+ }
+
+ if (scm_is_pair (staff_ext)
+ && is_number_pair (scm_cdr (staff_ext)))
+ {
+ staff_refpoints_ = ly_scm2interval (scm_cdr (staff_ext));
+ }
+}
+
+Interval
+Paper_system::staff_refpoints () const
+{
+ return staff_refpoints_;
+}
%token <scm> MUSIC_FUNCTION_SCM_MUSIC_MUSIC
%token <scm> MUSIC_FUNCTION_SCM_SCM
%token <scm> MUSIC_FUNCTION_SCM_SCM_MUSIC
+%token <scm> MUSIC_FUNCTION_SCM_SCM_SCM
%token <scm> MUSIC_IDENTIFIER
%token <scm> NOTENAME_PITCH
%token <scm> NUMBER_IDENTIFIER
| MUSIC_FUNCTION_SCM_SCM embedded_scm embedded_scm {
$$ = scm_list_4 ($1, make_input (@$), $2, $3);
}
+ | MUSIC_FUNCTION_SCM_SCM_SCM embedded_scm embedded_scm embedded_scm {
+ $$ = scm_list_5 ($1, make_input (@$), $2, $3, $4);
+ }
| MUSIC_FUNCTION_SCM_SCM_MUSIC embedded_scm embedded_scm Music {
$$ = scm_list_5 ($1, make_input (@$), $2, $3, $4->self_scm ());
}
"Score_engraver::forbid_breaks to stop linebreaks. In practice, this "
"means that you can make a breakpoint by creating a barline (assuming "
"that there are no beams or notes that prevent a breakpoint.) ",
- /* create */ "System PaperColumn NonMusicalPaperColumn",
- /* accept */ "break-event",
- /* read */ "currentMusicalColumn currentCommandColumn verticallySpacedContexts",
- /* write */ "");
+ /* create */
+ "System ",
+
+ /* accept */
+ "break-event",
+ /* read */
+ "currentMusicalColumn "
+ "currentCommandColumn "
+ "verticallySpacedContexts",
+ /* write */
+ "");
Paper_system *pl = new Paper_system (sys_stencil, false);
pl->staff_refpoints_ = staff_refpoints;
- Item *break_point = this->get_bound (LEFT);
- pl->break_before_penalty_
- = robust_scm2double (break_point->get_property ("page-penalty"), 0.0);
-
+ pl->read_left_bound (this->get_bound (LEFT));
+
return pl->unprotect ();
}
\context {
\Voice
\name "TabVoice"
+ \alias "Voice"
\consists "Tab_note_heads_engraver"
\remove "Note_heads_engraver"
\remove "Fingering_engraver"
#(use-modules (srfi srfi-1))
-applymusic =
+applyMusic =
#(def-music-function (parser location func music) (procedure? ly:music?)
(func music))
#(def-music-function (parser location music) (ly:music?)
(make-autochange-music music))
-applycontext =
+applyContext =
#(def-music-function (parser location proc) (procedure?)
(make-music 'ApplyContext
'origin location
(display-lily-music music)
music)
-applyoutput =
+applyOutput =
#(def-music-function (parser location proc) (procedure?)
(make-music 'ApplyOutputEvent
'origin location
'procedure proc))
+outputProperty =
+#(def-music-function (parser location name prop value)
+ (symbol? symbol? scheme?)
+
+
+ "Set @var{prop} to @var{value} in all grobs named @var{name} "
+
+ (make-music 'ApplyOutputEvent
+ 'origin location
+ 'procedure
+ (lambda (grob orig-context context)
+ (if (equal?
+ (cdr (assoc 'name (ly:grob-property grob 'meta)))
+ name)
+ (set! (ly:grob-property grob prop) value)
+ ))))
+
breathe =
#(def-music-function (parser location) ()
(make-music 'EventChord
'''Performer_group_performer -> Performer_group, Engraver_group_engraver -> Engraver_group
inside-slur -> avoid-slur'''))
+
+
+def conv (str):
+ str = re.sub(r'\\applyoutput', '\\applyOutput', str)
+ str = re.sub(r'\\applycontext', '\\applyContext', str)
+ str = re.sub(r'\\applymusic', '\\applyMusic', str)
+ str = re.sub(r'ly:grob-suicide', 'ly:grob-suicide!', str)
+ return str
+
+conversions.append (((2, 7, 10), conv,
+ '''\\applyxxx -> \\applyXxx'''))
(length-fraction ,number? "Length of ledger line as fraction of note head size.")
(lengths ,list? "Default stem lengths. The list gives a length
for each flag-count.")
+ (line-break-system-details ,list?
+ "Alist of properties to use when this
+column is the start of a system.")
+
(line-count ,integer? "The number of staff lines.")
(measure-length ,ly:moment? "Length of a
measure. Used in some spacing situations.")
ly:grob-script-priority-less
ly:grob-set-property!
ly:grob-staff-position
- ly:grob-suicide
+ ly:grob-suicide!
ly:grob-system
ly:grob-translate-axis!
ly:grob?