From 3357cca546aa50c8dea8d0b2dd9db2b688fac6bf Mon Sep 17 00:00:00 2001 From: Reinhold Kainhofer Date: Sat, 7 Jun 2008 00:35:19 +0200 Subject: [PATCH] First attempt to include text in \tempo indications A tempo indication in general is either a text markup, a note=count or both. So far, lilypond only supported the note=count type of tempo indications in its \tempo command. With this patch I'm trying to extend the \tempo function to include a text string, too. It allows any of the following types of tempo settings: \tempo 4=120 \tempo "Allegro" 4=120 \tempo "Allegro" \tempo \markup{\italic \medium "Allegro"} etc. The patch is not perfect yet, but works really well. What it does: - Extend the parser to allow the above forms for \tempo - Add a tempoText property, similar to tempoUnitCount - Metronome_mark_engraver uses this property and checks whether it has changed - Extend the metronomeMarkFormatter to take four arguments (text, duration, count, context) and print either the text, the note=count or text (note=count), depending on whether the properties are set to sensible values. What is still missing: -) The metronomeMarkFormatter function looks ugly and could probably be simplified -) The things in brackets should use \concat -) Extend the define-extra-display-method to also check for tempoText and produce any of the allowed \tempo forms when you use \displayLilyMusic --- lily/metronome-engraver.cc | 20 ++++++++++++----- lily/parser.yy | 14 +++++++++++- scm/define-context-properties.scm | 1 + scm/define-music-display-methods.scm | 1 + scm/ly-syntax-constructors.scm | 19 +++++++++++++++++ scm/translation-functions.scm | 38 +++++++++++++++++++++++++--------- 6 files changed, 76 insertions(+), 17 deletions(-) diff --git a/lily/metronome-engraver.cc b/lily/metronome-engraver.cc index 5bc7153..5b5d81d 100644 --- a/lily/metronome-engraver.cc +++ b/lily/metronome-engraver.cc @@ -16,6 +16,7 @@ using namespace std; #include "grob-array.hh" #include "item.hh" #include "stream-event.hh" +#include "text-interface.hh" #include "translator.icc" @@ -33,6 +34,7 @@ protected: SCM last_duration_; SCM last_count_; + SCM last_text_; protected: virtual void derived_mark () const; @@ -52,6 +54,7 @@ Metronome_mark_engraver::derived_mark () const { scm_gc_mark (last_count_); scm_gc_mark (last_duration_); + scm_gc_mark (last_text_); } void @@ -72,16 +75,19 @@ Metronome_mark_engraver::process_music () { SCM count = get_property ("tempoUnitCount"); SCM duration = get_property ("tempoUnitDuration"); - - if (unsmob_duration (duration) - && scm_is_number (count) + SCM text = get_property ("tempoText"); + + if ( ( (unsmob_duration (duration) && scm_is_number (count)) + || Text_interface::is_markup (text) ) && !(ly_is_equal (count, last_count_) - && ly_is_equal (duration, last_duration_))) + && ly_is_equal (duration, last_duration_) + && ly_is_equal (text, last_text_))) { text_ = make_item ("MetronomeMark", SCM_EOL); SCM proc = get_property ("metronomeMarkFormatter"); - SCM result = scm_call_3 (proc, + SCM result = scm_call_4 (proc, + text, duration, count, context ()->self_scm ()); @@ -91,6 +97,7 @@ Metronome_mark_engraver::process_music () last_duration_ = duration; last_count_ = count; + last_text_ = text; } ADD_TRANSLATOR (Metronome_mark_engraver, @@ -108,7 +115,8 @@ ADD_TRANSLATOR (Metronome_mark_engraver, "stavesFound " "metronomeMarkFormatter " "tempoUnitDuration " - "tempoUnitCount ", + "tempoUnitCount " + "tempoText ", /* write */ "" diff --git a/lily/parser.yy b/lily/parser.yy index 3b690e8..19c8d1e 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -821,7 +821,19 @@ output_def_body: tempo_event: TEMPO steno_duration '=' bare_unsigned { $$ = MAKE_SYNTAX ("tempo", @$, $2, scm_int2num ($4)); - } + } + | TEMPO string steno_duration '=' bare_unsigned { + $$ = MAKE_SYNTAX ("tempoWithText", @$, make_simple_markup($2), $3, scm_int2num ($5)); + } + | TEMPO full_markup steno_duration '=' bare_unsigned { + $$ = MAKE_SYNTAX ("tempoWithText", @$, $2, $3, scm_int2num ($5)); + } + | TEMPO string { + $$ = MAKE_SYNTAX ("tempoText", @$, make_simple_markup($2) ); + } + | TEMPO full_markup { + $$ = MAKE_SYNTAX ("tempoText", @$, $2 ); + } ; /* diff --git a/scm/define-context-properties.scm b/scm/define-context-properties.scm index 469b900..e269e8f 100644 --- a/scm/define-context-properties.scm +++ b/scm/define-context-properties.scm @@ -432,6 +432,7 @@ note head; it takes a string number, a list of string tunings and a minute.") (tempoUnitCount ,number? "Count for specifying tempo.") (tempoUnitDuration ,ly:duration? "Unit for specifying tempo.") + (tempoText ,markup? "Text for tempo marks.") (tieWaitForNote ,boolean? "If true, tied notes do not have to follow each other directly. This can be used for writing out arpeggios.") diff --git a/scm/define-music-display-methods.scm b/scm/define-music-display-methods.scm index b1b9111..b9c4e26 100644 --- a/scm/define-music-display-methods.scm +++ b/scm/define-music-display-methods.scm @@ -880,6 +880,7 @@ Otherwise, return #f." symbol 'melismaBusy))) "\\melismaEnd")) +;;; TODO: Add the tempoText property here, too! ;;; \tempo (define-extra-display-method ContextSpeccedMusic (expr parser) "If expr is a tempo, return \"\\tempo x = nnn\", otherwise return #f." diff --git a/scm/ly-syntax-constructors.scm b/scm/ly-syntax-constructors.scm index 9e6325a..5843cac 100644 --- a/scm/ly-syntax-constructors.scm +++ b/scm/ly-syntax-constructors.scm @@ -89,6 +89,25 @@ (make-property-set 'tempoUnitCount tempo))) 'Score)) +(define-ly-syntax-simple (tempoWithText text duration tempo ) + (context-spec-music + (make-sequential-music + (list + (make-property-set 'tempoWholesPerMinute + (ly:moment-mul (ly:make-moment tempo 1) + (ly:duration-length duration))) + (make-property-set 'tempoUnitDuration duration) + (make-property-set 'tempoUnitCount tempo) + (make-property-set 'tempoText text))) + 'Score)) + +(define-ly-syntax-simple (tempoText text) + (context-spec-music + (make-sequential-music + (list + (make-property-set 'tempoText text))) + 'Score)) + (define-ly-syntax-simple (skip-music dur) (make-music 'SkipMusic 'duration dur)) diff --git a/scm/translation-functions.scm b/scm/translation-functions.scm index 366f44f..3561030 100644 --- a/scm/translation-functions.scm +++ b/scm/translation-functions.scm @@ -6,16 +6,34 @@ ;;;; Jan Nieuwenhuizen ;; metronome marks -(define-public (format-metronome-markup dur count context) - (let* ((note-mark (make-smaller-markup - (make-note-by-number-markup (ly:duration-log dur) - (ly:duration-dot-count dur) - 1)))) - (make-line-markup - (list - (make-general-align-markup Y DOWN note-mark) - (make-simple-markup "=") - (make-simple-markup (number->string count)))))) +(define-public (format-metronome-markup text dur count context) + (let* ((note-mark (if (ly:duration? dur) + (make-smaller-markup + (make-note-by-number-markup (ly:duration-log dur) + (ly:duration-dot-count dur) + 1)) + #f)) + (note-markup (if (and note-mark (number? count) (> count 0) ) + (list + (make-general-align-markup Y DOWN note-mark) + (make-simple-markup "=") + (make-simple-markup (number->string count))) + #f)) + (text-markup (if (not (null? text)) + (list (make-bold-markup text)) + #f))) + (if text-markup + (if note-markup + (make-line-markup (append text-markup (list (make-simple-markup "(")) note-markup (list (make-simple-markup ")")))) + (make-line-markup text-markup) + ) + (if note-markup + (make-line-markup note-markup) + #f + ) + ) + ) +) (define-public (format-mark-alphabet mark context) (make-bold-markup (make-markalphabet-markup (1- mark)))) -- 1.5.4.3