]> git.donarmstrong.com Git - lilypond.git/commitdiff
Merge branch 'master' of ssh+git://jneem@git.sv.gnu.org/srv/git/lilypond
authorJoe Neeman <joeneeman@gmail.com>
Sun, 10 Dec 2006 17:59:50 +0000 (19:59 +0200)
committerJoe Neeman <joeneeman@gmail.com>
Sun, 10 Dec 2006 17:59:50 +0000 (19:59 +0200)
30 files changed:
Documentation/topdocs/NEWS.tely
Documentation/user/advanced-notation.itely
Documentation/user/instrument-notation.itely
Documentation/user/lilypond.tely
Documentation/user/non-music.itely
Documentation/user/spacing.itely
input/regression/markup-scheme.ly
input/regression/tie-broken-minimum-length.ly [new file with mode: 0644]
lily/arpeggio.cc
lily/include/paper-column.hh
lily/music-wrapper.cc
lily/paper-column.cc
lily/span-arpeggio-engraver.cc
lily/spanner.cc
lily/stream-event-scheme.cc
lily/system.cc
lily/tab-harmonic-engraver.cc [new file with mode: 0644]
lily/tab-note-heads-engraver.cc
lily/tuplet-bracket.cc
ly/engraver-init.ly
scm/define-grob-interfaces.scm
scm/define-grob-properties.scm
scm/define-grobs.scm
scm/define-markup-commands.scm
scm/lily-library.scm
scm/lily.scm
scm/markup.scm
scm/music-functions.scm
scm/output-lib.scm
scm/stencil.scm

index 528204b090e7dca18a8bafbf5105e7ef09199923..574febff57b224e850f4eb0e6bc89ff92f84e15f 100644 (file)
@@ -81,7 +81,6 @@ accurately. This allows tighter horizontal spacing.
 now positioned automatically to avoid collisions.
 
 @lilypond[fragment,ragged-right,relative=1]
-  \override TextScript #'outside-staff-priority = #1
   c''
   \once \override TextScript #'self-alignment-X = #CENTER
   a,^"this doesn't collide with the c"
index 542728bfc5a5531f3e615bfdd6befbe7b0234620..a414fe7b44c3909cb42013f05212ea98d2de7229 100644 (file)
@@ -303,9 +303,8 @@ but it can also be used anywhere text is called in lilypond
 }
 @end lilypond
 
-Text can also be placed on its own, away from any @code{\score}
-block.  This is primarily used in a @code{\book} (see
-@ref{Multiple scores in a book}).
+A @code{\markup} command can also be placed on its own, away from any
+@code{\score} block, see @ref{Multiple scores in a book}.
 
 @lilypond[quote,ragged-right,verbatim]
 \markup{ Here is some text. }
@@ -1135,9 +1134,9 @@ the staff.  They are created by invoking the function
 }
 @end lilypond
 
-The @code{set-octavation} function also takes -1 (for 8va bassa) and 2
-(for 15ma) as arguments.  Internally the function sets the properties
-@code{ottavation} (e.g., to @code{"8va"}) and
+The @code{set-octavation} function also takes -1 (for 8va bassa), 2@tie{}(for 15ma),
+and -2 (for 15ma bassa) as arguments.  Internally the function sets the properties
+@code{ottavation} (e.g., to @code{"8va"} or @code{"8vb"}) and
 @code{centralCPosition}.  For overriding the text of the bracket, set
 @code{ottavation} after invoking @code{set-octavation}, i.e.,
 
@@ -2221,7 +2220,7 @@ used in music for beginners
 The command @code{\setEasyHeads} overrides settings for the
 @internalsref{NoteHead} object.  To make the letters readable, it has
 to be printed in a large font size.  To print with a larger font, see
-@ref{Setting global staff size}.
+@ref{Setting the staff size}.
 
 @refcommands
 
index 4ca0142e04eb581bf3b42256a8b13a72f9e5dc81..42e4348cc61d112f6be43395cce00eb8eb49b551 100644 (file)
@@ -148,7 +148,7 @@ usually the setup for a score will start with a setup of the staves,
 and the @context{Voice} is inserted afterwards
 
 @example
-\new Staff = down
+\context Staff = down
   \new Voice @{ @dots{} \change Staff = up @dots{} @}
 @end example
 
@@ -4548,6 +4548,15 @@ automatically.
 @end lilypond
 
 
+@refbugs
+
+When using figured bass above the staff with extender lines and
+@code{implicitBassFigures} the lines may become swapped around.
+Maintaining order consistently will be impossible when multiple figures
+have overlapping extender lines.  To avoid this problem, plese
+use @code{stacking-dir} on @code{BassFigureAlignment}.
+
+
 @seealso
 
 Program reference: @internalsref{NewBassFigure},
index bcdbc5682cae4fd1ab7a04ba14e9241af5872561..ce5b8b4f1096d886611866f52d669f54acb8f3d6 100644 (file)
@@ -133,7 +133,7 @@ Free Documentation License''.
 @top GNU LilyPond --- The music typesetter
 @c HJJ: Info needs `@top', which is a synonym for `@unnumbered' in TeX.
 
-This is the user manual for GNU LilyPond 2.8.x series.
+This is the user manual for GNU LilyPond 2.10.x series.
 @ifhtml
 (See the bottom of this page for the exact version number).
 @end ifhtml
