diff options
author | David Kastrup <dak@gnu.org> | 2016-06-16 19:52:01 +0200 |
---|---|---|
committer | David Kastrup <dak@gnu.org> | 2016-06-24 09:31:27 +0200 |
commit | d862072d207e75b01f157198d8ea90fd360eb210 (patch) | |
tree | c95d6254cc4c0494553220de6749b17af6895597 | |
parent | 5c7507115ca03b8f2f2b46e34d670ed50074b00d (diff) |
Issue 4897: Allow multiple \with per context creation
This allows using more than one \with context modification in
connection with \new, \context, \addlyrics, \drums, \lyrics, \chords,
\figures . While combining them inside of a single \with {...} is
possible, sometimes it may be inconvenient.
-rw-r--r-- | lily/parser.yy | 76 |
1 files changed, 40 insertions, 36 deletions
diff --git a/lily/parser.yy b/lily/parser.yy index 1695aea625..741aee7d73 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -1486,16 +1486,40 @@ context_modification_arg: | MUSIC_IDENTIFIER ; -optional_context_mod: - /**/ { - $$ = SCM_EOL; - } - | context_modification +/* A list of single mods collected from a (possibly empty) sequence of + * context modifications, usually written as \with ... \with ... + */ + +optional_context_mods: + context_modification_mods_list { - $$ = $1; + if (scm_is_pair ($1)) + $$ = scm_append_x (scm_reverse_x ($1, SCM_EOL)); } ; +/* The worker for optional_context_mods conses a (reversed) list where + * each element contains the list of single context mods from one + * context modification block. Context_mod::get_mods creates fresh + * copies, so it's okay to use append! on them. + */ + +context_modification_mods_list: + /**/ { + $$ = SCM_EOL; + } + | context_modification_mods_list context_modification + { + if (Context_mod *m = unsmob<Context_mod> ($2)) + $$ = scm_cons (m->get_mods (), $1); + } + ; + +/* A Context_mod is a container for a list of context mods like + * \consists ... \override ... . context_mod_list produces a + * Context_mod from the inside of a \with { ... } statement. + */ + context_mod_list: /**/ { $$ = Context_mod ().smobbed_copy (); @@ -1526,36 +1550,20 @@ context_mod_list: ; context_prefix: - CONTEXT symbol optional_id optional_context_mod { - Context_mod *ctxmod = unsmob<Context_mod> ($4); - SCM mods = SCM_EOL; - if (ctxmod) - mods = ctxmod->get_mods (); - $$ = START_MAKE_SYNTAX (context_specification, $2, $3, mods, SCM_BOOL_F); + CONTEXT symbol optional_id optional_context_mods { + $$ = START_MAKE_SYNTAX (context_specification, $2, $3, $4, SCM_BOOL_F); } - | NEWCONTEXT symbol optional_id optional_context_mod { - Context_mod *ctxmod = unsmob<Context_mod> ($4); - SCM mods = SCM_EOL; - if (ctxmod) - mods = ctxmod->get_mods (); - $$ = START_MAKE_SYNTAX (context_specification, $2, $3, mods, SCM_BOOL_T); + | NEWCONTEXT symbol optional_id optional_context_mods { + $$ = START_MAKE_SYNTAX (context_specification, $2, $3, $4, SCM_BOOL_T); } ; new_lyrics: - ADDLYRICS optional_context_mod lyric_mode_music { - Context_mod *ctxmod = unsmob<Context_mod> ($2); - SCM mods = SCM_EOL; - if (ctxmod) - mods = ctxmod->get_mods (); - $$ = scm_acons ($3, mods, SCM_EOL); + ADDLYRICS optional_context_mods lyric_mode_music { + $$ = scm_acons ($3, $2, SCM_EOL); } - | new_lyrics ADDLYRICS optional_context_mod lyric_mode_music { - Context_mod *ctxmod = unsmob<Context_mod> ($3); - SCM mods = SCM_EOL; - if (ctxmod) - mods = ctxmod->get_mods (); - $$ = scm_acons ($4, mods, $1); + | new_lyrics ADDLYRICS optional_context_mods lyric_mode_music { + $$ = scm_acons ($4, $3, $1); } ; @@ -2510,12 +2518,8 @@ mode_changed_music: } parser->lexer_->pop_state (); } - | mode_changing_head_with_context optional_context_mod grouped_music_list { - Context_mod *ctxmod = unsmob<Context_mod> ($2); - SCM mods = SCM_EOL; - if (ctxmod) - mods = ctxmod->get_mods (); - $$ = MAKE_SYNTAX (context_specification, @$, $1, SCM_EOL, mods, SCM_BOOL_T, $3); + | mode_changing_head_with_context optional_context_mods grouped_music_list { + $$ = MAKE_SYNTAX (context_specification, @$, $1, SCM_EOL, $2, SCM_BOOL_T, $3); if (scm_is_eq ($1, ly_symbol2scm ("ChordNames"))) { $$ = MAKE_SYNTAX (unrelativable_music, @$, $$); |