Am Freitag, 13. Juni 2008 schrieb Neil Puttock:
> 2008/6/12 Reinhold Kainhofer <[EMAIL PROTECTED]>:
> > Am Mittwoch, 11. Juni 2008 schrieb Neil Puttock:
> >
> > Here is an updated patch with all the issues resolved. I've also added a
> > regression test, the corresponding PDF file is uploaded at:
> > http://www.fam.tuwien.ac.at/~reinhold/temp/metronome-text.pdf
-...]
> - since format-metronome-markup determines whether to create the text
> markup by checking for an empty list, you probably want the parser to
> send SCM_EOL for \tempo dur = count; otherwise you'll get the
> unfortunate result shown below. :)

Oops, you really got me there. If there is a text, I set the tempoText 
property, but I forgot that if that property is already set, I need to unset 
it there... Fixed with the attached patch.

> - ideally, you need two concat operations to prevent the spaces around
> the equals sign being lost.

Right. However, using two concats would make things much more complicated. I 
simply inserted an explicit space before and after the =...

Cheers,
Reinhold


-- 
------------------------------------------------------------------
Reinhold Kainhofer, Vienna University of Technology, Austria
email: [EMAIL PROTECTED], http://reinhold.kainhofer.com/
 * Financial and Actuarial Mathematics, TU Wien, http://www.fam.tuwien.ac.at/
 * K Desktop Environment, http://www.kde.org, KOrganizer maintainer
 * Chorvereinigung "Jung-Wien", http://www.jung-wien.at/
From 21b04a532c6e527ca2d1eff1b40d475426587033 Mon Sep 17 00:00:00 2001
From: Reinhold Kainhofer <[EMAIL PROTECTED]>
Date: Sat, 7 Jun 2008 00:35:19 +0200
Subject: [PATCH] New Feature: 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.

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   |   35 +++++++++++++++++++++++++++
 lily/metronome-engraver.cc           |   21 +++++++++++----
 lily/parser.yy                       |   16 ++++++++++-
 python/convertrules.py               |    9 +++++++
 scm/define-context-properties.scm    |    4 ++-
 scm/define-music-display-methods.scm |   37 +++++++++++++++++++++++++---
 scm/display-lily.scm                 |    2 +-
 scm/ly-syntax-constructors.scm       |   22 ++++++++++++----
 scm/translation-functions.scm        |   44 ++++++++++++++++++++++++++-------
 9 files changed, 160 insertions(+), 30 deletions(-)
 create mode 100644 input/regression/metronome-text.ly

diff --git a/input/regression/metronome-text.ly b/input/regression/metronome-text.ly
new file mode 100644
index 0000000..904035f
--- /dev/null
+++ b/input/regression/metronome-text.ly
@@ -0,0 +1,35 @@
+\version "2.11.48"
+
+\header{
+  texidoc="
+The tempo command supports text markup and/or note=count. Using the
+Score.hideTempoNote, one can hide the note=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
+  
+}
diff --git a/lily/metronome-engraver.cc b/lily/metronome-engraver.cc
index 5bc7153..c7f7277 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,9 @@ ADD_TRANSLATOR (Metronome_mark_engraver,
 		"stavesFound "
 		"metronomeMarkFormatter "
 		"tempoUnitDuration "
-		"tempoUnitCount ",
+		"tempoUnitCount "
+		"tempoText "
+		"tempoHideNote ",
 
 		/* write */
 		""
diff --git a/lily/parser.yy b/lily/parser.yy
index 3b690e8..feb763f 100644
--- a/lily/parser.yy
+++ b/lily/parser.yy
@@ -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 );
+	}
 	;
 
 /*
diff --git a/python/convertrules.py b/python/convertrules.py
index 66c0835..7bf3286 100644
--- a/python/convertrules.py
+++ b/python/convertrules.py
@@ -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
diff --git a/scm/define-context-properties.scm b/scm/define-context-properties.scm
index 469b900..77ad346 100644
--- a/scm/define-context-properties.scm
+++ b/scm/define-context-properties.scm
@@ -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.")
diff --git a/scm/define-music-display-methods.scm b/scm/define-music-display-methods.scm
index b1b9111..6240c4e 100644
--- a/scm/define-music-display-methods.scm
+++ b/scm/define-music-display-methods.scm
@@ -880,10 +880,11 @@ 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."
-  (with-music-match (expr (music 'ContextSpeccedMusic
+  (let* ((count_expr (with-music-match (expr (music 'ContextSpeccedMusic
 			    element (music 'SequentialMusic
 				      elements ((music 'PropertySet
 						  symbol 'tempoWholesPerMinute)
@@ -893,9 +894,37 @@ Otherwise, return #f."
 						(music 'PropertySet
 						  value ?unit-count
 						  symbol 'tempoUnitCount)))))
-    (format #f "\\tempo ~a = ~a"
-	    (duration->lily-string ?unit-duration #:force-duration #t)
-	    ?unit-count)))
+			(format #f "~a = ~a"
+				(duration->lily-string ?unit-duration #:force-duration #t)
+				?unit-count)))
+	 ; Extract a textual representation. We need to match count, duration etc. too!
+	 (text_expr (or (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)
+						(music 'PropertySet
+						  value ?tempo-text
+						 symbol 'tempoText)))))
+			    ?tempo-text)
+			(with-music-match (expr (music 'ContextSpeccedMusic
+			    element (music 'SequentialMusic
+				      elements ((music 'PropertySet
+						  value ?tempo-text
+						 symbol 'tempoText)))))
+			  ?tempo-text))))
+    (if text_expr
+      (if count_expr (format #f "\\tempo ~a ~a" (scheme-expr->lily-string text_expr) count_expr)
+                     (format #f "\\tempo ~a" (scheme-expr->lily-string text_expr)))
+      (if count_expr (format #f "\\tempo ~a" count_expr)
+                     #f))
+  )
+)
 
 ;;; \clef 
 (define clef-name-alist #f)
diff --git a/scm/display-lily.scm b/scm/display-lily.scm
index eb1b876..c53da46 100644
--- a/scm/display-lily.scm
+++ b/scm/display-lily.scm
@@ -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))
diff --git a/scm/ly-syntax-constructors.scm b/scm/ly-syntax-constructors.scm
index 9e6325a..d19b360 100644
--- a/scm/ly-syntax-constructors.scm
+++ b/scm/ly-syntax-constructors.scm
@@ -78,15 +78,25 @@
   (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 (append props (list 
+            (if text (make-property-set 'tempoText text)
+                     (make-property-unset 'tempoText)))))
+    (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)
diff --git a/scm/translation-functions.scm b/scm/translation-functions.scm
index 366f44f..70026d0 100644
--- a/scm/translation-functions.scm
+++ b/scm/translation-functions.scm
@@ -6,16 +6,40 @@
 ;;;;		     Jan Nieuwenhuizen <[EMAIL PROTECTED]>
 
 ;; 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))))
-- 
1.5.4.3

_______________________________________________
lilypond-devel mailing list
lilypond-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/lilypond-devel

Reply via email to