]> git.donarmstrong.com Git - lilypond.git/commitdiff
Merge branch 'issue4609' into HEAD
authorDavid Kastrup <dak@gnu.org>
Sun, 20 Sep 2015 13:16:31 +0000 (15:16 +0200)
committerDavid Kastrup <dak@gnu.org>
Sun, 20 Sep 2015 13:16:31 +0000 (15:16 +0200)
14 files changed:
Documentation/changes.tely
Documentation/learning/tweaks.itely
Documentation/notation/changing-defaults.itely
input/regression/revert-once.ly [new file with mode: 0644]
lily/context-property.cc
lily/context-scheme.cc
lily/context.cc
lily/engraver-group.cc
lily/include/context.hh
lily/include/grob-properties.hh
lily/include/property-iterator.hh
lily/nested-property.cc
lily/property-iterator.cc
scm/define-music-display-methods.scm

index ca142c3286fc8bbe11b116ac05ddbdbd52e8da45..7ba1fa281bee1eff0d4d02ce6a4079250b596efd 100644 (file)
@@ -61,6 +61,24 @@ which scares away people.
 
 @end ignore
 
+@item
+All of @code{\override}, @code{\revert}, @code{\set}, and
+@code{\unset} now work with the @code{\once} prefix for making
+one-time settings.
+@lilypond[quote,verbatim]
+\relative {
+  c'4 d
+  \override NoteHead.color = #red
+  e4 f |
+  \once \override NoteHead.color = #green
+  g4 a
+  \once \revert NoteHead.color
+  b c |
+  \revert NoteHead.color
+  f2 c |
+}
+@end lilypond
+
 @item
 When outputting MIDI, LilyPond will now store the @code{title}
 defined in a score's @code{\header} block (or, if there is no
index c1e2cc20f35786139ac13340708577cc8f04c185..cd8df5c91289d2a5b44f7f88b2f15661ea5eea7d 100644 (file)
@@ -310,9 +310,9 @@ of the note head to the default value for the final two notes:
 @funindex \once
 @funindex once
 
-Both the @code{\override} and the @code{\set} commands may be prefixed
-by @code{\once}.  This causes the following @code{\override} or
-@code{\set} command to be effective only during the current musical
+@code{\override}, @code{\revert}. @code{\set}, and @code{\unset}
+commands may be prefixed with @code{\once}.  This causes such a
+command to be effective only during the current musical
 moment before the property reverts back to its previous value (this can
 be different from the default if another @code{\override} is still in
 effect).  Using the same example, we can change the color of a single
@@ -328,8 +328,10 @@ note like this:
   e4 f |
   \once \override NoteHead.color = #green
   g4 a
-  \revert NoteHead.color
+  \once \revert NoteHead.color
   b c |
+  \revert NoteHead.color
+  f2 c |
 }
 @end lilypond
 
@@ -347,12 +349,6 @@ predefined commands to limit their effect to one musical moment:
 }
 @end lilypond
 
-However, predefined commands of the form @code{\@dots{}Neutral},
-@code{\@dots{}Off} and @code{\un@dots{}} use @code{\revert} internally
-rather than @code{\override} so prefixing these with @code{\once} has no
-effect.
-
-
 @node The overrideProperty command
 @unnumberedsubsubsec The @code{@bs{}overrideProperty} command
 
index efcf8549b3d35ac6e152a64874eed1cabfbf00f7..bb5a2c2b60fb443ce0c07f462884647e820cc785 100644 (file)
@@ -2050,8 +2050,8 @@ are equivalent if the current bottom context is @code{Voice}.
 
 
 @cindex \once
-Preceding a @code{\set} command by @code{\once} makes the
-setting apply to only a single time-step:
+Preceding a @code{\set} or @code{\unset} command by @code{\once}
+makes the setting apply to only a single time-step:
 
 @lilypond[quote,fragment,verbatim]
 c''4
@@ -2181,7 +2181,7 @@ grobs in the affected context from the current time forward:
 @funindex \once
 @cindex overriding for only one moment
 
