From 9468b77cb2ae93b992bfb9105016f3393d206b47 Mon Sep 17 00:00:00 2001 From: David Kastrup Date: Thu, 10 Dec 2015 13:05:59 +0100 Subject: [PATCH] Issue 5167/5: Allow defining markup commands in LilyPond syntax This works with assignments of the form \markup with-red = \markup \with-color #red \etc or similar. The resulting definition (in addition to being available as \with-red command inside of markups) can be used with the `markup' macro and also gets a `make-with-red-markup' convenience function. --- lily/include/lily-imports.hh | 2 ++ lily/lily-imports.cc | 2 ++ lily/parser.yy | 55 ++++++++++++++++++++++++++++++++---- 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/lily/include/lily-imports.hh b/lily/include/lily-imports.hh index a22da30f66..cc61ea7d9a 100644 --- a/lily/include/lily-imports.hh +++ b/lily/include/lily-imports.hh @@ -61,6 +61,7 @@ namespace Lily { extern Variable chordmodifiers; extern Variable construct_chord_elements; extern Variable default_time_signature_settings; + extern Variable define_markup_command; extern Variable drum_pitch_names; extern Variable grob_compose_function; extern Variable grob_offset_function; @@ -87,6 +88,7 @@ namespace Lily { extern Variable make_span_event; extern Variable markup_p; extern Variable markup_command_signature; + extern Variable markup_function_p; extern Variable markup_list_function_p; extern Variable markup_list_p; extern Variable midi_program; diff --git a/lily/lily-imports.cc b/lily/lily-imports.cc index 699b0850e7..5bb4863168 100644 --- a/lily/lily-imports.cc +++ b/lily/lily-imports.cc @@ -55,6 +55,7 @@ namespace Lily { Variable chordmodifiers ("chordmodifiers"); Variable construct_chord_elements ("construct-chord-elements"); Variable default_time_signature_settings ("default-time-signature-settings"); + Variable define_markup_command ("define-markup-command"); Variable drum_pitch_names ("drumPitchNames"); Variable grob_compose_function ("grob::compose-function"); Variable grob_offset_function ("grob::offset-function"); @@ -81,6 +82,7 @@ namespace Lily { Variable make_span_event ("make-span-event"); Variable markup_p ("markup?"); Variable markup_command_signature ("markup-command-signature"); + Variable markup_function_p ("markup-function?"); Variable markup_list_function_p ("markup-list-function?"); Variable markup_list_p ("markup-list?"); Variable midi_program ("midi-program"); diff --git a/lily/parser.yy b/lily/parser.yy index d9812b1b9f..ddccd41658 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -696,6 +696,20 @@ assignment: parser->lexer_->set_identifier (path, $5); $$ = SCM_UNSPECIFIED; } + | markup_mode_word '=' identifier_init + { + if (scm_is_false (Lily::markup_function_p ($3))) + { + parser->parser_error (@3, _ ("Not a markup function")); + } else { + scm_primitive_eval + (scm_list_3 + (Lily::define_markup_command, + scm_string_to_symbol ($1), + ly_quote_scm ($3))); + } + $$ = SCM_UNSPECIFIED; + } ; @@ -3899,11 +3913,33 @@ markup_mode: } ; +// Sort-of ugly: We need this as markup of its own as well as in +// markup function assignments, without triggering lookahead or the +// '=' for assignments will be parsed in markup mode and not +// recognized. Worse: the next token following something like +// \markup "string" would be parsed in markup mode as well. +// +// So we make a single production here that's used either in markup or +// in assignment. + +markup_mode_word: + markup_mode markup_word + { + $$ = $2; + parser->lexer_->pop_state (); + } + ; + + full_markup: markup_mode markup_top { $$ = $2; parser->lexer_->pop_state (); } + | markup_mode_word + { + $$ = make_simple_markup ($1); + } ; partial_markup: @@ -3923,7 +3959,7 @@ markup_top: $$ = scm_car (MAKE_SYNTAX (composed_markup_list, @2, $1, scm_list_1 ($2))); } - | simple_markup { + | simple_markup_noword { $$ = $1; } ; @@ -4070,14 +4106,21 @@ markup_head_1_list: } ; +markup_word: + STRING + | SYMBOL + ; + simple_markup: - STRING { - $$ = make_simple_markup ($1); - } - | SYMBOL { + markup_word + { $$ = make_simple_markup ($1); } - | SCORE { + | simple_markup_noword + ; + +simple_markup_noword: + SCORE { parser->lexer_->push_note_state (Lily::pitchnames); } '{' score_body '}' { Score *sc = unsmob ($4); -- 2.39.2