]> git.donarmstrong.com Git - lilypond.git/blobdiff - ly/music-functions-init.ly
Merge branch 'master' into lilypond/translation
[lilypond.git] / ly / music-functions-init.ly
index 185ee7be382af797b8ebe2e432f6e6b18fa4d3d6..59c452065c3a03cc33fda0e489908c5f15faff69 100644 (file)
@@ -2,7 +2,7 @@
 
 %%%% This file is part of LilyPond, the GNU music typesetter.
 %%%%
-%%%% Copyright (C) 2003--2011 Han-Wen Nienhuys <hanwen@xs4all.nl>
+%%%% Copyright (C) 2003--2012 Han-Wen Nienhuys <hanwen@xs4all.nl>
 %%%%                          Jan Nieuwenhuizen <janneke@gnu.org>
 %%%%
 %%%% LilyPond is free software: you can redistribute it and/or modify
@@ -18,7 +18,7 @@
 %%%% You should have received a copy of the GNU General Public License
 %%%% along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
 
-\version "2.14.0"
+\version "2.15.18"
 
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -227,7 +227,7 @@ as @code{\\compoundMeter #'((3 2 8))} or shorter
                         (ly:moment-main-denominator mlen))))
   #{
     \once \override Staff.TimeSignature #'stencil = #(lambda (grob)
-               (grob-interpret-markup grob (format-compound-time $args)))
+               (grob-interpret-markup grob (format-compound-time args)))
     \set Timing.timeSignatureFraction = $timesig
     \set Timing.baseMoment = $beat
     \set Timing.beatStructure = $beatGrouping
