]> git.donarmstrong.com Git - lilypond.git/commitdiff
* ly/engraver-init.ly (AncientRemoveEmptyStaffContext): remove
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Fri, 9 Dec 2005 23:58:55 +0000 (23:58 +0000)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Fri, 9 Dec 2005 23:58:55 +0000 (23:58 +0000)
Span_arpeggio_engraver, add Tweak_engraver to Score context.

* lily/parser.yy: reorganize file layout.

* ly/music-functions-init.ly: add tweak music function.

* lily/grob-info.cc (ultimate_music_cause): new function:
recursively lookup causes.

* lily/parser.yy (chord_body_element): allow music functions for
post-events, allow music functions for chord elements.

* lily/font-config-scheme.cc (display_fontset): add cast.

* python/convertrules.py (FatalConversionError.sub_syms): \tag
#'(a b) -> \tag #'a \tag #'b rule.

* python/musicexp.py (Output_printer.dump_version): new function

21 files changed:
ChangeLog
Documentation/topdocs/NEWS.tely
Documentation/user/advanced-notation.itely
THANKS
input/regression/grob-tweak.ly [new file with mode: 0644]
lily/auto-beam-engraver.cc
lily/beam-engraver.cc
lily/font-config-scheme.cc
lily/grob-info.cc
lily/include/grob-info.hh
lily/lily-lexer.cc
lily/note-head-line-engraver.cc
lily/parser.yy
lily/stem-engraver.cc
lily/tweak-engraver.cc [new file with mode: 0644]
ly/engraver-init.ly
ly/music-functions-init.ly
python/convertrules.py
python/musicexp.py
scm/define-grobs.scm
scm/define-music-properties.scm

index 82318adeb4e66a27ef09f862388a84ce3000aae1..c89f366dac1cb2c4c07e04cee96509ac021be430 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,35 @@
-2005-12-09  Werner Lemberg  <wl@gnu.org>
+2005-12-10  Han-Wen Nienhuys  <hanwen@xs4all.nl>
 
-       * mf/feta-beugel.mf (draw_brace): Use subpaths to assure correct
-       tension values.
+       * ly/engraver-init.ly (AncientRemoveEmptyStaffContext): remove
+       Span_arpeggio_engraver, add Tweak_engraver to Score context. 
+
+       * lily/parser.yy: reorganize file layout.
+
+       * ly/music-functions-init.ly: add tweak music function.
+
+       * lily/grob-info.cc (ultimate_music_cause): new function:
+       recursively lookup causes. 
+
+       * lily/parser.yy (chord_body_element): allow music functions for
+       post-events, allow music functions for chord elements. 
+       * lily/font-config-scheme.cc (display_fontset): add cast.
+
+       * python/convertrules.py (FatalConversionError.sub_syms): \tag
+       #'(a b) -> \tag #'a \tag #'b rule.
+
+       * python/musicexp.py (Output_printer.dump_version): new function
+
+2005-12-09  Han-Wen Nienhuys  <hanwen@xs4all.nl>
+
+       * lily/parser.yy (FIXME): remove \tag
+       (FIXME): remove tag_music() function.
+
+       * lily/lily-lexer.cc: remove \tag
+
+       * ly/music-functions-init.ly: define music-function "tag"
+
+       * lily/parser.yy (chord_body_element): allow tags in chord bodies.
 
 2005-12-08  Han-Wen Nienhuys  <hanwen@xs4all.nl>
 
index 6801d958110890196cb11e37ef2e05fe65e645d8..b71f00ebce08e09686188d9a0c41bb4c61424d6a 100644 (file)
@@ -45,6 +45,31 @@ This document is also available in @uref{NEWS.pdf,PDF}.
 
 
 @itemize @bullet
+@item With the @code{\tweak} music function, layout objects that are directly
+connected to input may be tuned,
+
+@lilypond[relative=2,fragment,raggedright]
+<
+  \tweak #'font-size #3  c
+  \tweak #'color #red  e
+  \tweak #'style #cross  g
+  \tweak #'duration-log #1  a
+>4
+@end lilypond
+
+This feature was sponsored by Sean Reed and Bertalan Fodor.
+
+@item Generic music functions may now also be used on articulations
+and chord elements, eg.
+
+@verbatim
+  < \displayMusic c
+    e-\keepWithTag #'bla -\tag #'bla ^2 >
+@end verbatim
+
+This feature was sponsored by Sean Reed and Bertalan Fodor.
+
+
 @item Spaces between lyrics and distance between syllables with
 hyphens may now be separately tuned through the
 @code{LyricSpace} grob.
index 0433e25fad79877b1d2424b82de67af983a7330d..a498d1f6d5513dc6a4087f529d7efa6a6cabbeca 100644 (file)
@@ -1097,10 +1097,11 @@ would yield
 
 @lilypondfile[raggedright,quote]{tag-filter.ly}
 
-The argument of the @code{\tag} command should be a symbol, or a list
-of symbols, for example,
+The argument of the @code{\tag} command should be a symbol. It's 
+possible to put multiple tags on a piece of music, with multiple
+@code{\tag} entries, 
 @example
-\tag #'(original-part transposed-part) @dots{}
+  \tag #'original-part \tag #'transposed-part @dots{}
 @end example
 
 