-@code{\once} can be used with @code{\override}
+@code{\once} can be used with @code{\override} or @code{\revert}
 to affect only the current time step:
 
 @lilypond[quote,verbatim]
diff --git a/input/regression/revert-once.ly b/input/regression/revert-once.ly
new file mode 100644 (file)
index 0000000..e8cad6c
--- /dev/null
@@ -0,0 +1,30 @@
+\version "2.19.28"
+
+\header {
+  texidoc = "@code{\\once \\revert} can be used for reverting a property
+once rather than permanently."
+}
+
+\layout {
+  ragged-right = ##t
+}
+
+\relative {
+  c'4-"b" d-"b"
+  \override NoteHead.color = #red
+  e4-"r" f-"r" |
+  \once \override NoteHead.color = #green
+  g4-"g" a-"r"
+  \once \revert NoteHead.color
+  b-"b" c-"r" |
+  \temporary \override NoteHead.color = #yellow
+  g-"y" e-"y"
+  \once \revert NoteHead.color
+  d-"r" c-"y" |
+  \revert NoteHead.color
+  d-"r" e-"r"
+  \once \revert NoteHead.color
+  f-"b" d-"r" |
+  \revert NoteHead.color
+  c1-"b"
+}
index 99b16f669b116d3028c738e2532918ae01ae265c..87bfbc5b9d842d9fe0771da958b0054c85e4a4d4 100644 (file)
@@ -82,7 +82,11 @@ private:
   // cooked_from_ is the value of alist_ from which the expansion has
   // been done
   SCM cooked_from_;
-  // nested_ is a count of nested overrides in alist_
+  // nested_ is a count of nested overrides in alist_ Or rather: of
+  // entries that must not appear in the cooked list and are
+  // identified by having a "key" that is not a symbol.  Temporary
+  // overrides and reverts also meet that description and have a
+  // nominal key of #t/#f and a value of the original cons cell.
   int nested_;
 
   Grob_properties (SCM alist, SCM based_on) :
@@ -234,6 +238,59 @@ Grob_property_info::push (SCM grob_property_path, SCM new_value)
   return SCM_EOL;
 }
 
