.htaccess
*.tfm
*.afm
+*.orig
+*.rej
+2006-11-07 Erlend Aasland <erlenda@gmail.com>
+
+ * scm/music-function.scm (add-ballon-text): add FIXME comment.
+
+ * scm/define-grob-properties.scm: remove old balloon stuff,
+ and do some trivial beautification.
+
+2006-11-06 Nicolas Sceaux <nicolas.sceaux@free.fr>
+
+ * scm/music-functions.scm (markup-expression->make-markup): fix
+ the case when a markup found in a markup list is a simple
+ string (Issue #147).
+
+2006-11-05 Han-Wen Nienhuys <hanwen@lilypond.org>
+
+ * lily/instrument-name-engraver.cc:
+ * input/regression/instrument-name-dynamic.ly:
+ ignore dynamic and pedal line spanners.
+
+ * Documentation/topdocs/NEWS.tely:
+ * Documentation/user/advanced-notation.itely:
+ * THANKS:
+ * input/regression/balloon.ly:
+ * lily/balloon.cc:
+ * ly/music-functions-init.ly:
+ * scm/define-event-classes.scm:
+ * scm/define-grobs.scm:
+ * scm/define-music-properties.scm:
+ * scm/define-music-types.scm:
+ * scm/output-lib.scm:
+ * lily/balloon-engraver.cc:
+ rewrite balloon-text support. This is now a separate grob, with itsvictim as the parent. This involves addingBalloon_engraver, AnnotateOutputEvent, annotate-output-event,\balloonText, \balloonGrobText, and modifying Balloon_interface::print.
+
+ * lily/paper-score.cc:
+ remove progress again
+
+ * lily/chord-name-engraver.cc:
+ formatting nitpicks.
+
+ * lily/paper-score.cc:
+ some useless statistics.
+
+ * buildscripts/git-update-changelog.py:
+ update todo/done after rejection due to removal analysis.
+
+ * buildscripts/git-update-changelog.py:
+ check whether removals from a diff actually apply.
+
+2006-11-05 Joe Neeman <joeneeman@gmail.com>
+
+ * lily/include/page-turn-page-breaking.hh: remove unused
+ fields in Break_node
+
+ * lily/page-turn-page-breaking.cc (calc_demerits):
+ * lily/optimal-page-breaking.cc (try_page_spacing): remove
+ uniformity penalties.
+
+2006-11-05 Werner Lemberg <wl@gnu.org>
+
+ * Documentation/user/changing-defaults.itely,
+ Documentation/user/preface.itely: Use `--', not `---'.
+ Minor improvements.
+
+ * Documentation/user/introduction.itely: Minor improvements.
+ (Automated engraving): Make example using \applyOutput work
+ actually.
+
+ * input/regression/apply-output.ly: Improve.
+
+2006-11-05 Han-Wen Nienhuys <hanwen@lilypond.org>
+
+ * lily/dynamic-engraver.cc:
+ formatting cleanup
+
+ * input/regression/note-head-harmonic.ly:
+ * lily/stem.cc:
+ * input/regression/note-head-harmonic-whole.ly:
+ Center harmonic heads if stem is invisible. Fixes #140
+
+ * lily/input.cc:
+ end context snippet with '\n'
+
+ * lily/parse-scm.cc:
+ catch all GUILE exceptions
+
+ * VERSION:
+ bump version
+
+ * lily/include/lily-lexer.hh:
+ * lily/lily-lexer.cc:
+ * lily/lily-parser.cc:
+ Lily_parser* arg for copy ctor too.
+
+ * scripts/abc2ly.py:
+ abc2ly new tempo syntax
+
2006-11-04 Heikki Junes <hjunes@gmail.com>
* po/fi.po: update Finnish translation.
* only show user-visible changes.
@end ignore
+@item Balloon texts can be entered more ergonomically, and are no
+longer clipped from the output.
+
+@lilypond[fragment,ragged-right,relative=1]
+\new Voice \with {\consists "Balloon_engraver" }
+{
+ \balloonGrobText #'Stem #'(3 . 4) \markup { "I'm a Stem" }
+ <c-\balloonText #'(-2 . -2) \markup { \simple #"hoi" } >8
+}
+@end lilypond
+
@item Slurs now avoid clefs and key changes.
The following example demonstrates its use.
@lilypond[quote,verbatim,fragment,ragged-right,relative=2]
-\applyOutput #'Voice
- #(add-balloon-text 'NoteHead "heads, or tails?"
- '(1 . -3))
- c8
+\new Voice \with { \consists "Balloon_engraver" }
+{
+ \balloonGrobText #'Stem #'(3 . 4) \markup { "I'm a Stem" }
+ <c-\balloonText #'(-2 . -2) \markup { Hello } >8
+}
@end lilypond
@noindent
-The function @code{add-balloon-text} takes the name of a grob, the
-label to print, and the position where to put the label relative to
-the object. In the above example, the text ``heads or tails?'' ends
-3 spaces below and 1 space to the right of the marked head.
+There are two music functions, @code{balloonText} and
+@code{balloonGrobText}. The latter takes the name of the grob to
+adorn, while the former may be used as an articulation on a note.
+The other arguments are the offset and the text of the label.
@cindex balloon
@cindex notation, explaining
@item forget
This is sort of the opposite of @code{no-reset}: Accidentals
-are not remembered at all---and hence all accidentals are
+are not remembered at all -- and hence all accidentals are
typeset relative to the key signature, regardless of what was
before in the music
@cindex regular rhythms
@cindex regular spacing
-The fragment only uses quarter notes: notes that are played in a
+Each bar in the fragment only uses notes that are played in a
constant rhythm. The spacing should reflect that. Unfortunately, the
eye deceives us a little; not only does it notice the distance between
note heads, it also takes into account the distance between
combination should be put farther apart, and the notes of a
down-stem/@/up-stem
combination should be put closer together, all depending on the
-combined vertical positions of the notes. The first two measures are
-printed with this correction, the last two measures without. The notes
-in the last two measures form down-stem/@/up-stem clumps of notes.
+combined vertical positions of the notes. The upper two measures are
+printed with this correction, the lower two measures without, forming
+down-stem/@/up-stem clumps of notes.
@cindex typography
fragment.
@lilypond[quote,ragged-right]
+#(set-global-staff-size 30)
+
#(define (mc-squared grob orig current)
- (let ((interfaces (ly:grob-property grob 'interfaces))
- (pos (ly:grob-property grob 'staff-position)))
- (if (and (memq 'note-head-interface interfaces)
- (memq pos '(-2 -3 -5)))
+ (let* ((interfaces (ly:grob-interfaces grob))
+ (pos (ly:grob-property grob 'staff-position)))
+ (if (memq 'note-head-interface interfaces)
(begin
(ly:grob-set-property! grob 'stencil ly:text-interface::print)
(ly:grob-set-property! grob 'font-family 'roman)
- (ly:grob-set-property!
- grob 'text
- (make-raise-markup
- -0.5
- (case pos
- ((-5) (make-simple-markup "m"))
- ((-3) (make-simple-markup "c "))
- ((-2) (make-smaller-markup (make-bold-markup "2")))
- (else (make-simple-markup "bla")))))))))
+ (ly:grob-set-property! grob 'text
+ (make-raise-markup -0.5
+ (case pos
+ ((-5) (make-simple-markup "m"))
+ ((-3) (make-simple-markup "c "))
+ ((-2) (make-smaller-markup (make-bold-markup "2")))
+ (else (make-simple-markup "bla")))))))))
\new Voice \relative c' {
\stemUp
\time 2/4
<d f g>4
\once \override NoteHead #'stencil = #ly:note-head::brew-ez-stencil
+ \once \override NoteHead #'font-size = #-7
+ \once \override NoteHead #'font-family = #'sans
+ \once \override NoteHead #'font-series = #'bold
<d f g>
\once \override NoteHead #'style = #'cross
<d f g>
It must have been during a rehearsal of the EJE (Eindhoven Youth
-Orchestra), somewhere in 1995 that Jan, one of the cranked violists
+Orchestra), somewhere in 1995 that Jan, one of the cranked violists,
told Han-Wen, one of the distorted French horn players, about the
grand new project he was working on. It was an automated system for
printing music (to be precise, it was MPP, a preprocessor for
an instrument. In the beginning, discovering how it works is fun, and
the things you cannot do are challenging. After the initial excitement,
you have to practice and practice. Scales and studies can be dull, and
-if you are not motivated by others---teachers, conductors or
-audience---it is very tempting to give up. You continue, and gradually
+if you are not motivated by others -- teachers, conductors or
+audience -- it is very tempting to give up. You continue, and gradually
playing becomes a part of your life. Some days it comes naturally, and
it is wonderful, and on some days it just does not work, but you keep
playing, day after day.
Han-Wen Nienhuys - Core development
Jan Nieuwenhuizen - Core development
-Graham Percival - Documentation Editor
+Graham Percival - Documentation Editor and Bug Meister
Mats Bengtsson - Support Guru
Kieren MacMillan
Lee T. Wilkirson
Lieke van der Meer
+Manuzhai
Mark Dewey
Marcus Macauley
Markus Schneider
Trevor Daniels
Vaclav Smilauer
Vicente Solsona Dellá
+Victor Eijkhout
+Villum Sejersen
Werner Lemberg
Will Oram
Zoltan V. Laszlo
self.diff = read_pipe ('git show %s' % self.committish)
def compare (self, other):
return sign (time.mktime (self.date) - time.mktime (other.date))
+
+
+ def check_diff_chunk (self, filename, chunk):
+ removals = []
+ def note_removal (m):
+ removals.append (m.group (1))
+
+ re.sub ('\n-([^\n]+)', note_removal, chunk)
+
+ if removals == []:
+ return True
+
+ if not os.path.exists (filename):
+ return False
+
+ contents = open (filename).read ()
+ for r in removals:
+ if r not in contents:
+ return False
+
+ return True
+
+ def check_diff (self):
+ chunks = re.split ('\ndiff --git ', self.diff)
+
+ ok = True
+ for c in chunks:
+ m = re.search ('^a/([^ ]+)', c)
+ if not m:
+ continue
+
+ file = m.group (1)
+
+ c = re.sub('\n--- [^\n]+', '', c)
+ ok = ok and self.check_diff_chunk (file, c)
+ if not ok:
+ break
+
+ return ok
def touched_files (self):
files = []
try:
previously_done = dict((c, 1) for c in open ('.git-commits-done').read ().split ('\n'))
- except OSError:
+ except IOError:
previously_done = {}
commits = [c for c in commits if not previously_done.has_key (c.committish)]
commits = sorted (commits, cmp=Commit.compare)
+ system ('cvs up')
file_adddel = []
collated_log = ''
collated_message = ''
-
commits_done = []
while commits:
c = commits[0]
- commits = commits[1:]
- commits_done.append (c)
-
if not c.has_patch ():
print 'patchless commit (merge?)'
continue
-
+
+ ok = c.check_diff ()
+
+ if not ok:
+ print "Patch doesn't seem to apply"
+ print 'skipping', c.committish
+ print 'message:', c.message
+
+ break
+
+
+ commits = commits[1:]
+ commits_done.append (c)
+
print 'patch ', c.committish
try:
c.apply (file_adddel)
+\version "2.9.28"
-\version "2.9.6"
\header {
-
texidoc = "The @code{\applyOutput} expression is the most flexible way to
tune properties for individual grobs.
Here, the layout of a note head is changed depending on its vertical
position.
"
+}
+\layout {
+ ragged-right = ##t
}
-\layout { ragged-right = ##t }
-#(define (mc-squared gr org cur)
+#(define (mc-squared gr org cur)
(let*
(
(ifs (ly:grob-interfaces gr))
(sp (ly:grob-property gr 'staff-position))
)
- (if (and (memq 'note-head-interface ifs)
- (memq sp '(-2 -3 -5)))
+ (if (memq 'note-head-interface ifs)
(begin
(ly:grob-set-property! gr 'stencil ly:text-interface::print)
(ly:grob-set-property! gr 'font-family 'roman)
- (ly:grob-set-property!
- gr 'text
+ (ly:grob-set-property! gr 'text
(make-raise-markup -0.5
(case sp
((-5) (make-simple-markup "m"))
))))
)))
-\context Voice \relative c' {
+\context Voice \relative c' {
\stemUp
- \set autoBeaming = ##f
+ \set autoBeaming = ##f
+
{ <d f g b>8
- \applyOutput #'Voice #mc-squared
+ \applyOutput #'Voice #mc-squared
<d f g b>
}
-
}
+% EOF
\header {
+
texidoc = "With balloon texts, objects in the output can be marked,
with lines and explanatory text added."
+
}
-\version "2.9.6"
+\version "2.9.28"
\layout{ ragged-right = ##t }
+\new Voice \with {\consists "Balloon_engraver" }
{
-
\relative c' {
-
- %% by hand:
- \once\override Stem #'stencil = #ly:balloon-interface::print
- \once\override Stem #'original-stencil = #ly:stem::print
- \once\override Stem #'balloon-text = #"I'm a stem"
- \once\override Stem #'balloon-text-offset = #'(3 . 4)
- \once\override Stem #'balloon-text-props
- = #'((font-family . roman))
-
-
- %% use predefd function.
- \applyOutput #'Voice #(add-balloon-text
- 'NoteHead "heads, or tails?"
- '(0 . -3))
-
-
- c8
+ \balloonGrobText #'Stem #'(3 . 4) \markup { "I'm a Stem" }
+ <c-\balloonText #'(-2 . -2) \markup { \simple #"hoi" } >8
}
}
--- /dev/null
+\version "2.9.28"
+
+\header {
+ texidoc = "
+ Instrument names (aligned on axis group spanners) ignore dynamic and
+ pedal line spanners."
+}
+
+\relative {
+ \set Staff.shortInstrumentName = "foo"
+ f1 | f1 | f1 |
+ f1\< | f1 | f1\! |
+}
+
+\paper {
+ line-width = 3\cm
+ indent = 0\cm
+}
+
+% EOF
--- /dev/null
+\header {
+
+ texidoc = "A harmonic note head must be centered if the base note
+ is a whole note."
+
+}
+
+
+\version "2.9.29"
+
+\paper {
+ ragged-right = ##t
+}
+
+\relative c' {
+ <e a\harmonic>1
+ <e'' a\harmonic>1
+}
+
texidoc = " The handling of stems for harmonic notes must be
completely identical to normal note heads.
- Harmonic heads do not get dots. If @code{harmonicAccidentals} is unset, they also don't get accidentals."
+ Harmonic heads do not get dots. If @code{harmonicAccidentals} is
+ unset, they also don't get accidentals."
}
--- /dev/null
+/*
+ balloon-engraver.cc -- implement Balloon_engraver
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 2006 Han-Wen Nienhuys <hanwen@lilypond.org>
+
+*/
+
+#include "engraver.hh"
+
+
+#include "stream-event.hh"
+#include "item.hh"
+
+#include "translator.icc"
+
+class Balloon_engraver : public Engraver
+{
+ TRANSLATOR_DECLARATIONS(Balloon_engraver);
+
+ DECLARE_TRANSLATOR_LISTENER(annotate_output);
+ DECLARE_ACKNOWLEDGER(grob);
+ vector<Stream_event *> events_;
+
+ void stop_translation_timestep ();
+
+ void balloonify (Grob *, Stream_event *);
+};
+
+IMPLEMENT_TRANSLATOR_LISTENER (Balloon_engraver, annotate_output);
+void
+Balloon_engraver::listen_annotate_output (Stream_event *ev)
+{
+ events_.push_back (ev);
+}
+
+void
+Balloon_engraver::stop_translation_timestep ()
+{
+ events_.clear ();
+}
+
+Balloon_engraver::Balloon_engraver ()
+{
+}
+
+void
+Balloon_engraver::balloonify (Grob *g, Stream_event *event)
+{
+ Grob * b = make_item ("BalloonTextItem", event->self_scm ());
+ b->set_property ("text", event->get_property ("text"));
+ b->set_parent (g, Y_AXIS);
+ b->set_parent (g, X_AXIS);
+}
+
+void
+Balloon_engraver::acknowledge_grob (Grob_info info)
+{
+ Stream_event *cause = info.event_cause ();
+
+ SCM arts = cause ? cause->get_property ("articulations") : SCM_EOL;
+ for (SCM s = arts; scm_is_pair (s); s = scm_cdr (s))
+ {
+ Stream_event *e = unsmob_stream_event (scm_car (s));
+ if (e->in_event_class ("annotate-output-event"))
+ {
+ balloonify (info.grob (), e);
+ }
+ }
+
+ for (vsize i = 0; i < events_.size (); i++)
+ {
+ if (info.grob ()->name () == ly_symbol2string (events_[i]->get_property ("symbol")))
+ balloonify (info.grob (), events_[i]);
+ }
+}
+
+
+
+ADD_ACKNOWLEDGER(Balloon_engraver,grob);
+
+ADD_TRANSLATOR(Balloon_engraver,
+ "Create balloon texts",
+ "BalloonTextItem ",
+ /*read*/ "",
+ /*write*/ ""
+ );
{
Grob *me = unsmob_grob (smob);
- SCM stil = me->get_property ("original-stencil");
- if (!unsmob_stencil (stil))
- return stil;
+ Grob *p = me->get_parent (X_AXIS);
+
+ Offset off(me->relative_coordinate (p, X_AXIS),
+ me->relative_coordinate (p, Y_AXIS));
- SCM scm_off = me->get_property ("balloon-text-offset");
+ Box b (p->extent (p, X_AXIS),
+ p->extent (p, Y_AXIS));
- if (!is_number_pair (scm_off))
- return stil;
-
- Offset off = ly_scm2offset (scm_off);
- Stencil *s = unsmob_stencil (stil);
- Box orig_extent = s->extent_box ();
- Box box_extent = orig_extent;
-
- Real w = robust_scm2double (me->get_property ("balloon-padding"), .1);
- box_extent.widen (w, w);
+ Real padding = robust_scm2double (me->get_property ("padding"), .1);
+ b.widen (padding, padding);
// FIXME
- Stencil fr = Lookup::frame (box_extent, 0.1, 0.05);
-
- fr.add_stencil (*s);
+ Stencil fr = Lookup::frame (b, 0.1, 0.05);
- SCM bt = me->get_property ("balloon-text");
+ SCM bt = me->get_property ("text");
SCM chain = Font_interface::text_font_alist_chain (me);
- chain = scm_cons (me->get_property ("balloon-text-props"), chain);
- SCM text = Text_interface::interpret_markup (me->layout ()->self_scm (),
+ SCM stencil = Text_interface::interpret_markup (me->layout ()->self_scm (),
chain, bt);
- Stencil *text_stil = unsmob_stencil (text);
+ Stencil *text_stil = unsmob_stencil (stencil);
Offset z1;
for (int i = X_AXIS; i < NO_AXES; i++)
{
Axis a ((Axis)i);
- z1[a] = box_extent [a].linear_combination (sign (off[a]));
+ z1[a] = b[a].linear_combination (sign (off[a]));
text_stil->align_to (a, -sign (off[a]));
}
text_stil->translate (z2);
fr.add_stencil (*text_stil);
- fr = Stencil (orig_extent, fr.expr ());
+ fr.translate (-off);
return fr.smobbed_copy ();
}
"A collection of routines to put text balloons around an object.",
/* properties */
- "balloon-padding "
- "balloon-text-props "
- "balloon-text-offset "
- "balloon-text "
- "original-stencil ");
+ "padding "
+ "text "
+ );
ADD_TRANSLATOR (Chord_name_engraver,
/* doc */ "Catch note-events "
"and generate the appropriate chordname.",
+
/* create */ "ChordName",
- /* read */ "chordChanges chordNameExceptions chordNameFunction "
- "chordNoteNamer chordRootNamer chordNameExceptions majorSevenSymbol",
+ /* read */ "chordChanges "
+ "chordNameExceptions "
+ "chordNameFunction "
+ "chordNoteNamer "
+ "chordRootNamer "
+ "chordNameExceptions "
+ "majorSevenSymbol "
+ ,
/* write */ "");
"alignments. The symbols are collected onto a DynamicLineSpanner grob\n"
"which takes care of vertical positioning. ",
- /* create */ "DynamicLineSpanner DynamicText Hairpin TextSpanner",
+ /* create */
+ "DynamicLineSpanner "
+ "DynamicText "
+ "Hairpin "
+ "TextSpanner ",
+
/* read */ "",
/* write */ "");
#include "stem.hh"
#include "stream-event.hh"
#include "text-interface.hh"
+#include "rhythmic-head.hh"
/*
Note_head::brew_ez_stencil (SCM smob)
{
Grob *me = unsmob_grob (smob);
- int log = Note_head::get_balltype (me);
+ int log = Rhythmic_head::duration_log (me);
SCM cause = me->get_property ("cause");
SCM spitch = unsmob_stream_event (cause)->get_property ("pitch");
int first_page_number_;
vsize page_count_;
- Real force_;
- Real penalty_;
-
- Real line_force_;
- Real line_penalty_;
-
/* true if every score here is too widely spaced */
bool too_many_lines_;
Break_node ()
{
prev_ = break_pos_ = VPOS;
- penalty_ = force_ = 0;
- line_penalty_ = line_force_ = 0;
demerits_ = infinity_f;
first_page_number_ = 0;
page_count_ = 0;
SCM make_lines (vector<Break_node> *breaks);
SCM make_pages (vector<Break_node> const &breaks, SCM systems);
- Real calc_demerits (Break_node const &me);
void calc_subproblem (vsize i);
};
#endif /* PAGE_TURN_PAGE_BREAKING_HH */
{
if (source_file_)
s = location_string () + ": " + s + "\n"
- + source_file_->quote_input (start_);
+ + source_file_->quote_input (start_) + "\n";
::message (s);
}
{
if (dynamic_cast<Spanner *> (info.grob ())
&& Axis_group_interface::has_axis (info.grob (), Y_AXIS)
+
+ /* ugh. */
+
+ && !info.grob ()->internal_has_interface (ly_symbol2scm ("dynamic-interface"))
+ && !info.grob ()->internal_has_interface (ly_symbol2scm ("piano-pedal-interface"))
&& (!Align_interface::has_interface (info.grob ())))
{
axis_groups_.push_back (info.grob ());
{
Grob_info info = primitives[i];
Item *primitive = dynamic_cast<Item *> (info.grob ());
- int duration_log = Note_head::get_balltype (primitive);
+ int duration_log = Rhythmic_head::duration_log (primitive);
Stream_event *nr = info.event_cause ();
nd->get_property ("style")))
merge_possible = false;
- int upball_type = Note_head::get_balltype (nu);
- int dnball_type = Note_head::get_balltype (nd);
+ int upball_type = Rhythmic_head::duration_log (nu);
+ int dnball_type = Rhythmic_head::duration_log (nd);
/* Do not merge whole notes (or longer, like breve, longa, maxima). */
if (merge_possible && (upball_type <= 0 || dnball_type <= 0))
#include <cmath>
#include <cctype>
#include <algorithm> // min, max
+
using namespace std;
#include "directional-element-interface.hh"
-#include "dots.hh"
#include "font-interface.hh"
#include "international.hh"
-#include "lookup.hh"
-#include "misc.hh"
-#include "music.hh"
-#include "output-def.hh"
-#include "rhythmic-head.hh"
-#include "staff-symbol-referencer.hh"
-#include "staff-symbol.hh"
#include "warn.hh"
static Stencil
return ly_offset2scm (get_stem_attachment (fm, key));
}
-int
-Note_head::get_balltype (Grob *me)
-{
- SCM s = me->get_property ("duration-log");
- return scm_is_number (s) ? min (int (scm_to_int (s)), 2) : 0;
-}
ADD_INTERFACE (Note_head, "note-head-interface",
"Note head",
ret.demerits_ = ret.force_[0] * ret.force_[0] * page_weighting;
for (vsize i = 1; i < ret.force_.size (); i++)
- {
- Real uniformity = fabs (ret.force_[i] - ret.force_[i-1]);
- ret.demerits_ += (ret.force_[i] * ret.force_[i]
- + uniformity * uniformity) * page_weighting;
- }
+ ret.demerits_ += ret.force_[i] * ret.force_[i] * page_weighting;
/* for a while we tried averaging page and line forces instead of summing
them, but it caused the following problem. If there is a single page
{
}
-Real
-Page_turn_page_breaking::calc_demerits (const Break_node &me)
-{
- Real prev_f = 0;
- Real prev_dem = 0;
- Real page_weighting = robust_scm2double (book_->paper_->c_variable ("page-spacing-weight"), 10);
- if (me.prev_ != VPOS)
- {
- prev_f = state_[me.prev_].force_;
- prev_dem = state_[me.prev_].demerits_;
- }
-
- Real dem = me.force_ * me.force_ * page_weighting
- + me.line_force_ * me.line_force_
- + fabs (me.force_ - prev_f);
- if (isinf (me.line_force_) || isinf (me.force_) || me.page_count_ == 0)
- dem = infinity_f;
-
- return dem + prev_dem + me.penalty_ + me.line_penalty_;
-}
-
Page_turn_page_breaking::Break_node
Page_turn_page_breaking::put_systems_on_pages (vsize start,
vsize end,
Real page_h = page_height (1, false); // FIXME
SCM force_sym = last ? ly_symbol2scm ("blank-last-page-force") : ly_symbol2scm ("blank-page-force");
Real blank_force = robust_scm2double (book_->paper_->lookup_variable (force_sym), 0);
+ Real page_weighting = robust_scm2double (book_->paper_->c_variable ("page-spacing-weight"), 10);
int min_p_count = min_page_count (lines, page_h, ragged_all, ragged_last);
bool auto_first = to_boolean (book_->paper_->c_variable ("auto-first-page-number"));
ret.first_page_number_ = page_number;
if (auto_first && start == 0)
ret.first_page_number_ += 1 - (ret.page_count_ % 2);
- ret.force_ = 0;
- for (vsize i = 0; i < result.force_.size (); i++)
- ret.force_ += fabs (result.force_[i]);
- ret.penalty_ = result.penalty_;
ret.div_ = div;
ret.system_count_ = result.systems_per_page_;
ret.too_many_lines_ = true;
- ret.line_force_ = 0;
- ret.line_penalty_ = 0;
+ ret.demerits_ = result.penalty_;
+ if (start > 0)
+ ret.demerits_ += state_[start-1].demerits_;
for (vsize i = 0; i < lines.size (); i++)
{
- ret.line_force_ += fabs (lines[i].force_);
- ret.line_penalty_ += lines[i].break_penalty_;
+ ret.demerits_ += lines[i].force_ * lines[i].force_;
+ ret.demerits_ += lines[i].break_penalty_;
if (lines[i].force_ < 0)
ret.too_many_lines_ = false;
}
+ for (vsize i = 0; i < result.force_.size (); i++)
+ ret.demerits_ += result.force_[i] * result.force_[i] * page_weighting;
return ret;
}
vector<Line_details> line = line_details (start, end, div[d]);
cur = put_systems_on_pages (start, end, line, div[d], p_num);
- cur.demerits_ = calc_demerits (cur);
if (isinf (cur.demerits_)
|| (cur.page_count_ > 2
system_->element_count (),
system_->spanner_count ()));
- message (_ ("Preprocessing graphical objects...") + " ");
+ message (_ ("Preprocessing graphical objects..."));
/* FIXME: Check out why we need this - removing gives assertion failures
down the road.
return SCM_UNDEFINED;
}
-/*
- Do some magical incantations: if not, lily will exit on the first
- GUILE error, leaving no location trace.
-*/
-
-#if GUILE_MINOR_VERSION < 7
-#define READ_ERROR "misc-error"
-#else
-#define READ_ERROR "read-error"
-#endif
-
SCM
protected_ly_parse_scm (Parse_start *ps)
{
- return scm_internal_catch (ly_symbol2scm (READ_ERROR),
+ /*
+ Catch #t : catch all Scheme level errors.
+ */
+ return scm_internal_catch (SCM_BOOL_T,
&catch_protected_parse_body,
(void *) ps,
&parse_handler, (void *) ps);
dir = UP;
set_grob_direction (me, dir);
}
-
+
+ bool is_harmonic_centered = false;
+ for (vsize i = 0; i < heads.size (); i++)
+ is_harmonic_centered = is_harmonic_centered
+ || heads[i]->get_property ("style") == ly_symbol2scm ("harmonic");
+ is_harmonic_centered = is_harmonic_centered && is_invisible (me);
+
Real w = hed->extent (hed, X_AXIS)[dir];
for (vsize i = 0; i < heads.size (); i++)
- heads[i]->translate_axis (w - heads[i]->extent (heads[i], X_AXIS)[dir],
- X_AXIS);
+ {
+ Real amount = w - heads[i]->extent (heads[i], X_AXIS)[dir];
+ if (is_harmonic_centered)
+ amount =
+ hed->extent (hed, X_AXIS).linear_combination (CENTER)
+ - heads[i]->extent (heads[i], X_AXIS).linear_combination (CENTER);
+
+ heads[i]->translate_axis (amount, X_AXIS);
+ }
bool parity = true;
Real lastpos = Real (Staff_symbol_referencer::get_position (heads[0]));
for (vsize i = 1; i < heads.size (); i++)
'origin location
'procedure proc))
+
+balloonText =
+#(define-music-function (parser location offset text) (number-pair? markup?)
+
+ (make-music 'AnnotateOutputEvent
+ 'X-offset (car offset)
+ 'Y-offset (cdr offset)
+ 'text text))
+
+balloonGrobText =
+#(define-music-function (parser location grob-name offset text) (symbol? number-pair? markup?)
+
+ (make-music 'AnnotateOutputEvent
+ 'symbol grob-name
+ 'X-offset (car offset)
+ 'Y-offset (cdr offset)
+ 'text text))
+
bar =
#(define-music-function (parser location type)
(string?)
(StreamEvent .
(RemoveContext ChangeParent Override Revert UnsetProperty
SetProperty music-event OldMusicEvent CreateContext Prepare
- OneTimeStep Finish))
- (music-event . (arpeggio-event breathing-event extender-event span-event
+ OneTimeStep Finish))
+ (music-event . (annotate-output-event
+ arpeggio-event breathing-event extender-event span-event
rhythmic-event dynamic-event break-event percent-event
key-change-event string-number-event stroke-finger-event tie-event part-combine-event
beam-forbid-event script-event
tremolo-event bend-after-event fingering-event glissando-event
harmonic-event hyphen-event laissez-vibrer-event mark-event
- multi-measure-text-event note-grouping-event
+ multi-measure-text-event note-grouping-event
pes-or-flexa-event repeat-tie-event spacing-section-event
layout-instruction-event))
- (layout-instruction-event . (apply-output-event))
+
+ (layout-instruction-event . (apply-output-event ))
(script-event . (articulation-event text-script-event))
(part-combine-event . (solo-one-event solo-two-event unisono-event))
(break-event . (line-break-event page-break-event page-turn-event))
(alteration-alist ,list? "List of @code{(@var{pitch}
. @var{accidental})} pairs for key signature.")
(add-stem-support ,boolean? "If set, the Stem object is included in this script's support")
-
(align-dir ,ly:dir? "Which side to align? @code{-1}: left side,
@code{0}: around center of width, @code{1}: right side.")
(allow-loose-spacing ,boolean? "If set, column can be detached from main spacing.")
(arpeggio-direction ,ly:dir? "If set, put an
arrow on the arpeggio squiggly line.")
-
-
(arrow ,boolean? "Add an arrow to the line.")
(arrow-length ,number? "Arrow length.")
(arrow-width ,number? "Arrow width.")
-
(auto-knee-gap ,ly:dimension? "If a gap is found between note heads
where a horizontal beam fits that is larger than this number, make a kneed beam.")
(average-spacing-wishes ,boolean? "If set, the spacing wishes are averaged over staves.")
+ (avoid-note-head ,boolean? "If set, the stem of a chord does not
+pass through all note heads, but starts at the last note head. ")
(axes ,list? "list of axis numbers.
In the case of alignment grobs, this should contain only one number.")
-
- (balloon-text ,markup? "Text to add to help balloon")
- (balloon-text-props ,list? "Font properties
-for balloon text.")
- (balloon-text-offset ,number-pair?
- "Where to put text relative to balloon.")
- (balloon-padding ,ly:dimension? "Text to add to help balloon")
- (original-stencil ,ly:stencil? "The
-original stencil drawer to draw the balloon around.")
-
-
(bar-size ,ly:dimension? "size of a bar line.")
(barre-type ,symbol? "Type of barre indication used in a fret diagram.
Choices include @code{curved} and @code{straight}.")
beams to make. 0 is the central beam, 1 is the next beam toward the
note etc. This information is used to determine how to connect the
beaming patterns from stem to stem inside a beam.")
-
-
(before-line-breaking ,boolean? "Dummy property, used to trigger a callback function.")
(between-cols ,pair? "Where to attach a loose column to")
(bound-padding ,number? "The amount of padding to insert around spanner bounds.")
tuplet bracket.")
(break-visibility ,vector? "A vector of 3 booleans, #(end-of-line unbroken begin-of-line).
#t means visible, #f means killed.")
-
(c0-position ,integer? "An integer indicating the position of
middle C.")
(cautionary-style ,symbol? "How to print cautionary
measure of the closeness of the inner stems. It is used for damping
the slope of the beam.")
(collapse-height ,ly:dimension? "Minimum height of system start delimiter. If equal or smaller, the bracket is removed.")
-
(color ,color? "The color of this grob.")
-
(control-points ,list? "List of offsets (number-pairs) that form
control points for the tie/slur/bracket shape. For beziers, this
should list the control points of a 3rd order bezier curve." )
-
(connect-to-neighbor ,pair? "Pair of booleans, indicating whether this
grob looks as a continued break.")
(damping ,number? "Amount of beam slope damping. ")
(dash-period ,number? "the length of one dash + white space. If
negative, no line is drawn at all.")
-
(dash-fraction ,number? "Size of the dashes, relative to
dash-period. Should be between 0.0 (no line) and 1.0 (continuous
line).")
-
(default-direction ,ly:dir? "Direction determined by note head positions.")
(digit-names ,vector "Names for string finger digits. ")
(direction ,ly:dir? "If side-position is 1 (#X), then this property determines if the object is placed #LEFT, #CENTER or #RIGHT with respect to the other object. Otherwise, it determines if the object is placed #UP #CENTER or #DOWN. Numerical values may also be used. #UP=1, #DOWN=-1, #LEFT=-1, #RIGHT=1, CENTER=0 but also other numerical values are permitted.")
-
(dot-color ,symbol? "Color of dots. Options include
@code{black} and @code{white}.")
(dot-radius ,number? "Radius of dots.")
(edge-text ,pair? "A pair specifying the texts to be set at the
edges '(@var{left-text} . @var{right-text}).")
(eccentricity ,number? "How asymmetrical to make a slur. Positive means move the center to the right.")
-
(enclose-bounds ,number?
"How much of the bound a spanner should enclose:
+1 = completely, 0 = center, -1 not at all.")
-
(expand-limit ,integer? "maximum number of measures expanded in church rests.")
-
;; remove me?
(extra-X-extent ,number-pair? "A grob is enlarged in X dimension
by this much.")
(extra-Y-extent ,number-pair? "See @code{extra-X-extent}.")
-
(X-extent ,number-pair? "Hard coded extent in X direction. ")
(Y-extent ,number-pair? "See @code{X-extent}.")
-
(extra-offset ,number-pair? "A pair representing an offset. This
offset is added just before outputting the symbol, so the typesetting
engine is completely oblivious to it.")
-
(finger-code ,symbol? "Code for the type of fingering indication in a
fret diagram. Options include @code{none}, @code{in-dot}, and @code{below-string}.")
(flag-count ,number? "The number of tremolo beams.")
typeset on a Stem. Valid options include @code{()} and
@code{mensural}. Additionally, @code{\"no-flag\"} switches off the
flag.")
-
(font-family ,symbol? "The font family is the broadest category for selecting text fonts. Options include: @code{sans}, @code{roman} ")
(font-encoding ,symbol? "The font encoding is the broadest
category for selecting a font. Options include: @code{fetaMusic},
@code{font-family}, @code{font-series} and @code{font-shape}.")
(font-magnification ,number? "Magnification of the font, when it
is selected with @code{font-name}.")
-
(font-size ,number? "The font size, compared the `normal'
size. 0 is style-sheet's normal size, -1 is smaller, +1 is bigger.
Each step of 1 is approximately 12% larger, 6 steps are exactly a
factor 2 larger. Fractional values are allowed.")
-
(font-series ,symbol? "Select the series of a font. Choices
include @code{medium}, @code{bold}, @code{bold-narrow}, etc.")
(font-shape ,symbol? "Select the shape of a font. Choices include @code{upright},
@code{italic}, @code{caps}.")
-
(forced ,boolean? "manually forced accidental")
(forced-distance ,ly:dimension? "A fixed distance between object
reference points in an alignment.")
-
(force-hshift ,number? "This specifies a manual shift for notes
in collisions. The unit is the note head width of the first voice
note. This is used by @internalsref{note-collision-interface}.")
-
(fraction ,number-pair? "Numerator and denominator of a time
signature object.")
(french-beaming ,boolean? "Use French beaming style for this
stem. The stem will stop at the innermost beams.")
(fret-count ,integer? "The number of frets in a fret diagram.")
-
;; ugh: double, change.
(full-size-change ,boolean? "Don't make a change clef smaller.")
(non-default ,boolean? "Set for manually specified clefs.")
-
-
(glyph ,string? "a string determining what (style) of glyph is
typeset. Valid choices depend on the function that is reading this
property.")
(height ,ly:dimension? "Height of an object in staff-space.")
(height-limit ,ly:dimension? "Maximum slur height: the longer the
slur, the closer it is to this height.")
-
(horizontal-shift ,integer? "An integer that identifies ranking
of note-column for horizontal shifting. This is used by
@internalsref{note-collision-interface}.")
unbeamed stems.")
(length-fraction ,number? "Multiplier for lengths. Used for
determining ledger lines and stem lengths.")
-
(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.")
(line-positions ,list? "Vertical positions of staff lines.")
(line-thickness ,number? "The thickness of the tie/slur contour.")
to beams from this stem. Further beams are typeset as beamlets.")
(measure-length ,ly:moment? "Length of a
measure. Used in some spacing situations.")
-
(measure-count ,integer? "The number of measures for a
multimeasure rest.")
(merge-differently-headed ,boolean? "Merge
smaller of the two heads will be rendered invisible. This used
polyphonic guitar notation. The value of this setting is used by
@internalsref{note-collision-interface} .")
-
(merge-differently-dotted ,boolean? "Merge note heads in
collisions, even if they have a different number of dots. This normal
notation for some types of polyphonic music. ")
-
(minimum-length-fraction ,number? "Minimum length of ledger line as fraction of note head size.")
(minimum-distance ,ly:dimension? "Minimum distance between rest
and notes or beam.")
center of the staff.")
(neutral-position ,number? "Position (in half staff spaces) where
to flip the direction of custos stem.")
-
(next ,ly:grob? "Object that is next relation (eg. the lyric syllable following an extender.")
(note-names ,vector? "Vector of strings containing names for
easy-notation note heads.")
staff-space unit of the current staff.")
(ratio ,number? "Parameter for slur shape. The higher this number, the
quicker the slur attains it @code{height-limit}.")
-
(remove-empty ,boolean? "If set, remove group if it contains no
@code{interesting-items}")
(remove-first ,boolean? "Remove the first staff of a orchestral score?")
for stems with the same direction to compensate for note-head to stem distance.")
(script-priority ,number? "A sorting key that determines in what
order a script is within a stack of scripts.")
-
(self-alignment-X ,number? "Specify alignment of an object. The
value -1 means left aligned, 0 centered, and 1 right-aligned in X
direction. Values in between may also be specified.")
(self-alignment-Y ,number? "like @code{self-alignment-X} but for
Y axis.")
-
(shorten-pair ,number-pair? "The lengths to shorten a
text-spanner on both sides, for example a pedal bracket. Positive values
shorten the text-spanner, while negative values lengthen it.")
of spacing tuples: @code{(@var{break-align-symbol} @var{type}
. @var{distance})}, where @var{type} can be the symbols
@code{minimum-space} or @code{extra-space}.")
-
(spacing-increment ,number? "Add this much space for a doubled
duration. Typically, the width of a note head. See also
@internalsref{spacing-spanner-interface}.")
-
(springs-and-rods ,boolean? "Dummy variable for triggering spacing routines.")
(stacking-dir ,ly:dir? "Stack objects in which direction?")
- (staff-space ,ly:dimension? "Amount of space between staff lines,
-expressed in global staff-space.")
+ (staff-padding ,ly:dimension?
+ "Maintain this much space between reference points
+and the staff. Its effect is to align objects of differing
+sizes (like the dynamic @b{p} and @b{f}) on their baselines.")
(staff-position ,number? "Vertical position, measured in half
staff spaces, counted from the middle line.")
-
+ (staff-space ,ly:dimension? "Amount of space between staff lines,
+expressed in global staff-space.")
(stemlet-length ,number? "How long should a stem over a rest be?")
(stem-attachment ,number-pair? "A (@var{x} . @var{y}) pair where the stem attaches to the notehead.")
-
(stem-end-position ,number? "Where does the stem end (the end is opposite to the support-head.")
-
;;[TODO: doco]
(stem-spacing-correction ,number? "Optical correction amount for
stems that are placed in tight configurations. For opposite
directions, this amount is the correction for two normal sized stems
that overlap completely.")
(stencil ,ly:stencil? "The symbol to print.")
-
(strict-note-spacing ,boolean? "If set, unbroken columns
with non-musical material (clefs, barlines, etc.) are not spaced
separately, but put before musical columns.")
(string-count ,integer? "The number of strings in a fret diagram.")
(string-fret-finger-combinations ,list? "List consisting of (string-number fret-number finger-number) entries.")
(stroke-style ,string? "set to \"grace\" to turn stroke through flag on.")
-
(style ,symbol? "This setting determines in what style a grob is
typeset. Valid choices depend on the @code{stencil} callback reading
this property.")
(thickness ,number? "Line thickness, generally measured in
@code{line-thickness}.")
(thin-kern ,number? "The space after a hair-line in a bar line.")
-
(threshold ,number-pair? "(@var{min} . @var{max}), where
@var{min} and @var{max} are dimensions in staff space.")
(tie-configuration ,list? "List of (@var{position} . @var{dir})
(zigzag-width ,ly:dimension? "The width of one
zigzag-squiggle. This number will be adjusted slightly so that the
glissando line can be constructed from a whole number of squiggles.")
-
- (avoid-note-head ,boolean? "If set, the stem of a chord does not
-pass through all note heads, but starts at the last note head. ")
- (staff-padding ,ly:dimension?
- "Maintain this much space between reference points
-and the staff. Its effect is to align objects of differing
-sizes (like the dynamic @b{p} and @b{f}) on their baselines.")
-
)))
side-position-interface
font-interface))))))
+ (BalloonTextItem
+ . ((stencil . ,ly:balloon-interface::print)
+ (text . ,(grob::calc-property-by-copy 'text))
+ (X-offset . ,(grob::calc-property-by-copy 'X-offset))
+ (Y-offset . ,(grob::calc-property-by-copy 'Y-offset))
+ (meta . ((class . Item)
+ (interfaces . (text-interface
+ font-interface))))))
(BarLine
. (
(break-align-symbol . staff-bar)
(LyricText
. (
(stencil . ,lyric-text::print)
- (text . ,lyric-text::calc-text)
+ (text . ,(grob::calc-property-by-copy 'text))
(X-offset . ,ly:self-alignment-interface::aligned-on-x-parent)
(self-alignment-X . 0)
(word-space . 0.6)
(Rest
. (
(stencil . ,ly:rest::print)
- (duration-log . ,note-head::calc-duration-log)
+ (duration-log . ,stem::calc-duration-log)
(X-extent . ,ly:rest::width)
(Y-extent . ,ly:rest::height)
(Y-offset . ,ly:rest::y-offset-callback)
(Stem
. (
(direction . ,ly:stem::calc-direction)
- (duration-log . ,note-head::calc-duration-log)
+ (duration-log . ,stem::calc-duration-log)
(default-direction . ,ly:stem::calc-default-direction)
(stem-end-position . ,ly:stem::calc-stem-end-position)
. (
(stencil . ,ly:text-interface::print)
(Y-offset . ,ly:staff-symbol-referencer::callback)
- (duration-log . ,note-head::calc-duration-log)
(font-size . -2)
(stem-attachment . (0.0 . 1.35))
(font-series . bold)
(define-markup-command (note-by-number layout props log dot-count dir) (number? number? number?)
"Construct a note symbol, with stem. By using fractional values for
@var{dir}, you can obtain longer or shorter stems."
+
(define (get-glyph-name-candidates dir log style)
(map (lambda (dir-name)
(format "noteheads.~a~a~a" dir-name (min log 2)
(size-factor (magstep (chain-assoc-get 'font-size props 0)))
(style (chain-assoc-get 'style props '()))
(stem-length (* size-factor (max 3 (- log 1))))
- (head-glyph-name (get-glyph-name font (get-glyph-name-candidates dir log style)))
+ (head-glyph-name (get-glyph-name font (get-glyph-name-candidates (sign dir) log style)))
(head-glyph (ly:font-get-glyph font head-glyph-name))
(attach-indices (ly:note-head::stem-attachment font head-glyph-name))
(stem-thickness (* size-factor 0.13))
(stemy (* dir stem-length))
(attach-off (cons (interval-index
(ly:stencil-extent head-glyph X)
- (* dir (car attach-indices)))
- (* dir ; fixme, this is inconsistent between X & Y.
+ (* (sign dir) (car attach-indices)))
+ (* (sign dir) ; fixme, this is inconsistent between X & Y.
(interval-index
(ly:stencil-extent head-glyph Y)
(cdr attach-indices)))))
(stem-glyph (and (> log 0)
(ly:round-filled-box
(ordered-cons (car attach-off)
- (+ (car attach-off) (* (- dir) stem-thickness)))
+ (+ (car attach-off) (* (- (sign dir)) stem-thickness)))
(cons (min stemy (cdr attach-off))
(max stemy (cdr attach-off)))
(/ stem-thickness 3))))
(map
(lambda (x) (apply music-property-description x))
`(
+ (X-offset ,number? "Offset of resulting grob; only used for balloon texts.")
+ (Y-offset ,number? "Offset of resulting grob; only used for balloon texts. ")
+
(alteration ,number? "alteration for figured bass")
(absolute-octave ,integer?
where x is one of \\ppp, \\pp, \\p, \\mp, \\mf, \\f, \\ff, \\fff.")
(types . (general-music event dynamic-event absolute-dynamic-event))
))
+
+ (AnnotateOutputEvent
+ . ((description . "Print an annotation of an output element.")
+ (types . (general-music event annotate-output-event))
+ ))
+
(ApplyContext
. (
(description . "Call the argument with the current context during interpreting phase")
(types . (general-music apply-context))
(iterator-ctor . ,ly:apply-context-iterator::constructor)
))
+
(ApplyOutputEvent
. (
(description . "
(types . (general-music event rhythmic-event bass-figure-event))
))
+
(BeamEvent
. (
(description . "Starts or stops a beam.
(else ;; scheme arg
arg)))
(define (inner-markup->make-markup mrkup)
- (let ((cmd (proc->command-keyword (car mrkup)))
- (args (map transform-arg (cdr mrkup))))
- `(,cmd ,@args)))
+ (if (string? mrkup)
+ `(#:simple ,mrkup)
+ (let ((cmd (proc->command-keyword (car mrkup)))
+ (args (map transform-arg (cdr mrkup))))
+ `(,cmd ,@args))))
;; body:
(if (string? markup-expression)
markup-expression
(music-map apply-duration lyric-music))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-
-(define-public ((add-balloon-text object-name text off) grob orig-context cur-context)
- "Usage: see input/regression/balloon.ly "
- (let* ((meta (ly:grob-property grob 'meta))
- (cb (ly:grob-property-data grob 'stencil))
- (nm (if (pair? meta) (cdr (assoc 'name meta)) "nonexistant")))
- (if (and (equal? nm object-name)
- (procedure? cb))
- (begin
- (ly:grob-set-property! grob 'stencil ly:balloon-interface::print)
- (set! (ly:grob-property grob 'original-stencil) cb)
- (set! (ly:grob-property grob 'balloon-text) text)
- (set! (ly:grob-property grob 'balloon-text-offset) off)
- (set! (ly:grob-property grob 'balloon-text-props) '((font-family . roman)))))))
-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; accidentals
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; note heads
-(define-public (note-head::calc-duration-log grob)
+
+(define-public (stem::calc-duration-log grob)
(ly:duration-log
(ly:event-property (event-cause grob) 'duration)))
+(define-public (note-head::calc-duration-log grob)
+ (min 2
+ (ly:duration-log
+ (ly:event-property (event-cause grob) 'duration))))
+
(define-public (dots::calc-dot-count grob)
(ly:duration-dot-count
(ly:event-property (event-cause grob) 'duration)))
(make-tied-lyric-markup text)
text))))
-(define-public (lyric-text::calc-text grob)
- (ly:event-property (event-cause grob) 'text))
+(define-public ((grob::calc-property-by-copy prop) grob)
+ (ly:event-property (event-cause grob) prop))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; fret boards