]> git.donarmstrong.com Git - lilypond.git/commitdiff
Change \footnote user interface and behavior to match \hide/\omit etc.
authorDavid Kastrup <dak@gnu.org>
Thu, 11 Oct 2012 10:48:25 +0000 (12:48 +0200)
committerDavid Kastrup <dak@gnu.org>
Thu, 25 Oct 2012 18:29:29 +0000 (20:29 +0200)
This does the following changes to the footnote user interface for
footnotes in music rather than in markups:

Time-based footnote syntax:

    \footnote [mark] offset #'Grob text \default
->  \footnote [mark] offset text [ Context. ] Grob

Like with any override, you now need to specify Context if it is not
supposed to be Bottom, like with Staff.TimeSignature.

Music-based footnote syntax:

    \footnote [mark] offset text music
->  stays identical

    \footnote [mark] offset #'Grob text music
->  \single\footnote [mark] offset text Grob music

Specifying Context.Grob is possible, but Context gets ignored.

lily/footnote-engraver.cc
ly/engraver-init.ly
ly/music-functions-init.ly
python/convertrules.py

index 71cd9dd6ffeba996c535865dff3b337decc7369f..39e18cd57c897db66fb029fdd4bf7d4f5e375664 100644 (file)
@@ -33,45 +33,22 @@ class Footnote_engraver : public Engraver
 {
   TRANSLATOR_DECLARATIONS (Footnote_engraver);
 
-  DECLARE_TRANSLATOR_LISTENER (footnote);
   DECLARE_ACKNOWLEDGER (grob);
   DECLARE_END_ACKNOWLEDGER (grob);
-  vector<Stream_event *> events_;
+
   vector<Drul_array<Spanner *> > annotated_spanners_;
 
-  void stop_translation_timestep ();
   void finalize ();
-  virtual void derived_mark () const;
 
   void footnotify (Grob *, SCM);
 };
 
-IMPLEMENT_TRANSLATOR_LISTENER (Footnote_engraver, footnote);
-void
-Footnote_engraver::listen_footnote (Stream_event *ev)
-{
-  events_.push_back (ev);
-}
-
-void
-Footnote_engraver::stop_translation_timestep ()
-{
-  events_.clear ();
-}
-
 void
 Footnote_engraver::finalize ()
 {
   annotated_spanners_.clear ();
 }
 
-void
-Footnote_engraver::derived_mark () const
-{
-  for (vsize i = 0; i < events_.size (); ++i)
-    scm_gc_mark (events_[i]->self_scm ());
-}
-
 Footnote_engraver::Footnote_engraver ()
 {
 }
@@ -115,24 +92,8 @@ Footnote_engraver::acknowledge_grob (Grob_info info)
 
       // This grob has exhausted its footnote
       info.grob ()->set_property ("footnote-music", SCM_EOL);
-      return;
-    }
 
-  if (!events_.empty ())
-    {
-      string grobname = info.grob ()->name ();
-
-      for (vsize i = 0; i < events_.size (); i++)
-        {
-          SCM name = events_[i]->get_property ("symbol");
-          if (scm_is_symbol (name)
-              && grobname == ly_symbol2string (name))
-            {
-              footnotify (info.grob (), events_[i]->self_scm ());
-              // Event has exhausted its footnote
-              events_[i]->set_property ("symbol", SCM_EOL);
-            }
-        }
+      return;
     }
 }
 
index 06060c02e1d8dd82c02e6de1b4a89cf42d06d283..b6d2a42615235a974edf1824fbf76ecee9362a68 100644 (file)
@@ -85,7 +85,6 @@
   \consists "Figured_bass_position_engraver"
   \consists "Script_row_engraver"
   \consists "Cue_clef_engraver"
-  \consists "Footnote_engraver"
 
   localKeySignature = #'()
   createSpacing = ##t
index eb9f1cf7ec5a716902c05bdba9e9fe6f4927742f..371beab4d7becc64f6711bfd12a5a3735b31cedc 100644 (file)
@@ -368,24 +368,23 @@ featherDurations=
      argument))
 
 footnote =