+// Used for \once \override, returns a token for matched_pop
+SCM
+Grob_property_info::temporary_override (SCM grob_property_path, SCM new_value)
+{
+  SCM cell = push (grob_property_path, new_value);
+  if (!scm_is_pair (cell))
+    return cell;
+  if (scm_is_symbol (scm_car (cell)))
+    props_->nested_++;
+  cell = scm_cons (SCM_BOOL_T, cell);
+  props_->alist_ = scm_cons (cell, scm_cdr (props_->alist_));
+  return cell;
+}
+
+// Used for \once \revert, returns a token for matched_pop
+SCM
+Grob_property_info::temporary_revert (SCM grob_property_path)
+{
+  if (!check ())
+    return SCM_EOL;
+
+  SCM current_alist = props_->alist_;
+  SCM daddy = props_->based_on_;
+  SCM tail = SCM_EOL;
+
+  if (!scm_is_pair (grob_property_path)
+      || !scm_is_symbol (scm_car (grob_property_path)))
+    {
+      programming_error ("Grob property path should be list of symbols.");
+      return SCM_EOL;
+    }
+
+  if (scm_is_pair (scm_cdr (grob_property_path)))
+    {
+      tail = assoc_tail (grob_property_path, current_alist, daddy);
+      if (scm_is_false (tail))
+        return SCM_EOL;
+    }
+  else
+    {
+      tail = assq_tail (scm_car (grob_property_path), current_alist, daddy);
+      if (scm_is_false (tail))
+        return SCM_EOL;
+      ++props_->nested_;
+    }
+
+  SCM cell = scm_cons (SCM_BOOL_F, scm_car (tail));
+  props_->alist_ = partial_list_copy (current_alist, tail,
+                                      scm_cons (cell, scm_cdr (tail)));
+  return cell;
+}
+
+
 void
 Grob_property_info::matched_pop (SCM cell)
 {
@@ -247,7 +304,18 @@ Grob_property_info::matched_pop (SCM cell)
     {
       if (scm_is_eq (scm_car (p), cell))
         {
-          if (scm_is_pair (scm_car (cell)))
+          SCM key = scm_car (cell);
+          if (scm_is_false (key))
+            {
+              // temporary revert, reactivate
+              cell = scm_cdr (cell);
+              if (scm_is_symbol (scm_car (cell)))
+                props_->nested_--;
+              props_->alist_ = partial_list_copy (current_alist, p,
+                                                  scm_cons (cell, scm_cdr (p)));
+              return;
+            }
+          if (!scm_is_symbol (key))
             props_->nested_--;
           props_->alist_ = partial_list_copy (current_alist, p, scm_cdr (p));
           return;
@@ -337,7 +405,7 @@ apply_property_operations (Context *tg, SCM pre_init_ops)
       else if (scm_is_eq (type, ly_symbol2scm ("assign")))
         tg->set_property (scm_car (entry), scm_cadr (entry));
       else if (scm_is_eq (type, ly_symbol2scm ("apply")))
-       scm_apply_1 (scm_car (entry), tg->self_scm (), scm_cdr (entry));
+        scm_apply_1 (scm_car (entry), tg->self_scm (), scm_cdr (entry));
       else if (scm_is_eq (type, ly_symbol2scm ("unset")))
         tg->unset_property (scm_car (entry));
     }
index a26c168faccb2e073959d240f390a7a651d3613e..169d0b7b3d66ade4fd6d437e3434714c214b57df 100644 (file)
@@ -92,6 +92,19 @@ LY_DEFINE (ly_context_pushpop_property, "ly:context-pushpop-property",
   return SCM_UNSPECIFIED;
 }
 
+LY_DEFINE (ly_context_matched_pop_property, "ly:context-matched-pop-property",
+           3, 0, 0, (SCM context, SCM grob, SCM cell),
+           "This undoes a particular @code{\\override},"
+           " @code{\\once \\override} or @code{\\once \\revert}"
+           " when given the specific alist pair to undo.")
+{
+  Context *tg = LY_ASSERT_SMOB (Context, context, 1);
+  LY_ASSERT_TYPE (ly_is_symbol, grob, 2);
+  Grob_property_info (tg, grob).matched_pop (cell);
+  return SCM_UNSPECIFIED;
+}
+
+
 LY_DEFINE (ly_context_property, "ly:context-property",
            2, 1, 0, (SCM context, SCM sym, SCM def),
            "Return the value for property @var{sym} in @var{context}."
index 7e3c646a6f7e2569ea7451213e6ab9fe6b58c10c..ef6fecf4b1aa123e566d858c4a576f2c3f45951e 100644 (file)
@@ -252,7 +252,25 @@ Context::set_property_from_event (SCM sev)
       ok = type_check_assignment (sym, val, ly_symbol2scm ("translation-type?"));
 
       if (ok)
-        set_property (sym, val);
+        {
+          if (to_boolean (ev->get_property ("once")))
+            {
+              if (Global_context *g = get_global_context ())
+                {
+                  SCM old_val = SCM_UNDEFINED;
+                  if (here_defined (sym, &old_val))
+                    g->add_finalization (scm_list_4 (ly_context_set_property_x_proc,
+                                                     self_scm (),
+                                                     sym,
+                                                     old_val));
+                  else
+                    g->add_finalization (scm_list_3 (ly_context_unset_property_proc,
+                                                     self_scm (),
+                                                     sym));
+                }
+            }
+          set_property (sym, val);
+        }
     }
 }
 
@@ -262,8 +280,28 @@ Context::unset_property_from_event (SCM sev)
   Stream_event *ev = unsmob<Stream_event> (sev);
 
   SCM sym = ev->get_property ("symbol");
-  type_check_assignment (sym, SCM_EOL, ly_symbol2scm ("translation-type?"));
-  unset_property (sym);
+  bool ok = type_check_assignment (sym, SCM_EOL, ly_symbol2scm ("translation-type?"));
+
+  if (ok)
+    {
+      if (to_boolean (ev->get_property ("once")))
+        {
+          if (Global_context *g = get_global_context ())
+            {
+              SCM old_val = SCM_UNDEFINED;
+              if (here_defined (sym, &old_val))
+                g->add_finalization (scm_list_4 (ly_context_set_property_x_proc,
+                                                 self_scm (),
+                                                 sym,
+                                                 old_val));
+              else
+                g->add_finalization (scm_list_3 (ly_context_unset_property_proc,
+                                                 self_scm (),
+                                                 sym));
+            }
+        }
+      unset_property (sym);
+    }
 }
 
 /*
index c69b974a69631aba681068aaadf91bae9789fa1a..cf1832fe1fb73dd25f93e621e7a20d077485bbd0 100644 (file)
@@ -20,6 +20,7 @@
 #include "context.hh"
 #include "dispatcher.hh"
 #include "engraver-group.hh"
+#include "global-context.hh"
 #include "grob.hh"
 #include "grob-properties.hh"
 #include "paper-score.hh"
@@ -30,19 +31,48 @@ void
 Engraver_group::override (SCM sev)
 {
   Stream_event *ev = unsmob<Stream_event> (sev);
+  SCM sym = ev->get_property ("symbol");
+  Grob_property_info gpi (context (), sym);
 
-  Grob_property_info (context (), ev->get_property ("symbol"))
-    .push (ev->get_property ("property-path"),
-           ev->get_property ("value"));
+  if (to_boolean (ev->get_property ("once")))
+    {
+      SCM token = gpi.temporary_override (ev->get_property ("property-path"),
+                                          ev->get_property ("value"));
+      if (scm_is_pair (token))
+        if (Global_context *g = context ()->get_global_context ())
+          {
+            g->add_finalization (scm_list_4 (ly_context_matched_pop_property_proc,
+                                             context ()->self_scm (),
+                                             sym,
+                                             token));
+          }
+    }
+  else
+    gpi.push (ev->get_property ("property-path"),
+              ev->get_property ("value"));
 }
 
 void
 Engraver_group::revert (SCM sev)
 {
   Stream_event *ev = unsmob<Stream_event> (sev);
+  SCM sym = ev->get_property ("symbol");
+  Grob_property_info gpi (context (), sym);
 
-  Grob_property_info (context (), ev->get_property ("symbol"))
-    .pop (ev->get_property ("property-path"));
+  if (to_boolean (ev->get_property ("once")))
+    {
+      SCM token = gpi.temporary_revert (ev->get_property ("property-path"));
+      if (scm_is_pair (token))
+        if (Global_context *g = context ()->get_global_context ())
+          {
+            g->add_finalization (scm_list_4 (ly_context_matched_pop_property_proc,
+                                             context ()->self_scm (),
+                                             sym,
+                                             token));
+          }
+    }
+  else
+    gpi.pop (ev->get_property ("property-path"));
 }
 
 void
index 28e80fd2db070b32001b82ceaf508a11869f3977..b9aa6292b67736e07150b18c04d0c8d18e385c33 100644 (file)
@@ -195,7 +195,12 @@ void set_context_property_on_children (Context *trans, SCM sym, SCM val);
 SCM nested_property_alist (SCM alist, SCM prop_path, SCM value);
 SCM nested_create_alist (SCM prop_path, SCM value);
 SCM partial_list_copy (SCM alist, SCM tail, SCM newtail);
+SCM assq_tail (SCM key, SCM alist, SCM alist_end);
+SCM assoc_tail (SCM key, SCM alist, SCM alist_end);
 SCM evict_from_alist (SCM, SCM, SCM);
 SCM nalist_to_alist (SCM nalist, int nested);
+extern SCM ly_context_set_property_x_proc;
+extern SCM ly_context_unset_property_proc;
+extern SCM ly_context_matched_pop_property_proc;
 
 #endif /* CONTEXT_HH */
