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.
This patch extends 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.
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.
- Add a tempoHideNote property to hide note=count in the metronome mark
- Extend the define-extra-display-method to also check for tempoText and
produce any of the allowed \tempo forms when you use \displayLilyMusic
- Added a convert-ly rule to warn the user about the change to the signature
of the metronomeMarkFormater function
--- /dev/null
+\version "2.11.48"
+
+\header{
+ texidoc="
+The tempo command supports text markup and/or duration=count. Using the
+Score.hideTempoNote, one can hide the duration=count in the tempo mark.
+"
+}
+
+\relative c'' {
+ \tempo "Allegro" c1
+ \tempo "Allegro" c1
+ \set Score.tempoText = #"blah" d1
+ \tempo \markup{\italic \medium "Allegro"} c1\break
+ \tempo 4=120 c1
+ \tempo "Allegro" 4=120 c1
+ \tempo "Allegro" 4=120 c1
+ \tempo "Allegro" 4=110 c1
+ \tempo "Allegretto" 4=110 c1\break
+
+ \set Score.tempoHideNote = ##f
+ \tempo "Allegro" 4=120 c1
+ \set Score.tempoHideNote = ##t
+ \tempo "No note" 8=160 c1
+ \tempo "Still not" c1
+ \tempo "Allegro" 4=120 c1
+ \set Score.tempoHideNote = ##f
+ \tempo "With note" 8=80 c1\break
+
+ % Unsetting the tempoText using only note=count:
+ \tempo 8=80 c1
+ \tempo "Allegro" 8=80 c1
+ \tempo 8=80 c1
+
+}
#include "grob-array.hh"
#include "item.hh"
#include "stream-event.hh"
+#include "text-interface.hh"
#include "translator.icc"
SCM last_duration_;
SCM last_count_;
+ SCM last_text_;
protected:
virtual void derived_mark () const;
{
scm_gc_mark (last_count_);
scm_gc_mark (last_duration_);
+ scm_gc_mark (last_text_);
}
void
{
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 ());
last_duration_ = duration;
last_count_ = count;
+ last_text_ = text;
}
ADD_TRANSLATOR (Metronome_mark_engraver,
"stavesFound "
"metronomeMarkFormatter "
"tempoUnitDuration "
- "tempoUnitCount ",
+ "tempoUnitCount "
+ "tempoText "
+ "tempoHideNote ",
/* write */
""
tempo_event:
TEMPO steno_duration '=' bare_unsigned {
- $$ = MAKE_SYNTAX ("tempo", @$, $2, scm_int2num ($4));
- }
+ $$ = MAKE_SYNTAX ("tempo", @$, SCM_BOOL_F, $2, scm_int2num ($4));
+ }
+ | TEMPO string steno_duration '=' bare_unsigned {
+ $$ = MAKE_SYNTAX ("tempo", @$, make_simple_markup($2), $3, scm_int2num ($5));
+ }
+ | TEMPO full_markup steno_duration '=' bare_unsigned {
+ $$ = MAKE_SYNTAX ("tempo", @$, $2, $3, scm_int2num ($5));
+ }
+ | TEMPO string {
+ $$ = MAKE_SYNTAX ("tempoText", @$, make_simple_markup($2) );
+ }
+ | TEMPO full_markup {
+ $$ = MAKE_SYNTAX ("tempoText", @$, $2 );
+ }
;
/*
return str
conversions.append (((2, 11, 48), conv, """\\compressMusic -> \\scaleDurations"""))
+
+def conv (str):
+ if re.search ('metronomeMarkFormatter', str):
+ stderr_write (NOT_SMART % _ ("metronomeMarkFormatter got an additional text argument.\n"))
+ stderr_write (_ ("The function assigned to Score.metronomeMarkFunction now uses the signature\n%s") %
+ "\t(format-metronome-markup text dur count context)\n")
+ return str
+
+conversions.append (((2, 11, 49), conv, """metronomeMarkFormatter uses text markup as second argument"""))
\ No newline at end of file
@code{melismaBusy}, @code{slurMelismaBusy}, @code{tieMelismaBusy}, and
@code{beamMelismaBusy}.")
(metronomeMarkFormatter ,procedure? "How to produce a metronome
-markup. Called with two arguments, event and context.")
+markup. Called with four arguments: text, duration, count and context.")
(midiInstrument ,string? "Name of the MIDI instrument to use.")
(midiMaximumVolume ,number? "Analogous to
@code{midiMinimumVolume}.")
minute.")
(tempoUnitCount ,number? "Count for specifying tempo.")
(tempoUnitDuration ,ly:duration? "Unit for specifying tempo.")
+ (tempoText ,markup? "Text for tempo marks.")
+ (tempoHideNote ,boolean? "Hide the note=count in tempo marks.")
(tieWaitForNote ,boolean? "If true, tied notes do not have to
follow each other directly. This can be used for writing out
arpeggios.")
"\\melismaEnd"))
;;; \tempo
+;;; Check for all three different syntaxes of tempo:
+;;; \tempo string duration=note, \tempo duration=note and \tempo string
(define-extra-display-method ContextSpeccedMusic (expr parser)
"If expr is a tempo, return \"\\tempo x = nnn\", otherwise return #f."
- (with-music-match (expr (music 'ContextSpeccedMusic
+ (or (with-music-match (expr (music 'ContextSpeccedMusic
+ element (music 'SequentialMusic
+ elements ((music 'PropertySet
+ value ?unit-text
+ symbol 'tempoText)
+ (music 'PropertySet
+ symbol 'tempoWholesPerMinute)
+ (music 'PropertySet
+ value ?unit-duration
+ symbol 'tempoUnitDuration)
+ (music 'PropertySet
+ value ?unit-count
+ symbol 'tempoUnitCount)))))
+ (format #f "\\tempo ~a ~a = ~a"
+ (scheme-expr->lily-string ?unit-text)
+ (duration->lily-string ?unit-duration #:force-duration #t)
+ ?unit-count))
+ (with-music-match (expr (music 'ContextSpeccedMusic
+ element (music 'SequentialMusic
+ elements ((music 'PropertyUnset
+ symbol 'tempoText)
+ (music 'PropertySet
+ symbol 'tempoWholesPerMinute)
+ (music 'PropertySet
+ value ?unit-duration
+ symbol 'tempoUnitDuration)
+ (music 'PropertySet
+ value ?unit-count
+ symbol 'tempoUnitCount)))))
+ (format #f "\\tempo ~a = ~a"
+ (duration->lily-string ?unit-duration #:force-duration #t)
+ ?unit-count))
+ (with-music-match (expr (music 'ContextSpeccedMusic
element (music 'SequentialMusic
elements ((music 'PropertySet
- symbol 'tempoWholesPerMinute)
- (music 'PropertySet
- value ?unit-duration
- symbol 'tempoUnitDuration)
- (music 'PropertySet
- value ?unit-count
- symbol 'tempoUnitCount)))))
- (format #f "\\tempo ~a = ~a"
- (duration->lily-string ?unit-duration #:force-duration #t)
- ?unit-count)))
+ value ?tempo-text
+ symbol 'tempoText)))))
+ (format #f "\\tempo ~a" (scheme-expr->lily-string ?tempo-text)))))
;;; \clef
(define clef-name-alist #f)
(define (gen-condition expr pattern)
"Helper function for `with-music-match'.
Generate an form that checks if the properties of `expr'
-match thoses desscribed in `pattern'."
+match thoses described in `pattern'."
(let* (;; all (property . value) found at the first depth in pattern,
;; including a (name . <Musictype>) pair.
(pat-all-props (cons (cons 'name (second pattern))
(make-music 'TransposedMusic
'element (ly:music-transpose music pitch)))
-(define-ly-syntax-simple (tempo duration tempo)
+(define-ly-syntax-simple (tempo text duration tempo)
+ (let ((props (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))))
+ (set! props (cons
+ (if text (make-property-set 'tempoText text)
+ (make-property-unset 'tempoText))
+ props))
+ (context-spec-music
+ (make-sequential-music props)
+ 'Score)))
+
+(define-ly-syntax-simple (tempoText text)
(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 (skip-music dur)
;;;; Jan Nieuwenhuizen <janneke@gnu.org>
;; 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* ((hide_note (eq? #t (ly:context-property context 'tempoHideNote)))
+ (note-mark (if (and (not hide_note) (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) )
+ (make-concat-markup (list
+ (make-general-align-markup Y DOWN note-mark)
+ (make-simple-markup " ")
+ (make-simple-markup "=")
+ (make-simple-markup " ")
+ (make-simple-markup (number->string count))))
+ #f))
+ (text-markup (if (not (null? text))
+ (make-bold-markup text)
+ #f)))
+ (if text-markup
+ (if note-markup
+ (make-line-markup (list text-markup
+ (make-concat-markup (list (make-simple-markup "(")
+ note-markup
+ (make-simple-markup ")")))))
+ (make-line-markup (list text-markup))
+ )
+ (if note-markup
+ (make-line-markup (list note-markup))
+ #f
+ )
+ )
+ )
+)
(define-public (format-mark-alphabet mark context)
(make-bold-markup (make-markalphabet-markup (1- mark))))