configure
gcstat*.scm
lily-[0-9a-f][0-9a-f][0-9a-f]*
+lilypond-issues.csv
lsr-unsafe.txt
nohup.out
out
provided:
@example
-cd $LILYPOND_BUILD_DIR
-../scripts/auxiliar/make-countdown-announcement.sh "Jan 1, 2001" James
+cd $LILYPOND_GIT
+scripts/auxiliar/make-countdown-announcement.sh "Jan 1, 2001" James
@end example
The script produces an announcement that is easily readable in all
--- /dev/null
+\version "2.19.11"
+
+\header {
+ texidoc = "When @code{parent-alignment-X} property is unset,
+the value of @code{self-alignment-X} will be used as the factor
+for parent alignment. This happens e.g. for LyricTexts."
+}
+
+{
+ \time 4/2
+ % use breve noteheads because their refpoints aren't on their
+ % left edges - this may help catching subtle bugs.
+ \override NoteHead.style = #'altdefault
+ <>^"alignments “synchronized”:"
+ f'\breve f' f'
+ <>^"parent-alignment set to ##f:"
+ f' f' f'
+}
+\addlyrics {
+ \override LyricSpace.minimum-distance = 5
+
+ \override LyricText.self-alignment-X = #LEFT
+ left
+ \override LyricText.self-alignment-X = #CENTER
+ center
+ \override LyricText.self-alignment-X = #RIGHT
+ right
+
+ \override LyricText.parent-alignment-X = ##f
+ \override LyricText.self-alignment-X = #LEFT
+ left
+ \override LyricText.self-alignment-X = #CENTER
+ center
+ \override LyricText.self-alignment-X = #RIGHT
+ right
+}
--- /dev/null
+\version "2.19.11"
+
+\header {
+ texidoc = "@code{\\partial} can be can be called in mid-piece in
+multiple contexts."
+}
+
+
+melodyOne = \relative {
+ \time 6/8
+ a'8 a a a a a |
+ \partial 8
+ d8 |
+ c8 c c c c c |
+}
+
+chordsOne = \chordmode {
+ \time 6/8
+ a2. |
+ \partial 8
+ s8 |
+ a2. |
+}
+
+\score {
+ <<
+ \set Score.barNumberVisibility = #all-bar-numbers-visible
+ \override Score.BarNumber.break-visibility = #all-visible
+ \new ChordNames { \chordsOne }
+ \new Staff { \melodyOne }
+ >>
+}
--- /dev/null
+\version "2.19.11"
+
+\header {
+ texidoc = "Grobs using @code{ly:self-alignment-interface::aligned-on-x-parent}
+and @code{ly:self-alignment-interface::aligned-on-y-parent}
+callbacks support separate alignments for self and parent."
+}
+
+{ f'1 f' f' }
+\addlyrics {
+ \override LyricSpace.minimum-distance = 5
+ \override LyricText.self-alignment-X = #LEFT
+ \override LyricText.parent-alignment-X = #LEFT
+ left-left
+ \override LyricText.self-alignment-X = #LEFT
+ \override LyricText.parent-alignment-X = #CENTER
+ left-center
+ \override LyricText.self-alignment-X = #LEFT
+ \override LyricText.parent-alignment-X = #RIGHT
+ left-right
+}
+
+{ f'1 f' f' }
+\addlyrics {
+ \override LyricSpace.minimum-distance = 5
+ \override LyricText.self-alignment-X = #CENTER
+ \override LyricText.parent-alignment-X = #LEFT
+ center-left
+ \override LyricText.self-alignment-X = #CENTER
+ \override LyricText.parent-alignment-X = #CENTER
+ center-center
+ \override LyricText.self-alignment-X = #CENTER
+ \override LyricText.parent-alignment-X = #RIGHT
+ center-right
+}
+
+{ f'1 f' f' }
+\addlyrics {
+ \override LyricSpace.minimum-distance = 5
+ \override LyricText.self-alignment-X = #RIGHT
+ \override LyricText.parent-alignment-X = #LEFT
+ right-left
+ \override LyricText.self-alignment-X = #RIGHT
+ \override LyricText.parent-alignment-X = #CENTER
+ right-center
+ \override LyricText.self-alignment-X = #RIGHT
+ \override LyricText.parent-alignment-X = #RIGHT
+ right-right
+}
*/
SCM val;
- while (trans && trans->where_defined (ly_symbol2scm ("localAlterations"), &val) == trans)
+ while (trans && trans->here_defined (ly_symbol2scm ("localAlterations"), &val))
{
trans->set_property ("localAlterations", ly_deep_copy (last_keysig_));
trans = trans->get_parent_context ();
#include "context.hh"
#include "engraver.hh"
+#include "global-context.hh"
#include "international.hh"
#include "item.hh"
#include "main.hh"
grob_property_path, new_value);
}
+bool
+typecheck_grob (SCM symbol, SCM value)
+{
+ if (is_unpure_pure_container (value))
+ return typecheck_grob (symbol, unpure_pure_container_unpure_part (value))
+ && typecheck_grob (symbol, unpure_pure_container_pure_part (value));
+ return ly_is_procedure (value)
+ || is_simple_closure (value)
+ || type_check_assignment (symbol, value, ly_symbol2scm ("backend-type?"));
+}
+
/*
Grob descriptions (ie. alists with layout properties) are
represented as a (ALIST . BASED-ON) pair, where BASED-ON is the
{
SCM current_context_val = SCM_EOL;
- Context *where = context->where_defined (context_property,
- ¤t_context_val);
+ if (!context->here_defined (context_property, ¤t_context_val))
+ {
+ Context *g = context->get_global_context ();
+ if (!g)
+ return; // Context is probably dead
- /*
- Don't mess with MIDI.
- */
- if (!where)
- return;
+ /*
+ Don't mess with MIDI.
+ */
+ if (g == context
+ || !g->here_defined (context_property, ¤t_context_val))
+ return;
- if (where != context)
- {
- SCM base = updated_grob_properties (context, context_property);
+ /* where != context */
+
+ SCM base = updated_grob_properties (context->get_parent_context (),
+ context_property);
current_context_val = scm_cons (base, base);
context->set_property (context_property, current_context_val);
}
*/
target_alist = scm_acons (symbol, new_value, target_alist);
- bool ok = true;
- bool pc = is_unpure_pure_container (new_value);
- SCM vals[] = {pc ? unpure_pure_container_unpure_part (new_value) : new_value,
- pc ? unpure_pure_container_pure_part (new_value) : SCM_BOOL_F
- };
-
- for (int i = 0; i < 2; i++)
- if (!ly_is_procedure (vals[i])
- && !is_simple_closure (vals[i]))
- ok = ok && type_check_assignment (symbol, vals[i],
- ly_symbol2scm ("backend-type?"));
/*
tack onto alist. We can use set_car, since
updated_grob_properties () in child contexts will check
for changes in the car.
*/
- if (ok)
+ if (typecheck_grob (symbol, new_value))
{
scm_set_car_x (current_context_val, target_alist);
}
SCM grob_property_path)
{
SCM current_context_val = SCM_EOL;
- if (context->where_defined (context_property, ¤t_context_val)
- == context)
+ if (context->here_defined (context_property, ¤t_context_val))
{
SCM current_alist = scm_car (current_context_val);
SCM daddy = scm_cdr (current_context_val);
return (daddy_context_) ? daddy_context_->where_defined (sym, value) : 0;
}
+/* Quick variant of where_defined. Checks only the context itself. */
+
+bool
+Context::here_defined (SCM sym, SCM *value) const
+{
+#ifndef NDEBUG
+ if (profile_property_accesses)
+ note_property_access (&context_property_lookup_table, sym);
+#endif
+
+ return properties_dict ()->try_retrieve (sym, value);
+}
+
/*
return SCM_EOL when not found.
*/
SCM internal_get_property (SCM name_sym) const;
SCM properties_as_alist () const;
Context *where_defined (SCM name_sym, SCM *value) const;
+ bool here_defined (SCM name_sym, SCM *value) const;
void unset_property (SCM var_sym);
void instrumented_set_property (SCM, SCM, const char *, int, const char *);
*/
#include "context.hh"
+#include "global-context.hh"
#include "input.hh"
#include "international.hh"
#include "moment.hh"
{
public:
DECLARE_SCHEME_CALLBACK (constructor, ());
+ DECLARE_SCHEME_CALLBACK (finalization, (SCM, SCM));
protected:
virtual void process (Moment);
};
if (Duration * dur
= Duration::unsmob (get_music ()->get_property ("duration")))
{
- // Partial_iterator is an iterator rather than an engraver, so
- // the active context it is getting called in does not depend on
- // which context definition the engraver might be defined.
- //
- // Using where_defined to find the context where measurePosition
- // should be overwritten does not actually work since the
- // Timing_translator does not set measurePosition when
- // initializing.
-
- Context *timing = Context::unsmob (scm_call_2 (ly_lily_module_constant ("ly:context-find"),
- get_outlet ()->self_scm (),
- ly_symbol2scm ("Timing")));
-
- if (!timing)
- programming_error ("missing Timing in \\partial");
+ Moment length = Moment (dur->get_length ());
+ if (get_outlet ()->now_mom () > 0)
+ {
+ Global_context *tg = get_outlet ()->get_global_context ();
+ tg->add_finalization (scm_list_3 (finalization_proc,
+ get_outlet ()->self_scm (),
+ length.smobbed_copy ()));
+ }
else
{
- Moment mp = robust_scm2moment (timing->get_property ("measurePosition"),
- Rational (0));
+ // Partial_iterator is an iterator rather than an engraver,
+ // so the active context it is getting called in does not
+ // depend on which context definition the engraver might be
+ // defined.
+ //
+ // Using where_defined to find the context where
+ // measurePosition should be overwritten does not actually
+ // work since the Timing_translator does not set
+ // measurePosition when initializing.
- if (get_outlet ()->now_mom () > 0)
- mp.main_part_ = measure_length (timing);
+ Context *timing = Context::unsmob
+ (scm_call_2 (ly_lily_module_constant ("ly:context-find"),
+ get_outlet ()->self_scm (),
+ ly_symbol2scm ("Timing")));
+ if (!timing)
+ programming_error ("missing Timing in \\partial");
else
- mp.main_part_ = 0;
-
- Moment length = Moment (dur->get_length ());
- timing->set_property ("measurePosition", (mp - length).smobbed_copy ());
+ {
+ Moment mp = robust_scm2moment
+ (timing->get_property ("measurePosition"),
+ Rational (0));
+ mp.main_part_ = 0;
+ timing->set_property
+ ("measurePosition", (mp - length).smobbed_copy ());
+ }
}
}
else
}
IMPLEMENT_CTOR_CALLBACK (Partial_iterator);
+
+MAKE_SCHEME_CALLBACK (Partial_iterator, finalization, 2);
+SCM
+Partial_iterator::finalization (SCM ctx, SCM length)
+{
+ LY_ASSERT_SMOB (Context, ctx, 1);
+ LY_ASSERT_SMOB (Moment, length, 2);
+ Context *timing = Context::unsmob
+ (scm_call_2 (ly_lily_module_constant ("ly:context-find"),
+ ctx,
+ ly_symbol2scm ("Timing")));
+ if (!timing) {
+ programming_error ("missing Timing in \\partial");
+ return SCM_UNSPECIFIED;
+ }
+ Moment mp = robust_scm2moment (timing->get_property ("measurePosition"),
+ Rational (0));
+ mp.main_part_ = measure_length (timing);
+ timing->set_property ("measurePosition",
+ (mp - *Moment::unsmob (length)).smobbed_copy ());
+ return SCM_UNSPECIFIED;
+}
bool once = to_boolean (m->get_property ("once"));
SCM symbol = m->get_property ("symbol");
SCM previous_value = SCM_UNDEFINED;
- if (once) {
- Context *w = o->where_defined (symbol, &previous_value);
- if (o != w)
- previous_value = SCM_UNDEFINED;
- }
+ if (once)
+ o->here_defined (symbol, &previous_value);
+
send_stream_event (o, "SetProperty", m->origin (),
ly_symbol2scm ("symbol"), symbol,
ly_symbol2scm ("value"), m->get_property ("value"));
bool once = to_boolean (m->get_property ("once"));
SCM symbol = m->get_property ("symbol");
SCM previous_value = SCM_UNDEFINED;
- if (once) {
- Context *w = o->where_defined (symbol, &previous_value);
- if (o != w)
- previous_value = SCM_UNDEFINED;
- }
+ if (once)
+ o->here_defined (symbol, &previous_value);
+
send_stream_event (o, "UnsetProperty", m->origin (),
ly_symbol2scm ("symbol"), symbol);
if (!score_def)
return SCM_BOOL_F;
- score_def = scale_output_def (score_def, output_scale (od));
+ /* Don't rescale if the layout has already been scaled */
+ if (to_boolean (score_def->c_variable ("cloned")))
+ score_def = score_def->clone ();
+ else
+ score_def = scale_output_def (score_def, output_scale (od));
+
score_def->parent_ = od;
SCM context = ly_run_translator (sc->get_music (), score_def->unprotect ());
he = him->extent (him, a);
}
- SCM sym = (a == X_AXIS) ? ly_symbol2scm ("self-alignment-X")
- : ly_symbol2scm ("self-alignment-Y");
- SCM align_prop (me->internal_get_property (sym));
+ SCM self_align = (a == X_AXIS)
+ ? me->internal_get_property (ly_symbol2scm ("self-alignment-X"))
+ : me->internal_get_property (ly_symbol2scm ("self-alignment-Y"));
- if (!scm_is_number (align_prop))
- return scm_from_int (0);
+ SCM par_align = (a == X_AXIS)
+ ? me->internal_get_property (ly_symbol2scm ("parent-alignment-X"))
+ : me->internal_get_property (ly_symbol2scm ("parent-alignment-Y"));
- Real x = 0.0;
- Real align = scm_to_double (align_prop);
+ if (par_align == SCM_EOL)
+ par_align = self_align;
+ Real x = 0.0;
Interval ext (me->extent (me, a));
- // Empty extent doesn't mean an error - we simply don't align such grobs.
- // However, empty extent and non-empty stencil would be suspicious.
- if (!ext.is_empty ())
- x -= ext.linear_combination (align);
- else if (me->get_stencil ())
- warning (me->name () + " has empty extent and non-empty stencil.");
+ if (scm_is_number (self_align))
+ {
+ // Empty extent doesn't mean an error - we simply don't align such grobs.
+ // However, empty extent and non-empty stencil would be suspicious.
+ if (!ext.is_empty ())
+ x -= ext.linear_combination (scm_to_double (self_align));
+ else if (me->get_stencil ())
+ warning (me->name () + " has empty extent and non-empty stencil.");
+ }
- // See comment above.
- if (!he.is_empty ())
- x += he.linear_combination (align);
- else if (him->get_stencil ())
- warning (him->name () + " has empty extent and non-empty stencil.");
+ if (scm_is_number (par_align))
+ {
+ // See comment above.
+ if (!he.is_empty ())
+ x += he.linear_combination (scm_to_double (par_align));
+ else if (him->get_stencil ())
+ warning (him->name () + " has empty extent and non-empty stencil.");
+ }
return scm_from_double (x);
}
"@end table\n",
/* properties */
+ "parent-alignment-X "
+ "parent-alignment-Y "
"self-alignment-X "
"self-alignment-Y "
"X-align-on-main-noteheads "
(page-turn-permission ,symbol? "Instructs the page breaker on
whether to put a page turn at this column. Can be @code{force} or
@code{allow}.")
+ (parent-alignment-X ,number? "Specify on which point
+of the parent the object is aligned. The value @w{@code{-1}} means
+aligned on parent's left edge, @code{0}@tie{}on@tie{}center, and
+@code{1}@tie{}right edge, in X@tie{}direction. Other numerical
+values may also be specified - the unit is half the parent's width.
+If unset, the value from @code{self-alignment-X} property will be
+used.")
+ (parent-alignment-Y ,number? "Like @code{parent-alignment-X}
+but for the Y@tie{}axis.")
(parenthesized ,boolean? "Parenthesize this grob.")
(positions ,number-pair? "Pair of staff coordinates
@code{(@var{left} . @var{right})}, where both @var{left} and
(self-alignment-X ,number? "Specify alignment of an object. The
value @w{@code{-1}} means left aligned, @code{0}@tie{}centered, and
@code{1}@tie{}right-aligned in X@tie{}direction. Other numerical
-values may also be specified.")
+values may also be specified - the unit is half the object width.")
(self-alignment-Y ,number? "Like @code{self-alignment-X} but for
the Y@tie{}axis.")
(sharp-positions ,list? "Sharps in key signatures are placed
(font-size . -2)
(glyph-name-alist . ,standard-alteration-glyph-name-alist)
(outside-staff-priority . 0)
+ (parent-alignment-X . ,CENTER)
(script-priority . 0)
(self-alignment-X . ,CENTER)
(side-axis . ,Y)
X 'color))
(font-shape . italic)
(font-size . -4)
+ (parent-alignment-X . ,CENTER)
(self-alignment-X . ,CENTER)
(staff-padding . 0.7)
(stencil . ,ly:text-interface::print)
(font-series . bold)
(outside-staff-priority . 450)
(padding . 0.5)
+ (parent-alignment-X . #f)
(script-priority . 200)
(self-alignment-X . #f)
(side-axis . ,Y)
(font-encoding . fetaText)
(font-size . -2)
(padding . 0.2)
+ (parent-alignment-X . ,CENTER)
(self-alignment-X . ,CENTER)
(side-axis . ,Y)
(staff-padding . 0.25)
(font-encoding . fetaText)
(font-series . bold)
(font-shape . italic)
+ (parent-alignment-X . ,CENTER)
(positioning-done . ,ly:script-interface::calc-positioning-done)
(right-padding . 0.5)
(self-alignment-X . ,CENTER)
(font-encoding . fetaText)
(font-size . -5) ; don't overlap when next to heads.
(padding . 0.5)
+ (parent-alignment-X . ,CENTER)
+ (parent-alignment-Y . ,CENTER)
(positioning-done . ,ly:script-interface::calc-positioning-done)
(script-priority . 100)
(self-alignment-X . ,CENTER)
(GridLine
. (
(layer . 0)
+ (parent-alignment-X . ,CENTER)
(self-alignment-X . ,CENTER)
(stencil . ,ly:grid-line-interface::print)
(X-extent . ,ly:grid-line-interface::width)
(extra-spacing-height . (0.2 . -0.2))
(font-series . medium)
(font-size . 1.0)
+ (parent-alignment-X . ())
(self-alignment-X . ,CENTER)
(stencil . ,lyric-text::print)
(text . ,(grob::calc-property-by-copy 'text))
(direction . ,UP)
(font-encoding . fetaText)
(padding . 0.4)
+ (parent-alignment-X . ,CENTER)
(self-alignment-X . ,CENTER)
(side-axis . ,Y)
(springs-and-rods . ,ly:multi-measure-rest::set-text-rods)
(direction . ,UP)
(outside-staff-priority . 450)
(padding . 0.2)
+ (parent-alignment-X . ,CENTER)
(self-alignment-X . ,CENTER)
(skyline-horizontal-padding . 0.2)
(staff-padding . 0.25)
(font-encoding . fetaText)
(font-size . -2)
(padding . 0.2)
+ (parent-alignment-X . ,CENTER)
(self-alignment-X . ,CENTER)
(staff-padding . 0.25)
(stencil . ,ly:text-interface::print)
(beam-thickness . 0.48) ; staff-space
(beam-width . ,ly:stem-tremolo::calc-width) ; staff-space
(direction . ,ly:stem-tremolo::calc-direction)
+ (parent-alignment-X . ,CENTER)
(slope . ,ly:stem-tremolo::calc-slope)
(stencil . ,ly:stem-tremolo::print)
(style . ,ly:stem-tremolo::calc-style)
(font-encoding . fetaText)
(font-size . -5) ; don't overlap when next to heads.
(padding . 0.5)
+ (parent-alignment-X . ,CENTER)
(script-priority . 100)
(self-alignment-X . ,CENTER)
(self-alignment-Y . ,CENTER)
(font-shape . italic)
(font-size . -4) ; don't overlap when next to heads.
(padding . 0.5)
+ (parent-alignment-X . ,CENTER)
(script-priority . 100)
(self-alignment-X . ,CENTER)
(self-alignment-Y . ,CENTER)
;; sync with Fingering ?
(padding . 0.3)
+ (parent-alignment-X . #f)
(script-priority . 200)
;; self-alignment cannot be LEFT because of fingering diagrams.
(self-alignment-X . #f)
@code{\\fermata} articulation instead of a markup.
@lilypond[verbatim,quote]
- { c1^\\markup \\fermata d1_\\markup \\fermata }
+ { c''1^\\markup \\fermata d''1_\\markup \\fermata }
\\markup { \\fermata \\override #`(direction . ,DOWN) \\fermata }
@end lilypond
CSV_FILE=lilypond-issues.csv # comma-separated values
TSV_FILE=lilypond-issues.tsv # tab-separated values
-URL_BASE="http://code.google.com/p/lilypond/issues"
+URL_BASE="https://code.google.com/p/lilypond/issues"
QUERY_STR="q=Patch%3Apush%2Ccountdown%2Creview%2Cnew%2Cwaiting&colspec=Patch%20Owner%20ID%20Summary&sort=patch"
DEADLINE=$1
-PATCH_MEISTER=${2:-"The Patch Mister"}
+PATCH_MEISTER=${2:-"The Patch Meister"}
MAILMAP='
"adam.spiers","Adam Spiers"
"aleksandr.andreev","Aleksandr Andreev"
"graham@percival-music.ca","Graham Percival"
"hanwenn","Han-Wen Nienhuys"
"hjunes","Heikki Junes"
+"ht.lilypond.development","Heikki Tauriainen"
"ianhulin44","Ian Hulin"
"idragosani","Brett McCoy"
"jameselihubailey","James E. Bailey"
sed '{
1d
/^$/d
+s/\t/ /g
s/^"//
s/","/\t/g
s/",*$//
}' $CSV_FILE | cut -sf1-4 > $TSV_FILE
+ISSUES_WITH_MISSING_FIELDS=`sed -n '/\t\t\|\t$/p' $TSV_FILE |
+ awk -F"\t" '{ print $3 }'`
+
+if [ "$ISSUES_WITH_MISSING_FIELDS" ]; then
+ COUNT=`wc --lines <(echo "$ISSUES_WITH_MISSING_FIELDS") | sed 's/ .*//'`
+ LINKS_WITH_MISSING_FIELDS=`echo "$ISSUES_WITH_MISSING_FIELDS" |
+ sed "s!^! $URL_BASE/detail?id=!"`
+ if [ $COUNT -eq 1 ]; then
+ echo -e "\nError: The following issue is missing an OWNER or SUMMARY:" >&2
+ else
+ echo -e "\nError: Each of the following issues is missing an OWNER or SUMMARY:" >&2
+ fi
+ echo "$LINKS_WITH_MISSING_FIELDS" >&2
+ echo "Please add the missing information in the tracker and start over." >&2
+ remove-if-exists $TSV_FILE
+ exit 1
+fi
+
+
EMAILS_USED=`awk -F"\t" '{ print $2 }' $TSV_FILE | sort --unique`
KNOWN_EMAILS=`
IFS=$'\n'