index 7b128353b80bcc734d77c0770de874c35759f680..5822dd01fb915e5ecda1b4247468ad66c37e87e7 100644 (file)
@@ -48,6 +48,8 @@ public:
   bool create ();
   SCM updated ();
   SCM push (SCM path, SCM value);
+  SCM temporary_override (SCM path, SCM value);
+  SCM temporary_revert (SCM path);
   void matched_pop (SCM);
   void pop (SCM path);
   void pushpop (SCM path, SCM value)
index 3f9577f6f720fbb065860702255f9bb98ffcc833..984d41ef57d5b9acc60a71090ff8ac77d993fbff 100644 (file)
@@ -29,11 +29,9 @@ class Property_iterator : public Simple_music_iterator
 {
 public:
   DECLARE_SCHEME_CALLBACK (constructor, ());
-  DECLARE_SCHEME_CALLBACK (once_finalization, (SCM, SCM, SCM));
   DECLARE_CLASSNAME (Property_iterator);
 
 protected:
-  virtual void do_quit ();
   virtual void process (Moment);
 };
 
@@ -53,11 +51,9 @@ class Push_property_iterator : public Simple_music_iterator
 {
 public:
   DECLARE_SCHEME_CALLBACK (constructor, ());
-  DECLARE_SCHEME_CALLBACK (once_finalization, (SCM, SCM));
   DECLARE_CLASSNAME (Push_property_iterator);
 protected:
   virtual void process (Moment);
-  virtual void do_quit ();
 };
 
 class Pop_property_iterator : public Simple_music_iterator