diff --git a/THANKS b/THANKS
index adf32cc13c10560b00ecafc0db8872aba701325c..6a8d315dec2b7abff27220b3249661048219542c 100644 (file)
--- a/THANKS
+++ b/THANKS
@@ -16,10 +16,10 @@ Bruce Fairchild
 Cameron Horsburgh
 Heikki Junes
 Joe Neeman
+Nicolas Sceaux
 Sven Axelsson
+Werner Lemberg
 Yoshinobu Ishizaki
-Nicolas Sceaux
-
 
 SPONSORS
 
@@ -36,6 +36,7 @@ Kris Shaffer
 Mark van den Borre
 Nancho Alvarez
 Nicolas Sceaux
+Sean Reed
 Steve Doonan
 Sven Axelsson
 Trent Johnston
diff --git a/input/regression/grob-tweak.ly b/input/regression/grob-tweak.ly
new file mode 100644 (file)
index 0000000..baf6ef1
--- /dev/null
@@ -0,0 +1,22 @@
+\header
+{
+
+  texidoc = "With the @code{\tweak} function, individual grobs that
+  are directly caused by events may be tuned directly."
+
+}
+
+\version "2.7.22"
+\paper {
+  raggedright = ##t
+}
+
+{
+  \set fingeringOrientations = #'(right)
+  <
+    \tweak #'font-size #3  c
+    \tweak #'color #red  d-\tweak #'font-size #8 -4
+    \tweak #'style #'cross  g
+    \tweak #'duration-log #1  a
+  >4
+}
index cdf0ad31df7a5076a773d2b40030ad5aa17d47c6..9609e40aa0cf16b9b5db79f03d9b079c19eb8bf4 100644 (file)
@@ -334,7 +334,7 @@ Auto_beam_engraver::acknowledge_stem (Grob_info info)
 {
   check_bar_property ();
   Item *stem = dynamic_cast<Item *> (info.grob ());
-  Music *m = info.music_cause ();
+  Music *m = info.ultimate_music_cause ();
   if (!m->is_mus_type ("rhythmic-event"))
     {
       programming_error ("stem must have rhythmic structure");
index 102af1f2ac3d3576478c39971ce41a71cacb00fb..4ba9dd7a99c0afe6b31e5cf35d32186a528800f9 100644 (file)
@@ -221,52 +221,55 @@ Beam_engraver::acknowledge_rest (Grob_info info)
     }
 }
 
+
+
 void
 Beam_engraver::acknowledge_stem (Grob_info info)
 {
-  if (beam_)
+  if (!beam_)
+    return;
+  
+  Moment now = now_mom ();
+  if (!valid_start_point ())
+    return;
+
+  Item *stem = dynamic_cast<Item *> (info.grob ());
+  if (Stem::get_beam (stem))
+    return;
+
+  
+  
+  Music *m = info.ultimate_music_cause ();
+  if (!m->is_mus_type ("rhythmic-event"))
     {
-      Moment now = now_mom ();
-
-      if (!valid_start_point ())
-       return;
-
-      Item *stem = dynamic_cast<Item *> (info.grob ());
-      if (Stem::get_beam (stem))
-       return;
-
-      Music *m = info.music_cause ();
-      if (!m->is_mus_type ("rhythmic-event"))
-       {
-         String s = _ ("stem must have Rhythmic structure");
-         if (info.music_cause ())
-           info.music_cause ()->origin ()->warning (s);
-         else
-           ::warning (s);
-
-         return;
-       }
+      String s = _ ("stem must have Rhythmic structure");
+      if (info.music_cause ())
+       info.music_cause ()->origin ()->warning (s);
+      else
+       ::warning (s);
 
-      last_stem_added_at_ = now;
-      int durlog = unsmob_duration (m->get_property ("duration"))->duration_log ();
-      if (durlog <= 2)
-       {
-         m->origin ()->warning (_ ("stem doesn't fit in beam"));
-         prev_start_ev_->origin ()->warning (_ ("beam was started here"));
-         /*
-           don't return, since
+      return;
+    }
 
-           [r4 c8] can just as well be modern notation.
-         */
-       }
+  last_stem_added_at_ = now;
+  int durlog = unsmob_duration (m->get_property ("duration"))->duration_log ();
+  if (durlog <= 2)
+    {
+      m->origin ()->warning (_ ("stem doesn't fit in beam"));
+      prev_start_ev_->origin ()->warning (_ ("beam was started here"));
+      /*
+       don't return, since
 
-      stem->set_property ("duration-log",
-                         scm_from_int (durlog));
-      Moment stem_location = now - beam_start_mom_ + beam_start_location_;
-      beam_info_->add_stem (stem_location,
-                           max (durlog- 2, 0));
-      Beam::add_stem (beam_, stem);
+       [r4 c8] can just as well be modern notation.
+      */
     }
+
+  stem->set_property ("duration-log",
+                     scm_from_int (durlog));
+  Moment stem_location = now - beam_start_mom_ + beam_start_location_;
+  beam_info_->add_stem (stem_location,
+                       max (durlog- 2, 0));
+  Beam::add_stem (beam_, stem);
 }
 
 ADD_ACKNOWLEDGER (Beam_engraver, stem);
index 79b069befa1767fc3c59145da6dc569ea928c795..279ffb57b3a2bdb3e69a2c8701110d78145a5d4d 100644 (file)
@@ -29,7 +29,7 @@ display_fontset (FcFontSet *fs)
                              "designsize", 0, &str) == FcResultMatch)
        printf ("designsize %s\n ", str);
       
