]> git.donarmstrong.com Git - lilypond.git/commitdiff
New Feature: Include text in \tempo indications
authorReinhold Kainhofer <reinhold@kainhofer.com>
Fri, 6 Jun 2008 22:35:19 +0000 (00:35 +0200)
committerReinhold Kainhofer <reinhold@kainhofer.com>
Mon, 23 Jun 2008 16:08:53 +0000 (18:08 +0200)
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

input/regression/metronome-text.ly [new file with mode: 0644]
lily/metronome-engraver.cc
lily/parser.yy
python/convertrules.py
scm/define-context-properties.scm
scm/define-music-display-methods.scm
scm/display-lily.scm
scm/ly-syntax-constructors.scm
scm/translation-functions.scm

diff --git a/input/regression/metronome-text.ly b/input/regression/metronome-text.ly
new file mode 100644 (file)
index 0000000..c8216eb
--- /dev/null
@@ -0,0 +1,35 @@
+\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
+
+}
index 5bc715339c69365ccda96429896bf3242418bc7c..c7f7277b438b8da0502970d93bd607e08e2c3d7b 100644 (file)
@@ -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,9 @@ ADD_TRANSLATOR (Metronome_mark_engraver,
                "stavesFound "
                "metronomeMarkFormatter "
                "tempoUnitDuration "
-               "tempoUnitCount ",
+               "tempoUnitCount "
+               "tempoText "
+               "tempoHideNote ",
 
                /* write */
                ""
index 9a78c74437038cf361333fba44d9dd0ad1db3816..59cbf58502275c853ff0f07e344f8e46d1dd635f 100644 (file)
@@ -820,8 +820,20 @@ output_def_body:
 
 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 );
+       }
        ;
 
 /*
index 9291513f7b300c2d85bf583e83b49522f92c6f60..6cddc6debc6f70e5fa273488e85afa67c7a490bb 100644 (file)
@@ -3056,3 +3056,12 @@ def conv (str):
     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
index 469b900acee053f7ffceef6d33d9814df9f161bf..77ad34698b9f555c92b2b998544a2f3eee27d5bd 100644 (file)
@@ -301,7 +301,7 @@ manual beams are considered.  Possible values include
 @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}.")
@@ -432,6 +432,8 @@ 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.")
+     (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.")
index b1b9111e13c58839086288e8d49834eaf695ed2e..e7b258dfed37fd15c0538b30ad01858a170ab5d6 100644 (file)
@@ -881,21 +881,48 @@ Otherwise, return #f."
     "\\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)
index eb1b876739308d4bdff97b309902bf0f4ebb5c8f..c53da4680a80e4149b117722cfceec3ca3907b55 100644 (file)
@@ -132,7 +132,7 @@ display method will be called."
 (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))
index 9e6325a1563b9897828eb8e8ebfa3e2cfac3fdb2..4479d01d3191f8c794338be8beb1896f8505a4ba 100644 (file)
   (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)
index 2ceee74ab77f767d5d875d41d479597fedf0cf48..fc7552fc355d4ed4e87520e6848cbd7afb3c1214 100644 (file)
@@ -6,16 +6,40 @@
 ;;;;                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))))