]> git.donarmstrong.com Git - lilypond.git/blobdiff - ly/music-functions-init.ly
Web: remove non-Free software from Easier Editing
[lilypond.git] / ly / music-functions-init.ly
index 6244f1dd7d89042b76e1e6bfd871df3fca1199d5..9f7fcf8f9623a9c09fab707a0d5027be28c8bbc1 100644 (file)
@@ -342,23 +342,49 @@ featherDurations=
      argument))
 
 footnote =
-#(define-event-function (parser location text offset grob-name footnote)
-   ((markup?) number-pair? (symbol? '()) markup?)
-   (_i "Attach @var{text} at @var{offset} with @var{text} referring to
-@var{footnote}.  If @var{text} is given as @code{\\default}, use
-autonumbering instead.  Note that, for this to take effect,
-auto-numbering must be turned on in the paper block.  Otherwise, no
-number will appear.  Footnotes are applied like articulations.  If a
-symbol @var{grob-name} is specified, all grobs of that kind at the
-current time step are affected.")
-   (make-music
-    'FootnoteEvent
-    'X-offset (car offset)
-    'Y-offset (cdr offset)
-    'automatically-numbered (not text)
-    'text (or text (make-null-markup))
-    'footnote-text footnote
-    'symbol grob-name))
+#(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
+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}.
+
+Like with @code{\\tweak}, if you use a footnote on a following
+post-event, the @code{\\footnote} command itself needs to be attached
+to the preceding note or rest as a post-event with @code{-}.")
+   (let ((mus (make-music
+              'FootnoteEvent
+              'X-offset (car offset)
+              '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)))))
 
 grace =
 #(def-grace-function startGraceMusic stopGraceMusic
@@ -1012,6 +1038,48 @@ a context modification duplicating their effect.")
      (musicop music)
      mods))
 
+shape =
+#(define-music-function (parser location grob offsets)
+   (string? list?)
+   (_i "Offset control-points of @var{grob} by @var{offsets}.  The argument
+is a list of number pairs or list of such lists.  Each element of a pair
+represents an offset to one of the coordinates of a control-point.")
+   (define ((shape-curve offsets) grob)
+     (let* ((orig (ly:grob-original grob))
+            (siblings (if (ly:spanner? grob)
+                          (ly:spanner-broken-into orig) '()))
+            (total-found (length siblings))
+            (function (assoc-get 'control-points
+                                 (reverse (ly:grob-basic-properties grob))))
+            (coords (function grob)))
+
+       (define (offset-control-points offsets)
+         (if (null? offsets)
+             coords
+             (map
+               (lambda (x y) (coord-translate x y))
+               coords offsets)))
+
+       (define (helper sibs offs)
+         (if (pair? offs)
+             (if (eq? (car sibs) grob)
+                 (offset-control-points (car offs))
+                 (helper (cdr sibs) (cdr offs)))
+             coords))
+
+       ;; we work with lists of lists
+       (if (or (null? offsets)
+               (not (list? (car offsets))))
+           (set! offsets (list offsets)))
+
+       (if (>= total-found 2)
+           (helper siblings offsets)
+           (offset-control-points (car offsets)))))
+
+   #{
+     \once \override $grob #'control-points = #(shape-curve offsets)
+   #})
+
 shiftDurations =
 #(define-music-function (parser location dur dots arg)
    (integer? integer? ly:music?)