]> git.donarmstrong.com Git - lilypond.git/commitdiff
New instrument name positioning in scheme.
authorNeil Puttock <n.puttock@gmail.com>
Sun, 9 Aug 2009 22:25:15 +0000 (23:25 +0100)
committerNeil Puttock <n.puttock@gmail.com>
Sun, 9 Aug 2009 22:33:54 +0000 (23:33 +0100)
* split ly:system-start-text::print into three scheme callbacks in
  output-lib.scm (X-/Y-offset calculations and print function)

* compensate for system start delimiter extents so all instrument names
  in a system are aligned correctly based on self-alignment-X

* use 'when from left-bound instead of get_break_index () to determine
  which text to print; this fixes incorrect indentation and text for
  shortInstrumentName overrides (Issue #452)

* remove acknowledger for system-start-text from
  system-start-delimiter-engraver.cc

* remove system-start-text.cc

* add system-start-text-interface to define-grob-interfaces.scm

* add library functions used by new callbacks to lily-library.scm
  and output-lib.scm

* update snippets broken by changes

* add news entry and convert rule

Documentation/changes.tely
Documentation/snippets/incipit.ly
Documentation/snippets/new/incipit.ly [new file with mode: 0644]
input/regression/incipit.ly
lily/system-start-delimiter-engraver.cc
lily/system-start-text.cc [deleted file]
python/convertrules.py
scm/define-grob-interfaces.scm
scm/define-grobs.scm
scm/lily-library.scm
scm/output-lib.scm

index 3d1b6f51fb0e48fdca42ec1973845c0b9ae368ec..98c22f58dcfeaedea4eaa6bc72d0f19d36f68046 100644 (file)
@@ -62,6 +62,43 @@ which scares away people.
 
 @end ignore
 
+@item
+Instrument names and vocal names now take into account the extent of
+system start delimiters in other staves for their positioning,
+resulting in improved default alignment for left-, center- and
+right-aligned names.
+@lilypond[quote,indent=18\mm]
+<<
+  \new StaffGroup <<
+    \new GrandStaff <<
+      \new Staff {
+        \set Staff.instrumentName = #"Piccolo"
+        c''1
+      }
+      \new Staff {
+        \set Staff.instrumentName = #"Flute"
+        c''1
+      }
+    >>
+    \new Staff {
+      \set Staff.instrumentName = #"Bassoon"
+      \clef tenor
+      c'1
+    }
+  >>
+  \new PianoStaff <<
+    \set PianoStaff.instrumentName = #"Piano"
+    \context Staff = "up" {
+      c'1
+    }
+    \context Staff = "down" {
+      \clef bass
+      c1
+    }
+  >>
+>>
+@end lilypond
+
 @item
 Braces in markup can now be selected by point size using the markup commands
 @code{\left-brace} and @code{\right-brace}.
@@ -95,7 +132,7 @@ c4( d e f)
 @end lilypond
 
 @item
-An eyeglasses markup was added, incidating strongly to look at the
+An eyeglasses markup was added, indicating strongly to look at the
 conductor for instructions:
 @lilypond[quote,relative=2]
 \mark \markup { \eyeglasses }
index 46710df5a18c9af6e9e6386149130c2f3acfd923..3501ce2334e47cbae4807ba99f23c42eb4060dd1 100644 (file)
@@ -1,11 +1,10 @@
-%% Do not edit this file; it is automatically
-%% generated from LSR http://lsr.dsi.unimi.it
-%% This file is in the public domain.
+% Do not edit this file; it is automatically
+% generated from Documentation/snippets/new
+% This file is in the public domain.
+%% Note: this file works from version 2.13.4
 \version "2.13.4"
 
 \header {
-  lsrtags = "staff-notation, ancient-notation"
-
 %% Translation of GIT committish: b2d4318d6c53df8469dfa4da09b27c15a374d0ca
   texidoces = "
 Los «incipit» se pueden escribir utilizando el grob del nombre del
@@ -14,48 +13,52 @@ nombre del instrumento y del incipit."
 
  doctitlees = "Incipit"
 
+  lsrtags = "staff-notation, ancient-notation"
   texidoc = "
 Incipits can be added using the instrument name grob, but keeping
 separate the instrument name definition and the incipit definition.
-
 "
   doctitle = "Incipit"
 } % begin verbatim
 
+
 incipit =
 #(define-music-function (parser location incipit-music) (ly:music?)
   #{
     \once \override Staff.InstrumentName #'self-alignment-X = #RIGHT
     \once \override Staff.InstrumentName #'self-alignment-Y = #UP
-    \once \override Staff.InstrumentName #'Y-offset = #4
+    \once \override Staff.InstrumentName #'Y-offset =
+      #(lambda (grob)
+         (+ 4 (system-start-text::calc-y-offset grob)))
     \once \override Staff.InstrumentName #'padding = #0.3
     \once \override Staff.InstrumentName #'stencil =
