]> git.donarmstrong.com Git - lilypond.git/blob - scm/music-functions.scm
Merge branch 'staging' of ssh://git.sv.gnu.org/srv/git/lilypond into staging
[lilypond.git] / scm / music-functions.scm
1 ;;;; This file is part of LilyPond, the GNU music typesetter.
2 ;;;;
3 ;;;; Copyright (C) 1998--2011 Jan Nieuwenhuizen <janneke@gnu.org>
4 ;;;;                 Han-Wen Nienhuys <hanwen@xs4all.nl>
5 ;;;;
6 ;;;; LilyPond is free software: you can redistribute it and/or modify
7 ;;;; it under the terms of the GNU General Public License as published by
8 ;;;; the Free Software Foundation, either version 3 of the License, or
9 ;;;; (at your option) any later version.
10 ;;;;
11 ;;;; LilyPond is distributed in the hope that it will be useful,
12 ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 ;;;; GNU General Public License for more details.
15 ;;;;
16 ;;;; You should have received a copy of the GNU General Public License
17 ;;;; along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
18
19 ; for define-safe-public when byte-compiling using Guile V2
20 (use-modules (scm safe-utility-defs))
21
22 ;; (use-modules (ice-9 optargs))
23
24 ;;; ly:music-property with setter
25 ;;; (ly:music-property my-music 'elements)
26 ;;;   ==> the 'elements property
27 ;;; (set! (ly:music-property my-music 'elements) value)
28 ;;;   ==> set the 'elements property and return it
29 (define-public ly:music-property
30   (make-procedure-with-setter ly:music-property
31                               ly:music-set-property!))
32
33 (define-safe-public (music-is-of-type? mus type)
34   "Does @code{mus} belong to the music class @code{type}?"
35   (memq type (ly:music-property mus 'types)))
36
37 ;; TODO move this
38 (define-public ly:grob-property
39   (make-procedure-with-setter ly:grob-property
40                               ly:grob-set-property!))
41
42 (define-public ly:grob-object
43   (make-procedure-with-setter ly:grob-object
44                               ly:grob-set-object!))
45
46 (define-public ly:grob-parent
47   (make-procedure-with-setter ly:grob-parent
48                               ly:grob-set-parent!))
49
50 (define-public ly:prob-property
51   (make-procedure-with-setter ly:prob-property
52                               ly:prob-set-property!))
53
54 (define-public ly:context-property
55   (make-procedure-with-setter ly:context-property
56                               ly:context-set-property!))
57
58 (define-public (music-map function music)
59   "Apply @var{function} to @var{music} and all of the music it contains.
60
61 First it recurses over the children, then the function is applied to
62 @var{music}."
63   (let ((es (ly:music-property music 'elements))
64         (e (ly:music-property music 'element)))
65     (set! (ly:music-property music 'elements)
66           (map (lambda (y) (music-map function y)) es))
67     (if (ly:music? e)
68         (set! (ly:music-property music 'element)
69               (music-map function  e)))
70     (function music)))
71
72 (define-public (music-filter pred? music)
73   "Filter out music expressions that do not satisfy @var{pred?}."
74
75   (define (inner-music-filter pred? music)
76     "Recursive function."
77     (let* ((es (ly:music-property music 'elements))
78            (e (ly:music-property music 'element))
79            (as (ly:music-property music 'articulations))
80            (filtered-as (filter ly:music? (map (lambda (y) (inner-music-filter pred? y)) as)))
81            (filtered-e (if (ly:music? e)
82                            (inner-music-filter pred? e)
83                            e))
84            (filtered-es (filter ly:music? (map (lambda (y) (inner-music-filter pred? y)) es))))
85       (set! (ly:music-property music 'element) filtered-e)
86       (set! (ly:music-property music 'elements) filtered-es)
87       (set! (ly:music-property music 'articulations) filtered-as)
88       ;; if filtering emptied the expression, we remove it completely.
89       (if (or (not (pred? music))
90               (and (eq? filtered-es '()) (not (ly:music? e))
91                    (or (not (eq? es '()))
92                        (ly:music? e))))
93           (set! music '()))
94       music))
95
96   (set! music (inner-music-filter pred? music))
97   (if (ly:music? music)
98       music
99       (make-music 'Music)))       ;must return music.
100
101 (define-public (display-music music)
102   "Display music, not done with @code{music-map} for clarity of
103 presentation."
104
105   (display music)
106   (display ": { ")
107   (let ((es (ly:music-property music 'elements))
108         (e (ly:music-property music 'element)))
109     (display (ly:music-mutable-properties music))
110     (if (pair? es)
111         (begin (display "\nElements: {\n")
112                (map display-music es)
113                (display "}\n")))
114     (if (ly:music? e)
115         (begin
116           (display "\nChild:")
117           (display-music e))))
118   (display " }\n")
119   music)
120
121 ;;;
122 ;;; A scheme music pretty printer
123 ;;;
124 (define (markup-expression->make-markup markup-expression)
125   "Transform `markup-expression' into an equivalent, hopefuly readable, scheme expression.
126 For instance,
127   \\markup \\bold \\italic hello
128 ==>
129   (markup #:line (#:bold (#:italic (#:simple \"hello\"))))"
130   (define (proc->command-keyword proc)
131     "Return a keyword, eg. `#:bold', from the `proc' function, eg. #<procedure bold-markup (layout props arg)>"
132     (let ((cmd-markup (symbol->string (procedure-name proc))))
133       (symbol->keyword (string->symbol (substring cmd-markup 0 (- (string-length cmd-markup)
134                                                                   (string-length "-markup")))))))
135   (define (transform-arg arg)
136     (cond ((and (pair? arg) (markup? (car arg))) ;; a markup list
137            (apply append (map inner-markup->make-markup arg)))
138           ((and (not (string? arg)) (markup? arg)) ;; a markup
139            (inner-markup->make-markup arg))
140           (else                                  ;; scheme arg
141            (music->make-music arg))))
142   (define (inner-markup->make-markup mrkup)
143     (if (string? mrkup)
144         `(#:simple ,mrkup)
145         (let ((cmd (proc->command-keyword (car mrkup)))
146               (args (map transform-arg (cdr mrkup))))
147           `(,cmd ,@args))))
148   ;; body:
149   (if (string? markup-expression)
150       markup-expression
151       `(markup ,@(inner-markup->make-markup markup-expression))))
152
153 (define-public (music->make-music obj)
154   "Generate an expression that, once evaluated, may return an object
155 equivalent to @var{obj}, that is, for a music expression, a
156 @code{(make-music ...)} form."
157   (cond (;; markup expression
158          (markup? obj)
159          (markup-expression->make-markup obj))
160         (;; music expression
161          (ly:music? obj)
162          `(make-music
163            ',(ly:music-property obj 'name)
164            ,@(apply append (map (lambda (prop)
165                                   `(',(car prop)
166                                     ,(music->make-music (cdr prop))))
167                                 (remove (lambda (prop)
168                                           (eqv? (car prop) 'origin))
169                                         (ly:music-mutable-properties obj))))))
170         (;; moment
171          (ly:moment? obj)
172          `(ly:make-moment ,(ly:moment-main-numerator obj)
173                           ,(ly:moment-main-denominator obj)
174                           ,(ly:moment-grace-numerator obj)
175                           ,(ly:moment-grace-denominator obj)))
176         (;; note duration
177          (ly:duration? obj)
178          `(ly:make-duration ,(ly:duration-log obj)
179                             ,(ly:duration-dot-count obj)
180                             ,(car (ly:duration-factor obj))
181                             ,(cdr (ly:duration-factor obj))))
182         (;; note pitch
183          (ly:pitch? obj)
184          `(ly:make-pitch ,(ly:pitch-octave obj)
185                          ,(ly:pitch-notename obj)
186                          ,(ly:pitch-alteration obj)))
187         (;; scheme procedure
188          (procedure? obj)
189          (or (procedure-name obj) obj))
190         (;; a symbol (avoid having an unquoted symbol)
191          (symbol? obj)
192          `',obj)
193         (;; an empty list (avoid having an unquoted empty list)
194          (null? obj)
195          `'())
196         (;; a proper list
197          (list? obj)
198          `(list ,@(map music->make-music obj)))
199         (;; a pair
200          (pair? obj)
201          `(cons ,(music->make-music (car obj))
202                 ,(music->make-music (cdr obj))))
203         (else
204          obj)))
205
206 (use-modules (ice-9 pretty-print))
207 (define*-public (display-scheme-music obj #:optional (port (current-output-port)))
208   "Displays `obj', typically a music expression, in a friendly fashion,
209 which often can be read back in order to generate an equivalent expression.
210
211 Returns `obj'.
212 "
213   (pretty-print (music->make-music obj) port)
214   (newline)
215   obj)
216
217 ;;;
218 ;;; Scheme music expression --> Lily-syntax-using string translator
219 ;;;
220 (use-modules (srfi srfi-39)
221              (scm display-lily))
222
223 (define*-public (display-lily-music expr parser #:key force-duration)
224   "Display the music expression using LilyPond syntax"
225   (memoize-clef-names supported-clefs)
226   (parameterize ((*indent* 0)
227                  (*previous-duration* (ly:make-duration 2))
228                  (*force-duration* force-duration))
229     (display (music->lily-string expr parser))
230     (newline)))
231
232 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
233
234 (define-public (shift-one-duration-log music shift dot)
235   "Add @var{shift} to @code{duration-log} of @code{'duration} in
236 @var{music} and optionally @var{dot} to any note encountered.
237 The number of dots in the shifted music may not be less than zero."
238   (let ((d (ly:music-property music 'duration)))
239     (if (ly:duration? d)
240         (let* ((cp (ly:duration-factor d))
241                (nd (ly:make-duration
242                     (+ shift (ly:duration-log d))
243                     (max 0 (+ dot (ly:duration-dot-count d)))
244                     (car cp)
245                     (cdr cp))))
246           (set! (ly:music-property music 'duration) nd)))
247     music))
248
249 (define-public (shift-duration-log music shift dot)
250   (music-map (lambda (x) (shift-one-duration-log x shift dot))
251              music))
252
253 (define-public (make-repeat name times main alts)
254   "Create a repeat music expression, with all properties initialized
255 properly."
256   (define (first-note-duration music)
257     "Finds the duration of the first NoteEvent by searching depth-first
258 through MUSIC."
259     (if (memq 'note-event (ly:music-property music 'types))
260         (ly:music-property music 'duration)
261         (let loop ((elts (if (ly:music? (ly:music-property music 'element))
262                              (list (ly:music-property music 'element))
263                              (ly:music-property music 'elements))))
264           (and (pair? elts)
265                (let ((dur (first-note-duration (car elts))))
266                  (if (ly:duration? dur)
267                      dur
268                      (loop (cdr elts))))))))
269
270   (let ((talts (if (< times (length alts))
271                    (begin
272                      (ly:warning (_ "More alternatives than repeats.  Junking excess alternatives"))
273                      (take alts times))
274                    alts))
275         (r (make-repeated-music name)))
276     (set! (ly:music-property r 'element) main)
277     (set! (ly:music-property r 'repeat-count) (max times 1))
278     (set! (ly:music-property r 'elements) talts)
279     (if (and (equal? name "tremolo")
280              (or (pair? (ly:music-property main 'elements))
281                  (ly:music? (ly:music-property main 'element))))
282         ;; This works for single-note and multi-note tremolos!
283         (let* ((children (if (music-is-of-type? main 'sequential-music)
284                              ;; \repeat tremolo n { ... }
285                              (length (extract-named-music main 'EventChord))
286                              ;; \repeat tremolo n c4
287                              1))
288                ;; # of dots is equal to the 1 in bitwise representation (minus 1)!
289                (dots (1- (logcount (* times children))))
290                ;; The remaining missing multiplicator to scale the notes by
291                ;; times * children
292                (mult (/ (* times children (ash 1 dots)) (1- (ash 2 dots))))
293                (shift (- (ly:intlog2 (floor mult))))
294                (note-duration (first-note-duration r))
295                (duration-log (if (ly:duration? note-duration)
296                                  (ly:duration-log note-duration)
297                                  1))
298                (tremolo-type (ash 1 duration-log)))
299           (set! (ly:music-property r 'tremolo-type) tremolo-type)
300           (if (not (integer?  mult))
301               (ly:warning (_ "invalid tremolo repeat count: ~a") times))
302           ;; Adjust the time of the notes
303           (ly:music-compress r (ly:make-moment 1 children))
304           ;; Adjust the displayed note durations
305           (shift-duration-log r shift dots))
306         r)))
307
308 (define (calc-repeat-slash-count music)
309   "Given the child-list @var{music} in @code{PercentRepeatMusic},
310 calculate the number of slashes based on the durations.  Returns @code{0}
311 if durations in @var{music} vary, allowing slash beats and double-percent
312 beats to be distinguished."
313   (let* ((durs (map (lambda (elt)
314                       (duration-of-note elt))
315                     (extract-named-music music 'EventChord)))
316          (first-dur (car durs)))
317
318     (if (every (lambda (d) (equal? d first-dur)) durs)
319         (max (- (ly:duration-log first-dur) 2) 1)
320         0)))
321
322 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
323 ;; clusters.
324
325 (define-public (note-to-cluster music)
326   "Replace @code{NoteEvents} by @code{ClusterNoteEvents}."
327   (if (eq? (ly:music-property music 'name) 'NoteEvent)
328       (make-music 'ClusterNoteEvent
329                   'pitch (ly:music-property music 'pitch)
330                   'duration (ly:music-property music 'duration))
331       music))
332
333 (define-public (notes-to-clusters music)
334   (music-map note-to-cluster music))
335
336 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
337 ;; repeats.
338
339 (define-public (unfold-repeats music)
340   "Replace all repeats with unfolded repeats."
341
342   (let ((es (ly:music-property music 'elements))
343         (e (ly:music-property music 'element)))
344
345     (if (memq 'repeated-music (ly:music-property music 'types))
346         (let* ((props (ly:music-mutable-properties music))
347                (old-name (ly:music-property music 'name))
348                (flattened (flatten-alist props)))
349           (set! music (apply make-music (cons 'UnfoldedRepeatedMusic
350                                               flattened)))
351
352           (if (equal? old-name 'TremoloRepeatedMusic)
353               (let* ((seq-arg? (memq 'sequential-music
354                                      (ly:music-property e 'types)))
355                      (count (ly:music-property music 'repeat-count))
356                      (dot-shift (if (= 0 (remainder count 3))
357                                     -1 0))
358                      (child-count (if seq-arg?
359                                       (length (ly:music-property e 'elements))
360                                       0)))
361
362                 (if (= 0 -1)
363                     (set! count (* 2 (quotient count 3))))
364
365                 (shift-duration-log music (+ (if (= 2 child-count)
366                                                  1 0)
367                                              (ly:intlog2 count)) dot-shift)
368
369                 (if seq-arg?
370                     (ly:music-compress e (ly:make-moment child-count 1)))))))
371
372     (if (pair? es)
373         (set! (ly:music-property music 'elements)
374               (map unfold-repeats es)))
375     (if (ly:music? e)
376         (set! (ly:music-property music 'element)
377               (unfold-repeats e)))
378     music))
379
380 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
381 ;; property setting music objs.
382
383 (define-public (make-grob-property-set grob gprop val)
384   "Make a @code{Music} expression that sets @var{gprop} to @var{val} in
385 @var{grob}.  Does a pop first, i.e., this is not an override."
386   (make-music 'OverrideProperty
387               'symbol grob
388               'grob-property gprop
389               'grob-value val
390               'pop-first #t))
391
392 (define-public (make-grob-property-override grob gprop val)
393   "Make a @code{Music} expression that overrides @var{gprop} to @var{val}
394 in @var{grob}."
395   (make-music 'OverrideProperty
396               'symbol grob
397               'grob-property gprop
398               'grob-value val))
399
400 (define-public (make-grob-property-revert grob gprop)
401   "Revert the grob property @var{gprop} for @var{grob}."
402   (make-music 'RevertProperty
403               'symbol grob
404               'grob-property gprop))
405
406 (define direction-polyphonic-grobs
407   '(AccidentalSuggestion
408     DotColumn
409     Dots
410     Fingering
411     LaissezVibrerTie
412     LigatureBracket
413     PhrasingSlur
414     RepeatTie
415     Rest
416     Script
417     Slur
418     Stem
419     TextScript
420     Tie
421     TupletBracket
422     TrillSpanner))
423
424 (define-safe-public (make-voice-props-set n)
425   (make-sequential-music
426    (append
427     (map (lambda (x) (make-grob-property-set x 'direction
428                                              (if (odd? n) -1 1)))
429          direction-polyphonic-grobs)
430     (list
431      (make-property-set 'graceSettings
432                         ;; TODO: take this from voicedGraceSettings or similar.
433                         '((Voice Stem font-size -3)
434                           (Voice Flag font-size -3)
435                           (Voice NoteHead font-size -3)
436                           (Voice TabNoteHead font-size -4)
437                           (Voice Dots font-size -3)
438                           (Voice Stem length-fraction 0.8)
439                           (Voice Stem no-stem-extend #t)
440                           (Voice Beam beam-thickness 0.384)
441                           (Voice Beam length-fraction 0.8)
442                           (Voice Accidental font-size -4)
443                           (Voice AccidentalCautionary font-size -4)
444                           (Voice Script font-size -3)
445                           (Voice Fingering font-size -8)
446                           (Voice StringNumber font-size -8)))
447
448      (make-grob-property-set 'NoteColumn 'horizontal-shift (quotient n 2))
449      (make-grob-property-set 'MultiMeasureRest 'staff-position (if (odd? n) -4 4))))))
450
451 (define-safe-public (make-voice-props-revert)
452   (make-sequential-music
453    (append
454     (map (lambda (x) (make-grob-property-revert x 'direction))
455          direction-polyphonic-grobs)
456     (list (make-property-unset 'graceSettings)
457           (make-grob-property-revert 'NoteColumn 'horizontal-shift)
458           (make-grob-property-revert 'MultiMeasureRest 'staff-position)))))
459
460
461 (define-safe-public (context-spec-music m context #:optional id)
462   "Add \\context CONTEXT = ID to M."
463   (let ((cm (make-music 'ContextSpeccedMusic
464                         'element m
465                         'context-type context)))
466     (if (string? id)
467         (set! (ly:music-property cm 'context-id) id))
468     cm))
469
470 (define-public (descend-to-context m context)
471   "Like @code{context-spec-music}, but only descending."
472   (let ((cm (context-spec-music m context)))
473     (ly:music-set-property! cm 'descend-only #t)
474     cm))
475
476 (define-public (make-non-relative-music mus)
477   (make-music 'UnrelativableMusic
478               'element mus))
479
480 (define-public (make-apply-context func)
481   (make-music 'ApplyContext
482               'procedure func))
483
484 (define-public (make-sequential-music elts)
485   (make-music 'SequentialMusic
486               'elements elts))
487
488 (define-public (make-simultaneous-music elts)
489   (make-music 'SimultaneousMusic
490               'elements elts))
491
492 (define-safe-public (make-event-chord elts)
493   (make-music 'EventChord
494               'elements elts))
495
496 (define-public (make-skip-music dur)
497   (make-music 'SkipMusic
498               'duration dur))
499
500 (define-public (make-grace-music music)
501   (make-music 'GraceMusic
502               'element music))
503
504 ;;;;;;;;;;;;;;;;
505
506 ;; mmrest
507 (define-public (make-multi-measure-rest duration location)
508   (make-music 'MultiMeasureRestMusic
509               'origin location
510               'duration duration))
511
512 (define-public (make-property-set sym val)
513   (make-music 'PropertySet
514               'symbol sym
515               'value val))
516
517 (define-public (make-property-unset sym)
518   (make-music 'PropertyUnset
519               'symbol sym))
520
521 (define-safe-public (make-articulation name)
522   (make-music 'ArticulationEvent
523               'articulation-type name))
524
525 (define-public (make-lyric-event string duration)
526   (make-music 'LyricEvent
527               'duration duration
528               'text string))
529
530 (define-safe-public (make-span-event type span-dir)
531   (make-music type
532               'span-direction span-dir))
533
534 (define-public (override-head-style heads style)
535   "Override style for @var{heads} to @var{style}."
536   (make-sequential-music
537     (if (pair? heads)
538         (map (lambda (h)
539               (make-grob-property-override h 'style style))
540          heads)
541         (list (make-grob-property-override heads 'style style)))))
542
543 (define-public (revert-head-style heads)
544   "Revert style for @var{heads}."
545   (make-sequential-music
546     (if (pair? heads)
547         (map (lambda (h)
548               (make-grob-property-revert h 'style))
549          heads)
550         (list (make-grob-property-revert heads 'style)))))
551
552 (define-public (style-note-heads heads style music)
553  "Set @var{style} for all @var{heads} in @var{music}.  Works both
554 inside of and outside of chord construct."
555   ;; are we inside a <...>?
556   (if (eq? (ly:music-property music 'name) 'NoteEvent)
557       ;; yes -> use a tweak
558       (begin
559         (set! (ly:music-property music 'tweaks)
560               (acons 'style style (ly:music-property music 'tweaks)))
561         music)
562       ;; not in <...>, so use overrides
563       (make-sequential-music
564         (list
565           (override-head-style heads style)
566           music
567           (revert-head-style heads)))))
568
569  (define-public (set-mus-properties! m alist)
570   "Set all of @var{alist} as properties of @var{m}."
571   (if (pair? alist)
572       (begin
573         (set! (ly:music-property m (caar alist)) (cdar alist))
574         (set-mus-properties! m (cdr alist)))))
575
576 (define-public (music-separator? m)
577   "Is @var{m} a separator?"
578   (let ((ts (ly:music-property m 'types)))
579     (memq 'separator ts)))
580
581 ;;; splitting chords into voices.
582 (define (voicify-list lst number)
583   "Make a list of Musics.
584
585 voicify-list :: [ [Music ] ] -> number -> [Music]
586 LST is a list music-lists.
587
588 NUMBER is 0-base, i.e., Voice=1 (upstems) has number 0.
589 "
590   (if (null? lst)
591       '()
592       (cons (context-spec-music
593              (make-sequential-music
594               (list (make-voice-props-set number)
595                     (make-simultaneous-music (car lst))))
596              'Bottom  (number->string (1+ number)))
597             (voicify-list (cdr lst) (1+ number)))))
598
599 (define (voicify-chord ch)
600   "Split the parts of a chord into different Voices using separator"
601   (let ((es (ly:music-property ch 'elements)))
602     (set! (ly:music-property  ch 'elements)
603           (voicify-list (split-list-by-separator es music-separator?) 0))
604     ch))
605
606 (define-public (voicify-music m)
607   "Recursively split chords that are separated with @code{\\\\}."
608   (if (not (ly:music? m))
609       (ly:error (_ "music expected: ~S") m))
610   (let ((es (ly:music-property m 'elements))
611         (e (ly:music-property m 'element)))
612
613     (if (pair? es)
614         (set! (ly:music-property m 'elements) (map voicify-music es)))
615     (if (ly:music? e)
616         (set! (ly:music-property m 'element)  (voicify-music e)))
617     (if (and (equal? (ly:music-property m 'name) 'SimultaneousMusic)
618              (reduce (lambda (x y ) (or x y)) #f (map music-separator? es)))
619         (set! m (context-spec-music (voicify-chord m) 'Staff)))
620     m))
621
622 (define-public (empty-music)
623   (make-music 'Music))
624
625 ;; Make a function that checks score element for being of a specific type.
626 (define-public (make-type-checker symbol)
627   (lambda (elt)
628     (grob::has-interface elt symbol)))
629
630 (define-public ((outputproperty-compatibility func sym val) grob g-context ao-context)
631   (if (func grob)
632       (set! (ly:grob-property grob sym) val)))
633
634
635 (define-public ((set-output-property grob-name symbol val)  grob grob-c context)
636   "Usage example:
637 @code{\\applyoutput #(set-output-property 'Clef 'extra-offset '(0 . 1))}"
638   (let ((meta (ly:grob-property grob 'meta)))
639     (if (equal? (assoc-get 'name meta) grob-name)
640         (set! (ly:grob-property grob symbol) val))))
641
642
643 (define-public (skip->rest mus)
644   "Replace @var{mus} by @code{RestEvent} of the same duration if it is a
645 @code{SkipEvent}.  Useful for extracting parts from crowded scores."
646
647   (if  (memq (ly:music-property mus 'name) '(SkipEvent SkipMusic))
648    (make-music 'RestEvent 'duration (ly:music-property mus 'duration))
649    mus))
650
651
652 (define-public (music-has-type music type)
653   (memq type (ly:music-property music 'types)))
654
655 (define-public (music-clone music)
656   (define (alist->args alist acc)
657     (if (null? alist)
658         acc
659         (alist->args (cdr alist)
660                      (cons (caar alist) (cons (cdar alist) acc)))))
661
662   (apply
663    make-music
664    (ly:music-property music 'name)
665    (alist->args (ly:music-mutable-properties music) '())))
666
667 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
668 ;; warn for bare chords at start.
669
670 (define-public (ly:music-message music msg)
671   (let ((ip (ly:music-property music 'origin)))
672     (if (ly:input-location? ip)
673         (ly:input-message ip msg)
674         (ly:message msg))))
675
676 (define-public (ly:music-warning music msg)
677   (let ((ip (ly:music-property music 'origin)))
678     (if (ly:input-location? ip)
679         (ly:input-warning ip msg)
680         (ly:warning msg))))
681
682 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
683 ;;
684 ;; setting stuff for grace context.
685 ;;
686
687 (define (vector-extend v x)
688   "Make a new vector consisting of V, with X added to the end."
689   (let* ((n (vector-length v))
690          (nv (make-vector (+ n 1) '())))
691     (vector-move-left! v 0 n nv 0)
692     (vector-set! nv n x)
693     nv))
694
695 (define (vector-map f v)
696   "Map F over V.  This function returns nothing."
697   (do ((n (vector-length v))
698        (i 0 (+ i 1)))
699       ((>= i n))
700     (f (vector-ref v i))))
701
702 (define (vector-reverse-map f v)
703   "Map F over V, N to 0 order.  This function returns nothing."
704   (do ((i (- (vector-length v) 1) (- i 1)))
705       ((< i 0))
706     (f (vector-ref v i))))
707
708 (define-public (add-grace-property context-name grob sym val)
709   "Set @var{sym}=@var{val} for @var{grob} in @var{context-name}."
710   (define (set-prop context)
711     (let* ((where (ly:context-property-where-defined context 'graceSettings))
712            (current (ly:context-property where 'graceSettings))
713            (new-settings (append current
714                                  (list (list context-name grob sym val)))))
715       (ly:context-set-property! where 'graceSettings new-settings)))
716   (context-spec-music (make-apply-context set-prop) 'Voice))
717
718 (define-public (remove-grace-property context-name grob sym)
719   "Remove all @var{sym} for @var{grob} in @var{context-name}."
720   (define (sym-grob-context? property sym grob context-name)
721     (and (eq? (car property) context-name)
722          (eq? (cadr property) grob)
723          (eq? (caddr property) sym)))
724   (define (delete-prop context)
725     (let* ((where (ly:context-property-where-defined context 'graceSettings))
726            (current (ly:context-property where 'graceSettings))
727            (prop-settings (filter
728                             (lambda(x) (sym-grob-context? x sym grob context-name))
729                             current))
730            (new-settings current))
731       (for-each (lambda(x)
732                  (set! new-settings (delete x new-settings)))
733                prop-settings)
734       (ly:context-set-property! where 'graceSettings new-settings)))
735   (context-spec-music (make-apply-context delete-prop) 'Voice))
736
737
738
739 (defmacro-public def-grace-function (start stop . docstring)
740   "Helper macro for defining grace music"
741   `(define-music-function (parser location music) (ly:music?)
742      ,@docstring
743      (make-music 'GraceMusic
744                  'origin location
745                  'element (make-music 'SequentialMusic
746                                       'elements (list (ly:music-deep-copy ,start)
747                                                       music
748                                                       (ly:music-deep-copy ,stop))))))
749
750 (defmacro-public define-syntax-function (type args signature . body)
751   "Helper macro for `ly:make-music-function'.
752 Syntax:
753   (define-syntax-function (result-type? parser location arg1 arg2 ...) (result-type? arg1-type arg2-type ...)
754     ...function body...)
755
756 argX-type can take one of the forms @code{predicate?} for mandatory
757 arguments satisfying the predicate, @code{(predicate?)} for optional
758 parameters of that type defaulting to @code{#f}, @code{@w{(predicate?
759 value)}} for optional parameters with a specified default
760 value (evaluated at definition time).  An optional parameter can be
761 omitted in a call only when it can't get confused with a following
762 parameter of different type.
763
764 Predicates with syntactical significance are @code{ly:pitch?},
765 @code{ly:duration?}, @code{ly:music?}, @code{markup?}.  Other
766 predicates require the parameter to be entered as Scheme expression.
767
768 @code{result-type?} can specify a default in the same manner as
769 predicates, to be used in case of a type error in arguments or
770 result."
771
772   (set! signature (map (lambda (pred)
773                          (if (pair? pred)
774                              `(cons ,(car pred)
775                                     ,(and (pair? (cdr pred)) (cadr pred)))
776                              pred))
777                        (cons type signature)))
778   (if (and (pair? body) (pair? (car body)) (eqv? '_i (caar body)))
779       ;; When the music function definition contains a i10n doc string,
780       ;; (_i "doc string"), keep the literal string only
781       (let ((docstring (cadar body))
782             (body (cdr body)))
783         `(ly:make-music-function (list ,@signature)
784                                  (lambda ,args
785                                    ,docstring
786                                    ,@body)))
787       `(ly:make-music-function (list ,@signature)
788                                (lambda ,args
789                                  ,@body))))
790
791 (defmacro-public define-music-function rest
792   "Defining macro returning music functions.
793 Syntax:
794   (define-music-function (parser location arg1 arg2 ...) (arg1-type? arg2-type? ...)
795     ...function body...)
796
797 argX-type can take one of the forms @code{predicate?} for mandatory
798 arguments satisfying the predicate, @code{(predicate?)} for optional
799 parameters of that type defaulting to @code{#f}, @code{@w{(predicate?
800 value)}} for optional parameters with a specified default
801 value (evaluated at definition time).  An optional parameter can be
802 omitted in a call only when it can't get confused with a following
803 parameter of different type.
804
805 Predicates with syntactical significance are @code{ly:pitch?},
806 @code{ly:duration?}, @code{ly:music?}, @code{markup?}.  Other
807 predicates require the parameter to be entered as Scheme expression.
808
809 Must return a music expression.  The @code{origin} is automatically
810 set to the @code{location} parameter."
811
812   `(define-syntax-function (ly:music? (make-music 'Music 'void #t)) ,@rest))
813
814
815 (defmacro-public define-scheme-function rest
816   "Defining macro returning Scheme functions.
817 Syntax:
818   (define-scheme-function (parser location arg1 arg2 ...) (arg1-type? arg2-type? ...)
819     ...function body...)
820
821 argX-type can take one of the forms @code{predicate?} for mandatory
822 arguments satisfying the predicate, @code{(predicate?)} for optional
823 parameters of that type defaulting to @code{#f}, @code{@w{(predicate?
824 value)}} for optional parameters with a specified default
825 value (evaluated at definition time).  An optional parameter can be
826 omitted in a call only when it can't get confused with a following
827 parameter of different type.
828
829 Predicates with syntactical significance are @code{ly:pitch?},
830 @code{ly:duration?}, @code{ly:music?}, @code{markup?}.  Other
831 predicates require the parameter to be entered as Scheme expression.
832
833 Can return arbitrary expressions.  If a music expression is returned,
834 its @code{origin} is automatically set to the @code{location}
835 parameter."
836
837   `(define-syntax-function scheme? ,@rest))
838
839 (defmacro-public define-void-function rest
840   "This defines a Scheme function like @code{define-scheme-function} with
841 void return value (i.e., what most Guile functions with `unspecified'
842 value return).  Use this when defining functions for executing actions
843 rather than returning values, to keep Lilypond from trying to interpret
844 the return value."
845   `(define-syntax-function (void? *unspecified*) ,@rest *unspecified*))
846
847 (defmacro-public define-event-function rest
848   "Defining macro returning event functions.
849 Syntax:
850   (define-event-function (parser location arg1 arg2 ...) (arg1-type? arg2-type? ...)
851     ...function body...)
852
853 argX-type can take one of the forms @code{predicate?} for mandatory
854 arguments satisfying the predicate, @code{(predicate?)} for optional
855 parameters of that type defaulting to @code{#f}, @code{@w{(predicate?
856 value)}} for optional parameters with a specified default
857 value (evaluated at definition time).  An optional parameter can be
858 omitted in a call only when it can't get confused with a following
859 parameter of different type.
860
861 Predicates with syntactical significance are @code{ly:pitch?},
862 @code{ly:duration?}, @code{ly:music?}, @code{markup?}.  Other
863 predicates require the parameter to be entered as Scheme expression.
864
865 Must return an event expression.  The @code{origin} is automatically
866 set to the @code{location} parameter."
867
868   `(define-syntax-function (ly:event? (make-music 'Event 'void #t)) ,@rest))
869
870 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
871
872 (define-public (cue-substitute quote-music)
873   "Must happen after @code{quote-substitute}."
874
875   (if (vector? (ly:music-property quote-music 'quoted-events))
876       (let* ((dir (ly:music-property quote-music 'quoted-voice-direction))
877              (clef (ly:music-property quote-music 'quoted-music-clef))
878              (main-voice (if (eq? 1 dir) 1 0))
879              (cue-voice (if (eq? 1 dir) 0 1))
880              (main-music (ly:music-property quote-music 'element))
881              (return-value quote-music))
882
883         (if (or (eq? 1 dir) (eq? -1 dir))
884
885             ;; if we have stem dirs, change both quoted and main music
886             ;; to have opposite stems.
887             (begin
888               (set! return-value
889                     ;; cannot context-spec Quote-music, since context
890                     ;; for the quotes is determined in the iterator.
891                     (make-sequential-music
892                      (list
893                       (if (null? clef)
894                           (make-music 'Music)
895                           (make-cue-clef-set clef))
896                       (context-spec-music (make-voice-props-set cue-voice) 'CueVoice "cue")
897                       quote-music
898                       (context-spec-music (make-voice-props-revert) 'CueVoice "cue")
899                       (if (null? clef)
900                           (make-music 'Music)
901                           (make-cue-clef-unset)))))
902               (set! main-music
903                     (make-sequential-music
904                      (list
905                       (make-voice-props-set main-voice)
906                       main-music
907                       (make-voice-props-revert))))
908               (set! (ly:music-property quote-music 'element) main-music)))
909
910         return-value)
911       quote-music))
912
913 (define-public ((quote-substitute quote-tab) music)
914   (let* ((quoted-name (ly:music-property music 'quoted-music-name))
915          (quoted-vector (and (string? quoted-name)
916                              (hash-ref quote-tab quoted-name #f))))
917
918
919     (if (string? quoted-name)
920         (if (vector? quoted-vector)
921             (begin
922               (set! (ly:music-property music 'quoted-events) quoted-vector)
923               (set! (ly:music-property music 'iterator-ctor)
924                     ly:quote-iterator::constructor))
925             (ly:music-warning music (ly:format (_ "cannot find quoted music: `~S'") quoted-name))))
926     music))
927
928
929 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
930 ;; switch it on here, so parsing and init isn't checked (too slow!)
931 ;;
932 ;; automatic music transformations.
933
934 (define (switch-on-debugging m)
935   (if (defined? 'set-debug-cell-accesses!)
936       (set-debug-cell-accesses! 15000))
937   m)
938
939 (define (music-check-error music)
940   (define found #f)
941   (define (signal m)
942     (if (and (ly:music? m)
943              (eq? (ly:music-property m 'error-found) #t))
944         (set! found #t)))
945
946   (for-each signal (ly:music-property music 'elements))
947   (signal (ly:music-property music 'element))
948
949   (if found
950       (set! (ly:music-property music 'error-found) #t))
951   music)
952
953 (define (precompute-music-length music)
954   (set! (ly:music-property music 'length)
955         (ly:music-length music))
956   music)
957
958 (define-public (make-duration-of-length moment)
959  "Make duration of the given @code{moment} length."
960  (ly:make-duration 0 0
961   (ly:moment-main-numerator moment)
962   (ly:moment-main-denominator moment)))
963
964 (define (make-skipped moment bool)
965  "Depending on BOOL, set or unset skipTypesetting,
966 then make SkipMusic of the given MOMENT length, and
967 then revert skipTypesetting."
968  (make-sequential-music
969   (list
970    (context-spec-music (make-property-set 'skipTypesetting bool)
971     'Score)
972    (make-music 'SkipMusic 'duration
973     (make-duration-of-length moment))
974    (context-spec-music (make-property-set 'skipTypesetting (not bool))
975     'Score))))
976
977 (define (skip-as-needed music parser)
978   "Replace MUSIC by
979  << {  \\set skipTypesetting = ##f
980  LENGTHOF(\\showFirstLength)
981  \\set skipTypesetting = ##t
982  LENGTHOF(\\showLastLength) }
983  MUSIC >>
984  if appropriate.
985
986  When only showFirstLength is set,
987  the 'length property of the music is
988  overridden to speed up compiling."
989   (let*
990       ((show-last (ly:parser-lookup parser 'showLastLength))
991        (show-first (ly:parser-lookup parser 'showFirstLength))
992        (show-last-length (and (ly:music? show-last)
993                               (ly:music-length show-last)))
994        (show-first-length (and (ly:music? show-first)
995                                (ly:music-length show-first)))
996        (orig-length (ly:music-length music)))
997
998     ;;FIXME: if using either showFirst- or showLastLength,
999     ;; make sure that skipBars is not set.
1000
1001     (cond
1002
1003      ;; both properties may be set.
1004      ((and show-first-length show-last-length)
1005       (let
1006           ((skip-length (ly:moment-sub orig-length show-last-length)))
1007         (make-simultaneous-music
1008          (list
1009           (make-sequential-music
1010            (list
1011             (make-skipped skip-length #t)
1012             ;; let's draw a separator between the beginning and the end
1013             (context-spec-music (make-property-set 'whichBar "||")
1014                                 'Timing)))
1015           (make-skipped show-first-length #f)
1016           music))))
1017
1018      ;; we may only want to print the last length
1019      (show-last-length
1020       (let
1021           ((skip-length (ly:moment-sub orig-length show-last-length)))
1022         (make-simultaneous-music
1023          (list
1024           (make-skipped skip-length #t)
1025           music))))
1026
1027      ;; we may only want to print the beginning; in this case
1028      ;; only the first length will be processed (much faster).
1029      (show-first-length
1030       ;; the first length must not exceed the original length.
1031       (if (ly:moment<? show-first-length orig-length)
1032           (set! (ly:music-property music 'length)
1033                 show-first-length))
1034       music)
1035
1036      (else music))))
1037
1038
1039 (define-public toplevel-music-functions
1040   (list
1041    (lambda (music parser) (voicify-music music))
1042    (lambda (x parser) (music-map music-check-error x))
1043    (lambda (x parser) (music-map precompute-music-length x))
1044    (lambda (music parser)
1045
1046      (music-map (quote-substitute (ly:parser-lookup parser 'musicQuotes))  music))
1047
1048    ;; switch-on-debugging
1049    (lambda (x parser) (music-map cue-substitute x))
1050
1051    (lambda (x parser)
1052      (skip-as-needed x parser)
1053    )))
1054
1055 ;;;;;;;;;;
1056 ;;; general purpose music functions
1057
1058 (define (shift-octave pitch octave-shift)
1059   (_i "Add @var{octave-shift} to the octave of @var{pitch}.")
1060   (ly:make-pitch
1061      (+ (ly:pitch-octave pitch) octave-shift)
1062      (ly:pitch-notename pitch)
1063      (ly:pitch-alteration pitch)))
1064
1065
1066 ;;;;;;;;;;;;;;;;;
1067 ;; lyrics
1068
1069 (define (apply-durations lyric-music durations)
1070   (define (apply-duration music)
1071     (if (and (not (equal? (ly:music-length music) ZERO-MOMENT))
1072              (ly:duration?  (ly:music-property music 'duration)))
1073         (begin
1074           (set! (ly:music-property music 'duration) (car durations))
1075           (set! durations (cdr durations)))))
1076
1077   (music-map apply-duration lyric-music))
1078
1079
1080 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1081 ;; accidentals
1082
1083 (define (recent-enough? bar-number alteration-def laziness)
1084   (or (number? alteration-def)
1085       (equal? laziness #t)
1086       (<= bar-number (+ (cadr alteration-def) laziness))))
1087
1088 (define (accidental-invalid? alteration-def)
1089   "Checks an alteration entry for being invalid.
1090
1091 Non-key alterations are invalidated when tying into the next bar or
1092 when there is a clef change, since neither repetition nor cancellation
1093 can be omitted when the same note occurs again.
1094
1095 Returns @code{#f} or the reason for the invalidation, a symbol."
1096   (let* ((def (if (pair? alteration-def)
1097                   (car alteration-def)
1098                   alteration-def)))
1099     (and (symbol? def) def)))
1100
1101 (define (extract-alteration alteration-def)
1102   (cond ((number? alteration-def)
1103          alteration-def)
1104         ((pair? alteration-def)
1105          (car alteration-def))
1106         (else 0)))
1107
1108 (define (check-pitch-against-signature context pitch barnum laziness octaveness)
1109   "Checks the need for an accidental and a @q{restore} accidental against
1110 @code{localKeySignature}.  The @var{laziness} is the number of measures
1111 for which reminder accidentals are used (i.e., if @var{laziness} is zero,
1112 only cancel accidentals in the same measure; if @var{laziness} is three,
1113 we cancel accidentals up to three measures after they first appear.
1114 @var{octaveness} is either @code{'same-octave} or @code{'any-octave} and
1115 specifies whether accidentals should be canceled in different octaves."
1116   (let* ((ignore-octave (cond ((equal? octaveness 'any-octave) #t)
1117                               ((equal? octaveness 'same-octave) #f)
1118                               (else
1119                                (ly:warning (_ "Unknown octaveness type: ~S ") octaveness)
1120                                (ly:warning (_ "Defaulting to 'any-octave."))
1121                                #t)))
1122          (key-sig (ly:context-property context 'keySignature))
1123          (local-key-sig (ly:context-property context 'localKeySignature))
1124          (notename (ly:pitch-notename pitch))
1125          (octave (ly:pitch-octave pitch))
1126          (pitch-handle (cons octave notename))
1127          (need-restore #f)
1128          (need-accidental #f)
1129          (previous-alteration #f)
1130          (from-other-octaves #f)
1131          (from-same-octave (assoc-get pitch-handle local-key-sig))
1132          (from-key-sig (or (assoc-get notename local-key-sig)
1133
1134     ;; If no key signature match is found from localKeySignature, we may have a custom
1135     ;; type with octave-specific entries of the form ((octave . pitch) alteration)
1136     ;; instead of (pitch . alteration).  Since this type cannot coexist with entries in
1137     ;; localKeySignature, try extracting from keySignature instead.
1138                            (assoc-get pitch-handle key-sig))))
1139
1140     ;; loop through localKeySignature to search for a notename match from other octaves
1141     (let loop ((l local-key-sig))
1142       (if (pair? l)
1143           (let ((entry (car l)))
1144             (if (and (pair? (car entry))
1145                      (= (cdar entry) notename))
1146                 (set! from-other-octaves (cdr entry))
1147                 (loop (cdr l))))))
1148
1149     ;; find previous alteration-def for comparison with pitch
1150     (cond
1151      ;; from same octave?
1152      ((and (not ignore-octave)
1153            from-same-octave
1154            (recent-enough? barnum from-same-octave laziness))
1155       (set! previous-alteration from-same-octave))
1156
1157      ;; from any octave?
1158      ((and ignore-octave
1159            from-other-octaves
1160            (recent-enough? barnum from-other-octaves laziness))
1161       (set! previous-alteration from-other-octaves))
1162
1163      ;; not recent enough, extract from key signature/local key signature
1164      (from-key-sig
1165       (set! previous-alteration from-key-sig)))
1166
1167     (if (accidental-invalid? previous-alteration)
1168         (set! need-accidental #t)
1169
1170         (let* ((prev-alt (extract-alteration previous-alteration))
1171                (this-alt (ly:pitch-alteration pitch)))
1172
1173           (if (not (= this-alt prev-alt))
1174               (begin
1175                 (set! need-accidental #t)
1176                 (if (and (not (= this-alt 0))
1177                          (and (< (abs this-alt) (abs prev-alt))
1178                              (> (* prev-alt this-alt) 0)))
1179                     (set! need-restore #t))))))
1180
1181     (cons need-restore need-accidental)))
1182
1183 (define-public ((make-accidental-rule octaveness laziness) context pitch barnum measurepos)
1184   "Create an accidental rule that makes its decision based on the octave of
1185 the note and a laziness value.
1186
1187 @var{octaveness} is either @code{'same-octave} or @code{'any-octave} and
1188 defines whether the rule should respond to accidental changes in other
1189 octaves than the current.  @code{'same-octave} is the normal way to typeset
1190 accidentals -- an accidental is made if the alteration is different from the
1191 last active pitch in the same octave.  @code{'any-octave} looks at the last
1192 active pitch in any octave.
1193
1194 @var{laziness} states over how many bars an accidental should be remembered.
1195 @code{0}@tie{}is the default -- accidental lasts over 0@tie{}bar lines, that
1196 is, to the end of current measure.  A positive integer means that the
1197 accidental lasts over that many bar lines.  @w{@code{-1}} is `forget
1198 immediately', that is, only look at key signature.  @code{#t} is `forever'."
1199
1200   (check-pitch-against-signature context pitch barnum laziness octaveness))
1201
1202 (define (key-entry-notename entry)
1203   "Return the pitch of an entry in localKeySignature.  The entry is either of the form
1204   '(notename . alter) or '((octave . notename) . (alter barnum . measurepos))."
1205   (if (number? (car entry))
1206       (car entry)
1207       (cdar entry)))
1208
1209 (define (key-entry-octave entry)
1210   "Return the octave of an entry in localKeySignature (or #f if the entry does not have
1211   an octave)."
1212   (and (pair? (car entry)) (caar entry)))
1213
1214 (define (key-entry-bar-number entry)
1215   "Return the bar number of an entry in localKeySignature (or #f if the entry does not
1216   have a bar number)."
1217   (and (pair? (car entry)) (caddr entry)))
1218
1219 (define (key-entry-measure-position entry)
1220   "Return the measure position of an entry in localKeySignature (or #f if the entry does
1221   not have a measure position)."
1222   (and (pair? (car entry)) (cdddr entry)))
1223
1224 (define (key-entry-alteration entry)
1225   "Return the alteration of an entry in localKeySignature.
1226
1227 For convenience, returns @code{0} if entry is @code{#f}."
1228   (if entry
1229       (if (number? (car entry))
1230           (cdr entry)
1231           (cadr entry))
1232       0))
1233
1234 (define-public (find-pitch-entry keysig pitch accept-global accept-local)
1235   "Return the first entry in @var{keysig} that matches @var{pitch}.
1236 @var{accept-global} states whether key signature entries should be included.
1237 @var{accept-local} states whether local accidentals should be included.
1238 If no matching entry is found, @var{#f} is returned."
1239   (and (pair? keysig)
1240        (let* ((entry (car keysig))
1241               (entryoct (key-entry-octave entry))
1242               (entrynn (key-entry-notename entry))
1243               (oct (ly:pitch-octave pitch))
1244               (nn (ly:pitch-notename pitch)))
1245          (if (and (equal? nn entrynn)
1246                   (or (and accept-global (not entryoct))
1247                       (and accept-local (equal? oct entryoct))))
1248              entry
1249              (find-pitch-entry (cdr keysig) pitch accept-global accept-local)))))
1250
1251 (define-public (neo-modern-accidental-rule context pitch barnum measurepos)
1252   "An accidental rule that typesets an accidental if it differs from the
1253 key signature @emph{and} does not directly follow a note on the same
1254 staff line.  This rule should not be used alone because it does neither
1255 look at bar lines nor different accidentals at the same note name."
1256   (let* ((keysig (ly:context-property context 'localKeySignature))
1257          (entry (find-pitch-entry keysig pitch #t #t)))
1258     (if (not entry)
1259         (cons #f #f)
1260         (let* ((global-entry (find-pitch-entry keysig pitch #t #f))
1261                (key-acc (key-entry-alteration global-entry))
1262                (acc (ly:pitch-alteration pitch))
1263                (entrymp (key-entry-measure-position entry))
1264                (entrybn (key-entry-bar-number entry)))
1265           (cons #f (not (or (equal? acc key-acc)
1266                             (and (equal? entrybn barnum) (equal? entrymp measurepos)))))))))
1267
1268 (define-public (teaching-accidental-rule context pitch barnum measurepos)
1269   "An accidental rule that typesets a cautionary accidental if it is
1270 included in the key signature @emph{and} does not directly follow a note
1271 on the same staff line."
1272   (let* ((keysig (ly:context-property context 'localKeySignature))
1273          (entry (find-pitch-entry keysig pitch #t #t)))
1274     (if (not entry)
1275         (cons #f #f)
1276         (let* ((global-entry (find-pitch-entry keysig pitch #f #f))
1277                (key-acc (key-entry-alteration global-entry))
1278                (acc (ly:pitch-alteration pitch))
1279                (entrymp (key-entry-measure-position entry))
1280                (entrybn (key-entry-bar-number entry)))
1281           (cons #f (not (or (equal? acc key-acc)
1282                             (and (equal? entrybn barnum) (equal? entrymp measurepos)))))))))
1283
1284 (define-public (set-accidentals-properties extra-natural
1285                                            auto-accs auto-cauts
1286                                            context)
1287   (context-spec-music
1288    (make-sequential-music
1289     (append (if (boolean? extra-natural)
1290                 (list (make-property-set 'extraNatural extra-natural))
1291                 '())
1292             (list (make-property-set 'autoAccidentals auto-accs)
1293                   (make-property-set 'autoCautionaries auto-cauts))))
1294    context))
1295
1296 (define-public (set-accidental-style style . rest)
1297   "Set accidental style to @var{style}.  Optionally take a context
1298 argument, e.g. @code{'Staff} or @code{'Voice}.  The context defaults
1299 to @code{Staff}, except for piano styles, which use @code{GrandStaff}
1300 as a context."
1301   (let ((context (if (pair? rest)
1302                      (car rest) 'Staff))
1303         (pcontext (if (pair? rest)
1304                       (car rest) 'GrandStaff)))
1305     (cond
1306       ;; accidentals as they were common in the 18th century.
1307       ((equal? style 'default)
1308        (set-accidentals-properties #t
1309                                    `(Staff ,(make-accidental-rule 'same-octave 0))
1310                                    '()
1311                                    context))
1312       ;; accidentals from one voice do NOT get cancelled in other voices
1313       ((equal? style 'voice)
1314        (set-accidentals-properties #t
1315                                    `(Voice ,(make-accidental-rule 'same-octave 0))
1316                                    '()
1317                                    context))
1318       ;; accidentals as suggested by Kurt Stone, Music Notation in the 20th century.
1319       ;; This includes all the default accidentals, but accidentals also needs cancelling
1320       ;; in other octaves and in the next measure.
1321       ((equal? style 'modern)
1322        (set-accidentals-properties #f
1323                                    `(Staff ,(make-accidental-rule 'same-octave 0)
1324                                            ,(make-accidental-rule 'any-octave 0)
1325                                            ,(make-accidental-rule 'same-octave 1))
1326                                    '()
1327                                    context))
1328       ;; the accidentals that Stone adds to the old standard as cautionaries
1329       ((equal? style 'modern-cautionary)
1330        (set-accidentals-properties #f
1331                                    `(Staff ,(make-accidental-rule 'same-octave 0))
1332                                    `(Staff ,(make-accidental-rule 'any-octave 0)
1333                                            ,(make-accidental-rule 'same-octave 1))
1334                                    context))
1335       ;; same as modern, but accidentals different from the key signature are always
1336       ;; typeset - unless they directly follow a note of the same pitch.
1337       ((equal? style 'neo-modern)
1338        (set-accidentals-properties #f
1339                                    `(Staff ,(make-accidental-rule 'same-octave 0)
1340                                            ,(make-accidental-rule 'any-octave 0)
1341                                            ,(make-accidental-rule 'same-octave 1)
1342                                            ,neo-modern-accidental-rule)
1343                                    '()
1344                                    context))
1345       ((equal? style 'neo-modern-cautionary)
1346        (set-accidentals-properties #f
1347                                    `(Staff ,(make-accidental-rule 'same-octave 0))
1348                                    `(Staff ,(make-accidental-rule 'any-octave 0)
1349                                            ,(make-accidental-rule 'same-octave 1)
1350                                            ,neo-modern-accidental-rule)
1351                                    context))
1352       ((equal? style 'neo-modern-voice)
1353        (set-accidentals-properties #f
1354                                    `(Voice ,(make-accidental-rule 'same-octave 0)
1355                                            ,(make-accidental-rule 'any-octave 0)
1356                                            ,(make-accidental-rule 'same-octave 1)
1357                                            ,neo-modern-accidental-rule
1358                                      Staff ,(make-accidental-rule 'same-octave 0)
1359                                            ,(make-accidental-rule 'any-octave 0)
1360                                            ,(make-accidental-rule 'same-octave 1)
1361                                       ,neo-modern-accidental-rule)
1362                                    '()
1363                                    context))
1364       ((equal? style 'neo-modern-voice-cautionary)
1365        (set-accidentals-properties #f
1366                                    `(Voice ,(make-accidental-rule 'same-octave 0))
1367                                    `(Voice ,(make-accidental-rule 'any-octave 0)
1368                                            ,(make-accidental-rule 'same-octave 1)
1369                                            ,neo-modern-accidental-rule
1370                                      Staff ,(make-accidental-rule 'same-octave 0)
1371                                            ,(make-accidental-rule 'any-octave 0)
1372                                            ,(make-accidental-rule 'same-octave 1)
1373                                            ,neo-modern-accidental-rule)
1374                                    context))
1375       ;; Accidentals as they were common in dodecaphonic music with no tonality.
1376       ;; Each note gets one accidental.
1377       ((equal? style 'dodecaphonic)
1378        (set-accidentals-properties #f
1379                                    `(Staff ,(lambda (c p bn mp) '(#f . #t)))
1380                                    '()
1381                                    context))
1382       ;; Multivoice accidentals to be read both by musicians playing one voice
1383       ;; and musicians playing all voices.
1384       ;; Accidentals are typeset for each voice, but they ARE cancelled across voices.
1385       ((equal? style 'modern-voice)
1386        (set-accidentals-properties  #f
1387                                     `(Voice ,(make-accidental-rule 'same-octave 0)
1388                                             ,(make-accidental-rule 'any-octave 0)
1389                                             ,(make-accidental-rule 'same-octave 1)
1390                                       Staff ,(make-accidental-rule 'same-octave 0)
1391                                             ,(make-accidental-rule 'any-octave 0)
1392                                             ,(make-accidental-rule 'same-octave 1))
1393                                     '()
1394                                     context))
1395       ;; same as modernVoiceAccidental eccept that all special accidentals are typeset
1396       ;; as cautionaries
1397       ((equal? style 'modern-voice-cautionary)
1398        (set-accidentals-properties #f
1399                                    `(Voice ,(make-accidental-rule 'same-octave 0))
1400                                    `(Voice ,(make-accidental-rule 'any-octave 0)
1401                                            ,(make-accidental-rule 'same-octave 1)
1402                                      Staff ,(make-accidental-rule 'same-octave 0)
1403                                            ,(make-accidental-rule 'any-octave 0)
1404                                            ,(make-accidental-rule 'same-octave 1))
1405                                    context))
1406       ;; stone's suggestions for accidentals on grand staff.
1407       ;; Accidentals are cancelled across the staves in the same grand staff as well
1408       ((equal? style 'piano)
1409        (set-accidentals-properties #f
1410                                    `(Staff ,(make-accidental-rule 'same-octave 0)
1411                                            ,(make-accidental-rule 'any-octave 0)
1412                                            ,(make-accidental-rule 'same-octave 1)
1413                                      GrandStaff
1414                                            ,(make-accidental-rule 'any-octave 0)
1415                                            ,(make-accidental-rule 'same-octave 1))
1416                                    '()
1417                                    pcontext))
1418       ((equal? style 'piano-cautionary)
1419        (set-accidentals-properties #f
1420                                    `(Staff ,(make-accidental-rule 'same-octave 0))
1421                                    `(Staff ,(make-accidental-rule 'any-octave 0)
1422                                            ,(make-accidental-rule 'same-octave 1)
1423                                      GrandStaff
1424                                            ,(make-accidental-rule 'any-octave 0)
1425                                            ,(make-accidental-rule 'same-octave 1))
1426                                    pcontext))
1427
1428       ;; same as modern, but cautionary accidentals are printed for all sharp or flat
1429       ;; tones specified by the key signature.
1430        ((equal? style 'teaching)
1431        (set-accidentals-properties #f
1432                                     `(Staff ,(make-accidental-rule 'same-octave 0))
1433                                     `(Staff ,(make-accidental-rule 'same-octave 1)
1434                                            ,teaching-accidental-rule)
1435                                    context))
1436
1437       ;; do not set localKeySignature when a note alterated differently from
1438       ;; localKeySignature is found.
1439       ;; Causes accidentals to be printed at every note instead of
1440       ;; remembered for the duration of a measure.
1441       ;; accidentals not being remembered, causing accidentals always to
1442       ;; be typeset relative to the time signature
1443       ((equal? style 'forget)
1444        (set-accidentals-properties '()
1445                                    `(Staff ,(make-accidental-rule 'same-octave -1))
1446                                    '()
1447                                    context))
1448       ;; Do not reset the key at the start of a measure.  Accidentals will be
1449       ;; printed only once and are in effect until overridden, possibly many
1450       ;; measures later.
1451       ((equal? style 'no-reset)
1452        (set-accidentals-properties '()
1453                                    `(Staff ,(make-accidental-rule 'same-octave #t))
1454                                    '()
1455                                    context))
1456       (else
1457        (ly:warning (_ "unknown accidental style: ~S") style)
1458        (make-sequential-music '())))))
1459
1460 (define-public (invalidate-alterations context)
1461   "Invalidate alterations in @var{context}.
1462
1463 Elements of @code{'localKeySignature} corresponding to local
1464 alterations of the key signature have the form
1465 @code{'((octave . notename) . (alter barnum . measurepos))}.
1466 Replace them with a version where @code{alter} is set to @code{'clef}
1467 to force a repetition of accidentals.
1468
1469 Entries that conform with the current key signature are not invalidated."
1470   (let* ((keysig (ly:context-property context 'keySignature)))
1471     (set! (ly:context-property context 'localKeySignature)
1472           (map-in-order
1473            (lambda (entry)
1474              (let* ((localalt (key-entry-alteration entry))
1475                     (localoct (key-entry-octave entry)))
1476                (if (or (accidental-invalid? localalt)
1477                        (not localoct)
1478                        (= localalt
1479                           (key-entry-alteration
1480                            (find-pitch-entry
1481                             keysig
1482                             (ly:make-pitch localoct
1483                                            (key-entry-notename entry)
1484                                            0)
1485                             #t #t))))
1486                    entry
1487                    (cons (car entry) (cons 'clef (cddr entry))))))
1488            (ly:context-property context 'localKeySignature)))))
1489
1490 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1491
1492 (define-public (skip-of-length mus)
1493   "Create a skip of exactly the same length as @var{mus}."
1494   (let* ((skip
1495           (make-music
1496            'SkipEvent
1497            'duration (ly:make-duration 0 0))))
1498
1499     (make-event-chord (list (ly:music-compress skip (ly:music-length mus))))))
1500
1501 (define-public (mmrest-of-length mus)
1502   "Create a multi-measure rest of exactly the same length as @var{mus}."
1503
1504   (let* ((skip
1505           (make-multi-measure-rest
1506            (ly:make-duration 0 0) '())))
1507     (ly:music-compress skip (ly:music-length mus))
1508     skip))
1509
1510 (define-public (pitch-of-note event-chord)
1511   (let ((evs (filter (lambda (x)
1512                        (music-has-type x 'note-event))
1513                      (ly:music-property event-chord 'elements))))
1514
1515     (and (pair? evs)
1516          (ly:music-property (car evs) 'pitch))))
1517
1518 (define-public (duration-of-note event-chord)
1519   (let ((evs (filter (lambda (x)
1520                        (music-has-type x 'rhythmic-event))
1521                      (ly:music-property event-chord 'elements))))
1522
1523     (and (pair? evs)
1524          (ly:music-property (car evs) 'duration))))
1525
1526 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1527
1528 (define-public (extract-named-music music music-name)
1529   "Return a flat list of all music named @var{music-name} from @var{music}."
1530    (let ((extracted-list
1531           (if (ly:music? music)
1532               (if (eq? (ly:music-property music 'name) music-name)
1533                   (list music)
1534                   (let ((elt (ly:music-property music 'element))
1535                         (elts (ly:music-property music 'elements)))
1536                     (if (ly:music? elt)
1537                         (extract-named-music elt music-name)
1538                         (if (null? elts)
1539                             '()
1540                             (map (lambda(x)
1541                                     (extract-named-music x music-name ))
1542                              elts)))))
1543               '())))
1544      (flatten-list extracted-list)))
1545
1546 (define-public (event-chord-notes event-chord)
1547   "Return a list of all notes from @var{event-chord}."
1548   (filter
1549     (lambda (m) (eq? 'NoteEvent (ly:music-property m 'name)))
1550     (ly:music-property event-chord 'elements)))
1551
1552 (define-public (event-chord-pitches event-chord)
1553   "Return a list of all pitches from @var{event-chord}."
1554   (map (lambda (x) (ly:music-property x 'pitch))
1555        (event-chord-notes event-chord)))