summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog16
-rw-r--r--input/regression/instrument-name.ly27
-rw-r--r--lily/accidental-engraver.cc3
-rw-r--r--lily/context-key-manager.cc100
-rw-r--r--lily/context-specced-music-iterator.cc4
-rw-r--r--lily/context.cc99
-rw-r--r--lily/include/context-key-manager.hh43
-rw-r--r--lily/include/context.hh19
-rw-r--r--lily/parser.yy51
-rw-r--r--lily/system-start-delimiter.cc11
-rw-r--r--ly/engraver-init.ly5
-rw-r--r--scm/define-grobs.scm1
-rw-r--r--scm/define-music-properties.scm1
13 files changed, 259 insertions, 121 deletions
diff --git a/ChangeLog b/ChangeLog
index 14a972cd51..f6c966df0a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2006-02-12 Han-Wen Nienhuys <hanwen@xs4all.nl>
+
+ * scm/define-music-properties.scm (all-music-properties):
+ create-new property.
+
+ * lily/context-specced-music-iterator.cc (construct_children):
+ inspect 'create-new property iso. magical $uniqueContextId context
+ id.
+
+ * lily/parser.yy (optional_id): allow \new "Bar" = "foo" too.
+
+ * lily/context-key-manager.cc (Module): new file. Encapsulate
+ object key generation.
+
+ * lily/include/context-key-manager.hh (Module): new file.
+
2006-02-11 Han-Wen Nienhuys <hanwen@xs4all.nl>
* scm/define-grobs.scm (all-grob-descriptions): center instrument
diff --git a/input/regression/instrument-name.ly b/input/regression/instrument-name.ly
index 374b4a9e97..2d1efa6151 100644
--- a/input/regression/instrument-name.ly
+++ b/input/regression/instrument-name.ly
@@ -17,17 +17,20 @@ PianoStaff.
-
-\context PianoStaff <<
- \context Staff = "treble" {
- \set PianoStaff.instrument = "Piano"
- \set Staff.instrument = "Right" { c''4 }}
- \context Staff = "bass" {
- \set Staff.instrument = "Left"
- \clef bass c4
+\new StaffGroup <<
+ \context PianoStaff <<
+ \context Staff = "treble" {
+ \set PianoStaff.instrument = "Piano"
+ \set Staff.instrument = "Right" { c''4 }}
+ \context Staff = "bass" {
+ \set Staff.instrument = "Left"
+ \clef bass c4
+ }
+ >>
+
+ \lyrics {
+ \set vocalName = "bert"
+ blah
}
+ \new Staff { c''4 }
>>
-
-
-
-
diff --git a/lily/accidental-engraver.cc b/lily/accidental-engraver.cc
index 0534eebbd3..bd088021de 100644
--- a/lily/accidental-engraver.cc
+++ b/lily/accidental-engraver.cc
@@ -391,6 +391,7 @@ Accidental_engraver::make_standard_accidental (Music *note,
Engraver *trans)
{
+ (void)note;
/*
We construct the accidentals at the originating Voice
level, so that we get the property settings for
@@ -428,7 +429,7 @@ Accidental_engraver::make_suggested_accidental (Music *note,
Grob *note_head,
Engraver *trans)
{
-
+ (void) note;
Grob *a
= make_grob_from_properties (trans,
ly_symbol2scm ("AccidentalSuggestion"),
diff --git a/lily/context-key-manager.cc b/lily/context-key-manager.cc
new file mode 100644
index 0000000000..2f1fbe310b
--- /dev/null
+++ b/lily/context-key-manager.cc
@@ -0,0 +1,100 @@
+/*
+ context-key-manager.cc -- implement Context_key_manager
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+
+*/
+
+#include "context-key-manager.hh"
+#include "object-key.hh"
+#include "lilypond-key.hh"
+#include "main.hh"
+
+Context_key_manager::Context_key_manager (Object_key const *key)
+{
+ key_ = key;
+}
+
+void
+Context_key_manager::unprotect () const
+{
+ if (key_)
+ ((Object_key *)key_)->unprotect ();
+}
+
+
+Object_key const *
+Context_key_manager::get_context_key (Moment now, string type, string id)
+{
+ if (!use_object_keys)
+ return 0;
+
+ string now_key = type + "@" + id;
+
+ int disambiguation_count = 0;
+ if (context_counts_.find (now_key) != context_counts_.end ())
+ disambiguation_count = context_counts_[now_key];
+
+ context_counts_[now_key] = disambiguation_count + 1;
+
+ return new Lilypond_context_key (key (),
+ now,
+ type, id,
+ disambiguation_count);
+}
+
+
+Object_key const *
+Context_key_manager::get_grob_key (Moment m, string name)
+{
+ if (!use_object_keys)
+ return 0;
+
+ return create_grob_key (m, name);
+}
+
+/*
+ We want to have a key for some objects anyway, so we can invent a
+ unique identifier for each (book,score) tuple.
+*/
+Object_key const *
+Context_key_manager::create_grob_key (Moment now, string name)
+{
+ int disambiguation_count = 0;
+ if (grob_counts_.find (name) != grob_counts_.end ())
+ disambiguation_count = grob_counts_[name];
+ grob_counts_[name] = disambiguation_count + 1;
+
+ Object_key *k = new Lilypond_grob_key (key (),
+ now,
+ name,
+ disambiguation_count);
+
+ return k;
+}
+
+void
+Context_key_manager::gc_mark () const
+{
+ if (key_)
+ scm_gc_mark (key_->self_scm ());
+
+}
+
+void
+Context_key_manager::clear ()
+{
+ if (!use_object_keys)
+ return;
+
+ grob_counts_.clear ();
+ context_counts_.clear ();
+}
+
+Context_key_manager::Context_key_manager (Context_key_manager const &src)
+{
+ (void)src;
+ assert (false);
+}
diff --git a/lily/context-specced-music-iterator.cc b/lily/context-specced-music-iterator.cc
index 9036d72fb6..86342a5eb4 100644
--- a/lily/context-specced-music-iterator.cc
+++ b/lily/context-specced-music-iterator.cc
@@ -30,8 +30,8 @@ Context_specced_music_iterator::construct_children ()
Context *a = 0;
- if (c_id == "$uniqueContextId")
- a = get_outlet ()->create_unique_context (ct, ops);
+ if (to_boolean (get_music()->get_property ("create-new")))
+ a = get_outlet ()->create_unique_context (ct, c_id, ops);
else
a = get_outlet ()->find_create_context (ct, c_id, ops);
diff --git a/lily/context.cc b/lily/context.cc
index b1e4a6629d..2445ea12f3 100644
--- a/lily/context.cc
+++ b/lily/context.cc
@@ -10,7 +10,6 @@
#include "context-def.hh"
#include "international.hh"
-#include "lilypond-key.hh"
#include "ly-smobs.icc"
#include "main.hh"
#include "output-def.hh"
@@ -46,7 +45,8 @@ Context::check_removal ()
}
}
-Context::Context (Context const &)
+Context::Context (Context const &src)
+ : key_manager_ (src.key_manager_)
{
assert (false);
}
@@ -85,8 +85,8 @@ Context::add_context (Context *t)
Context::Context (Object_key const *key)
+ : key_manager_ (key)
{
- key_ = key;
daddy_context_ = 0;
init_ = false;
aliases_ = SCM_EOL;
@@ -106,26 +106,25 @@ Context::Context (Object_key const *key)
UGH UGH
const correctness.
*/
- if (key_)
- ((Object_key *)key)->unprotect ();
+ key_manager_.unprotect();
}
/* TODO: this shares code with find_create_context (). */
Context *
-Context::create_unique_context (SCM n, SCM operations)
+Context::create_unique_context (SCM name, string id, SCM operations)
{
/*
Don't create multiple score contexts.
*/
if (dynamic_cast<Global_context *> (this)
&& dynamic_cast<Global_context *> (this)->get_score_context ())
- return get_score_context ()->create_unique_context (n, operations);
+ return get_score_context ()->create_unique_context (name, id, operations);
/*
TODO: use accepts_list_.
*/
vector<Context_def*> path
- = unsmob_context_def (definition_)->path_to_acceptable_context (n, get_output_def ());
+ = unsmob_context_def (definition_)->path_to_acceptable_context (name, get_output_def ());
if (path.size ())
{
@@ -134,10 +133,15 @@ Context::create_unique_context (SCM n, SCM operations)
// start at 1. The first one (index 0) will be us.
for (vsize i = 0; i < path.size (); i++)
{
- SCM ops = (i == path.size () -1) ? operations : SCM_EOL;
-
+ SCM ops = SCM_EOL;
+ string id_str = "\\new";
+ if (i == path.size () - 1)
+ {
+ ops = operations;
+ id_str = id;
+ }
current = current->create_context (path[i],
- "\\new",
+ id_str,
ops);
}
@@ -150,11 +154,11 @@ Context::create_unique_context (SCM n, SCM operations)
*/
Context *ret = 0;
if (daddy_context_ && !dynamic_cast<Global_context *> (daddy_context_))
- ret = daddy_context_->create_unique_context (n, operations);
+ ret = daddy_context_->create_unique_context (name, id, operations);
else
{
warning (_f ("can't find or create new `%s'",
- ly_symbol2string (n).c_str ()));
+ ly_symbol2string (name).c_str ()));
ret = 0;
}
return ret;
@@ -228,7 +232,7 @@ Context::create_context (Context_def *cdef,
SCM ops)
{
string type = ly_symbol2string (cdef->get_context_name ());
- Object_key const *key = get_context_key (type, id);
+ Object_key const *key = key_manager_.get_context_key (now_mom(), type, id);
Context *new_context
= cdef->instantiate (ops, key);
@@ -239,55 +243,6 @@ Context::create_context (Context_def *cdef,
return new_context;
}
-Object_key const *
-Context::get_context_key (string type, string id)
-{
- if (!use_object_keys)
- return 0;
-
- string now_key = type + "@" + id;
-
- int disambiguation_count = 0;
- if (context_counts_.find (now_key) != context_counts_.end ())
- disambiguation_count = context_counts_[now_key];
-
- context_counts_[now_key] = disambiguation_count + 1;
-
- return new Lilypond_context_key (key (),
- now_mom (),
- type, id,
- disambiguation_count);
-}
-
-Object_key const *
-Context::get_grob_key (string name)
-{
- if (!use_object_keys)
- return 0;
-
- return create_grob_key (name);
-}
-
-/*
- We want to have a key for some objects anyway, so we can invent a
- unique identifier for each (book,score) tuple.
-*/
-Object_key const *
-Context::create_grob_key (string name)
-{
- int disambiguation_count = 0;
- if (grob_counts_.find (name) != grob_counts_.end ())
- disambiguation_count = grob_counts_[name];
- grob_counts_[name] = disambiguation_count + 1;
-
- Object_key *k = new Lilypond_grob_key (key (),
- now_mom (),
- name,
- disambiguation_count);
-
- return k;
-}
-
/*
Default child context as a SCM string, or something else if there is
none.
@@ -522,12 +477,23 @@ Context::print_smob (SCM s, SCM port, scm_print_state *)
return 1;
}
+Object_key const *
+Context::get_grob_key (string name)
+{
+ return key_manager_.get_grob_key (now_mom (), name);
+}
+
+Object_key const *
+Context::get_context_key (string name, string id)
+{
+ return key_manager_.get_context_key (now_mom (), name, id);
+}
+
SCM
Context::mark_smob (SCM sm)
{
Context *me = (Context *) SCM_CELL_WORD_1 (sm);
- if (me->key_)
- scm_gc_mark (me->key_->self_scm ());
+ me->key_manager_.gc_mark();
scm_gc_mark (me->context_list_);
scm_gc_mark (me->aliases_);
@@ -583,8 +549,7 @@ Context::clear_key_disambiguations ()
if (!use_object_keys)
return;
- grob_counts_.clear ();
- context_counts_.clear ();
+ key_manager_.clear ();
for (SCM s = context_list_; scm_is_pair (s); s = scm_cdr (s))
unsmob_context (scm_car (s))->clear_key_disambiguations ();
}
diff --git a/lily/include/context-key-manager.hh b/lily/include/context-key-manager.hh
new file mode 100644
index 0000000000..db7078fd42
--- /dev/null
+++ b/lily/include/context-key-manager.hh
@@ -0,0 +1,43 @@
+/*
+ context-key-manager.hh -- declare Context_key_manager
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+
+*/
+
+#ifndef CONTEXT_KEY_MANAGER_HH
+#define CONTEXT_KEY_MANAGER_HH
+
+#include "lily-proto.hh"
+
+#include <map>
+using namespace std;
+
+class Context_key_manager
+{
+ Object_key const *key_;
+ map<string, int> grob_counts_;
+ map<string, int> context_counts_;
+
+
+protected:
+ friend class Context;
+
+ Context_key_manager (Object_key const *);
+ Context_key_manager (Context_key_manager const &src);
+
+
+ void unprotect () const;
+ void gc_mark () const;
+ void clear ();
+ Object_key const *key () const { return key_; }
+ Object_key const *create_grob_key (Moment, string);
+ Object_key const *get_grob_key (Moment, string);
+ Object_key const *get_context_key (Moment, string, string);
+};
+
+#endif /* CONTEXT_KEY_MANAGER_HH */
+
+
diff --git a/lily/include/context.hh b/lily/include/context.hh
index 22e7e14221..6a2fcb0d22 100644
--- a/lily/include/context.hh
+++ b/lily/include/context.hh
@@ -9,12 +9,11 @@
#ifndef CONTEXT_HH
#define CONTEXT_HH
-#include <map>
-using namespace std;
#include "moment.hh"
#include "lily-proto.hh"
#include "virtual-methods.hh"
+#include "context-key-manager.hh"
class Context
{
@@ -30,14 +29,11 @@ private:
int iterator_count_;
bool init_;
- map<string, int> grob_counts_;
- map<string, int> context_counts_;
-
protected:
- Object_key const *key_;
Context *daddy_context_;
SCM definition_;
-
+ Context_key_manager key_manager_;
+
SCM properties_scm_;
SCM context_list_;
SCM accepts_list_;
@@ -48,11 +44,10 @@ protected:
friend class Context_def;
void clear_key_disambiguations ();
+
public:
- Object_key const *key () const { return key_; }
- Object_key const *create_grob_key (string);
- Object_key const *get_grob_key (string);
- Object_key const *get_context_key (string, string);
+ Object_key const *get_grob_key (string name);
+ Object_key const *get_context_key (string name, string id);
Context *create_context (Context_def *, string, SCM);
string id_string () const { return id_string_; }
@@ -90,7 +85,7 @@ public:
Context *find_create_context (SCM context_name,
string id, SCM ops);
- Context *create_unique_context (SCM context_name,
+ Context *create_unique_context (SCM context_name, string context_id,
SCM ops);
vector<Context*> path_to_acceptable_context (SCM alias,
Output_def *) const;
diff --git a/lily/parser.yy b/lily/parser.yy
index a85870f179..02599215fd 100644
--- a/lily/parser.yy
+++ b/lily/parser.yy
@@ -112,7 +112,7 @@ using namespace std;
#define MY_MAKE_MUSIC(x) make_music_by_name (ly_symbol2scm (x))
Music *property_op_to_music (SCM op);
-Music *context_spec_music (SCM type, SCM id, Music *m, SCM ops);
+Music *context_spec_music (SCM type, SCM id, Music *m, SCM ops, bool create_new);
SCM get_next_unique_context_id ();
SCM get_next_unique_lyrics_context_id ();
@@ -399,6 +399,7 @@ If we give names, Bison complains.
%type <scm> object_id_setting
%type <scm> octave_check
%type <scm> optional_context_mod
+%type <scm> optional_id
%type <scm> optional_notemode_duration
%type <scm> pitch
%type <scm> pitch_also_in_chords
@@ -1045,20 +1046,23 @@ Generic_prefix_music_scm:
}
;
+optional_id:
+ /**/ { $$ = SCM_EOL; }
+ | '=' simple_string {
+ $$ = $2;
+ }
+ ;
+
+
Prefix_composite_music:
Generic_prefix_music_scm {
$$ = run_music_function (THIS, $1);
}
- | CONTEXT simple_string '=' simple_string optional_context_mod Music {
- $$ = context_spec_music ($2, $4, $6, $5);
-
- }
- | CONTEXT simple_string optional_context_mod Music {
- $$ = context_spec_music ($2, SCM_UNDEFINED, $4, $3);
+ | CONTEXT simple_string optional_id optional_context_mod Music {
+ $$ = context_spec_music ($2, $3, $5, $4, false);
}
- | NEWCONTEXT simple_string optional_context_mod Music {
- $$ = context_spec_music ($2, get_next_unique_context_id (), $4,
- $3);
+ | NEWCONTEXT simple_string optional_id optional_context_mod Music {
+ $$ = context_spec_music ($2, $3, $5, $4, true);
}
| TIMES fraction Music
@@ -1103,8 +1107,7 @@ Prefix_composite_music:
THIS->lexer_->pop_state ();
}
| mode_changing_head_with_context optional_context_mod Grouped_music_list {
- $$ = context_spec_music ($1, get_next_unique_context_id (),
- $3, $2);
+ $$ = context_spec_music ($1, SCM_UNDEFINED, $3, $2, true);
if ($1 == ly_symbol2scm ("ChordNames"))
{
Music *chm = MY_MAKE_MUSIC ("UnrelativableMusic");
@@ -1220,7 +1223,7 @@ re_rhythmed_music:
name = get_next_unique_lyrics_context_id ();
voice = context_spec_music (scm_makfrom0str ("Voice"),
name,
- voice, SCM_EOL);
+ voice, SCM_EOL, false);
}
SCM context = scm_makfrom0str ("Lyrics");
@@ -1232,7 +1235,7 @@ re_rhythmed_music:
Music *music = unsmob_music (scm_car (s));
Music *com = make_lyric_combine_music (name, music);
Music *csm = context_spec_music (context,
- get_next_unique_context_id (), com, SCM_EOL);
+ SCM_UNDEFINED, com, SCM_EOL, true);
lst = scm_cons (csm->self_scm (), lst);
}
all->set_property ("elements", scm_cons (voice->self_scm (),
@@ -1328,14 +1331,14 @@ music_property_def:
ly_symbol2scm ("push"),
scm_cadr ($2),
$5, $3));
- $$ = context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
+ $$ = context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL, false);
}
| OVERRIDE context_prop_spec embedded_scm embedded_scm '=' scalar {
$$ = property_op_to_music (scm_list_5 (
ly_symbol2scm ("push"),
scm_cadr ($2),
$6, $4, $3));
- $$ = context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
+ $$ = context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL, false);
}
| REVERT context_prop_spec embedded_scm {
$$ = property_op_to_music (scm_list_3 (
@@ -1343,20 +1346,20 @@ music_property_def:
scm_cadr ($2),
$3));
- $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
+ $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL, false);
}
| SET context_prop_spec '=' scalar {
$$ = property_op_to_music (scm_list_3 (
ly_symbol2scm ("assign"),
scm_cadr ($2),
$4));
- $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
+ $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL, false);
}
| UNSET context_prop_spec {
$$ = property_op_to_music (scm_list_2 (
ly_symbol2scm ("unset"),
scm_cadr ($2)));
- $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
+ $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL, false);
}
| ONCE music_property_def {
SCM e = $2->get_property ("element");
@@ -1622,16 +1625,16 @@ command_element:
sounds_as_c.smobbed_copy());
$$->set_spot (@$);
$$ = context_spec_music (ly_symbol2scm ("Staff"), SCM_UNDEFINED,
- $$, SCM_EOL);
+ $$, SCM_EOL, false);
}
| PARTIAL duration_length {
Moment m = - unsmob_duration ($2)->get_length ();
Music *p = set_property_music (ly_symbol2scm ( "measurePosition"),m.smobbed_copy ());
p->set_spot (@$);
p = context_spec_music (ly_symbol2scm ("Timing"), SCM_UNDEFINED,
- p, SCM_EOL);
+ p, SCM_EOL, false);
p = context_spec_music (ly_symbol2scm ("Score"), SCM_UNDEFINED,
- p, SCM_EOL);
+ p, SCM_EOL, false);
$$ = p;
}
@@ -2657,7 +2660,7 @@ property_op_to_music (SCM op)
}
Music*
-context_spec_music (SCM type, SCM id, Music *m, SCM ops)
+context_spec_music (SCM type, SCM id, Music *m, SCM ops, bool create_new)
{
Music *csm = MY_MAKE_MUSIC ("ContextSpeccedMusic");
@@ -2667,6 +2670,8 @@ context_spec_music (SCM type, SCM id, Music *m, SCM ops)
csm->set_property ("context-type",
scm_is_symbol (type) ? type : scm_string_to_symbol (type));
csm->set_property ("property-operations", ops);
+ if (create_new)
+ csm->set_property ("create-new", SCM_BOOL_T);
if (scm_is_string (id))
csm->set_property ("context-id", id);
diff --git a/lily/system-start-delimiter.cc b/lily/system-start-delimiter.cc
index 5a4e220500..c33180540d 100644
--- a/lily/system-start-delimiter.cc
+++ b/lily/system-start-delimiter.cc
@@ -91,9 +91,15 @@ System_start_delimiter::text (Grob *me_grob, Real h)
SCM scm_stencil = Text_interface::is_markup (t)
? Text_interface::interpret_markup (me->layout ()->self_scm (), chain, t)
: SCM_EOL;
+
if (Stencil *p = unsmob_stencil (scm_stencil))
- return *p;
+ {
+ SCM align_y = me_grob->get_property ("self-alignment-Y");
+ if (scm_is_number (align_y))
+ p->align_to (Y_AXIS, robust_scm2double (align_y, 0.0));
+ return *p;
+ }
return Stencil();
}
@@ -206,6 +212,7 @@ ADD_INTERFACE (System_start_delimiter, "system-start-delimiter-interface",
"collapse-height "
"style "
"text "
- "long-text "
+ "long-text "
+ "self-alignment-Y "
"thickness "
);
diff --git a/ly/engraver-init.ly b/ly/engraver-init.ly
index 12208d9c10..6654a65ccb 100644
--- a/ly/engraver-init.ly
+++ b/ly/engraver-init.ly
@@ -350,7 +350,10 @@ printing of a single line of lyrics. "
\override VerticalAxisGroup #'remove-first = ##t
\override VerticalAxisGroup #'remove-empty = ##t
\override SeparationItem #'padding = #0.2
- \override InstrumentName #'Y-offset = #0.0
+ \override InstrumentName #'self-alignment-Y = ##f
+
+ %% sync with define-grobs.scm ;
+ \override InstrumentName #'font-size = #1.0
%% make sure that barlines aren't collapsed, when
%% Bar_engraver is there.
diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm
index 2a267ba39b..7157fcba4d 100644
--- a/scm/define-grobs.scm
+++ b/scm/define-grobs.scm
@@ -729,7 +729,6 @@
(stencil . ,ly:system-start-delimiter::print)
(X-offset . ,ly:side-position-interface::x-aligned-side)
(direction . ,LEFT)
- (Y-offset . ,ly:self-alignment-interface::y-aligned-on-self)
(self-alignment-Y . ,CENTER)
(meta . ((class . Spanner)
(interfaces . (system-start-text-interface
diff --git a/scm/define-music-properties.scm b/scm/define-music-properties.scm
index 32f6bbdac4..0286f9923f 100644
--- a/scm/define-music-properties.scm
+++ b/scm/define-music-properties.scm
@@ -38,6 +38,7 @@ TODO: consider making type into symbol ")
(compress-procedure ,procedure? "compress this music expression. Argument 1: the music, arg 2: factor")
(context-id ,string? "name of context")
(context-type ,symbol? "type of context")
+ (create-new ,boolean? "Create a fresh context.")
(descend-only ,boolean? "If set, this @code{\\context} will only
descend in the context tree.")
(denominator ,integer? "denominator in a time signature")