index 414548667f7120bf8d6188c77a789ac639d825ff..9fb163d7c0742c579367e23aabf8a6691fc6c5c1 100644 (file)
@@ -98,23 +98,29 @@ and texts are entered with a @code{\markup} block,
 
 @funindex \book
 
-The movements and texts are combined together in a @code{\book} block,
-like
+All the movements and texts which appear in the same @code{.ly} file 
+will normally be typeset in the form of a single output file. 
 
 @example
-\book @{
-  \score @{
-    @var{..}
-  @}
-  \markup @{
-    @var{..}
-  @}
-  \score @{
-    @var{..}
-  @}
+\score @{
+  @var{..}
+@}
+\markup @{
+  @var{..}
+@}
+\score @{
+  @var{..}
 @}
 @end example
 
+However, if you want multiple output files from the same @code{.ly}
+file, then you can add multiple @code{\book} blocks, where each such
+@code{\book} block will result in a separate output. If you do not
+specify any @code{\book} block in the file, LilyPond will implicitly
+treat the full file as a single @code{\book} block, see @ref{File
+structure}. One important exception is within lilypond-book documents,
+where you explicitly have to add a @code{\book} block, otherwise only
+the first @code{\score} or @code{\markup} will appear in the output.
 
 The header for each piece of music can be put inside the @code{\score}
 block.  The @code{piece} name from the header will be printed before
@@ -123,25 +129,23 @@ each movement.  The title for the entire book can be put inside the
 the top of the file is inserted.
 
 @example
-\book @{
-  \header @{
-    title = "Eight miniatures"
-    composer = "Igor Stravinsky"
-  @}
-  \score @{
-    @dots{}
-    \header @{ piece = "Romanze" @}
-  @}
-  \markup @{
-     ..text of second verse..
-  @}
-  \markup @{
-     ..text of third verse..
-  @}
-  \score @{
-    @dots{}
-    \header @{ piece = "Menuetto" @}
-  @}
+\header @{
+  title = "Eight miniatures"
+  composer = "Igor Stravinsky"
+@}
+\score @{
+  @dots{}
+  \header @{ piece = "Romanze" @}
+@}
+\markup @{
+   ..text of second verse..
+@}
+\markup @{
+   ..text of third verse..
+@}
+\score @{
+  @dots{}
+  \header @{ piece = "Menuetto" @}
 @}
 @end example
 
@@ -221,8 +225,13 @@ contain only one music expression.
 @item
 A @code{\book} block logically combines multiple movements
 (i.e., multiple @code{\score} blocks) in one document.  If there are
-a number of @code{\scores}, a single output file will be created
-in which all movements are concatenated.
+a number of @code{\scores}, one output file will be created for
+each @code{\book} block, in which all corresponding movements are
+concatenated. The only reason to explicitly specify @code{\book} blocks
+in a @code{.ly} file is if you wish multiple output files from a single
+input file. One exception is within lilypond-book documents, where you
+explicitly have to add a @code{\book} block if you want more than a
+single @code{\score} or @code{\markup} in the same example.
 
 This behavior can be changed by setting the variable
 @code{toplevel-book-handler} at toplevel.  The default handler is
@@ -469,8 +478,8 @@ some pieces include a lot more information.
 @node Creating titles
 @subsection Creating titles
 
-Titles are created for each @code{\score} block, and over a
-@code{\book}.
+Titles are created for each @code{\score} block, and for the full input
+file (or @code{\book} block).
 
 The contents of the titles are taken from the @code{\header} blocks.
 The header block for a book supports the following
@@ -661,14 +670,13 @@ variables in the @code{\paper} block.  The init file
 @table @code
 @funindex bookTitleMarkup
 @item bookTitleMarkup
-  This is the title put over an entire @code{\book} block.  Typically,
-  it has the composer and the title of the piece
+  This is the title added at the top of the entire output document.
+Typically, it has the composer and the title of the piece
 
 @funindex scoreTitleMarkup
 @item scoreTitleMarkup
-  This is the title put over a @code{\score} block within a
-@code{\book}.  Typically, it has the name of the movement (@code{piece}
-field).
+  This is the title put over a @code{\score} block.  Typically, it has
+the name of the movement (@code{piece} field).
 
 @funindex oddHeaderMarkup
 @item oddHeaderMarkup
index 6e22cf1a78c467b69bfa2b236366b6413c350fa9..658fc62dbae02bc59adb3161910a79a60aee0d2d 100644 (file)
@@ -229,8 +229,8 @@ book and the title of a piece). Default is@tie{}2mm.
 
 @funindex printallheaders
 @item printallheaders
-Setting this to #t will print all headers for each \score in a
-\book.  Normally only the piece and opus \headers are printed.
+Setting this to #t will print all headers for each \score in the
+output.  Normally only the piece and opus \headers are printed.
 
 @funindex systemSeparatorMarkup
 @item systemSeparatorMarkup
@@ -332,19 +332,20 @@ add space between the titles and the first system of the score.
 @section Music layout
 
 @menu
-* Setting global staff size::   
+* Setting the staff size::   
 * Score layout::                
 @end menu
 
 
-@node Setting global staff size
-@subsection Setting global staff size
+@node Setting the staff size
+@subsection Setting the staff size
 
 @cindex font size, setting
 @cindex staff size, setting
 @funindex layout file
 
-To set the global staff size, use @code{set-global-staff-size}.
+To set the staff size globally for all scores in a file (or
+in a @code{book} block, to be precise), use @code{set-global-staff-size}.
 
 @example
 #(set-global-staff-size 14)
@@ -354,6 +355,16 @@ To set the global staff size, use @code{set-global-staff-size}.
 This sets the global default size to 14pt staff height and scales all
 fonts accordingly.
 
+To set the staff size individually for each score, use 
+@example
+\score@{
+  ...
+  \layout@{
+  #(layout-set-staff-size 15)
+  @}
+@}
+@end example
+
 The Feta font provides musical symbols at eight different
 sizes.  Each font is tuned for a different staff size: at a smaller size
 the font becomes heavier, to match the relatively heavier staff lines.
index 608ba694ae4310c617d7188025db10295db47f34..e82b4b0ba372671647894d40f32bd592dbe10fd4 100644 (file)
@@ -43,8 +43,11 @@ For maintenance reasons, we don't excercise the entire markup command set.
     \combine "X" "+"   
     \combine "o" "/"
     \box \column { \line { "string 1" } \line { "string 2" } }
+    " "
     \italic Norsk
     \super "2"
+    \circle \dynamic "p"
+    " "
     \dynamic sfzp
     \huge { "A" \smaller "A" \smaller \smaller "A"
            \smaller \smaller \smaller "A" }
diff --git a/input/regression/tie-broken-minimum-length.ly b/input/regression/tie-broken-minimum-length.ly
new file mode 100644 (file)
index 0000000..51f9708
--- /dev/null
@@ -0,0 +1,20 @@
+
+\version "2.11.0"
+
+\header {
+
+  texidoc = " Broken ties honor @code{minimum-length} also.  This tie
+has a @code{minimum-length} of 5."
+
+}
+
+\relative {
+  \override Tie #'minimum-length = #5
+  f2. f16  f  f  f ~ | \break
+  f1
+}
+
+\paper {
+  indent = 0.0\mm
+  line-width = 40.0\mm
+}
index 76fd30ad8ff28f6f60442215de458edeb109616b..d9e9e80636854617517438444c42014b8ccad75b 100644 (file)
@@ -58,8 +58,11 @@ Arpeggio::print (SCM smob)
 
   if (heads.is_empty () || heads.length () < 0.5)
     {
-      programming_error ("no heads for arpeggio found?");
-      me->suicide ();
+      if (!to_boolean (me->get_property ("transparent")))
+       {
+         me->warning ("no heads for arpeggio found?");
+         me->suicide ();
+       }
       return SCM_EOL;
     }
 
index 542bd86e2b1760f2bff808f5fc169ee3e6355761..be6ab9378dbca9c3e4653160b974366c0564140d 100644 (file)
@@ -43,7 +43,7 @@ public:
   DECLARE_SCHEME_CALLBACK (before_line_breaking, (SCM));
 
   DECLARE_GROB_INTERFACE();
-  static int get_rank (Grob *);
+  static int get_rank (Grob const *);
   static bool is_musical (Grob *);
   static Moment when_mom (Grob *);
   static bool is_used (Grob *);
index 456af661cc339379d0e9d30150584be71002789c..051187a8a4215f6d3feb6e6e8cd2283526448d70 100644 (file)
@@ -25,6 +25,9 @@ Music_wrapper::length_callback (SCM m)
 {
   Music *me = unsmob_music (m);
   Music *elt = unsmob_music (me->get_property ("element"));
-  return elt->get_length ().smobbed_copy ();
+  if (elt)
+    return elt->get_length ().smobbed_copy ();
+  else
+    return Moment (0).smobbed_copy ();
 }
 
index 78b09c3875ba254781959298b420e874565d5813..2636b20fe4bccee354e4b9b915f060f8e6f082af 100644 (file)
@@ -34,9 +34,9 @@ Paper_column::do_break_processing ()
 }
 
 int