-#(define-music-function (parser location mark offset grob-name footnote music)
-   ((markup?) number-pair? (symbol?) markup? (ly:music?))
-   (_i "Make the markup @var{footnote} a footnote on @var{music}.  The
+#(define-music-function (parser location mark offset footnote item)
+   ((markup?) number-pair? markup? symbol-list-or-music?)
+   (_i "Make the markup @var{footnote} a footnote on @var{item}.  The
 footnote is marked with a markup @var{mark} moved by @var{offset} with
 respect to the marked music.
 
 If @var{mark} is not given or specified as @var{\\default}, it is
-replaced by an automatically generated sequence number.  If a symbol
-@var{grob-name} is specified, then grobs of that type will be marked
-if they have @var{music} as their ultimate cause; by default all grobs
-having @var{music} as their @emph{direct} cause will be marked,
-similar to the way @code{\\tweak} works.
-
-If @var{music} is given as @code{\\default}, a footnote event
-affecting @emph{all} grobs matching @var{grob-name} at a given time
-step is generated.  This may be required for creating footnotes on
-time signatures, clefs, and other items not cooperating with
-@code{\\tweak}.
+replaced by an automatically generated sequence number.  If @var{item}
+is a symbol list of form @samp{Grob} or @samp{Context.Grob}, then
+grobs of that type will be marked at the current time step in the
+given context (default @code{Bottom}).
+
+If @var{item} is music, the music will get a footnote attached to a
+grob immediately attached to the event, like @var{\\tweak} does.  For
+attaching a footnote to an @emph{indirectly} caused grob, write
+@code{\\single\\footnote}, use @var{item} to specify the grob, and
+follow it with the music to annotate.
 
 Like with @code{\\tweak}, if you use a footnote on a following
 post-event, the @code{\\footnote} command itself needs to be attached
@@ -396,21 +395,10 @@ to the preceding note or rest as a post-event with @code{-}.")
               'Y-offset (cdr offset)
               'automatically-numbered (not mark)
               'text (or mark (make-null-markup))
-              'footnote-text footnote
-              'symbol (or grob-name '()))))
-     (cond (music
-           (set! (ly:music-property music 'tweaks)
-                 (acons (if grob-name
-                            (cons grob-name 'footnote-music)
-                            'footnote-music)
-                        mus
-                        (ly:music-property music 'tweaks)))
-           music)
-          (grob-name mus)
-          (else
-           (ly:input-warning location
-                             (_ "\\footnote requires music or grob-name"))
-           (make-music 'Music)))))
+              'footnote-text footnote)))
+     (if (ly:music? item)
+         #{ \tweak #'footnote-music #mus #item #}
+         #{ \once\override $item #'footnote-music = #mus #})))
 
 grace =
 #(def-grace-function startGraceMusic stopGraceMusic
index 861e57ac4f3532da841897ed398e7e8f01c10714..28dad31843132f17ad948e18bf6d0fac364bd6cd 100644 (file)
@@ -3423,11 +3423,34 @@ def conv(str):
     str = re.sub (barstring + r'"empty"', '\\1\\2"-"', str)
     return str
 
+symbol_list = (r"#'(?:" + wordsyntax + r"|\(\s*(?:" + wordsyntax + r"\s+)*"
+               + wordsyntax + r"\s*\))")
+
 @rule ((2, 17, 6), r"""\accidentalStyle #'Context "style" -> \accidentalStyle Context.style
 \alterBroken "Context.grob" -> \alterBroken Context.grob
 \overrideProperty "Context.grob" -> \overrideProperty Context.grob
 \tweak Grob #'symbol -> \tweak Grob.symbol""")
 def conv (str):
+    def patrep (m):
+        def fn_path_replace (m):
+            x = string.join (re.findall (wordsyntax, m.group (2)), ".")
+            if x in ["TimeSignature", "KeySignature", "BarLine",
+                     "Clef", "StaffSymbol", "OttavaBracket",
+                     "LedgerLineSpanner"]:
+                x = "Staff." + x
+            return m.group (1) + x
+        if m.group (1):
+            return m.group (0)
+        x = m.group (2) + m.group (4)
+        
+        if m.group (3):
+            x = x + re.sub (r"(\s*)(" + symbol_list + ")", fn_path_replace,
+                            m.group (3))
+
+            if not m.group (5):
+                x = r"\single" + x
+        return x
+
     str = re.sub (r'''(\\accidentalStyle\s+)#?"([-A-Za-z]+)"''',
                   r"\1\2", str)
     str = re.sub (r'''(\\accidentalStyle\s+)#'([A-Za-z]+)\s+#?"?([-A-Za-z]+)"?''',
@@ -3436,6 +3459,11 @@ def conv (str):
                   r"\1\2.\3", str)
     str = re.sub (r'''(\\tweak\s+)#?"?([A-Za-z]+)"?\s+?#'([-A-Za-z]+)''',
                   r"\1\2.\3", str)
+    str = re.sub ("(" + matchmarkup + ")|"
+                  + r"(\\footnote(?:\s*"
+                  + matchmarkup + ")?" + matcharg + ")(" + matcharg
+                  + r")?(\s+" + matchmarkup + r")(\s+\\default)?",
+                  patrep, str)
     return str
 
 # Guidelines to write rules (please keep this at the end of this file)