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.

I'm now trying to extend the \tempo function, so that it includes an optional 
text markup, which is displayed in the tempo mark (e.g. 
http://lsr.dsi.unimi.it/LSR/Item?id=444). My idea is to allow any of the 
following types of tempo settings:
    \tempo 4=120 
    \tempo "Allegro" 4=120
    \tempo "Allegro"
    \tempo \markup{\italic \medium "Allegro"}
etc.

Attached is a patch (for current master), which is my first attempt to implent 
this. 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

So, in short, the patch is really on its way, but not yet ready for inclusion 
in master. With this mail I simply want to know if I'm on the right track 
with the patch and what could/should be done differently. (E.g. should the 
metronomeMarkFormatter include the logic whether to print text, note=count or 
both, or should that go into the engraver? Am I using the right methods to 
check for sensible values? etc.)

So, what shall I change in the patch?

An example file is also attached, which uses any of the \tempo forms given 
above. Apparently, it will only run with the patch applied...
Apparently, the PDF is too large for the mailing list (its 30kB binary), so I 
uploaded it to our server:
http://www.fam.tuwien.ac.at/~reinhold/temp/metronome-test.pdf

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 3357cca546aa50c8dea8d0b2dd9db2b688fac6bf Mon Sep 17 00:00:00 2001
From: Reinhold Kainhofer <[EMAIL PROTECTED]>
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 <[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* ((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

\version "2.11.48"

\displayLilyMusic \relative c'' { \tempo 4=120 c1 }
\displayLilyMusic \relative c'' { \tempo "Allegro" 4=120 c1 }
\displayLilyMusic \relative c'' { 
  \tempo "Allegro" 4=120 c1 
  \tempo "Allegro" 4=120 c1 
  \tempo "Allegro" 4=110 c1 
  \tempo "Allegretto" 4=110 c1 
}
\displayLilyMusic \relative c'' { \tempo "Allegro" c1 }
\displayLilyMusic \relative c'' { \tempo "Allegro" c1 \set Score.tempoText = #"blah" d1}
\displayLilyMusic \relative c'' { \tempo \markup{\italic \medium "Allegro"} c1 }
_______________________________________________
lilypond-devel mailing list
lilypond-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/lilypond-devel

Reply via email to