From fa202533ea1095ae183b24bd34b0beefb51d47ac Mon Sep 17 00:00:00 2001
From: Han-Wen Nienhuys <hanwen@xs4all.nl>
Date: Thu, 27 Jul 2006 15:52:39 +0000
Subject: [PATCH] * input/regression/instrument-switch.ly: new file.

* lily/instrument-switch-engraver.cc (process_music): new file.

* ly/engraver-init.ly: add Instrument_switch_engraver

* ly/music-functions-init.ly: \instrumentSwitch

* scm/define-context-properties.scm
(all-user-translation-properties): add instrumentCueName

* scm/define-grobs.scm (all-grob-descriptions): add InstrumentSwitch
---
 ChangeLog                             | 19 ++++++++
 input/regression/instrument-switch.ly | 31 ++++++++++++++
 lily/instrument-name-engraver.cc      | 27 ++++++++----
 lily/instrument-switch-engraver.cc    | 62 +++++++++++++++++++++++++++
 lily/lily-lexer.cc                    |  1 -
 lily/parser.yy                        |  6 ---
 ly/engraver-init.ly                   |  2 +-
 ly/music-functions-init.ly            | 46 ++++++++++++++++++--
 scm/define-context-properties.scm     |  1 +
 scm/define-grobs.scm                  | 14 ++++++
 10 files changed, 189 insertions(+), 20 deletions(-)
 create mode 100644 input/regression/instrument-switch.ly
 create mode 100644 lily/instrument-switch-engraver.cc

diff --git a/ChangeLog b/ChangeLog
index b4d20731a2..e1c3ed326f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,24 @@
+2006-07-27  Han-Wen Nienhuys  <hanwen@lilypond.org>
+
+	* input/regression/instrument-switch.ly: new file.
+
+	* lily/instrument-switch-engraver.cc (process_music): new file.
+
+	* ly/engraver-init.ly: add Instrument_switch_engraver
+
+	* ly/music-functions-init.ly: \instrumentSwitch
+
+	* scm/define-context-properties.scm
+	(all-user-translation-properties): add instrumentCueName
+
+	* scm/define-grobs.scm (all-grob-descriptions): add InstrumentSwitch
+
 2006-07-26  Han-Wen Nienhuys  <hanwen@lilypond.org>
 
+	* ly/music-functions-init.ly: music function \transposition.
+
+	* lily/parser.yy (command_element): softcode \transposition.
+
 	* lily/fall-engraver.cc (process_music): delta-pitch -> delta-step.
 	(process_music): oops.
 
diff --git a/input/regression/instrument-switch.ly b/input/regression/instrument-switch.ly
new file mode 100644
index 0000000000..73f6dff473
--- /dev/null
+++ b/input/regression/instrument-switch.ly
@@ -0,0 +1,31 @@
+
+\header {
+
+  texidoc = "The @code{switchInstrument} music function modifies
+properties for an in staff instrument switch. "
+  }
+
+\version "2.9.13"
+\addInstrumentDefinition #"bassClar"
+  #`((instrumentTransposition . ,(ly:make-pitch -1 6 FLAT))
+     (instrumentName . "bla") 
+     (shortInstrumentName . "bl")
+     (clefGlyph . "clefs.F") 
+     (middleCPosition . 6)
+     (clefPosition . 2)
+     (instrumentCueName . ,(make-bold-markup "cl. B"))
+     (midiInstrument . "clarinet"))
+
+
+\paper {
+  ragged-right = ##t
+}
+
+\relative
+{
+  c4
+  \instrumentSwitch "bassClar"
+  c2.\break
+  c1\break
+  c
+}
diff --git a/lily/instrument-name-engraver.cc b/lily/instrument-name-engraver.cc
index 76e0a88e33..4746d4a09d 100644
--- a/lily/instrument-name-engraver.cc
+++ b/lily/instrument-name-engraver.cc
@@ -34,6 +34,7 @@ protected:
   DECLARE_ACKNOWLEDGER (axis_group);
   void process_music ();
   void start_spanner ();
+  void consider_start_spanner ();
   void stop_spanner ();
 };
 
@@ -48,11 +49,11 @@ Instrument_name_engraver::Instrument_name_engraver ()
 void
 Instrument_name_engraver::process_music ()
 {
-  start_spanner ();
+  consider_start_spanner ();
 }
 
 void