@@ -293,13 +293,11 @@ endSpanners =
 #(define-music-function (parser location music) (ly:music?)
    (_i "Terminate the next spanner prematurely after exactly one note
 without the need of a specific end spanner.")
-   (if (eq? (ly:music-property music 'name) 'EventChord)
-       (let* ((elts (ly:music-property music 'elements))
-             (start-span-evs (filter (lambda (ev)
-                                       (and (music-has-type ev 'span-event)
-                                            (equal? (ly:music-property ev 'span-direction)
-                                                    START)))
-                                     elts))
+   (if (memq (ly:music-property music 'name) '(EventChord NoteEvent))
+       (let* ((start-span-evs (filter (lambda (ev)
+                                       (equal? (ly:music-property ev 'span-direction)
+                                               START))
+                                     (extract-typed-music music 'span-event)))
              (stop-span-evs
               (map (lambda (m)
                      (let ((c (music-clone m)))
@@ -314,7 +312,7 @@ without the need of a specific end spanner.")
         total)
 
        (begin
-        (ly:input-message location (_ "argument endSpanners is not an EventChord: ~a" music))
+        (ly:input-message location (_ "argument endSpanners is not an EventChord: ~a") music)
         music)))
 
 
@@ -325,83 +323,51 @@ featherDurations=
    (let ((orig-duration (ly:music-length argument))
         (multiplier (ly:make-moment 1 1)))
 
-     (music-map
+     (for-each
       (lambda (mus)
-       (if (and (eq? (ly:music-property mus 'name) 'EventChord)
-                (< 0 (ly:moment-main-denominator (ly:music-length mus))))
+       (if (< 0 (ly:moment-main-denominator (ly:music-length mus)))
            (begin
              (ly:music-compress mus multiplier)
-             (set! multiplier (ly:moment-mul factor multiplier))))
-       mus)
-      argument)
-
+             (set! multiplier (ly:moment-mul factor multiplier)))))
+      (extract-named-music argument '(EventChord NoteEvent RestEvent SkipEvent)))
      (ly:music-compress
       argument
       (ly:moment-div orig-duration (ly:music-length argument)))
 
      argument))
 
-footnoteGrob =
-#(define-music-function (parser location grob-name offset text footnote)
-   (symbol? number-pair? markup? markup?)
-   (_i "Attach @var{text} to @var{grob-name} at offset @var{offset},
-with @var{text} referring to @var{footnote} (use like @code{\\once})")
-   (make-music 'FootnoteEvent
-               'automatically-numbered #f
-              'symbol grob-name
-              'X-offset (car offset)
-              'Y-offset (cdr offset)
-              'text text
-              'footnote-text footnote))
-
-autoFootnoteGrob =
-#(define-music-function (parser location grob-name offset footnote)
-   (symbol? number-pair? markup?)
-   (_i "Footnote @var{grob-name} with the text in @var{footnote}
-allowing for the footnote to be automatically numbered such that
-the number appears at @var{offset}.  Note that, for this to take effect,
-auto-numbering must be turned on in the paper block.  Otherwise, no
-number will appear.  Use like @code{\\once})")
-   (make-music 'FootnoteEvent
-               'automatically-numbered #t
-              'symbol grob-name
-              'X-offset (car offset)
-              'Y-offset (cdr offset)
-               'text (make-null-markup)
-              'footnote-text footnote))
-
-
 footnote =
-#(define-music-function (parser location offset text footnote)
-   (number-pair? markup? markup?)
-   (_i "Attach @var{text} at @var{offset} with @var{text} referring
-to @var{footnote} (use like @code{\\tweak})")
-   (make-music 'FootnoteEvent
-               'automatically-numbered #f
-              'X-offset (car offset)
-              'Y-offset (cdr offset)
-              'text text
-              'footnote-text footnote))
-
-autoFootnote =
-#(define-music-function (parser location offset footnote)
-   (number-pair? markup?)
-   (_i "Footnote the item after which this comes with the text in
-@var{footnote} allowing for the footnote to be automatically numbered
-such that the number appears at @var{offset}.  Note that, for this to
-take effect, auto-numbering must be turned on in the paper block.
-Otherwise, no number will appear.  Use like @code{\\tweak})")
-   (make-music 'FootnoteEvent
-               'automatically-numbered #t
-              'X-offset (car offset)
-              'Y-offset (cdr offset)
-              'text (make-null-markup)
-              'footnote-text footnote))
+#(define-music-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))
 
 grace =
 #(def-grace-function startGraceMusic stopGraceMusic
    (_i "Insert @var{music} as grace notes."))
 
+grobdescriptions =
+#(define-scheme-function (parser location descriptions) (list?)
+   (_i "Create a context modification from @var{descriptions}, a list
+in the format of @code{all-grob-descriptions}.")
+   (ly:make-context-mod
+    (map (lambda (p)
+          (list 'assign (car p) (list (cdr p))))
+        descriptions)))
+
 harmonicByFret = #(define-music-function (parser location fret music) (number? ly:music?)
   (_i "Convert @var{music} into harmonics; the resulting notes resemble
 harmonics played on a fretted instrument by touching the strings above @var{fret}.")
@@ -410,7 +376,7 @@ harmonics played on a fretted instrument by touching the strings above @var{fret
         (make-sequential-music
          (list
           #{
-            \override TabNoteHead #'stencil = #(tab-note-head::print-custom-fret-label $fret)
+            \override TabNoteHead #'stencil = #(tab-note-head::print-custom-fret-label fret)
           #}
           (make-harmonic
             (calc-harmonic-pitch pitch music))
@@ -427,7 +393,7 @@ given through @var{ratio}.")
        (make-sequential-music
         (list
          #{
-           \override TabNoteHead #'stencil = #(tab-note-head::print-custom-fret-label $fret)
+           \override TabNoteHead #'stencil = #(tab-note-head::print-custom-fret-label fret)
          #}
          (make-harmonic
            (calc-harmonic-pitch pitch music))
@@ -469,6 +435,23 @@ keepWithTag =
         res)))
     music))
 
+key =
+#(define-music-function (parser location tonic pitch-alist)
+   ((ly:pitch? '()) (list? '()))
+   (_i "Set key to @var{tonic} and scale @var{pitch-alist}.
+If both are null, just generate @code{KeyChangeEvent}.")
+   (cond ((null? tonic) (make-music 'KeyChangeEvent))
+        ((null? pitch-alist)
+         (ly:parser-error parser (_ "second argument must be pitch list")
+                          location)
+         (make-music 'SequentialMusic 'void #t))
+        (else
+         (ly:music-transpose
+          (make-music 'KeyChangeEvent
+               'tonic (ly:make-pitch 0 0 0)
+               'pitch-alist pitch-alist)
+          tonic))))
+
 killCues =
 #(define-music-function (parser location music) (ly:music?)
    (_i "Remove cue notes from @var{music}.")
@@ -543,6 +526,22 @@ inversion =
 transpose from @var{around} to @var{to}.")
    (music-invert around to music))
 
+mark =
+#(define-music-function
+   (parser location label) ((scheme? '()))
+  "Make the music for the \\mark command."
+  (let* ((set (and (integer? label)
+                  (context-spec-music (make-property-set 'rehearsalMark label)
+                                     'Score)))
+        (ev (make-music 'MarkEvent
+                        'origin location)))
+
+    (if set
+       (make-sequential-music (list set ev))
+       (begin
+         (set! (ly:music-property ev 'label) label)
+         ev))))
+
 musicMap =
 #(define-music-function (parser location proc mus) (procedure? ly:music?)
    (_i "Apply @var{proc} to @var{mus} and all of the music it contains.")
@@ -578,6 +577,18 @@ octaveCheck =
    (make-music 'RelativeOctaveCheck
                'pitch pitch))
 
+once =
+#(define-music-function (parser location music) (ly:music?)
+   (_i "Set @code{once} to @code{#t} on all layout instruction events in @var{music}.")
+   (music-map
+    (lambda (m)
+      (cond ((music-is-of-type? m 'layout-instruction-event)
+            (set! (ly:music-property m 'once) #t))
+           ((ly:duration? (ly:music-property m 'duration))
+            (ly:music-warning m (_ "Cannot apply \\once to timed music"))))
+      m)
+    music))
+
 ottava =
 #(define-music-function (parser location octave) (integer?)
    (_i "Set the octavation.")
@@ -709,10 +720,16 @@ Example:
                         (and (not (null? origins)) (car origins)))))))
      ;;
      ;; first, split the music and fill in voices
-     (for-each (lambda (m)
-                    (push-music m)
-                    (if (bar-check? m) (change-voice)))
-                  (ly:music-property music 'elements))
+     ;; We flatten direct layers of SequentialMusic since they are
+     ;; pretty much impossible to avoid when writing music functions.
+     (let rec ((music music))
+       (for-each (lambda (m)
+                  (if (eq? (ly:music-property m 'name) 'SequentialMusic)
+                      (rec m)
+                      (begin
+                        (push-music m)
+                        (if (bar-check? m) (change-voice)))))
+                (ly:music-property music 'elements)))
      (if (not (null? current-sequence)) (change-voice))
      ;; un-circularize `voices' and reorder the voices
      (set! voices (map-in-order (lambda (dummy seqs)
@@ -824,13 +841,9 @@ pitchedTrill =
    (_i "Print a trill with @var{main-note} as the main note of the trill and
 print @var{secondary-note} as a stemless note head in parentheses.")
    (let* ((get-notes (lambda (ev-chord)
-                       (filter
-                        (lambda (m) (eq? 'NoteEvent (ly:music-property m 'name)))
-                        (ly:music-property ev-chord 'elements))))
+                      (extract-named-music ev-chord 'NoteEvent)))
           (sec-note-events (get-notes secondary-note))
-          (trill-events (filter (lambda (m) (music-has-type m 'trill-span-event))
-                                (ly:music-property main-note 'elements))))
-
+          (trill-events (extract-named-music main-note 'TrillSpanEvent)))
      (if (pair? sec-note-events)
          (begin
            (let* ((trill-pitch (ly:music-property (car sec-note-events) 'pitch))
@@ -924,15 +937,54 @@ rightHandFinger =
 
 scaleDurations =
 #(define-music-function (parser location fraction music)
-   (number-pair? ly:music?)
+   (fraction? ly:music?)
    (_i "Multiply the duration of events in @var{music} by @var{fraction}.")
    (ly:music-compress music
                      (ly:make-moment (car fraction) (cdr fraction))))
 
+settingsFrom =
+#(define-scheme-function (parser location ctx music)
+   ((symbol?) ly:music?)
+   (_i "Take the layout instruction events from @var{music}, optionally
+restricted to those applying to context type @var{ctx}, and return
+a context modification duplicating their effect.")
+   (let ((mods (ly:make-context-mod)))
+     (define (musicop m)
+       (if (music-is-of-type? m 'layout-instruction-event)
+          (ly:add-context-mod
+           mods
+           (case (ly:music-property m 'name)
+             ((PropertySet)
+              (list 'assign
+                    (ly:music-property m 'symbol)
+                    (ly:music-property m 'value)))
+             ((PropertyUnset)
+              (list 'unset
+                    (ly:music-property m 'symbol)))
+             ((OverrideProperty)
+              (list 'push
+                    (ly:music-property m 'symbol)
+                    (ly:music-property m 'grob-property-path)
+                    (ly:music-property m 'grob-value)))
+             ((RevertProperty)
+              (list 'pop
+                    (ly:music-property m 'symbol)
+                    (ly:music-property m 'grob-property-path)))))
+          (case (ly:music-property m 'name)
+            ((SequentialMusic SimultaneousMusic)
+             (for-each musicop (ly:music-property m 'elements)))
+            ((ContextSpeccedMusic)
+             (if (or (not ctx)
+                     (eq? ctx (ly:music-property m 'context-type)))
+                 (musicop (ly:music-property m 'element)))))))
+     (musicop music)
+     mods))
+
 shiftDurations =
 #(define-music-function (parser location dur dots arg)
    (integer? integer? ly:music?)
-   (_i "Scale @var{arg} up by a factor of 2^@var{dur}*(2-(1/2)^@var{dots}).")
+   (_i "Change the duration of @var{arg} by adding @var{dur} to the
+@code{durlog} of @var{arg} and @var{dots} to the @code{dots} of @var{arg}.")
 
    (music-map
     (lambda (x)
@@ -957,7 +1009,7 @@ the `parameters' assoc list.")
    #{
      \overrideProperty #"Score.NonMusicalPaperColumn"
      #'line-break-system-details
-     #$(list (cons 'alignment-extra-space (cdr (assoc 'system-stretch parameters)))
+     #(list (cons 'alignment-extra-space (cdr (assoc 'system-stretch parameters)))
             (cons 'system-Y-extent (cdr (assoc 'system-Y-extent parameters))))
    #})
 
@@ -986,6 +1038,25 @@ tag =
          (ly:music-property arg 'tags)))
    arg)
 
+time =
+#(define-music-function (parser location beat-structure fraction)
+   ((number-list? '()) fraction?)
+   (_i "Set @var{fraction} as time signature, with optional
+number list @var{beat-structure} before it.")
+  (make-music 'TimeSignatureMusic
+              'numerator (car fraction)
+              'denominator (cdr fraction)
+              'beat-structure beat-structure))
+
+times =
+#(define-music-function (parser location fraction music)
+   (fraction? ly:music?)
+   (_i "Scale @var{music} in time by @var{fraction}.")
+  (make-music 'TimeScaledMusic
+             'element (ly:music-compress music (ly:make-moment (car fraction) (cdr fraction)))
+             'numerator (car fraction)
+             'denominator (cdr fraction)))
+
 transpose =
 #(define-music-function
    (parser location from to music)
@@ -1053,7 +1124,6 @@ void =
 Use this if you want to have a scheme expression evaluated
 because of its side-effects, but its value ignored."))
 
-
 withMusicProperty =
 #(define-music-function (parser location sym val music)
    (symbol? scheme? ly:music?)