index 4c79918f09b6abe37e990fcd81348ab710a82c58..7c8b13047d726e8f8d45fc2e44300402e038d31a 100644 (file)
@@ -154,11 +154,20 @@ nalist_to_alist (SCM nalist, int nested)
   SCM copied = SCM_EOL;
   SCM partials = SCM_EOL;
   // partials is a alist of partial overrides
-  for (;;)
+  while (nested)
     {
       SCM elt = scm_car (nalist);
       nalist = scm_cdr (nalist);
       SCM key = scm_car (elt);
+      if (!scm_is_symbol (key))
+        --nested;
+      if (scm_is_bool (key))
+        {
+          if (scm_is_false (key))
+            continue;
+          elt = scm_cdr (elt);
+          key = scm_car (elt);
+        }
       if (scm_is_pair (key))
         // nested override: record for key in partial
         {
@@ -168,23 +177,20 @@ nalist_to_alist (SCM nalist, int nested)
                                   partials);
           else
             scm_set_cdr_x (pair, scm_cons (elt, scm_cdr (pair)));
-          if (!--nested)
-            break;
+          continue;
         }
-      else
-        // plain override: apply any known corresponding partials
+
+      // plain override: apply any known corresponding partials
+      SCM pair = assq_pop_x (key, &partials);
+      if (scm_is_true (pair))
         {
-          SCM pair = assq_pop_x (key, &partials);
-          if (scm_is_true (pair))
-            {
-              SCM value = scm_cdr (elt);
-              for (SCM pp = scm_cdr (pair); scm_is_pair (pp); pp = scm_cdr (pp))
-                value = nested_property_alist (value, scm_cdaar (pp), scm_cdar (pp));
-              copied = scm_acons (key, value, copied);
-            }
-          else
-            copied = scm_cons (elt, copied);
+          SCM value = scm_cdr (elt);
+          for (SCM pp = scm_cdr (pair); scm_is_pair (pp); pp = scm_cdr (pp))
+            value = nested_property_alist (value, scm_cdaar (pp), scm_cdar (pp));
+          copied = scm_acons (key, value, copied);
         }