-Instrument_name_engraver::start_spanner ()
+Instrument_name_engraver::consider_start_spanner ()
 {
   SCM long_text = get_property ("instrumentName");
   SCM short_text = get_property ("shortInstrumentName");
@@ -72,19 +73,27 @@ Instrument_name_engraver::start_spanner ()
     {
       if (text_spanner_)
 	stop_spanner ();
-      
-      text_spanner_ = make_spanner ("InstrumentName", SCM_EOL);
-	  
-      Grob *col = unsmob_grob (get_property ("currentCommandColumn"));
-      text_spanner_->set_bound (LEFT, col);
-      text_spanner_->set_property ("text", short_text);
-      text_spanner_->set_property ("long-text", long_text);
 
+      
       short_text_ = short_text;
       long_text_ = long_text;
+
+      start_spanner ();
     }
 }
 
+void
+Instrument_name_engraver::start_spanner ()
+{
+  text_spanner_ = make_spanner ("InstrumentName", SCM_EOL);
+	  
+  Grob *col = unsmob_grob (get_property ("currentCommandColumn"));
+  text_spanner_->set_bound (LEFT, col);
+  text_spanner_->set_property ("text", short_text_);
+  text_spanner_->set_property ("long-text", long_text_);
+}
+
+
 void
 Instrument_name_engraver::acknowledge_axis_group (Grob_info info)
 {
diff --git a/lily/instrument-switch-engraver.cc b/lily/instrument-switch-engraver.cc
new file mode 100644
index 0000000000..67a6803a0e
--- /dev/null
+++ b/lily/instrument-switch-engraver.cc
@@ -0,0 +1,62 @@
+/*
+  instrument-switch-engraver.cc -- implement
+
+  source file of the GNU LilyPond music typesetter
+
+  (c) 2006 Han-Wen Nienhuys <hanwen@lilypond.org>
+
+*/
+
+#include "engraver.hh"
+#include "item.hh"
+#include "translator.icc"
+
+
+class Instrument_switch_engraver : public Engraver
+{
+
+  TRANSLATOR_DECLARATIONS(Instrument_switch_engraver);
+protected:
+  Grob *text_;
+  SCM cue_name_;
+
+  void stop_translation_time_step ();
+  void process_music ();
+};
+
+
+Instrument_switch_engraver::Instrument_switch_engraver ()
+{
+  cue_name_ = SCM_EOL;
+  text_ = 0;
+}
+
+void
+Instrument_switch_engraver::process_music ()
+{
+  SCM cue_text = get_property ("instrumentCueName");
+  
+  if (!scm_is_eq (cue_name_, cue_text))
+    {
+      text_ = make_item ("InstrumentSwitch", SCM_EOL);
+      text_->set_property ("text", cue_text);
+      cue_name_ = cue_text;
+    }
+}
+
+void
+Instrument_switch_engraver::stop_translation_time_step ()
+{
+  text_ = 0;
+}
+
+ADD_TRANSLATOR(Instrument_switch_engraver,
+	       "Create a cue text for taking instrument.",
+			
+	       "InstrumentSwitch ",
+
+	       "",
+
+	       "instrumentCueName",
+			
+	       "");
diff --git a/lily/lily-lexer.cc b/lily/lily-lexer.cc
index e677b9e5c5..2392f47b36 100644
--- a/lily/lily-lexer.cc
+++ b/lily/lily-lexer.cc
@@ -74,7 +74,6 @@ static Keyword_ent the_key_tab[]
   {"time", TIME_T},
   {"times", TIMES},
   {"transpose", TRANSPOSE},
-  {"transposition", TRANSPOSITION},
   {"type", TYPE},
   {"unset", UNSET},
   {"with", WITH},
diff --git a/lily/parser.yy b/lily/parser.yy
index a970e8be88..d0109edac5 100644
--- a/lily/parser.yy
+++ b/lily/parser.yy
@@ -206,7 +206,6 @@ void set_music_properties (Music *p, SCM a);
 %token TEMPO "\\tempo"
 %token TIMES "\\times"
 %token TRANSPOSE "\\transpose"
-%token TRANSPOSITION "\\transposition"
 %token TYPE "\\type"
 %token UNSET "\\unset"
 %token WITH "\\with"
@@ -1470,11 +1469,6 @@ command_element:
 			$$ = MAKE_SYNTAX ("bar-check", @$, SCM_UNDEFINED);
 
 	}