-    #(lambda (grob)
-       (let* ((instrument-name (ly:grob-property grob 'long-text))
-              (layout (ly:output-def-clone (ly:grob-layout grob)))
-              (music (make-music 'SequentialMusic
-                      'elements (list (make-music 'ContextSpeccedMusic
-                                        'context-type 'MensuralStaff
-                                        'element (make-music 'PropertySet
-                                                   'symbol 'instrumentName
-                                                   'value instrument-name))
-                                      $incipit-music)))
-              (score (ly:make-score music))
-              (mm (ly:output-def-lookup layout 'mm))
-              (indent (ly:output-def-lookup layout 'indent))
-              (width (ly:output-def-lookup layout 'incipit-width))
-              (incipit-width (if (number? width)
-                                 (* width mm)
-                                 (* indent 0.5))))
-         (ly:output-def-set-variable! layout 'indent (- indent incipit-width))
-         (ly:output-def-set-variable! layout 'line-width indent)
-         (ly:output-def-set-variable! layout 'ragged-right #f)
-         (ly:output-def-set-variable! layout 'ragged-last #f)
-         (ly:output-def-set-variable! layout 'system-count 1)
-         (ly:score-add-output-def! score layout)
-         (ly:grob-set-property! grob 'long-text
-               (markup #:score score))
-         (ly:system-start-text::print grob)))
+      #(lambda (grob)
+         (let* ((instrument-name (ly:grob-property grob 'long-text))
+                (layout (ly:output-def-clone (ly:grob-layout grob)))
+                (music (make-sequential-music
+                        (list (context-spec-music
+                               (make-property-set
+                                'instrumentName instrument-name)
+                               'MensuralStaff)
+                              $incipit-music)))
+                (score (ly:make-score music))
+                (mm (ly:output-def-lookup layout 'mm))
+                (indent (ly:output-def-lookup layout 'indent))
+                (width (ly:output-def-lookup layout 'incipit-width))
+                (incipit-width (if (number? width)
+                                   (* width mm)
+                                   (* indent 0.5))))
+
+           (ly:output-def-set-variable! layout 'indent (- indent
+                                                          incipit-width))
+           (ly:output-def-set-variable! layout 'line-width indent)
+           (ly:output-def-set-variable! layout 'ragged-right #f)
+           (ly:output-def-set-variable! layout 'ragged-last #f)
+           (ly:output-def-set-variable! layout 'system-count 1)
+           (ly:score-add-output-def! score layout)
+           (ly:grob-set-property! grob 'long-text
+                                  (markup #:score score))
+           (system-start-text::print grob)))
   #})
 
 %%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/Documentation/snippets/new/incipit.ly b/Documentation/snippets/new/incipit.ly
new file mode 100644 (file)
index 0000000..4b18983
--- /dev/null
@@ -0,0 +1,273 @@
+\version "2.13.4"
+
+\header {
+  lsrtags = "staff-notation, ancient-notation"
+  texidoc = "
+Incipits can be added using the instrument name grob, but keeping
+separate the instrument name definition and the incipit definition.
+"
+  doctitle = "Incipit"
+}
+
+incipit =
+#(define-music-function (parser location incipit-music) (ly:music?)
+  #{
+    \once \override Staff.InstrumentName #'self-alignment-X = #RIGHT
+    \once \override Staff.InstrumentName #'self-alignment-Y = #UP
+    \once \override Staff.InstrumentName #'Y-offset =
+      #(lambda (grob)
+         (+ 4 (system-start-text::calc-y-offset grob)))
+    \once \override Staff.InstrumentName #'padding = #0.3
+    \once \override Staff.InstrumentName #'stencil =
+      #(lambda (grob)
+         (let* ((instrument-name (ly:grob-property grob 'long-text))
+                (layout (ly:output-def-clone (ly:grob-layout grob)))
+                (music (make-sequential-music
+                        (list (context-spec-music
+                               (make-property-set
+                                'instrumentName instrument-name)
+                               'MensuralStaff)
+                              $incipit-music)))
+                (score (ly:make-score music))
+                (mm (ly:output-def-lookup layout 'mm))
+                (indent (ly:output-def-lookup layout 'indent))
+                (width (ly:output-def-lookup layout 'incipit-width))
+                (incipit-width (if (number? width)
+                                   (* width mm)
+                                   (* indent 0.5))))
+
+           (ly:output-def-set-variable! layout 'indent (- indent
+                                                          incipit-width))
+           (ly:output-def-set-variable! layout 'line-width indent)
+           (ly:output-def-set-variable! layout 'ragged-right #f)
+           (ly:output-def-set-variable! layout 'ragged-last #f)
+           (ly:output-def-set-variable! layout 'system-count 1)
+           (ly:score-add-output-def! score layout)
+           (ly:grob-set-property! grob 'long-text
+                                  (markup #:score score))
+           (system-start-text::print grob)))
+  #})
+
+%%%%%%%%%%%%%%%%%%%%%%%%%
+
+global = {
+  \set Score.skipBars = ##t
+  \key g \major
+  \time 4/4
+
+  % the actual music
+  \skip 1*8
+
+  % let finis bar go through all staves
+  \override Staff.BarLine #'transparent = ##f
+
+  % finis bar
+  \bar "|."
+}
+
+discantusIncipit = <<
+  \new MensuralVoice = "discantusIncipit" <<
+    \repeat unfold 9 { s1 \noBreak }
+    {
+      \clef "neomensural-c1"
+      \key f \major
+      \time 2/2
+      c''1.
+    }
+  >>
+  \new Lyrics \lyricsto discantusIncipit { IV- }
+>>
+
+discantusNotes = {
+  \transpose c' c'' {
+    \clef "treble"
+    d'2. d'4 |
+    b e' d'2 |
+    c'4 e'4.( d'8 c' b |
+    a4) b a2 |
+    b4.( c'8 d'4) c'4 |
+    \once \override NoteHead #'transparent = ##t
+    c'1 |
+    b\breve |
+  }
+}
+
+discantusLyrics = \lyricmode {
+  Ju -- bi -- |
+  la -- te De -- |
+  o, om --
+  nis ter -- |
+  ra, __ om- |
+  "..." |
+  -us. |
+}
+
+altusIncipit = <<
+  \new MensuralVoice = "altusIncipit" <<
+    \repeat unfold 9 { s1 \noBreak }
+    {
+      \clef "neomensural-c3"
+      \key f \major
+      \time 2/2
+      r1 f'1.
+    }
+  >>
+  \new Lyrics \lyricsto altusIncipit { IV- }
+>>
+
+altusNotes = {
+  \transpose c' c'' {
+    \clef "treble"
+    % two measures
+    r2 g2. e4 fis g |
+    a2 g4 e |
+    fis g4.( fis16 e fis4) |
+    g1 |
+    \once \override NoteHead #'transparent = ##t
+    g1 |
+    g\breve |
+  }
+}
+
+altusLyrics = \lyricmode {
+  % two measures
+  Ju -- bi -- la -- te |
+  De -- o, om -- |
+  nis ter -- ra, |
+  "..." |
+  -us. |
+}
+
+tenorIncipit = <<
+  \new MensuralVoice = "tenorIncipit" <<
+    \repeat unfold 9 { s1 \noBreak }
+    {
+      \clef "neomensural-c4"
+      \key f \major
+      \time 2/2
+      r\longa
+      r\breve
+      r1 c'1.
+    }
+  >>
+  \new Lyrics \lyricsto tenorIncipit { IV- }
+>>
+
+tenorNotes = {
+  \transpose c' c' {
+    \once \override Staff.VerticalAxisGroup #'minimum-Y-extent = #'(-6 . 3)
+    \clef "treble_8"
+    R1 |
+    R1 |
+    R1 |
+    % two measures
+    r2 d'2. d'4 b e' |
+    \once \override NoteHead #'transparent = ##t
+    e'1 |
+    d'\breve |
+  }
+}
+
+tenorLyrics = \lyricmode {
+  % two measures
+  Ju -- bi -- la -- te |
+  "..." |
+  -us.
+}
+
+bassusIncipit = <<
+  \new MensuralVoice = "bassusIncipit" <<
+    \repeat unfold 9 { s1 \noBreak }
+    {
+      \clef "bass"
+      \key f \major
+      \time 2/2
+      %% incipit
+      r\maxima
+      f1.
+    }
+  >>
+  \new Lyrics \lyricsto bassusIncipit { IV- }
+>>
+
+bassusNotes = {
+  \transpose c' c' {
+    \clef "bass"
+    R1 |
+    R1 |
+    R1 |
+    R1 |
+    g2. e4 |
+    \once \override NoteHead #'transparent = ##t
+    e1 |
+    g\breve |
+  }
+}
+
+bassusLyrics = \lyricmode {
+  Ju -- bi- |
+  "..." |
+  -us.
+}
+
+\score {
+  <<
+    \new StaffGroup = choirStaff <<
+      \new Voice = "discantusNotes" <<
+        \global
+        \set Staff.instrumentName = #"Discantus"
+        \incipit \discantusIncipit
+        \discantusNotes
+      >>
+      \new Lyrics = "discantusLyrics" \lyricsto discantusNotes { \discantusLyrics }
+      \new Voice = "altusNotes" <<
+        \global
+        \set Staff.instrumentName = #"Altus"
+        \incipit \altusIncipit
+        \altusNotes
+      >>
+      \new Lyrics = "altusLyrics" \lyricsto altusNotes { \altusLyrics }
+      \new Voice = "tenorNotes" <<
+        \global
+        \set Staff.instrumentName = #"Tenor"
+        \incipit \tenorIncipit
+        \tenorNotes
+      >>
+      \new Lyrics = "tenorLyrics" \lyricsto tenorNotes { \tenorLyrics }
+      \new Voice = "bassusNotes" <<
+        \global
+        \set Staff.instrumentName = #"Bassus"
+        \incipit \bassusIncipit
+        \bassusNotes
+      >>
+      \new Lyrics = "bassusLyrics" \lyricsto bassusNotes { \bassusLyrics }
+    >>
+  >>
+  \layout {
+    \context {
+      \Score
+      %% no bar lines in staves or lyrics
+      \override BarLine #'transparent = ##t
+    }
+    %% the next two instructions keep the lyrics between the bar lines
+    \context {
+      \Lyrics
+      \consists "Bar_engraver"
+      \consists "Separating_line_group_engraver"
+    }
+    \context {
+      \Voice
+      %% no slurs
+      \override Slur #'transparent = ##t
+      %% Comment in the below "\remove" command to allow line
+      %% breaking also at those bar lines where a note overlaps
+      %% into the next measure.  The command is commented out in this
+      %% short example score, but especially for large scores, you
+      %% will typically yield better line breaking and thus improve
+      %% overall spacing if you comment in the following command.
+      %%\remove "Forbid_line_break_engraver"
+    }
+    indent = 6\cm
+    incipit-width = 4\cm
+  }
+}
index 31d9e6f252d66609a15f4ffa8384c0e536de3477..3dee8198a47481eac93f79c0fde9319acec994f5 100644 (file)
@@ -1,24 +1,27 @@
-\header {
-
-  texidoc = "Incipit can be printed using an InstrumentName grob."
+\version "2.13.4"
 
+\header {
+  texidoc = "Incipits can be printed using an @code{InstrumentName}
+grob."
 }
 
-\version "2.12.0"
-
-%% to avoid warnings:
+%% to prevent warnings/programming errors:
 #(set-object-property! 'music 'backend-type? ly:music?)
 #(set-object-property! 'music 'backend-doc "Incipit music")
+#(ly:add-interface 'incipit-interface "An incipit." '(music))
+#(let* ((instrument-def (assoc 'InstrumentName all-grob-descriptions))
+        (meta-def (assoc 'meta (cdr instrument-def)))
+        (interfaces-def (assoc 'interfaces (cdr meta-def)))
+        (interfaces (cdr interfaces-def)))
+   (set-cdr! interfaces-def (cons 'incipit-interface interfaces)))
 
 \score {
   \new Staff {
     %% All this would be shortcuted by an appropriate music function:
     \override Staff.InstrumentName #'music = ##{ \clef "petrucci-c1" c'4 d' e' f' #}
     \override Staff.InstrumentName #'self-alignment-X = #RIGHT
-    \override Staff.InstrumentName #'self-alignment-Y = #UP
-    \override Staff.InstrumentName #'Y-offset = #4
     \override Staff.InstrumentName #'padding = #0
-    \override Staff.InstrumentName #'stencil = 
+    \override Staff.InstrumentName #'stencil =
     #(lambda (grob)
        (let* ((instrument-name (ly:grob-property grob 'long-text))
               (layout (ly:output-def-clone (ly:grob-layout grob)))
          (ly:score-add-output-def! score layout)
          (set! (ly:grob-property grob 'long-text)
                (markup #:score score))
-         (ly:system-start-text::print grob)))
+         (system-start-text::print grob)))
 
     %% the instrument name definition is separated:
-    \set Staff.instrumentName = \markup Instrument
+    \set Staff.instrumentName = #"Instrument"
     c'4 d' e' f' g'1
   }
   \layout {
-    ragged-right = ##t
     indent = 5\cm
-    incipit-width = 3 \cm
+    incipit-width = 3\cm
   }
 }
\ No newline at end of file
index ea4fcf38a859a5930b2a1da7c5172fe8065e062a..7d8647051023099eec5019c699aeabb993b3b6e8 100644 (file)
@@ -5,28 +5,26 @@
   source file of the GNU LilyPond music typesetter
 
   (c) 2005--2009 Han-Wen Nienhuys <hanwen@xs4all.nl>
-
 */
 
 #include "engraver.hh"
-
-#include "side-position-interface.hh"
-#include "system-start-delimiter.hh"
-#include "staff-symbol.hh"
-#include "pointer-group-interface.hh"
-#include "paper-column.hh"
 #include "output-def.hh"
+#include "paper-column.hh"
+#include "pointer-group-interface.hh"
+#include "side-position-interface.hh"
 #include "spanner.hh"
+#include "staff-symbol.hh"
+#include "system-start-delimiter.hh"
 
 struct Bracket_nesting_node
 {
 public:
-  virtual ~Bracket_nesting_node (){}
+  virtual ~Bracket_nesting_node () {}
   virtual bool add_staff (Grob *) { return false; }
-  virtual void add_support (Grob *) { }
-  virtual void set_bound (Direction, Grob *){}
-  virtual void set_nesting_support (Grob*) {}
-  virtual void create_grobs (Engraver*, SCM) {}
+  virtual void add_support (Grob *) {}
+  virtual void set_bound (Direction, Grob *) {}
+  virtual void set_nesting_support (Grob *) {}
+  virtual void create_grobs (Engraver *, SCM) {}
 };
 
 struct Bracket_nesting_group : public Bracket_nesting_node
@@ -35,12 +33,12 @@ struct Bracket_nesting_group : public Bracket_nesting_node
   vector<Bracket_nesting_node*> children_;
   SCM symbol_;
 
-  void from_list (SCM ); 
+  void from_list (SCM);
   virtual void add_support (Grob *grob);
   virtual bool add_staff (Grob *grob);
-  virtual void set_nesting_support (Grob*);
+  virtual void set_nesting_support (Grob *);
   virtual void set_bound (Direction, Grob *grob);
-  virtual void create_grobs (Engraver*, SCM);
+  virtual void create_grobs (Engraver *, SCM);
   ~Bracket_nesting_group ();
   Bracket_nesting_group ();
 };
@@ -76,12 +74,11 @@ void
 Bracket_nesting_group::create_grobs (Engraver *engraver, SCM default_type)
 {
   SCM type = scm_is_symbol (symbol_) ? symbol_ : default_type;
-  delimiter_ = engraver->make_spanner (ly_symbol2string (type).c_str (), SCM_EOL);
+  delimiter_ = engraver->make_spanner (ly_symbol2string (type).c_str (),
+                                      SCM_EOL);
 
   for (vsize i = 0 ; i < children_.size (); i++)
-    {
-      children_[i]->create_grobs (engraver, default_type);
-    }
+    children_[i]->create_grobs (engraver, default_type);
 }
 
 void
@@ -89,9 +86,7 @@ Bracket_nesting_group::add_support (Grob *g)
 {
   Side_position_interface::add_support (g, delimiter_);
   for (vsize i = 0 ; i < children_.size (); i++)
-    {
-      children_[i]->add_support (g);
-    }
+    children_[i]->add_support (g);
 }
 
 Bracket_nesting_group::~Bracket_nesting_group ()
@@ -104,9 +99,7 @@ Bracket_nesting_group::set_bound (Direction d, Grob *g)
 {
   delimiter_->set_bound (d, g);
   for (vsize i = 0 ; i < children_.size (); i++)
-    {
-      children_[i]->set_bound (d, g);
-    }
+    children_[i]->set_bound (d, g);
 }
 
 void
@@ -114,11 +107,9 @@ Bracket_nesting_group::set_nesting_support (Grob *parent)
 {
   if (parent)
     Side_position_interface::add_support (delimiter_, parent);
-  
+
   for (vsize i = 0 ; i < children_.size (); i++)
-    {
-      children_[i]->set_nesting_support (delimiter_);
-    }
+    children_[i]->set_nesting_support (delimiter_);
 }
 
 
@@ -137,13 +128,10 @@ Bracket_nesting_group::from_list (SCM x)
       else if (entry == ly_symbol2scm ("SystemStartBrace")
               || entry == ly_symbol2scm ("SystemStartBracket")
               || entry == ly_symbol2scm ("SystemStartBar")
-              || entry == ly_symbol2scm ("SystemStartSquare")
-              )
+              || entry == ly_symbol2scm ("SystemStartSquare"))
        symbol_ = entry;
       else
-       {
-         children_.push_back (new Bracket_nesting_staff (0));
-       }
+       children_.push_back (new Bracket_nesting_staff (0));
     }
 }
 
@@ -154,11 +142,11 @@ Bracket_nesting_group::add_staff (Grob *grob)
     {
       if (children_[i]->add_staff (grob))
        {
-         Pointer_group_interface::add_grob (delimiter_, ly_symbol2scm ("elements"), grob);
+         Pointer_group_interface::add_grob (delimiter_,
+                                            ly_symbol2scm ("elements"), grob);
          return true;
        }
     }
-
   return false;
 }
 
@@ -174,9 +162,8 @@ public:
 
 protected:
   Bracket_nesting_group *nesting_;
-  
+
   DECLARE_ACKNOWLEDGER (system_start_delimiter);
-  DECLARE_ACKNOWLEDGER (system_start_text);
   DECLARE_ACKNOWLEDGER (staff_symbol);
 
   void process_music ();
@@ -199,7 +186,8 @@ System_start_delimiter_engraver::process_music ()
 
       nesting_->from_list (hierarchy);
       nesting_->create_grobs (this, delimiter_name);
-      nesting_->set_bound (LEFT, unsmob_grob (get_property ("currentCommandColumn")));
+      nesting_->set_bound (LEFT,
+                          unsmob_grob (get_property ("currentCommandColumn")));
     }
 }
 
@@ -229,14 +217,6 @@ System_start_delimiter_engraver::acknowledge_staff_symbol (Grob_info inf)
     }
 }
 
-
-
-void
-System_start_delimiter_engraver::acknowledge_system_start_text (Grob_info inf)
-{
-  nesting_->add_support (inf.grob ());
-}
-
 void
 System_start_delimiter_engraver::acknowledge_system_start_delimiter (Grob_info inf)
 {
@@ -247,7 +227,6 @@ System_start_delimiter_engraver::acknowledge_system_start_delimiter (Grob_info i
 
 ADD_ACKNOWLEDGER (System_start_delimiter_engraver, staff_symbol);
 ADD_ACKNOWLEDGER (System_start_delimiter_engraver, system_start_delimiter);
-ADD_ACKNOWLEDGER (System_start_delimiter_engraver, system_start_text);
 
 ADD_TRANSLATOR (System_start_delimiter_engraver,
                /* doc */
diff --git a/lily/system-start-text.cc b/lily/system-start-text.cc
deleted file mode 100644 (file)
index 33b0f68..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
-  system-start-text.cc -- implement System_start_text
-
-  source file of the GNU LilyPond music typesetter
-
-  (c) 2006--2009 Han-Wen Nienhuys <hanwen@xs4all.nl>
-
-*/
-
-#include "text-interface.hh"
-#include "pointer-group-interface.hh"
-#include "output-def.hh"
-#include "font-interface.hh"
-#include "spanner.hh"
-#include "stencil.hh"
-#include "item.hh"
-
-class System_start_text
-{
-public:
-  static Stencil get_stencil (Grob *);
-  DECLARE_GROB_INTERFACE ();
-
-  DECLARE_SCHEME_CALLBACK (print, (SCM));
-};
-
-Stencil
-System_start_text::get_stencil (Grob *me_grob)
-{
-  Spanner *me = dynamic_cast<Spanner*> (me_grob);
-  SCM t = me->get_property ("text");
-  if (me->get_break_index () == 0)
-    t = me->get_property ("long-text");
-          
-  
-  SCM chain = Font_interface::text_font_alist_chain (me);
-
-  SCM scm_stencil = Text_interface::is_markup (t)
-    ? Text_interface::interpret_markup (me->layout ()->self_scm (), chain, t)
-    : SCM_EOL;
-
-  
-  if (Stencil *p = unsmob_stencil (scm_stencil))
-    {
-      SCM align_y  = me_grob->get_property ("self-alignment-Y");
-      if (scm_is_number (align_y))
-       p->align_to (Y_AXIS, robust_scm2double (align_y, 0.0));
-
-      /* Horizontal alignment according to the self-alignment-X property
-       * and indent value. */
-      Output_def *layout = me_grob->layout ();
-      Real indent;
-      if (me->get_break_index () == 0)
-       indent = robust_scm2double (layout->c_variable ("indent"), 0);
-      else
-       indent = robust_scm2double (layout->c_variable ("short-indent"), 0);
-      Real align_x = robust_scm2double (me->get_property ("self-alignment-X"), 0);
-      Interval p_extent_x = p->extent (X_AXIS);
-      Interval padding (0.0, max (0.0, indent - p_extent_x.length ()));
-      Real right_padding = padding.length () - padding.linear_combination (align_x);
-      Box box (Interval (p_extent_x[LEFT], p_extent_x[RIGHT] + right_padding),
-              p->extent (Y_AXIS));
-      Stencil *aligned_p = new Stencil (box, p->expr ());
-      return *aligned_p;
-    }
-  return Stencil ();
-}
-
-
-MAKE_SCHEME_CALLBACK (System_start_text, print, 1);
-SCM
-System_start_text::print (SCM smob)
-{
-  Spanner *me = unsmob_spanner (smob);
-
-  if (!me->get_bound (LEFT)->break_status_dir ())
-    {
-      me->suicide ();
-      return SCM_EOL;
-    }
-
-  extract_grob_set (me, "elements", all_elts);
-  vector<Grob*> elts;
-  for (vsize i = 0; i < all_elts.size (); i++)
-    if (all_elts[i]->is_live ())
-      elts.push_back (all_elts[i]);
-
-  if (!elts.size ())
-    {
-      me->suicide ();
-      return SCM_EOL;
-    }
-  
-  Grob *common = common_refpoint_of_array (elts, me, Y_AXIS);
-
-  Interval ext;
-  for (vsize i = elts.size (); i--;)
-    {
-      Spanner *sp = dynamic_cast<Spanner *> (elts[i]);
-
-      if (sp
-         && sp->get_bound (LEFT) == me->get_bound (LEFT))
-       ext.add_point (sp->relative_coordinate (common, Y_AXIS));
-    }
-
-  Stencil m = get_stencil (me);
-  if (!ext.is_empty ())
-    m.translate_axis (ext.center (), Y_AXIS);
-  return m.smobbed_copy ();
-}
-
-
-ADD_INTERFACE (System_start_text,
-              "Text in front of the system.",
-
-              /* properties */
-              "text "
-              "long-text "
-              "self-alignment-Y "
-              "self-alignment-X "
-              );
index 187dfdd09baab156342095fb1e7385de9e745593..8f9c9d00d4b1a829c4eb2731b38bb12b170786e2 100644 (file)
@@ -10,7 +10,7 @@ _ = lilylib._
 
 
 NOT_SMART = _ ("Not smart enough to convert %s")
-UPDATE_MANUALLY        = _ ("Please refer to the manual for details, and update manually.")
+UPDATE_MANUALLY = _ ("Please refer to the manual for details, and update manually.")
 FROM_TO = _ ( "%s has been replaced by %s")
 
 
@@ -2911,7 +2911,8 @@ def conv(str):
        _ ("Autobeaming rules have changed.  override-auto-beam-setting and\n\
 revert-auto-beam-setting have been eliminated.  \\overrideBeamSettings has been\n\
 added.  BeatGrouping has been eliminated.\n\
-Different settings for vertical layout."))
+Different settings for vertical layout.\n\
+ly:system-start-text::print -> system-start-text::print"))
 def conv(str):
     if re.search("override-auto-beam-setting", str):
         stderr_write ("\n")
@@ -2923,9 +2924,9 @@ def conv(str):
         stderr_write (NOT_SMART % _("override-auto-beam-setting.\n\
    Autobeam settings are now reverted with \\revertBeamSettings.\n"))
         stderr_write (UPDATE_MANUALLY)
-    str = re.sub(r"\\set\s+#\'beatGrouping", r"\\setBeatGrouping", str)
-    if re.search(r"(\w+\.beatGrouping)", str):
-        stderr_write (NOT_SMART % _(".beatGrouping. \n\
+    str = re.sub(r"\\set\s+beatGrouping", r"\\setBeatGrouping", str)
+    if re.search(r"\w+\s*.\s*beatGrouping", str):
+        stderr_write (NOT_SMART % _("beatGrouping. \n\
    beatGrouping with a specified context must now be accomplished with\n\
    \\overrideBeamSettings.\n"))
         stderr_write (UPDATE_MANUALLY)
@@ -2934,6 +2935,7 @@ def conv(str):
         stderr_write(NOT_SMART % _("alignment-offsets has been changed to alignment-distances: \
 you must now specify the distances between staves rather than the offset of staves.\n"))
         stderr_write(UPDATE_MANUALLY)
+    str = re.sub ('ly:system-start-text::print', 'system-start-text::print', str)
     return str
 
 # Guidelines to write rules (please keep this at the end of this file)
index 0bed1adc6527ee0859ab3a4407695e5718849a69..f06b0d4a90c767a94e5cb53e01fae6a87980adbd 100644 (file)
@@ -167,11 +167,10 @@ interesting enough to maintain a hara-kiri staff."
  "A right hand finger instruction."
  '(digit-names))
 
-;;; todo: this is not typesetting info. Move to interpretation.
 (ly:add-interface
- 'tablature-interface
- "An interface for any notes set in a tablature staff."
- '())
+ 'system-start-text-interface
+ "Text in front of the system."
+ '(long-text self-alignment-X self-alignment-Y text))
 
 (ly:add-interface
  'trill-spanner-interface
index a20dc54cb00403e919a157ecfe554e163c8932e9..9a43c08933dcb46dd6676ae71d27b9fe37673ab1 100644 (file)
        (padding . 0.3)
        (self-alignment-X . ,CENTER)
        (self-alignment-Y . ,CENTER)
-       (stencil . ,ly:system-start-text::print)
-       (X-offset . ,ly:side-position-interface::x-aligned-side)
+       (stencil . ,system-start-text::print)
+       (X-offset . ,system-start-text::calc-x-offset)
+       (Y-offset . ,system-start-text::calc-y-offset)
        (meta . ((class . Spanner)
                 (interfaces . (font-interface
                                self-alignment-interface
index adb2bdfdc8ccde720798cb57a8d572885a221afc..e7f1d295d81ea98708163f173acf76e0f6067979 100644 (file)
@@ -2,7 +2,7 @@
 ;;;; lily-library.scm -- utilities
 ;;;;
 ;;;;  source file of the GNU LilyPond music typesetter
-;;;; 
+;;;;
 ;;;; (c) 1998--2009 Jan Nieuwenhuizen <janneke@gnu.org>
 ;;;; Han-Wen Nienhuys <hanwen@xs4all.nl>
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; moments
 
-(define-public ZERO-MOMENT (ly:make-moment 0 1)) 
+(define-public ZERO-MOMENT (ly:make-moment 0 1))
 
 (define-public (moment-min a b)
   (if (ly:moment<? a b) a b))
 
+(define-public (moment<=? a b)
+  (or (equal? a b)
+      (ly:moment<? a b)))
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; arithmetic
 (define-public (average x . lst)
@@ -59,7 +63,7 @@
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; parser <-> output hooks.
-               
+
 (define-public (collect-bookpart-for-book parser book-part)
   "Toplevel book-part handler"
   (define (add-bookpart book-part)
 
 (define-public (scorify-music music parser)
   "Preprocess MUSIC."
-  
+
   (for-each (lambda (func)
              (set! music (func music parser)))
            toplevel-music-functions)
@@ -239,7 +243,7 @@ found."
   (hash-fold (lambda (k v acc) (acons  k v  acc))
             '() t))
 
-;; todo: code dup with C++. 
+;; todo: code dup with C++.
 (define-safe-public (alist->hash-table lst)
   "Convert alist to table"
   (let ((m (make-hash-table (length lst))))
@@ -263,14 +267,14 @@ found."
 
 (define (split-list lst n)
   "Split LST in N equal sized parts"
-  
+
   (define (helper todo acc-vector k)
     (if (null? todo)
        acc-vector
        (begin
          (if (< k 0)
              (set! k (+ n k)))
-           
+
          (vector-set! acc-vector k (cons (car todo) (vector-ref acc-vector k)))
          (helper (cdr todo) acc-vector (1- k)))))
 
@@ -296,7 +300,7 @@ found."
 
 
   (reverse (helper lst '() 1)))
-  
+
 (define-public (list-join lst intermediate)
   "put INTERMEDIATE  between all elts of LST."
 
@@ -314,7 +318,7 @@ found."
 
 
 (define (flatten-list lst)
-  "Unnest LST" 
+  "Unnest LST"
   (if (null? lst)
       '()
       (if (pair? (car lst))
@@ -328,7 +332,7 @@ found."
 (define-public (uniq-list lst)
   "Uniq LST, assuming that it is sorted. Uses equal? for comparisons."
 
-  (reverse! 
+  (reverse!
    (fold (lambda (x acc)
           (if (null? acc)
               (list x)
@@ -363,7 +367,7 @@ found."
 
 (define-public (offset-add a b)
   (cons (+ (car a) (car b))
-       (+ (cdr a) (cdr b)))) 
+       (+ (cdr a) (cdr b))))
 
 (define-public (offset-flip-y o)
   (cons (car o) (- (cdr o))))
@@ -392,6 +396,8 @@ found."
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; intervals
 
+(define-public empty-interval '(+inf.0 . -inf.0))
+
 (define-public (interval-length x)
   "Length of the number-pair X, when an interval"
   (max 0 (- (cdr x) (car x))))
@@ -408,7 +414,7 @@ found."
 
 (define-public (interval-index interval dir)
   "Interpolate INTERVAL between between left (DIR=-1) and right (DIR=+1)"
-  
+
   (* (+  (interval-start interval) (interval-end interval)
         (* dir (- (interval-end interval) (interval-start interval))))
      0.5))
@@ -447,6 +453,10 @@ found."
            (inf? (cdr i))
            (> (car i) (cdr i)))))
 
+(define-public (add-point interval p)
+  (cons (min (interval-start interval) p)
+        (max (interval-end interval) p)))
+
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; string
@@ -455,10 +465,10 @@ found."
   (equal? suffix (substring s
                            (max 0 (- (string-length s) (string-length suffix)))
                            (string-length s))))
-            
+
 (define-public (string-startswith s prefix)
   (equal? prefix (substring s 0 (min (string-length s) (string-length prefix)))))
-            
+
 (define-public (string-encode-integer i)
   (cond
    ((= i  0) "o")
@@ -522,7 +532,7 @@ possibly turned off."
   (fold-right conc #f lst))
 
 (define-public (string-regexp-substitute a b str)
-  (regexp-substitute/global #f a str 'pre b 'post)) 
+  (regexp-substitute/global #f a str 'pre b 'post))
 
 (define (regexp-split str regex)
   (define matches '())
@@ -577,8 +587,8 @@ applied to function @var{getter}.")
   (string<? (symbol->string (car lst)) (symbol->string (car r))))
 
 ;;
-;; don't confuse users with #<procedure .. > syntax. 
-;; 
+;; don't confuse users with #<procedure .. > syntax.
+;;
 (define-public (scm->string val)
   (if (and (procedure? val)
           (symbol? (procedure-name val)))
@@ -633,7 +643,7 @@ applied to function @var{getter}.")
 
 (define-public (version-not-seen-message input-file-name)
   (ly:message
-   "~a:0: ~a ~a" 
+   "~a:0: ~a ~a"
     input-file-name
     (_ "warning:")
     (format #f
@@ -642,7 +652,7 @@ applied to function @var{getter}.")
 
 (define-public (old-relative-not-used-message input-file-name)
   (ly:message
-   "~a:0: ~a ~a" 
+   "~a:0: ~a ~a"
     input-file-name
     (_ "warning:")
     (_ "old relative compatibility not used")))
index db1181f740d87e27264992185eca317470ccdd84..c174a295c33e1540ce7a9a3812347aeb7fb045e8 100644 (file)
@@ -1,7 +1,7 @@
 ;;;; output-lib.scm -- implement Scheme output helper functions
 ;;;;
 ;;;;  source file of the GNU LilyPond music typesetter
-;;;; 
+;;;;
 ;;;; (c) 1998--2009 Jan Nieuwenhuizen <janneke@gnu.org>
 ;;;; Han-Wen Nienhuys <hanwen@xs4all.nl>
 
 (define-public (grob::has-interface grob iface)
   (memq iface (ly:grob-interfaces grob)))
 
+(define-public (grob::is-live? grob)
+  (pair? (ly:grob-basic-properties grob)))
+
 (define-public (make-stencil-boxer thickness padding callback)
 
   "Return function that adds a box around the grob passed as argument."
   (lambda (grob)
-    
+
     (box-stencil (callback grob) thickness padding)))
 
 (define-public (make-stencil-circler thickness padding callback)
   "Return function that adds a circle around the grob passed as argument."
-  
+
   (lambda (grob) (circle-stencil (callback grob) thickness padding)))
 
 (define-public (print-circled-text-callback grob)
@@ -33,7 +36,7 @@
 (define-public (event-cause grob)
   (let*
       ((cause (ly:grob-property  grob 'cause)))
-    
+
     (cond
      ((ly:stream-event? cause) cause)
      ((ly:grob? cause) (event-cause cause))
                        (eq? 'harmonic-event (ly:event-property ev 'class)))
                      (ly:event-property event 'articulations)))))
 
-    
+
     (make-whiteout-markup
      (make-vcenter-markup
       (format
        "~a"
        (- (ly:pitch-semitones pitch)
          (list-ref tuning
-                   ;; remove 1 because list index starts at 0 and guitar string at 1. 
+                   ;; remove 1 because list index starts at 0 and guitar string at 1.
                    (- string 1))))))
     ))
 
 ;;   the "first fret" on the fifth string is really the sixth fret
 ;;   on the banjo neck.
 ;; We solve this by defining a new fret-number-tablature function:
-(define-public (fret-number-tablature-format-banjo string 
+(define-public (fret-number-tablature-format-banjo string
                                             context event)
   (let*
       ((tuning (ly:context-property context 'stringTunings))
        (pitch (ly:event-property event 'pitch))
        )
   (make-whiteout-markup
-   (make-vcenter-markup  
+   (make-vcenter-markup
     (let ((fret (- (ly:pitch-semitones pitch) (list-ref tuning (- string 1)))))
       (number->string (cond
                       ((and (> fret 0) (= string 5))
    (ly:event-property (event-cause grob) 'duration)))
 
 (define-public (note-head::calc-duration-log grob)
-  (min 2 
+  (min 2
        (ly:duration-log
        (ly:event-property (event-cause grob) 'duration))))
 
 
 
 
-;; silly, use alist? 
+;; silly, use alist?
 (define-public (note-head::calc-glyph-name grob)
   (let*
       ((style (ly:grob-property grob 'style))
        (log (min 2 (ly:grob-property grob 'duration-log))))
-    
+
     (case style
       ;; "default" style is directly handled in note-head.cc as a
       ;; special case (HW says, mainly for performance reasons).
       ((harmonic-black) "2harmonic")
       ((harmonic-mixed) (if (<= log 1) "0harmonic"
                                        "2harmonic"))
-      ((baroque) 
+      ((baroque)
        ;; Oops, I actually would not call this "baroque", but, for
        ;; backwards compatibility to 1.4, this is supposed to take
        ;; brevis, longa and maxima from the neo-mensural font and all
@@ -214,19 +217,19 @@ centered, X==1 is at the right, X == -1 is at the left."
 ;; Bar lines.
 
 ;;
-;; How should a  bar line behave at a break? 
+;; How should a  bar line behave at a break?
 (define bar-glyph-alist
   '((":|:" . (":|" . "|:"))
     (":|.|:" . (":|" . "|:"))
     (":|.:" . (":|" . "|:"))
     ("||:" . ("||" . "|:"))
-    ("dashed" . ("dashed" . '())) 
+    ("dashed" . ("dashed" . '()))
     ("|" . ("|" . ()))
     ("||:" . ("||" . "|:"))
     ("|s" . (() . "|"))
     ("|:" . ("|" . "|:"))
     ("|." . ("|." . ()))
-    
+
     ;; hmm... should we end with a bar line here?
     (".|" . ("|" . ".|"))
     (":|" . (":|" . ()))
@@ -239,7 +242,7 @@ centered, X==1 is at the right, X == -1 is at the left."
     ("'" . ("'" . ()))
     ("empty" . (() . ()))
     ("brace" . (() . "brace"))
-    ("bracket" . (() . "bracket")) 
+    ("bracket" . (() . "bracket"))
     ))
 
 (define-public (bar-line::calc-glyph-name grob)
@@ -280,28 +283,28 @@ centered, X==1 is at the right, X == -1 is at the left."
   (let*
       ((ev (event-cause grob)))
 
-    (format "~a:~a" 
+    (format "~a:~a"
            (ly:event-property ev 'denominator)
            (ly:event-property ev 'numerator))))
 
 
-; a formatter function, which is simply a wrapper around an existing 
+; a formatter function, which is simply a wrapper around an existing
 ; tuplet formatter function. It takes the value returned by the given
-; function and appends a note of given length. 
+; function and appends a note of given length.
 (define-public ((tuplet-number::append-note-wrapper function note) grob)
   (let* ((txt (if function (function grob) #f)))
-    (if txt 
+    (if txt
       (markup txt #:fontsize -5 #:note note UP)
       (markup #:fontsize -5 #:note note UP))))
 
-; Print a tuplet denominator with a different number than the one derived from 
+; Print a tuplet denominator with a different number than the one derived from
 ; the actual tuplet fraction
 (define-public ((tuplet-number::non-default-tuplet-denominator-text denominator) grob)
-(number->string (if denominator 
-                    denominator 
+(number->string (if denominator
+                    denominator
                     (ly:event-property (event-cause grob) 'denominator))))
 
-; Print a tuplet fraction with different numbers than the ones derived from 
+; Print a tuplet fraction with different numbers than the ones derived from
 ; the actual tuplet fraction
 (define-public ((tuplet-number::non-default-tuplet-fraction-text denominator numerator) grob)
   (let* ((ev (event-cause grob))
@@ -309,7 +312,7 @@ centered, X==1 is at the right, X == -1 is at the left."
          (num (if numerator numerator (ly:event-property ev 'numerator))))
      (format "~a:~a" den num)))
 
-; Print a tuplet fraction with note durations appended to the numerator and the 
+; Print a tuplet fraction with note durations appended to the numerator and the
 ; denominator
 (define-public ((tuplet-number::fraction-with-notes denominatornote numeratornote) grob)
   (let* ((ev (event-cause grob))
@@ -317,17 +320,17 @@ centered, X==1 is at the right, X == -1 is at the left."
          (numerator (ly:event-property ev 'numerator)))
     ((tuplet-number::non-default-fraction-with-notes denominator denominatornote numerator numeratornote) grob)))
 
-; Print a tuplet fraction with note durations appended to the numerator and the 
+; Print a tuplet fraction with note durations appended to the numerator and the
 ; denominator
 (define-public ((tuplet-number::non-default-fraction-with-notes denominator denominatornote numerator numeratornote) grob)
   (let* ((ev (event-cause grob))
          (den (if denominator denominator (ly:event-property ev 'denominator)))
          (num (if numerator numerator (ly:event-property ev 'numerator))))
-     (make-concat-markup (list 
-          (make-simple-markup (format "~a" den)) 
+     (make-concat-markup (list
+          (make-simple-markup (format "~a" den))
           (markup #:fontsize -5 #:note denominatornote UP)
           (make-simple-markup " : ")
-          (make-simple-markup (format "~a" num)) 
+          (make-simple-markup (format "~a" num))
           (markup #:fontsize -5 #:note numeratornote UP)))))
 
 
@@ -361,10 +364,10 @@ centered, X==1 is at the right, X == -1 is at the left."
 
 (define-public (key-signature-interface::alteration-position step alter c0-position)
   ;; TODO: memoize - this is mostly constant.
-  
+
   ;; fes, ges, as and bes typeset in lower octave
   (define FLAT_TOP_PITCH 2)
-  
+
   ;; ais and bis typeset in lower octave
   (define SHARP_TOP_PITCH 4)
 
@@ -374,19 +377,19 @@ centered, X==1 is at the right, X == -1 is at the left."
          ((from-bottom-pos (modulo (+ 4 49 c0-position)  7))
           (p step)
           (c0 (- from-bottom-pos  4)))
-       
+
        (if
         (or (and (< alter 0) (or (> p FLAT_TOP_PITCH) (> (+ p c0) 4)) (> (+ p c0) 1))
             (and (> alter 0) (or (> p SHARP_TOP_PITCH) (> (+ p c0) 5)) (> (+ p c0) 2))
             )
 
-        ;; Typeset below c_position 
+        ;; Typeset below c_position
         (set! p (- p 7)))
 
        ;; Provide for the four cases in which there's a glitch
        ;; it's a hack, but probably not worth
        ;; the effort of finding a nicer solution.
-       ;; --dl. 
+       ;; --dl.
        (cond
         ((and (= c0 2) (= p 3) (> alter 0))
          (set! p (- p 7)))
@@ -419,7 +422,7 @@ centered, X==1 is at the right, X == -1 is at the left."
 
        (1 . "accidentals.doublesharp")
        (-1 . "accidentals.flatflat")
-       
+
        (3/4 . "accidentals.sharp.slashslash.stemstemstem")
        (1/4 . "accidentals.sharp.slashslash.stem")
        (-1/4 . "accidentals.mirroredflat")
@@ -442,7 +445,7 @@ centered, X==1 is at the right, X == -1 is at the left."
        (-8/9 . "accidentals.flat.slashslash")
        (-1 . "accidentals.flatflat")
        ))
-  
+
 (define-public alteration-hufnagel-glyph-name-alist
    '((-1/2 . "accidentals.hufnagelM1")
      (0 . "accidentals.vaticana0")
@@ -508,7 +511,7 @@ centered, X==1 is at the right, X == -1 is at the left."
        (lp (car stencils))
        (rp (cadr stencils))
        (padding (ly:grob-property grob 'padding 0.1)))
-    
+
     (ly:stencil-add
      (ly:stencil-translate-axis lp (- (car x-ext) padding) X)
      (ly:stencil-translate-axis rp (+ (cdr x-ext) padding) X))
@@ -537,7 +540,7 @@ centered, X==1 is at the right, X == -1 is at the left."
 
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; 
+;;
 
 (define-public (chain-grob-member-functions grob value . funcs)
   (for-each
@@ -553,14 +556,14 @@ centered, X==1 is at the right, X == -1 is at the left."
 (define-public (bend::print spanner)
   (define (close  a b)
     (< (abs (- a b)) 0.01))
-  
+
   (let*
       ((delta-y (* 0.5 (ly:grob-property spanner 'delta-position)))
        (left-span (ly:spanner-bound spanner LEFT))
        (dots (if (and (grob::has-interface left-span 'note-head-interface)
                      (ly:grob? (ly:grob-object left-span 'dot)))
                 (ly:grob-object left-span 'dot) #f))
-                
+
        (right-span (ly:spanner-bound spanner RIGHT))
        (thickness (* (ly:grob-property spanner 'thickness)
                     (ly:output-def-lookup (ly:grob-layout spanner)
@@ -588,12 +591,12 @@ centered, X==1 is at the right, X == -1 is at the left."
                     (+ left-x minimum-length)))
        (self-x (ly:grob-relative-coordinate spanner common X))
        (dx (- right-x left-x))
-       (exp (list 'path thickness 
+       (exp (list 'path thickness
                  `(quote
                    (rmoveto
                     ,(- left-x self-x) 0
 
-                    rcurveto                
+                    rcurveto
                     ,(/ dx 3)
                     0
                     ,dx ,(* 0.66 delta-y)
@@ -619,7 +622,7 @@ centered, X==1 is at the right, X == -1 is at the left."
                         (ly:grob-array-ref cols (1+ idx)) 'when)
                        (ly:grob-property
                         (ly:grob-array-ref cols idx) 'when))))
-      
+
       (moment-min (lambda (x y)
                    (cond
                     ((and x y)
@@ -628,7 +631,7 @@ centered, X==1 is at the right, X == -1 is at the left."
                            y))
                     (x x)
                     (y y)))))
-                    
+
     (fold moment-min #f (map get-difference
                             (iota (1- (ly:grob-array-length cols)))))))
 
@@ -641,7 +644,7 @@ centered, X==1 is at the right, X == -1 is at the left."
   (let*
       ((event (event-cause grob))
        (digit (ly:event-property event 'digit)))
-    
+
     (if (> digit 5)
        (ly:input-message (ly:event-property event 'origin)
                          "Warning: Fingering notation for finger number ~a" digit))
@@ -652,7 +655,7 @@ centered, X==1 is at the right, X == -1 is at the left."
 (define-public (string-number::calc-text grob)
   (let*
       ((digit (ly:event-property (event-cause  grob) 'string-number)))
-    
+
     (number->string digit 10)
   ))
 
@@ -679,11 +682,11 @@ centered, X==1 is at the right, X == -1 is at the left."
 
 (define-public (lyric-text::print grob)
   "Allow interpretation of tildes as lyric tieing marks."
-  
+
   (let*
       ((text (ly:grob-property grob 'text)))
 
-    (grob-interpret-markup grob 
+    (grob-interpret-markup grob
               (if (string? text)
                   (make-tied-lyric-markup text)
                   text))))
@@ -695,7 +698,7 @@ centered, X==1 is at the right, X == -1 is at the left."
 ;; fret boards
 
 (define-public (fret-board::calc-stencil grob)
-    (grob-interpret-markup 
+    (grob-interpret-markup
       grob
       (make-fret-diagram-verbose-markup
         (ly:grob-property grob 'dot-placement-list))))
@@ -723,3 +726,92 @@ centered, X==1 is at the right, X == -1 is at the left."
                               note-head-location)))
                 0.0))
           0.0))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; instrument names
+
+(define-public (system-start-text::print grob)
+  (let* ((left-bound (ly:spanner-bound grob LEFT))
+        (left-mom (ly:grob-property left-bound 'when))
+        (name (if (moment<=? left-mom ZERO-MOMENT)
+                  (ly:grob-property grob 'long-text)
+                  (ly:grob-property grob 'text))))
+
+    (if (and (markup? name)
+            (!= (ly:item-break-dir left-bound) CENTER))
+
+       (grob-interpret-markup grob name)
+       (ly:grob-suicide! grob))))
+
+(define-public (system-start-text::calc-x-offset grob)
+  (let* ((left-bound (ly:spanner-bound grob LEFT))
+        (left-mom (ly:grob-property left-bound 'when))
+        (layout (ly:grob-layout grob))
+        (indent (ly:output-def-lookup layout
+                                      (if (moment<=? left-mom ZERO-MOMENT)
+                                          'indent
+                                          'short-indent)
+                                      0.0))
+        (system (ly:grob-system grob))
+        (my-extent (ly:grob-extent grob system X))
+        (elements (ly:grob-object system 'elements))
+        (common (ly:grob-common-refpoint-of-array system elements X))
+        (total-ext empty-interval)
+        (align-x (ly:grob-property grob 'self-alignment-X 0))
+        (padding (min 0 (- (interval-length my-extent) indent)))
+        (right-padding (- padding
+                          (/ (* padding (1+ align-x)) 2))))
+
+    (let loop ((l (ly:grob-array-length elements)))
+      (if (> l 0)
+         (let ((elt (ly:grob-array-ref elements (1- l))))
+
+           (if (grob::has-interface elt 'system-start-delimiter-interface)
+               (let ((dims (ly:grob-extent elt common X)))
+                 (if (interval-sane? dims)
+                     (set! total-ext (interval-union total-ext dims)))))
+           (loop (1- l)))))
+
+    (+
+     (ly:side-position-interface::x-aligned-side grob)
+     right-padding
+     (- (interval-length total-ext)))))
+
+(define-public (system-start-text::calc-y-offset grob)
+
+  (define (live-elements-list me)
+    (let* ((elements (ly:grob-object me 'elements))
+          (elts-length (ly:grob-array-length elements))
+          (live-elements '()))
+      (let get-live ((len elts-length))
+       (if (> len 0)
+           (let ((elt (ly:grob-array-ref elements (1- len))))
+
+             (if (grob::is-live? elt)
+                 (set! live-elements (cons elt live-elements)))
+             (get-live (1- len)))))
+      live-elements))
+
+  (let* ((left-bound (ly:spanner-bound grob LEFT))
+        (live-elts (live-elements-list grob))
+        (system (ly:grob-system grob))
+        (extent empty-interval))
+
+    (if (and (pair? live-elts)
+            (interval-sane? (ly:grob-extent grob system Y)))
+       (let get-extent ((lst live-elts))
+         (if (pair? lst)
+             (let ((axis-group (car lst)))
+
+               (if (and (ly:spanner? axis-group)
+                        (equal? (ly:spanner-bound axis-group LEFT)
+                                left-bound))
+                   (set! extent (add-point
+                                 extent
+                                 (ly:grob-relative-coordinate axis-group system Y))))
+
+               (get-extent (cdr lst))))))
+
+    (+
+     (ly:self-alignment-interface::y-aligned-on-self grob)
+     (interval-center extent))))