+      else
+        copied = scm_cons (elt, copied);
     }
   // Now need to work off the remaining partials.  All of them are
   // unique, so we can push them to `copied' after resolving without
index bf95ee21eb12182be6b3fec91fa5a6aeb3d15b52..4725406323e46efceef64fb788543788009c6c76 100644 (file)
@@ -35,25 +35,11 @@ Property_iterator::process (Moment mom)
 {
   Context *o = get_outlet ();
   Music *m = get_music ();
-  bool once = to_boolean (m->get_property ("once"));
-  SCM symbol = m->get_property ("symbol");
-  SCM previous_value = SCM_UNDEFINED;
-  if (once)
-    o->here_defined (symbol, &previous_value);
 
   send_stream_event (o, "SetProperty", m->origin (),
-                     ly_symbol2scm ("symbol"), symbol,
-                     ly_symbol2scm ("value"), m->get_property ("value"));
-
-  /* For \once \set install a finalization hook to reset the property to the
-   * previous value after the timestep */
-  if (once)
-    {
-      Global_context *tg = get_outlet ()->get_global_context ();
-      tg->add_finalization (scm_list_4 (once_finalization_proc,
-                                        o->self_scm (), m->self_scm (),
-                                        previous_value));
-    }
+                     ly_symbol2scm ("symbol"), m->get_property ("symbol"),
+                     ly_symbol2scm ("value"), m->get_property ("value"),
+                     ly_symbol2scm ("once"), m->get_property ("once"));
 
   Simple_music_iterator::process (mom);
 }
@@ -63,47 +49,12 @@ Property_unset_iterator::process (Moment mom)
 {
   Context *o = get_outlet ();
   Music *m = get_music ();
-  bool once = to_boolean (m->get_property ("once"));
-  SCM symbol = m->get_property ("symbol");
-  SCM previous_value = SCM_UNDEFINED;
-  if (once)
-    o->here_defined (symbol, &previous_value);
 
   send_stream_event (o, "UnsetProperty", m->origin (),
-                     ly_symbol2scm ("symbol"), symbol);
-
-  /* For \once \unset install a finalization hook to reset the property to the
-   * previous value after the timestep */
-  if (once && !SCM_UNBNDP (previous_value))
-    {
-      Global_context *tg = get_outlet ()->get_global_context ();
-      tg->add_finalization (scm_list_4 (Property_iterator::once_finalization_proc,
-                                        o->self_scm (), m->self_scm (),
-                                        previous_value));
-    }
-
-  Simple_music_iterator::process (mom);
-}
-
-MAKE_SCHEME_CALLBACK (Property_iterator, once_finalization, 3);
-SCM
-Property_iterator::once_finalization (SCM ctx, SCM music, SCM previous_value)
-{
-  Music *m = unsmob<Music> (music);
-  Context *c = unsmob<Context> (ctx);
-
-  // Do not use UnsetProperty, which sets the default, but rather
-  // cache the value before the \once \set command and restore it now
-  send_stream_event (c, "SetProperty", m->origin (),
                      ly_symbol2scm ("symbol"), m->get_property ("symbol"),
-                     ly_symbol2scm ("value"), previous_value);
-
-  return SCM_UNSPECIFIED;
-}
+                     ly_symbol2scm ("once"), m->get_property ("once"));
 
-void
-Property_iterator::do_quit ()
-{
+  Simple_music_iterator::process (mom);
 }
 
 bool
@@ -140,9 +91,10 @@ Push_property_iterator::process (Moment m)
     {
       SCM grob_property_path = get_property_path (get_music ());
       SCM val = get_music ()->get_property ("grob-value");
+      SCM once = get_music ()->get_property ("once");
 
       if (to_boolean (get_music ()->get_property ("pop-first"))
-          && !to_boolean (get_music ()->get_property ("once")))
+          && !to_boolean (once))
         send_stream_event (get_outlet (), "Revert", get_music ()->origin (),
                            ly_symbol2scm ("symbol"), sym,
                            ly_symbol2scm ("property-path"), grob_property_path);