-	| TRANSPOSITION pitch {
-		Pitch middle_c;
-		Pitch sounds_as_c = pitch_interval (*unsmob_pitch ($2), middle_c);
-		$$ = MAKE_SYNTAX ("property-operation", @$, SCM_BOOL_F, ly_symbol2scm ("Staff"), ly_symbol2scm ("PropertySet"), ly_symbol2scm ("instrumentTransposition"), sounds_as_c.smobbed_copy ());
-	}
 	| PARTIAL duration_length	{
 		Moment m = - unsmob_duration ($2)->get_length ();
 		$$ = MAKE_SYNTAX ("property-operation", @$, SCM_BOOL_F, ly_symbol2scm ("Timing"), ly_symbol2scm ("PropertySet"), ly_symbol2scm ("measurePosition"), m.smobbed_copy ());
diff --git a/ly/engraver-init.ly b/ly/engraver-init.ly
index 7e51f51575..cba936c6f9 100644
--- a/ly/engraver-init.ly
+++ b/ly/engraver-init.ly
@@ -222,7 +222,7 @@ contained staves are not connected vertically."
   \consists "Tie_engraver"
   \consists "Tuplet_engraver"
   \consists "Grace_engraver"
-
+  \consists "Instrument_switch_engraver"
   \consists "Skip_event_swallow_translator"
 }
 
diff --git a/ly/music-functions-init.ly b/ly/music-functions-init.ly
index 141d107cd6..8ff3e62851 100644
--- a/ly/music-functions-init.ly
+++ b/ly/music-functions-init.ly
@@ -201,6 +201,39 @@ acceleration/deceleration. "
 grace =
 #(def-grace-function startGraceMusic stopGraceMusic)
 
+
+"instrument-definitions" = #'()
+
+addInstrumentDefinition =
+#(define-music-function
+   (parser location name lst) (string? list?)
+
+   (set! instrument-definitions (acons name lst instrument-definitions))
+
+   (make-music 'SequentialMusic 'void #t))
+
+
+instrumentSwitch =
+#(define-music-function
+   (parser location name) (string?)
+   (let*
+       ((handle  (assoc name instrument-definitions))
+	(instrument-def (if handle (cdr handle) '()))
+	)
+
+     (if (not handle)
+	 (ly:input-message "No such instrument: ~a" name))
+     (context-spec-music
+      (make-music 'SimultaneousMusic
+		  'elements
+		  (map (lambda (kv)
+			 (make-property-set
+			  (car kv)
+			  (cdr kv)))
+		       instrument-def))
+      'Staff)))
+
+
 keepWithTag =
 #(define-music-function
   (parser location tag music) (symbol? ly:music?)
@@ -290,7 +323,6 @@ removeWithTag =
 %% doing
 %% define-music-function in a .scm causes crash.
 
-
 octave =
 #(define-music-function (parser location pitch-note) (ly:music?)
    "octave check"
@@ -480,8 +512,8 @@ spacingTweaks =
    (make-music 'SequentialMusic 'void #t))
 
 
-transposedCueDuring = #
-(define-music-function
+transposedCueDuring =
+#(define-music-function
   (parser location what dir pitch-note main-music)
   (string? ly:dir? ly:music? ly:music?)
 
@@ -502,7 +534,15 @@ as a first or second voice."
 
 
 
+transposition =
+#(define-music-function (parser location pitch-note) (ly:music?)
+   "Set instrument transposition"
 
+   (context-spec-music
+    (make-property-set 'instrumentTransposition
+		       (ly:pitch-diff (ly:make-pitch 0 0 0) (pitch-of-note pitch-note)))
+        'Staff
+))
 
 tweak = #(define-music-function (parser location sym val arg)
 	   (symbol? scheme? ly:music?)
diff --git a/scm/define-context-properties.scm b/scm/define-context-properties.scm
index b97a71dbf4..837238ab58 100644
--- a/scm/define-context-properties.scm
+++ b/scm/define-context-properties.scm
@@ -253,6 +253,7 @@ selector for tab notation.")
 printed as numbers, but only as extender lines.")
      
 
+     (instrumentCueName ,markup? "Name to print if another instrument is to be taken.")
      (instrumentName ,markup? "The name to print left of a staff.  The
 @code{instrument} property labels the staff in the first system, and
 the @code{instr} property labels following lines.")
diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm
index d4c3636043..856ed8226e 100644
--- a/scm/define-grobs.scm
+++ b/scm/define-grobs.scm
@@ -731,6 +731,20 @@
 				side-position-interface
 				font-interface))))))
 
+    (InstrumentSwitch
+     . (
+	(padding . 0.3)
+	(stencil . ,ly:text-interface::print)
+	(Y-offset . ,ly:side-position-interface::y-aligned-side)
+	(X-offset . ,ly:self-alignment-interface::x-aligned-on-self)
+	(staff-padding . 2)
+	(direction . ,UP)
+	(self-alignment-X . ,CENTER)
+	(meta . ((class . Item)
+		 (interfaces . (system-start-text-interface
+				side-position-interface
+				font-interface))))))
+    
     (KeyCancellation
      . (
 	(stencil . ,ly:key-signature-interface::print)
-- 
2.39.5