-      printf ("%s\n", font);
+      printf ("%s\n", (const char*) font);
       free (font);
     }
 }
index be4a41c6c21d98071c1f99de49f3ae6b75209385..4ffbcf9c15da408c9c95f406e8b67c490a92781b 100644 (file)
@@ -27,7 +27,7 @@ Grob_info::Grob_info ()
 }
 
 Music *
-Grob_info::music_cause ()
+Grob_info::music_cause () const
 {
   SCM cause = grob_->get_property ("cause");
   return unsmob_music (cause);
@@ -65,3 +65,16 @@ Grob_info::item () const
 {
   return dynamic_cast<Item *> (grob_);
 }
+
+Music *
+Grob_info::ultimate_music_cause () const
+{
+  SCM cause = grob_->self_scm ();
+  while (unsmob_grob (cause))
+    {
+      cause = unsmob_grob (cause)->get_property ("cause");
+    }
+
+  return unsmob_music (cause);
+}
+
index 9dd40fea006b83643c2332852d6b41c00f90f534..61b903b64bb1afaee4b2a4d7961fe696f1d19a41 100644 (file)
@@ -27,7 +27,8 @@ public:
   Translator *origin_translator () const { return origin_trans_; }
 
   Context *context () const;
-  Music *music_cause ();
+  Music *music_cause () const;
+  Music *ultimate_music_cause () const;
   Link_array<Context> origin_contexts (Translator *) const;
   Grob_info (Translator *, Grob *);
   Grob_info ();
index 7a8deb6dc33047b4c1d7eff2c33354776966ee00..03ba2825205eaac51ed4ec4835c4b3b8026c4bb6 100644 (file)
@@ -73,7 +73,6 @@ static Keyword_ent the_key_tab[]
   {"set", SET},
   {"simultaneous", SIMULTANEOUS},
   {"skip", SKIP},
-  {"tag", TAG},
   {"tempo", TEMPO},
   {"time", TIME_T},
   {"times", TIMES},
index 34b6945088b9ece14261c144f72c80defeddd6f1..a7becd06ef97ada235420047603942a340a35342 100644 (file)
@@ -97,6 +97,7 @@ Note_head_line_engraver::stop_translation_timestep ()
 }
 
 #include "translator.icc"