@@ -150,58 +102,28 @@ Push_property_iterator::process (Moment m)
       send_stream_event (get_outlet (), "Override", get_music ()->origin (),
                          ly_symbol2scm ("symbol"), sym,
                          ly_symbol2scm ("property-path"), grob_property_path,
+                         ly_symbol2scm ("once"), once,
                          ly_symbol2scm ("value"), val);
     }
   Simple_music_iterator::process (m);
 }
 
-MAKE_SCHEME_CALLBACK (Push_property_iterator, once_finalization, 2);
-SCM
-Push_property_iterator::once_finalization (SCM ctx, SCM music)
-{
-  Music *mus = unsmob<Music> (music);
-  Context *c = unsmob<Context> (ctx);
-
-  SCM sym = mus->get_property ("symbol");
-  if (check_grob (mus, sym))
-    {
-      SCM grob_property_path = get_property_path (mus);
-
-      send_stream_event (c, "Revert", mus->origin (),
-                         ly_symbol2scm ("symbol"), sym,
-                         ly_symbol2scm ("property-path"), grob_property_path);
-    }
-  return SCM_UNSPECIFIED;
-}
-
 void
-Push_property_iterator::do_quit ()
+Pop_property_iterator::process (Moment mom)
 {
-  if (to_boolean (get_music ()->get_property ("once")))
-    {
-      SCM trans = get_outlet ()->self_scm ();
-      SCM music = get_music ()->self_scm ();
-
-      Global_context *tg = get_outlet ()->get_global_context ();
-      tg->add_finalization (scm_list_3 (once_finalization_proc,
-                                        trans, music));
-    }
-}
-
-void
-Pop_property_iterator::process (Moment m)
-{
-  SCM sym = get_music ()->get_property ("symbol");
+  Music *m = get_music ();
+  SCM sym = m->get_property ("symbol");
 
-  if (check_grob (get_music (), sym))
+  if (check_grob (m, sym))
     {
-      SCM grob_property_path = get_property_path (get_music ());
+      SCM grob_property_path = get_property_path (m);
 
-      send_stream_event (get_outlet (), "Revert", get_music ()->origin (),
+      send_stream_event (get_outlet (), "Revert", m->origin (),
                          ly_symbol2scm ("symbol"), sym,
+                         ly_symbol2scm ("once"), m->get_property ("once"),
                          ly_symbol2scm ("property-path"), grob_property_path);
     }
-  Simple_music_iterator::process (m);
+  Simple_music_iterator::process (mom);
 }
 
 IMPLEMENT_CTOR_CALLBACK (Pop_property_iterator);
index 0b9cb54fbb713ff5a9df2601cb6c0667ab261a74..10aecbd1db6794f29b3ee54f9cb99bdef23e47b4 100644 (file)
@@ -809,7 +809,8 @@ Otherwise, return #f."
             (new-line->lily-string))))
 
 (define-display-method PropertyUnset (expr)
-  (format #f "\\unset ~a~a~a"
+  (format #f "~a\\unset ~a~a~a"
+          (if (ly:music-property expr 'once #f) "\\once " "")
           (if (eqv? (*current-context*) 'Bottom)
               ""
               (format #f "~a . " (*current-context*)))
@@ -839,8 +840,11 @@ Otherwise, return #f."
 (define-display-method RevertProperty (expr)
   (let* ((symbol (ly:music-property expr 'symbol))
          (properties (ly:music-property expr 'grob-property-path
-                                        (list (ly:music-property expr 'grob-property)))))
-    (format #f "\\revert ~{~a~^.~}~a"
+                                        (list (ly:music-property expr
+                                                                 'grob-property))))
+         (once (ly:music-property expr 'once #f)))
+    (format #f "~a\\revert ~{~a~^.~}~a"
+            (if once "\\once " "")
             (if (eqv? (*current-context*) 'Bottom)
                 (cons symbol properties)
                 (cons* (*current-context*) symbol properties))