-Paper_column::get_rank (Grob *me)
+Paper_column::get_rank (Grob const *me)
 {
-  return dynamic_cast<Paper_column *> (me)->rank_;
+  return dynamic_cast<Paper_column const *> (me)->rank_;
 }
 
 System *
index 1e236324ac43aea6e8998b7f4ffcfac9c9d71397..4a81d5bdbab3bbacba2e8bd047606b5dc27f37d9 100644 (file)
@@ -73,12 +73,12 @@ Span_arpeggio_engraver::stop_translation_timestep ()
       for (vsize j = 0; j < arpeggios_.size (); j++)
        {
          extract_grob_set (arpeggios_[j], "stems", stems);
-         for (vsize i = stems.size (); i--;)
+         for (vsize i = 0; i < stems.size (); i++)
            Pointer_group_interface::add_grob (span_arpeggio_, ly_symbol2scm ("stems"),
                                               stems[i]);
 
          extract_grob_set (arpeggios_[j], "side-support-elements", sses);
-         for (vsize i = sses.size (); i--;)
+         for (vsize i = 0; i < sses.size (); i++)
            Pointer_group_interface::add_grob (span_arpeggio_, ly_symbol2scm ("side-support-elements"),
                                               sses[i]);
 
index 0f020202419c494b6bf2db2a639f65c7173d28d2..c0ac823b02b5329f8c7991b1f019aca551e1512f 100644 (file)
@@ -334,16 +334,33 @@ SCM
 Spanner::set_spacing_rods (SCM smob)
 {
   Grob *me = unsmob_grob (smob);
-
-  Rod r;
-  Spanner *sp = dynamic_cast<Spanner *> (me);
-  r.item_drul_[LEFT] = sp->get_bound (LEFT);
-  r.item_drul_[RIGHT] = sp->get_bound (RIGHT);
-
   SCM num_length = me->get_property ("minimum-length");
   if (scm_is_number (num_length))
     {
+      Rod r;
+      Spanner *sp = dynamic_cast<Spanner *> (me);
+      
+
+      System *root = get_root_system (me);
+      vector<Item*> cols (root->broken_col_range (sp->get_bound (LEFT)->get_column (),
+                                                 sp->get_bound (RIGHT)->get_column ()));
+
+      if (cols.size ())
+       {
+         Rod r ;
+         r.item_drul_[LEFT] = sp->get_bound (LEFT);
+         r.item_drul_[RIGHT] = cols[0]->find_prebroken_piece (LEFT);
+         r.distance_ = robust_scm2double (num_length, 0);
+         r.add_to_cols ();
+         
+         r.item_drul_[LEFT] = cols.back ()->find_prebroken_piece (RIGHT);
+         r.item_drul_[RIGHT] = sp->get_bound (RIGHT);
+         r.add_to_cols ();
+       }
+          
       r.distance_ = robust_scm2double (num_length, 0);
+      r.item_drul_[LEFT] = sp->get_bound (LEFT);
+      r.item_drul_[RIGHT] = sp->get_bound (RIGHT);
       r.add_to_cols ();
     }
   
index ea9365496187c371bbe721be6b72906b1b8586f2..1f890782a44cbfc09dca7c79626ac050b32c80ec 100644 (file)
@@ -26,7 +26,7 @@ LY_DEFINE (ly_make_stream_event, "ly:make-stream-event",
 LY_DEFINE (ly_event_property, "ly:event-property", 
            2, 0, 0, (SCM sev, SCM sym),
           "Get the property @var{sym} of stream event @var{mus}.\n"
-          "If @var{sym} is undefined, return @code{' ()}.\n")
+          "If @var{sym} is undefined, return @code{'()}.\n")
 {
   Stream_event *e = unsmob_stream_event (sev);
   SCM_ASSERT_TYPE (e, sev, SCM_ARG1, __FUNCTION__, "stream event");
index b8557a6f046f020dbdbf6c8502f044fb022b8a47..4d42bdb171c61ed52a4c58ad041f992eae80c281 100644 (file)
@@ -445,17 +445,18 @@ System::broken_col_range (Item const *left, Item const *right) const
   left = left->get_column ();
   right = right->get_column ();
 
+  
   extract_grob_set (this, "columns", cols);
-  vsize i = 0;
-  while (i < cols.size ()
-        && cols[i] != left)
-    i++;
 
+  vsize i = binary_search (cols, (Grob *) left,
+                          Paper_column::less_than);
+
+  int end_rank = Paper_column::get_rank (right);
   if (i < cols.size ())
     i++;
 
   while (i < cols.size ()
-        && cols[i] != right)
+        && Paper_column::get_rank (cols[i]) < end_rank)
     {
       Paper_column *c = dynamic_cast<Paper_column *> (cols[i]);
       if (Paper_column::is_breakable (c) && !c->system_)
diff --git a/lily/tab-harmonic-engraver.cc b/lily/tab-harmonic-engraver.cc
new file mode 100644 (file)
index 0000000..385b462
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+  tab-harmonic-engraver.cc -- implement Tab_harmonic_engraver
+
+  source file of the GNU LilyPond music typesetter
+
+  (c) 2005--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+
+*/
+
+#include "engraver.hh"
+
+#include "item.hh"
+#include "pointer-group-interface.hh"
+#include "simple-closure.hh"
+#include "stream-event.hh"
+#include "warn.hh"
+
+#include "translator.icc"
+
+class Tab_harmonic_engraver : public Engraver
+{
+  TRANSLATOR_DECLARATIONS (Tab_harmonic_engraver);
+
+protected:
+  DECLARE_ACKNOWLEDGER (note_head);
+};
+
+Tab_harmonic_engraver::Tab_harmonic_engraver()
+{
+}
+
+void
+Tab_harmonic_engraver::acknowledge_note_head (Grob_info info)
+{
+  if (Stream_event *note = info.event_cause ())
+    {
+      for (SCM s = note->get_property ("articulations");
+          scm_is_pair (s); s = scm_cdr (s))
+       {
+         Stream_event *ev = unsmob_stream_event (scm_car (s));
+         
+         if (!ev)
+           continue;
+
+         
+         if (ev->in_event_class ("harmonic-event"))
+           {
+             if (Item *victim = info.item ())
+               {
+                 Engraver *eng = dynamic_cast<Engraver*> (info.origin_translator ());
+                 Item *paren = eng->make_item ("HarmonicParenthesesItem", victim->self_scm ());
+                 Pointer_group_interface::add_grob (paren, ly_symbol2scm ("elements"), victim);
+
+                 paren->set_parent (victim, Y_AXIS);
+             
+                 Real size = robust_scm2double (paren->get_property ("font-size"), 0.0)
+                   + robust_scm2double (victim->get_property ("font-size"), 0.0);
+                 paren->set_property ("font-size", scm_from_double (size));
+               }
+           }
+       }
+    }
+}
+
+ADD_ACKNOWLEDGER (Tab_harmonic_engraver, note_head);
+ADD_TRANSLATOR (Tab_harmonic_engraver,
+               /* doc */ "Parenthesize objects whose music cause has the @code{parenthesize} "
+               "property.",
+               
+               /* create */
+               "HarmonicParenthesesItem ",
+               /* read */ "",
+               /* write */ "");
index 7870c0218a74b44fb3e64178c90124b66d0307b6..a9e655673420ec210e39b3aa818aea85b0653187 100644 (file)
@@ -1,9 +1,7 @@
 /*
   tab-note-heads-engraver.cc -- part of GNU LilyPond
 
-  based on note-heads-engraver.cc, by Jean-Baptiste Lamy <jiba@tuxfamily.org>,
-
-  (c) 2002--2006
+  (c) 2002--2006 Han-Wen Nienhuys, Jean-Baptiste Lamy <jiba@tuxfamily.org>,
 */
 
 #include <cctype>
@@ -20,6 +18,7 @@ using namespace std;
 #include "rhythmic-head.hh"
 #include "stream-event.hh"
 #include "warn.hh"
+#include "context.hh"
 
 #include "translator.icc"
 
@@ -67,8 +66,8 @@ Tab_note_heads_engraver::process_music ()
   vsize j = 0;
   for (vsize i = 0; i < note_events_.size (); i++)
     {
-      SCM stringTunings = get_property ("stringTunings");
-      int number_of_strings = scm_ilength (stringTunings);
+      SCM string_tunings = get_property ("stringTunings");
+      int number_of_strings = scm_ilength (string_tunings);
       bool high_string_one = to_boolean (get_property ("highStringOne"));
 
       Stream_event *event = note_events_[i];
@@ -115,22 +114,26 @@ Tab_note_heads_engraver::process_music ()
       while (!string_found)
        {
          int fret = unsmob_pitch (scm_pitch)->semitone_pitch ()
-           - scm_to_int (scm_list_ref (stringTunings, scm_from_int (tab_string - 1)));
+           - scm_to_int (scm_list_ref (string_tunings, scm_from_int (tab_string - 1)));
          if (fret < min_fret)
            tab_string += high_string_one ? 1 : -1;
          else
            string_found = true;
        }
 
-      SCM text = scm_call_3 (proc, scm_from_int (tab_string), stringTunings, scm_pitch);
+      SCM text = scm_call_3 (proc, scm_from_int (tab_string),
+                            context ()->self_scm (),
+                            event->self_scm ());
+      note->set_property ("text", text);
+
 
       int pos = 2 * tab_string - number_of_strings - 1; // No tab-note between the string !!!
       if (to_boolean (get_property ("stringOneTopmost")))
        pos = -pos;
 
-      note->set_property ("text", text);
-
       note->set_property ("staff-position", scm_from_int (pos));
+
+      
       notes_.push_back (note);
     }
 }
index 8af6073f83f2fce72bb3ba540057d875d46eccf1..d13cf1c613e50d7103533c0f9c779334e73008cb 100644 (file)
@@ -422,12 +422,12 @@ Tuplet_bracket::make_bracket (Grob *me, // for line properties.
     straight_corners[d] += -d * shorten[d] / length * dz;
   while (flip (&d) != LEFT);
 
-  if (gap.is_empty ())
-    gap = Interval (0, 0);
-  do
-    gap_corners[d] = (dz * 0.5) + gap[d] / length * dz;
-  while (flip (&d) != LEFT)
-    ;
+  if (!gap.is_empty ())
+    {
+      do
+       gap_corners[d] = (dz * 0.5) + gap[d] / length * dz;
+      while (flip (&d) != LEFT);
+    }
 
   Drul_array<Offset> flare_corners = straight_corners;
   do
@@ -441,14 +441,20 @@ Tuplet_bracket::make_bracket (Grob *me, // for line properties.
   Stencil m;
   do
     {
-      m.add_stencil (Line_interface::line (me, straight_corners[d],
-                                          gap_corners[d]));
+      if (!gap.is_empty ())
+       m.add_stencil (Line_interface::line (me, straight_corners[d],
+                                            gap_corners[d]));
 
       m.add_stencil (Line_interface::line (me, straight_corners[d],
                                           flare_corners[d]));
     }
+
   while (flip (&d) != LEFT);
 
+  if (gap.is_empty ())
+    m.add_stencil (Line_interface::line (me, straight_corners[LEFT],
+                                        straight_corners[RIGHT]));
+  
   return m;
 }
 
index 6461352d301dea4099d4fbbb2f12050780d8f079..938a0c856e0cb1a666f62f90619080a8ed9c2fd3 100644 (file)
@@ -653,6 +653,8 @@ AncientRemoveEmptyStaffContext = \context {
   \name "TabVoice"
   \alias "Voice"
   \consists "Tab_note_heads_engraver"
+  \consists "Tab_harmonic_engraver"
+
   \remove "Note_heads_engraver"
   \remove "Fingering_engraver"
   \remove "New_fingering_engraver"
index 661d12de5d841becb1f0b507fa7e0d977c9d8319..c6eb5204936c859ac80d3ea840048179a6ac6e7c 100644 (file)
 (ly:add-interface
  'parentheses-interface
  "Parentheses for other objects"
- '(padding))
+ '(padding stencils))
 
 (ly:add-interface
  'piano-pedal-interface
index 25861affa54c315b70711665903cda0d99e8b367..8184b16f6abcec73385d792399bd7b4faf055e94 100644 (file)
@@ -374,6 +374,7 @@ stems that are placed in tight configurations. For opposite
 directions, this amount is the correction for two normal sized stems
 that overlap completely.")
      (stencil ,ly:stencil? "The symbol to print.")
+     (stencils ,list? "Multiple stencils, used as intermediate value.")
      (strict-note-spacing ,boolean? "If set, unbroken columns
 with non-musical material (clefs, barlines, etc.) are not spaced
 separately, but put before musical columns.")
index 4b70e8428ac49f59c8dcaf300a5ba1970e870145..a67919a76f411eb84a177bb483bbf1f5d91b5093 100644 (file)
 
     (ParenthesesItem
      . ((stencil . ,parentheses-item::print)
+       (stencils . ,parentheses-item::calc-parenthesis-stencils)
        (font-size . -6)
        (padding . 0.2)
        (meta . ((class . Item)
                 (interfaces . (parentheses-interface font-interface))))
        ))
+
+    (HarmonicParenthesesItem
+     . ((stencil . ,parentheses-item::print)
+       (padding . 0)
+       (stencils . ,parentheses-item::calc-angled-bracket-stencils)
+       (meta . ((class . Item)
+                (interfaces . (parentheses-interface font-interface))))
+       ))
     
     (PhrasingSlur
      . ((details . ,default-slur-details)
                 (interfaces . (side-position-interface
                                system-start-delimiter-interface))))))
 
-
     (TabNoteHead
      . (
        (stencil . ,ly:text-interface::print)
        (Y-offset . ,ly:staff-symbol-referencer::callback)
+       (X-offset . ,ly:self-alignment-interface::x-aligned-on-self)
+       (direction . 0)
        (font-size . -2)
        (stem-attachment . (0.0 . 1.35))
        (font-series . bold)
        (stencil . ,ly:tie::print)
        (font-size . -6)
        (details . (
-                   ;; for a full list, see tie-helper.cc
+                   ;; for a full list, see tie-details.cc
                    (ratio . 0.333)
                    (center-staff-line-clearance . 0.6)
                    (tip-staff-line-clearance . 0.45)
index 25ced26a9b2bb54edde73d952ed08d70ced42f8e..5d96ecb179be690a0930a48c51ec4dfb72cddc8e 100644 (file)
@@ -127,17 +127,7 @@ circle of diameter 0 (ie sharp corners)."
 
 (define-markup-command (whiteout layout props arg) (markup?)
   "Provide a white underground for @var{arg}"
-  (let* ((stil (interpret-markup layout props arg))
-        (white
-         (interpret-markup layout props
-                           (make-with-color-markup
-                            white
-                            (make-filled-box-markup
-                             (ly:stencil-extent stil X)
-                             (ly:stencil-extent stil Y)
-                             0.0)))))
-
-    (ly:stencil-add white stil)))
+  (stencil-whiteout (interpret-markup layout props arg)))
 
 (define-markup-command (pad-markup layout props padding arg) (number? markup?)
   "Add space around a markup object."
index 3575e13264db2bfe53a05633b45d05a501d523fe..fc8d291dec662e041b4513336aaea10b94934230 100644 (file)
@@ -230,6 +230,18 @@ found."
 ;;;;;;;;;;;;;;;;
 ;; list
 
+(define (functional-or . rest)
+  (if (pair? rest)
+      (or (car rest)
+          (apply functional-and (cdr rest)))
+      #f))
+
+(define (functional-and . rest)
+  (if (pair? rest)
+      (and (car rest)
+          (apply functional-and (cdr rest)))
+      #t))
+
 (define (split-list lst n)
   "Split LST in N equal sized parts"
   
index 495ef18cbc57ce7055501bef6a7c53de9fb72c2d..32ab98e88e2a486b72c88d054380da72f3e9063b 100644 (file)
@@ -415,7 +415,10 @@ The syntax is the same as `define*-public'."
          (format "~a ~a ~a\n"
                  gc-protect-stat-count
                  sym
-                 (cdr (assoc sym stats)))
+                 (let ((sym-stat (assoc sym stats)))
+                   (if sym-stat 
+                       (cdr sym-stat)
+                       "?")))
          outfile))
        '(protected-objects bytes-malloced cell-heap-size
                           
index 268efaf879e971ef69c0a0292cbf40c83d244235..bd20798e91df98f8128447350e1dabbf8b20a0e5 100644 (file)
@@ -35,9 +35,32 @@ The command is now available in markup mode, e.g.
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; markup definer utilities
+
+(defmacro-public in-module-define-variable (module-name symbol value)
+  "Define a variable in a module and export its name.
+  (in-module-define-variable (some module) symbol value)"
+  (let ((gmodule (gensym "module")))
+    `(let ((,gmodule (resolve-module ',module-name)))
+       (module-define! ,gmodule ',symbol ,value)
+       (module-export! ,gmodule '(,symbol)))))
+
+(defmacro-public in-module-define-function
+                 (module-name function-name+arg-list . body)
+  "Define a public function in a module:
+  (in-module-define-function (some module) (function-name . args)
+    ..body..)"
+  `(in-module-define-variable
+    ,module-name
+    ,(car function-name+arg-list)
+    (let ((proc (lambda ,(cdr function-name+arg-list)
+                  ,@body)))
+      (set-procedure-property! proc
+                               'name
+                               ',(car function-name+arg-list))
+      proc)))
+
 ;;; `define-markup-command' can be used both for built-in markup
 ;;; definitions and user defined markups.
-
 (defmacro-public define-markup-command (command-and-args signature . body)
   "
 
@@ -54,25 +77,37 @@ Syntax:
   (define-markup-command (COMMAND layout props arg1 arg2 ...) (arg1-type? arg2-type? ...)
     \"documentation string\"
     ...command body...)
- or:
-  (define-markup-command COMMAND (arg1-type? arg2-type? ...)
-    function)
+or:
+  (define-markup-command COMMAND (arg1-type? arg2-type? ...) function)
 "
-  (let* ((command (if (pair? command-and-args) (car command-and-args) command-and-args))
-         (args (if (pair? command-and-args) (cdr command-and-args) '()))
-         (command-name (string->symbol (string-append (symbol->string command) "-markup")))
-         (make-markup-name (string->symbol (string-append "make-" (symbol->string command-name)))))
-    `(begin
-       (define-public ,(if (pair? args)
-                           (cons command-name args)
-                           command-name)
-         ,@body)
-       (set! (markup-command-signature ,command-name) (list ,@signature))
-       (if (not (member ,command-name markup-function-list))
-           (set! markup-function-list (cons ,command-name markup-function-list)))
-       (define-public (,make-markup-name . args)
-         (let ((sig (list ,@signature)))
-           (make-markup ,command-name ,(symbol->string make-markup-name) sig args))))))
+  (let* ((command (if (pair? command-and-args)
+                      (car command-and-args)
+                      command-and-args))
+         (command-name (string->symbol (format #f "~a-markup" command)))
+         (make-markup-name (string->symbol (format #f "make-~a-markup" command))))
+    `(let ((lily-module (resolve-module '(lily))))
+       ;; define the COMMAND-markup procedure in (lily) module
+       ,(if (pair? command-and-args)
+            ;; two cases:
+            ;; 1/ (define (COMMAND-markup layout props arg1 arg2 ...)
+            ;;      ..command body))
+            `(in-module-define-function (lily) (,command-name ,@(cdr command-and-args))
+               ,@body)
+            ;; 2/ (define COMMAND-markup function)
+            `(in-module-define-variable (lily) ,command-name ,(car body)))
+       (let ((command-proc (module-ref lily-module ',command-name)))
+         ;; register its command signature
+         (set! (markup-command-signature command-proc)
+               (list ,@signature))
+         ;; add the COMMAND-markup procedure to the list of markup functions
+         (if (not (member command-proc markup-function-list))
+             (set! markup-function-list (cons command-proc markup-function-list)))
+         ;; define the make-COMMAND-markup procedure in (lily) module
+         (in-module-define-function (lily) (,make-markup-name . args)
+           (make-markup command-proc
+                        ,(symbol->string make-markup-name)
+                        (list ,@signature)
+                        args))))))
 
 (define-public (make-markup markup-function make-name signature args)
   " Construct a markup object from MARKUP-FUNCTION and ARGS. Typecheck
@@ -266,8 +301,8 @@ Also set markup-signature and markup-keyword object properties."
 (define (markup-symbol-to-proc markup-sym)
   "Return the markup command procedure which name is `markup-sym', if any."
   (hash-fold (lambda (key val prev)
-                            (or prev
-                                (if (eqv? (procedure-name key) markup-sym) key #f)))
+               (or prev
+                   (if (eqv? (procedure-name key) markup-sym) key #f)))
              #f
              markup-command-signatures))
 
@@ -410,9 +445,3 @@ eg: ((italic) (raise 4) (bold)), maps the commands on each markup argument, eg:
           (car stencils))
       (ly:make-stencil '() '(0 . 0) '(0 . 0))))
 
-
-
-
-
-
-
index 61895f0c4c1e836cc565f41d611e4703e951e454..7b0d5d0658aead0f69b1da9ad422f46647cce5a3 100644 (file)
@@ -422,8 +422,8 @@ OTTAVATION to `8va', or whatever appropriate."
                     (string (cdr (assoc octavation '((2 . "15ma")
                                                      (1 . "8va")
                                                      (0 . #f)
-                                                     (-1 . "8va bassa")
-                                                     (-2 . "15ma bassa"))))))
+                                                     (-1 . "8vb")
+                                                     (-2 . "15mb"))))))
                (ly:context-set-property! context 'middleCPosition new-c0)
                (ly:context-set-property! context 'originalCentralCPosition c0)
                (ly:context-set-property! context 'ottavation string)))))
index 88904384cda91c194bd235967ff3c7b963326b31..9075abd86fb18148a7442c2e34c53cc72d87d36d 100644 (file)
 
 ;; The TabNoteHead tablatureFormat callback.
 ;; Compute the text grob-property
-(define-public (fret-number-tablature-format string tuning pitch)
-  (make-whiteout-markup
-   (make-vcenter-markup  
-    (number->string
-     (- (ly:pitch-semitones pitch)
-       (list-ref tuning
-                 ;; remove 1 because list index starts at 0 and guitar string at 1. 
-                 (- string 1)))))))
+(define-public (fret-number-tablature-format string
+                                            context event)
+  (let*
+      ((tuning (ly:context-property context 'stringTunings))
+       (pitch (ly:event-property event 'pitch))
+       (is-harmonic (apply
+                    functional-or
+                    (map
+                     (lambda (ev)
+                       (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. 
+                   (- string 1))))))
+    ))
 
 ;; The 5-string banjo has got a extra string, the fifth (duh), wich
 ;; starts at the fifth fret on the neck. Frets on the fifth string
 ;;   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 tuning pitch)
+(define-public (fret-number-tablature-format-banjo string 
+                                            context event)
+  (let*
+      ((tuning (ly:context-property context 'stringTuning))
+       (pitch (ly:event-property event 'pitch))
+       )
   (make-whiteout-markup
    (make-vcenter-markup  
     (let ((fret (- (ly:pitch-semitones pitch) (list-ref tuning (- string 1)))))
       (number->string (cond
                       ((and (> fret 0) (= string 5))
                        (+ fret 5))
-                      (else fret)))))))
+                      (else fret))))))
+  ))
 
 
 ; default tunings for common string instruments
@@ -285,6 +305,37 @@ centered, X==1 is at the right, X == -1 is at the left."
 ;; * Pitch Trill Heads
 ;; * Parentheses
 
+(define-public (parentheses-item::calc-parenthesis-stencils grob)
+  (let* (
+        (font (ly:grob-default-font grob))
+        (lp (ly:font-get-glyph font "accidentals.leftparen"))
+        (rp (ly:font-get-glyph font "accidentals.rightparen"))
+        )
+
+    (list lp rp)))
+
+
+(define (grob-text grob text)
+  (let*
+      ((layout (ly:grob-layout grob))
+       (defs (ly:output-def-lookup layout 'text-font-defaults))
+       (props (ly:grob-alist-chain grob defs)))
+
+    (ly:text-interface::interpret-markup
+     layout props text)))
+
+(define-public (parentheses-item::calc-angled-bracket-stencils grob)
+  (let* (
+        (font (ly:grob-default-font grob))
+        (lp (ly:stencil-aligned-to (ly:stencil-aligned-to (grob-text grob (ly:wide-char->utf-8 #x2329))
+                                                          Y CENTER)  X RIGHT))
+        (rp (ly:stencil-aligned-to (ly:stencil-aligned-to (grob-text grob (ly:wide-char->utf-8 #x232A))
+                                                          Y CENTER) X LEFT))
+        )
+
+    (list (stencil-whiteout lp)
+         (stencil-whiteout rp))))
+
 (define (parenthesize-elements grob . rest)
   (let*
       ((refp (if (null? rest)
@@ -292,10 +343,9 @@ centered, X==1 is at the right, X == -1 is at the left."
                 (car rest)))
        (elts (ly:grob-object grob 'elements))
        (x-ext (ly:relative-group-extent elts refp X))
-
-       (font (ly:grob-default-font grob))
-       (lp (ly:font-get-glyph font "accidentals.leftparen"))
-       (rp (ly:font-get-glyph font "accidentals.rightparen"))
+       (stencils (ly:grob-property grob 'stencils))
+       (lp (car stencils))
+       (rp (cadr stencils))
        (padding (ly:grob-property grob 'padding 0.1)))
     
     (ly:stencil-add
@@ -324,6 +374,7 @@ centered, X==1 is at the right, X == -1 is at the left."
     ))
 
 
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; 
 
index b2d425e6ead5c7061d7e327c0d08934b9a92dbe4..62b43cebc260a13f4f2ec3402c99ba9475dbe4df 100644 (file)
@@ -118,13 +118,32 @@ encloses the contents.
      `(text ,font-metric ,text) (car b) (cdr b))))
      
 (define-public (fontify-text-white scale font-metric text)
-  "Set TEXT with scale factor s"
+  "Set TEXT with scale factor SCALE"
   (let* ((b (ly:text-dimension font-metric text))
         ;;urg -- workaround for using ps font
          (c `(white-text ,(* 2 scale) ,text)))
     ;;urg -- extent is not from ps font, but we hope it's close
     (ly:make-stencil c (car b) (cdr b))))
 
+(define-public (stencil-with-color stencil color)
+  (ly:make-stencil
+   (list 'color color (ly:stencil-expr stencil))
+   (ly:stencil-extent stencil X)
+   (ly:stencil-extent stencil Y)))
+  
+(define-public (stencil-whiteout stencil)
+  (let*
+      ((x-ext (ly:stencil-extent stencil X))
+       (y-ext (ly:stencil-extent stencil Y))
+
+       )
+    
+    (ly:stencil-add
+     (stencil-with-color (ly:round-filled-box x-ext y-ext 0.0)
+                        white)
+     stencil)
+    ))
+
 (define-public (dimension-arrows destination) 
   "Draw twosided arrow from here to @var{destination}"