+
 ADD_ACKNOWLEDGER (Note_head_line_engraver, rhythmic_head);
 ADD_TRANSLATOR (Note_head_line_engraver,
                /* doc */ "Engrave a line between two note heads, for example a glissando.  If "
index 70f35f500000a3fb516bd9541d17c17bef939723..4b250d09663de35f5a561878152c5e274fd4d8ed 100644 (file)
@@ -1,5 +1,3 @@
-%{ // -*-Fundamental-*-
-
 /*
   parser.yy -- Bison/C++ parser for LilyPond
 
@@ -9,6 +7,54 @@
                  Jan Nieuwenhuizen <janneke@gnu.org>
 */
 
+%{
+
+#define YYERROR_VERBOSE 1
+#define YYPARSE_PARAM my_lily_parser
+#define YYLEX_PARAM my_lily_parser
+#define THIS\
+       ((Lily_parser *) my_lily_parser)
+
+#define yyerror THIS->parser_error
+
+/* We use custom location type: Input objects */
+#define YYLTYPE Input
+#define YYLLOC_DEFAULT(Current,Rhs,N) \
+       ((Current).set_location ((Rhs)[1], (Rhs)[N]))
+
+
+%}
+
+/* We use SCMs to do strings, because it saves us the trouble of
+deleting them.  Let's hope that a stack overflow doesnt trigger a move
+of the parse stack onto the heap. */
+
+%left PREC_TOP
+%left ADDLYRICS
+%left PREC_BOT
+
+%expect 1
+
+/* One shift/reduce problem
+
+1.  \repeat
+       \repeat .. \alternative
+
+    \repeat { \repeat .. \alternative }
+
+or
+
+    \repeat { \repeat } \alternative 
+*/
+
+
+%pure_parser
+%locations
+
+
+
+%{ // -*-Fundamental-*-
+
 /*
 FIXME:
 
@@ -47,174 +93,8 @@ using namespace std;
 #include "warn.hh"
 #include "music.hh"
 
-#define MY_MAKE_MUSIC(x)  make_music_by_name (ly_symbol2scm (x))
-
-Music *property_op_to_music (SCM op);
-Music *context_spec_music (SCM type, SCM id, Music *m, SCM ops);
-SCM get_next_unique_context_id ();
-SCM get_next_unique_lyrics_context_id ();
-
-#undef _
-#if !HAVE_GETTEXT
-#define _(x) x
-#else
-#include <libintl.h>
-#define _(x) gettext (x)
-#endif
-
-#define YYERROR_VERBOSE 1
-
-#define YYPARSE_PARAM my_lily_parser
-#define YYLEX_PARAM my_lily_parser
-#define THIS\
-       ((Lily_parser *) my_lily_parser)
-
-#define yyerror THIS->parser_error
-
-/* We use custom location type: Input objects */
-#define YYLTYPE Input
-#define YYLLOC_DEFAULT(Current,Rhs,N) \
-       ((Current).set_location ((Rhs)[1], (Rhs)[N]))
-
-
-/* Add symbols to the TAGS field of a music object.  */
-
-void
-tag_music (Music *m, SCM tag, Input ip)
-{
-       SCM tags = m->get_property ("tags");
-       if (scm_is_symbol (tag))
-               tags = scm_cons (tag, tags);
-       else if (ly_is_list (tag))
-               tags = ly_append2 (tag, tags);
-       else
-               ip.warning (_ ("tag must be symbol or list of symbols"));
-
-       m->set_property ("tags", tags);
-}
-
-bool
-is_regular_identifier (SCM id)
-{
-  String str = ly_scm2string (id);
-  char const *s = str.to_str0 ();
-
-  bool v = true;
-#if 0
-  isalpha (*s);
-  s++;
-#endif
-  while (*s && v)
-   {
-        v = v && isalnum (*s);
-        s++;
-   }
-  return v;
-}
-
-
-SCM
-get_first_context_id (SCM type, Music *m)
-{
-       SCM id = m->get_property ("context-id");
-       if (SCM_BOOL_T == scm_equal_p (m->get_property ("context-type"), type)
-           && scm_is_string (m->get_property ("context-id"))
-           && scm_c_string_length (id) > 0)
-       {
-               return id;
-       }
-       return SCM_EOL;
-}
-
-SCM
-make_simple_markup (SCM a)
-{
-       return a;
-}
-
-bool
-is_duration (int t)
-{
-  return t && t == 1 << intlog2 (t);
-}
-
-void
-set_music_properties (Music *p, SCM a)
-{
-  for (SCM k = a; scm_is_pair (k); k = scm_cdr (k))
-       p->internal_set_property (scm_caar (k), scm_cdar (k));
-}
-
-SCM
-make_chord_step (int step, int alter)
-{
-       if (step == 7)
-               alter += FLAT;
-
-       while (step < 0)
-               step += 7;
-       Pitch m ((step -1) / 7, (step - 1) % 7, alter);
-       return m.smobbed_copy ();
-}
-
-
-SCM
-make_chord (SCM pitch, SCM dur, SCM modification_list)
-{
-       SCM chord_ctor = ly_lily_module_constant ("construct-chord");
-       SCM ch = scm_call_3 (chord_ctor, pitch, dur, modification_list);
-
-       unsmob_music (ch)->protect();   
-       return ch;
-}
-
-/* Todo: actually also use apply iso. call too ...  */
-bool
-ly_input_procedure_p (SCM x)
-{
-       return ly_is_procedure (x)
-               || (scm_is_pair (x) && ly_is_procedure (scm_car (x)));
-}
-
-Music*
-set_property_music (SCM sym, SCM value)
-{
-       Music *p = MY_MAKE_MUSIC ("PropertySet");
-       p->set_property ("symbol", sym);
-       p->set_property ("value", value);
-       return p;
-}
-
-Music*
-make_music_relative (Pitch start, Music *music)
-{
-       Music *relative = MY_MAKE_MUSIC ("RelativeOctaveMusic");
-       relative->set_property ("element", music->self_scm ());
-       
-       Pitch last = music->to_relative_octave (start);
-       if (lily_1_8_relative)
-               music->set_property ("last-pitch", last.smobbed_copy ());
-       return relative;
-}
-
-Music*
-make_lyric_combine_music (SCM name, Music *music)
-{
-       Music *combine = MY_MAKE_MUSIC ("LyricCombineMusic");
-       combine->set_property ("element", music->self_scm ());
-       combine->set_property ("associated-context", name);
-       return combine;
-}
-
 %}
 
-/* We use SCMs to do strings, because it saves us the trouble of
-deleting them.  Let's hope that a stack overflow doesnt trigger a move
-of the parse stack onto the heap. */
-
-%left PREC_TOP
-%left ADDLYRICS
-%left PREC_BOT
 
 %union {
        Book *book;
@@ -225,40 +105,41 @@ of the parse stack onto the heap. */
        Score *score;
        int i;
 }
-%{
-
-int
-yylex (YYSTYPE *s, YYLTYPE *loc, void *v)
-{
-       Lily_parser *pars = (Lily_parser*) v;
-       Lily_lexer *lex = pars->lexer_;
-
-       lex->lexval = (void*) s;
-       lex->lexloc = loc;
-       lex->prepare_for_next_token ();
-       return lex->yylex ();
-}
-
-
-%}
 
-%expect 1
+%{
 
-/* One shift/reduce problem
+#define MY_MAKE_MUSIC(x)  make_music_by_name (ly_symbol2scm (x))
 
-1.  \repeat
-       \repeat .. \alternative
+Music *property_op_to_music (SCM op);
+Music *context_spec_music (SCM type, SCM id, Music *m, SCM ops);
+SCM get_next_unique_context_id ();
+SCM get_next_unique_lyrics_context_id ();
 
-    \repeat { \repeat .. \alternative }
+#undef _
+#if !HAVE_GETTEXT
+#define _(x) x
+#else
+#include <libintl.h>
+#define _(x) gettext (x)
+#endif
 
-or
 
-    \repeat { \repeat } \alternative 
-*/
 
+Music *make_lyric_combine_music (SCM name, Music *music);
+Music *make_music_relative (Pitch start, Music *music);
+Music *run_music_function (Lily_parser *, SCM expr);
+Music *set_property_music (SCM sym, SCM value);
+SCM get_first_context_id (SCM type, Music *m);
+SCM make_chord (SCM pitch, SCM dur, SCM modification_list);
+SCM make_chord_step (int step, int alter);
+SCM make_simple_markup (SCM a);
+bool is_duration (int t);
+bool is_regular_identifier (SCM id);
+bool ly_input_procedure_p (SCM x);
+int yylex (YYSTYPE *s, YYLTYPE *loc, void *v);
+void set_music_properties (Music *p, SCM a);
 
-%pure_parser
-%locations
+%}
 
 /* The third option is an alias that will be used to display the
    syntax error.  Bison CVS now correctly handles backslash escapes.
@@ -318,7 +199,6 @@ or
 %token SET "\\set"
 %token SIMULTANEOUS "\\simultaneous"
 %token SKIP "\\skip"
-%token TAG "\\tag"
 %token TEMPO "\\tempo"
 %token TIMES "\\times"
 %token TRANSPOSE "\\transpose"
@@ -435,7 +315,6 @@ If we give names, Bison complains.
 %type <i> tremolo_type
 
 %type <music> Composite_music
-%type <music> Generic_prefix_music
 %type <music> Grouped_music_list
 %type <music> Music
 %type <music> Prefix_composite_music
@@ -459,7 +338,6 @@ If we give names, Bison complains.
 %type <music> relative_music
 %type <music> simple_element
 %type <music> string_number_event
-%type <music> tagged_post_event
 %type <music> tempo_event
 %type <music> toplevel_music
 
@@ -474,6 +352,8 @@ If we give names, Bison complains.
 %type <scm> absolute_pitch
 %type <scm> assignment_id
 %type <scm> bare_number
+%type <scm> music_function_event
+%type <scm> music_function_chord_body
 %type <scm> bass_figure
 %type <scm> figured_bass_modification
 %type <scm> br_bass_figure
@@ -1113,10 +993,7 @@ Generic_prefix_music_scm:
        | MUSIC_FUNCTION_MARKUP full_markup {
                $$ = scm_list_3 ($1, make_input (@$), $2);
        }
-       | MUSIC_FUNCTION_MUSIC Music {
-               $$ = scm_list_3 ($1, make_input (@$), $2->self_scm ());
-               $2->unprotect ();
-       }
+
        | MUSIC_FUNCTION_SCM_MUSIC embedded_scm Music {
                $$ = scm_list_4 ($1, make_input (@$), $2, $3->self_scm ());
                $3->unprotect ();
@@ -1127,6 +1004,10 @@ Generic_prefix_music_scm:
        | MUSIC_FUNCTION_SCM_SCM_SCM embedded_scm embedded_scm embedded_scm {
                $$ = scm_list_5 ($1, make_input (@$), $2, $3, $4);
        }
+       | MUSIC_FUNCTION_MUSIC Music {
+               $$ = scm_list_3 ($1, make_input (@$), $2->self_scm ());
+               $2->unprotect ();
+       }
        | MUSIC_FUNCTION_SCM_SCM_MUSIC embedded_scm embedded_scm Music {
                $$ = scm_list_5 ($1, make_input (@$), $2, $3, $4->self_scm ());
        }
@@ -1154,46 +1035,9 @@ Generic_prefix_music_scm:
        }
        ;
 
-Generic_prefix_music:
-       Generic_prefix_music_scm {
-               SCM func = scm_car ($1);
-               Input *loc = unsmob_input (scm_cadr ($1));
-               SCM args = scm_cddr ($1);
-               SCM sig = scm_object_property (func, ly_symbol2scm ("music-function-signature"));
-
-               SCM type_check_proc = ly_lily_module_constant ("type-check-list");
-               bool ok  = true;
-
-               if (!to_boolean (scm_call_3  (type_check_proc, scm_cadr ($1), sig, args)))
-               {
-                       THIS->error_level_ = 1;
-                       ok = false;
-               }
-
-               SCM m = SCM_EOL;
-               if (ok)
-                       m = scm_apply_0 (func, scm_cons (THIS->self_scm(),
-                                                        scm_cdr ($1)));
-
-               if (unsmob_music (m))
-                       {
-                       $$ = unsmob_music (m);
-                       $$->protect ();
-                       }
-               else
-                       {
-                       if (ok)
-                               loc->error (_ ("music head function must return Music object")); 
-                       $$ = MY_MAKE_MUSIC ("Music");
-                       }
-               $$->set_spot (*loc);
-       }
-       ;
-
-
 Prefix_composite_music:
-       Generic_prefix_music {
-               $$ = $1;
+       Generic_prefix_music_scm {
+               $$ = run_music_function (THIS, $1);
        }
        | CONTEXT simple_string '=' simple_string optional_context_mod Music {
                $$ = context_spec_music ($2, $4, $6, $5);
@@ -1262,10 +1106,6 @@ Prefix_composite_music:
        }
        | relative_music        { $$ = $1; }
        | re_rhythmed_music     { $$ = $1; }
-       | TAG embedded_scm Music {
-               tag_music ($3, $2, @$);
-               $$ = $3;
-       }
        ;
 
 mode_changing_head: 
@@ -1689,8 +1529,33 @@ chord_body_element:
                }
                $$ = n;
        }
+       | music_function_chord_body { 
+               $$ = run_music_function (THIS, $1);
+               $$->set_spot (@$);
+       }
+       ;
+
+music_function_chord_body:
+       MUSIC_FUNCTION {
+               $$ = scm_list_2 ($1, make_input (@$));
+       }
+       | MUSIC_FUNCTION_MUSIC chord_body_element {
+               $$ = scm_list_3 ($1, make_input (@$),
+                                       $2->self_scm ());
+       }
+       | MUSIC_FUNCTION_SCM_MUSIC embedded_scm chord_body_element {
+               $$ = scm_list_4 ($1, make_input (@$),
+                                       $2, $3->self_scm ());
+       }
+       | MUSIC_FUNCTION_SCM_SCM_MUSIC embedded_scm embedded_scm
+               chord_body_element {
+
+               $$ = scm_list_5 ($1, make_input (@$),
+                                       $2, $3, $4->self_scm ());
+       }
        ;
 
+
 add_quote:
        ADDQUOTE string Music {
                SCM adder = ly_lily_module_constant ("add-quotable");
@@ -1847,26 +1712,30 @@ post_events:
                $$ = scm_cons ($2->self_scm (), $$);
                $2->unprotect ();
        }
-       | post_events tagged_post_event {
-               $2 -> set_spot (@2);
-               $$ = scm_cons ($2->self_scm (), $$);
-               $2->unprotect ();
-       }
        ;
 
-
-tagged_post_event:
-       '-' TAG embedded_scm post_event {
-               tag_music ($4, $3, @$);
-               $$ = $4;
+music_function_event:
+       MUSIC_FUNCTION_MUSIC post_event {
+               $$ = scm_list_3 ($1, make_input (@$), $2->self_scm ());
+       }
+       | MUSIC_FUNCTION_SCM_MUSIC embedded_scm post_event {
+               $$ = scm_list_4 ($1, make_input (@$), $2, $3->self_scm ());
+       }
+       | MUSIC_FUNCTION_SCM_SCM_MUSIC embedded_scm embedded_scm post_event {
+               $$ = scm_list_5 ($1, make_input (@$), $2, $3, $4->self_scm ());
        }
        ;
 
-
+       
 post_event:
        direction_less_event {
                $$ = $1;
        }
+       | '-' music_function_event {
+               Music *mus = run_music_function (THIS, $2);
+               mus->set_spot (@1);
+               $$ = mus;
+       }
        | HYPHEN {
                if (!THIS->lexer_->is_lyric_state ())
                        THIS->parser_error (@1, _ ("have to be in Lyric mode for lyrics"));
@@ -2834,6 +2703,174 @@ get_next_unique_lyrics_context_id ()
 {
        static int new_context_count;
        char s[128];
-       snprintf (s, 1024, "uniqueContext%d", new_context_count++);
+       snprintf (s, sizeof (s)-1, "uniqueContext%d", new_context_count++);
        return scm_makfrom0str (s);
 }
+
+
+Music *
+run_music_function (Lily_parser *parser, SCM expr)
+{
+       SCM func = scm_car (expr);
+       Input *loc = unsmob_input (scm_cadr (expr));
+       SCM args = scm_cddr (expr);
+       SCM sig = scm_object_property (func, ly_symbol2scm ("music-function-signature"));
+
+       SCM type_check_proc = ly_lily_module_constant ("type-check-list");
+       bool ok  = true;
+
+       if (!to_boolean (scm_call_3  (type_check_proc, scm_cadr (expr), sig, args)))
+       {
+               parser->error_level_ = 1;
+               ok = false;
+       }
+
+       SCM m = SCM_EOL;
+       if (ok)
+               m = scm_apply_0 (func, scm_cons (parser->self_scm(),
+                                                scm_cdr (expr)));
+
+
+       Music* retval = 0;
+       if (unsmob_music (m))
+               {
+               retval = unsmob_music (m);
+               retval->protect ();
+               }
+       else
+               {
+               if (ok)
+                       loc->error (_ ("music head function must return Music object")); 
+               retval = MY_MAKE_MUSIC ("Music");
+               }
+       retval->set_spot (*loc);
+       return retval;
+}
+
+bool
+is_regular_identifier (SCM id)
+{
+  String str = ly_scm2string (id);
+  char const *s = str.to_str0 ();
+
+  bool v = true;
+#if 0
+  isalpha (*s);
+  s++;
+#endif
+  while (*s && v)
+   {
+        v = v && isalnum (*s);
+        s++;
+   }
+  return v;
+}
+
+
+SCM
+get_first_context_id (SCM type, Music *m)
+{
+       SCM id = m->get_property ("context-id");
+       if (SCM_BOOL_T == scm_equal_p (m->get_property ("context-type"), type)
+           && scm_is_string (m->get_property ("context-id"))
+           && scm_c_string_length (id) > 0)
+       {
+               return id;
+       }
+       return SCM_EOL;
+}
+
+SCM
+make_simple_markup (SCM a)
+{
+       return a;
+}
+
+bool
+is_duration (int t)
+{
+  return t && t == 1 << intlog2 (t);
+}
+
+void
+set_music_properties (Music *p, SCM a)
+{
+  for (SCM k = a; scm_is_pair (k); k = scm_cdr (k))
+       p->internal_set_property (scm_caar (k), scm_cdar (k));
+}
+
+
+SCM
+make_chord_step (int step, int alter)
+{
+       if (step == 7)
+               alter += FLAT;
+
+       while (step < 0)
+               step += 7;
+       Pitch m ((step -1) / 7, (step - 1) % 7, alter);
+       return m.smobbed_copy ();
+}
+
+
+SCM
+make_chord (SCM pitch, SCM dur, SCM modification_list)
+{
+       SCM chord_ctor = ly_lily_module_constant ("construct-chord");
+       SCM ch = scm_call_3 (chord_ctor, pitch, dur, modification_list);
+
+       unsmob_music (ch)->protect();   
+       return ch;
+}
+
+
+/* Todo: actually also use apply iso. call too ...  */
+bool
+ly_input_procedure_p (SCM x)
+{
+       return ly_is_procedure (x)
+               || (scm_is_pair (x) && ly_is_procedure (scm_car (x)));
+}
+
+Music*
+set_property_music (SCM sym, SCM value)
+{
+       Music *p = MY_MAKE_MUSIC ("PropertySet");
+       p->set_property ("symbol", sym);
+       p->set_property ("value", value);
+       return p;
+}
+
+Music*
+make_music_relative (Pitch start, Music *music)
+{
+       Music *relative = MY_MAKE_MUSIC ("RelativeOctaveMusic");
+       relative->set_property ("element", music->self_scm ());
+       
+       Pitch last = music->to_relative_octave (start);
+       if (lily_1_8_relative)
+               music->set_property ("last-pitch", last.smobbed_copy ());
+       return relative;
+}
+
+Music *
+make_lyric_combine_music (SCM name, Music *music)
+{
+       Music *combine = MY_MAKE_MUSIC ("LyricCombineMusic");
+       combine->set_property ("element", music->self_scm ());
+       combine->set_property ("associated-context", name);
+       return combine;
+}
+
+
+int
+yylex (YYSTYPE *s, YYLTYPE *loc, void *v)
+{
+       Lily_parser *pars = (Lily_parser*) v;
+       Lily_lexer *lex = pars->lexer_;
+
+       lex->lexval = (void*) s;
+       lex->lexloc = loc;
+       lex->prepare_for_next_token ();
+       return lex->yylex ();
+}
index 052f4d653c3b0f53ca6fba634eb7d99ff4c386ec..019b05333facfd37b28e59b67c15eeab1331b853 100644 (file)
@@ -51,7 +51,7 @@ Stem_engraver::make_stem (Grob_info gi)
 {
   /* Announce the cause of the head as cause of the stem.  The
      stem needs a rhythmic structure to fit it into a beam.  */
-  stem_ = make_item ("Stem", gi.music_cause ()->self_scm ());
+  stem_ = make_item ("Stem", gi.grob ()->self_scm ());
 
   /*
     we take the duration log from the Event, since the duration-log
diff --git a/lily/tweak-engraver.cc b/lily/tweak-engraver.cc
new file mode 100644 (file)
index 0000000..da8f537
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+  tweak-engraver.cc -- implement Tweak_engraver
+
+  source file of the GNU LilyPond music typesetter
+
+  (c) 2005 Han-Wen Nienhuys <hanwen@xs4all.nl>
+
+*/
+
+#include "engraver.hh"
+
+#include "music.hh"
+#include "grob.hh"
+#include "translator.icc"
+
+class Tweak_engraver : public Engraver
+{
+  TRANSLATOR_DECLARATIONS (Tweak_engraver);
+
+protected:
+  DECLARE_ACKNOWLEDGER (grob);
+};
+
+Tweak_engraver::Tweak_engraver()
+{
+}
+
+void
+Tweak_engraver::acknowledge_grob (Grob_info info)
+{
+  if (Music *music = info.music_cause ())
+    {
+      for (SCM s = music->get_property ("tweaks");
+          scm_is_pair (s); s = scm_cdr (s))
+       {
+         info.grob ()->internal_set_property (scm_caar (s), scm_cdar (s));
+       }
+    }
+}
+
+ADD_ACKNOWLEDGER (Tweak_engraver, grob);
+ADD_TRANSLATOR (Tweak_engraver,
+               /* doc */ "Read the @code{tweaks} property from the originating Music event, and set properties." ,
+               
+               /* create */ "",
+               /* accept */ "",
+               /* read */ "",
+               /* write */ "");
index c051a64451b3879e29aef1061281a11510dfc666..6bc9228970cc5bdf564cd3affa1d4f8e194e49fb 100644 (file)
@@ -1,18 +1,18 @@
 \version "2.7.14"
 
 \context {
-  \name Global
+  \name "Global"
 
-  \accepts Score
+  \accepts "Score"
 
-  \defaultchild Score
+  \defaultchild "Score"
   \description "Hard coded entry point for LilyPond. Cannot be tuned."
   \grobdescriptions #all-grob-descriptions
 }
 
 \context {
   \type "Engraver_group"
-  \name Staff
+  \name "Staff"
   
   \consists "Output_property_engraver" 
   \consists "Bar_engraver"
@@ -64,8 +64,9 @@
 \context {
   \Staff
   \type "Engraver_group"
-  \name DrumStaff
-  \alias Staff
+  \name "DrumStaff"
+  \alias "Staff"
+  
   \remove "Accidental_engraver"
   \remove "Ottava_spanner_engraver"
   \remove "Key_engraver" 
@@ -74,9 +75,9 @@
   
   \description "Handles typesetting for percussion."
 
-  \denies Voice
-  \accepts DrumVoice
-  \defaultchild DrumVoice
+  \denies "Voice"
+  \accepts "DrumVoice"
+  \defaultchild "DrumVoice"
 
   clefGlyph = #"clefs.percussion"
   clefPosition = #0
@@ -86,7 +87,7 @@
 
 \context {
   \type "Engraver_group"
-  \name InnerChoirStaff
+  \name "InnerChoirStaff"
   \consists "System_start_delimiter_engraver"
   systemStartDelimiter = #'SystemStartBracket
 
@@ -416,9 +417,9 @@ AncientRemoveEmptyStaffContext = \context {
 }
 
 \context {
-  \type Score_engraver
+  \type "Score_engraver"
   \name "Score"
-
+  
   \description "This is the top level notation context.  No
     other context can contain a @code{Score} context.  This context
     handles the administration of time signatures.  It also makes sure
@@ -449,9 +450,10 @@ AncientRemoveEmptyStaffContext = \context {
   \consists "Vertical_align_engraver"
   \consists "Stanza_number_align_engraver"
   \consists "Bar_number_engraver"
-  \consists "Span_arpeggio_engraver"
-
+  \consists "Tweak_engraver"
+  
   \defaultchild "Staff"
+
   \accepts "Staff"
   \accepts "RhythmicStaff"
   \accepts "TabStaff"
@@ -468,7 +470,7 @@ AncientRemoveEmptyStaffContext = \context {
   \accepts "Devnull"
   \accepts "NoteNames"
   \accepts "FiguredBass"
-
+  
   soloText = #"Solo"
   soloIIText = #"Solo II"
   aDueText = #"a2"
index 798f46641da9721f74bd8c66f69d2884591826f5..0d7aeb26c0e81a222b0c17c15648280380d756c3 100644 (file)
@@ -6,6 +6,43 @@
 
 #(use-modules (srfi srfi-1))  
 
+
+tweak = #(def-music-function (parser location sym val arg)
+          (symbol? scheme? ly:music?)
+
+          "Add @code{sym . val} to the @code{tweaks} property of @var{arg}."
+
+          
+          (set!
+           (ly:music-property arg 'tweaks)
+           (acons sym val
+                  (ly:music-property arg 'tweaks)))
+          arg)
+
+          
+
+tag = #(def-music-function (parser location tag arg)
+   (symbol? ly:music?)
+
+   "Add @var{tag} to the @code{tags} property of @var{arg}."
+
+   (set!
+    (ly:music-property arg 'tags)
+    (cons tag
+         (ly:music-property arg 'tags)))
+   arg)
+
+tag = #(def-music-function (parser location tag arg)
+   (symbol? ly:music?)
+
+   "Add @var{tag} to the @code{tags} property of @var{arg}."
+
+   (set!
+    (ly:music-property arg 'tags)
+    (cons tag
+         (ly:music-property arg 'tags)))
+   arg)
+
 applyMusic =
 #(def-music-function (parser location func music) (procedure? ly:music?)
                (func music))
index bf0e4d1aa8435c2bbfe5f59cd646a348b9803b3c..6868b4937b09479e13bcfcec93dd4f23091afd92 100644 (file)
@@ -2651,3 +2651,16 @@ def conv (str):
 
 conversions.append (((2, 7, 15), conv,
                     '''Use grob closures iso. XY-offset-callbacks.'''))
+
+
+def conv (str):
+       def sub_syms (m):
+               syms =  m.group (1).split ()
+               tags = ["\\tag #'%s" % s for s in syms]
+               return ' '.join (tags)
+               
+       str = re.sub (r"\\tag #'\(([^)]+)\)",  sub_syms, str)
+       return str
+
+conversions.append (((2, 7, 22), conv,
+                    """\tag #'(a b) -> \tag #'a \tag #'b""" ))
index b2b5846a6f81afd32c065e68affa0c16113030b8..43c75c870fbd29b5bcf67cf77090ad8c9d2ed634 100644 (file)
@@ -25,6 +25,11 @@ class Output_printer:
                self.output_state_stack = [Output_stack_element()]
                self._skipspace = False
                self.last_duration = None
+
+       def dump_version (self):
+               self.newline ()
+               self.print_verbatim ('\\version "@TOPLEVEL_VERSION@"')
+               self.newline ()
                
        def get_indent (self):
                return self.nesting * self.indent
index c3be6e388616fc2dc74e79ffcb872d8d3933eb74..28c9b1c83e67824863f55eefd149cadf225b4338 100644 (file)
                                ledgered-interface))))))
 
     (Arpeggio
-     . (
-
-       (X-extent . ,Arpeggio::width)
+     . ((X-extent . ,Arpeggio::width)
        (stencil . ,Arpeggio::print)
-
        (Y-offset . ,Staff_symbol_referencer::callback)
        (X-offset . ,Side_position_interface::x_aligned_side)
        (direction . -1)
index 58d7eea429ee4d955171de30c9a442f4f65cb6c3..689f81180e38478b7bdd602fa020dbf55ad36c00 100644 (file)
@@ -83,6 +83,9 @@ It must take a single argument, being the context.")
      (quoted-context-type ,symbol? "The name of the context to direct quotes to, eg., @code{Voice}.")
      (quoted-context-id ,string? "The id of the context to direct quotes to, eg., @code{cue}.")
      (to-relative-callback ,procedure? "How to transform a piece of music to relative pitches")
+     (tweaks ,list? "An alist of properties to override in the backend
+for the grob made of this event.")
+     
      (repeat-count  ,integer? "do a @code{\repeat} how ofen?")
      (span-direction ,ly:dir? "Does this start or stop a spanner?")
      (split-list ,list? "splitting moments for part combiner.")