;;;;
;;;; source file of the GNU LilyPond music typesetter
;;;;
-;;;; (c) 1998--2005 Jan Nieuwenhuizen <janneke@gnu.org>
+;;;; (c) 1998--2006 Jan Nieuwenhuizen <janneke@gnu.org>
;;;; Han-Wen Nienhuys <hanwen@cs.uu.nl>
;; (use-modules (ice-9 optargs))
(make-procedure-with-setter ly:music-property
ly:music-set-property!))
+
+;; TODO move this
(define-public ly:grob-property
(make-procedure-with-setter ly:grob-property
ly:grob-set-property!))
+(define-public ly:prob-property
+ (make-procedure-with-setter ly:prob-property
+ ly:prob-set-property!))
+
(define-public (music-map function music)
"Apply @var{function} to @var{music} and all of the music it contains.
(symbol->keyword (string->symbol (substring cmd-markup 0 (- (string-length cmd-markup)
(string-length "-markup")))))))
(define (transform-arg arg)
- (cond ((and (pair? arg) (pair? (car arg))) ;; a markup list
+ (cond ((and (pair? arg) (markup? (car arg))) ;; a markup list
(apply append (map inner-markup->make-markup arg)))
- ((pair? arg) ;; a markup
+ ((and (not (string? arg)) (markup? arg)) ;; a markup
(inner-markup->make-markup arg))
- (else ;; scheme arg
+ (else ;; scheme arg
arg)))
(define (inner-markup->make-markup mrkup)
(let ((cmd (proc->command-keyword (car mrkup)))
(ly:music? obj)
`(make-music
',(ly:music-property obj 'name)
- ,@(append (map (lambda (prop)
- (list
- (car prop)
- (if (and (not (markup? (cdr prop)))
- (list? (cdr prop))
- (pair? (cdr prop))) ;; property is a non-empty list
- `(list ,@(map music->make-music (cdr prop)))
- (music->make-music (cdr prop)))))
- (remove (lambda (prop)
- (eqv? (car prop) 'origin))
- (ly:music-mutable-properties obj))))))
+ ,@(apply append (map (lambda (prop)
+ `(',(car prop)
+ ,(if (and (not (markup? (cdr prop)))
+ (list? (cdr prop))
+ (pair? (cdr prop))) ;; property is a non-empty list
+ `(list ,@(map music->make-music (cdr prop)))
+ (music->make-music (cdr prop)))))
+ (remove (lambda (prop)
+ (eqv? (car prop) 'origin))
+ (ly:music-mutable-properties obj))))))
(;; moment
(ly:moment? obj)
`(ly:make-moment ,(ly:moment-main-numerator obj)
(define-public (unfold-repeats music)
"
This function replaces all repeats with unfold repeats. "
-
+
(let ((es (ly:music-property music 'elements))
(e (ly:music-property music 'element))
)
(if (memq 'repeated-music (ly:music-property music 'types))
- (begin
- (if (equal? (ly:music-property music 'iterator-ctor)
- Chord_tremolo_iterator::constructor)
+ (let*
+ ((props (ly:music-mutable-properties music))
+ (old-name (ly:music-property music 'name))
+ (flattened (flatten-alist props)))
+
+ (set! music (apply make-music (cons 'UnfoldedRepeatedMusic
+ flattened)))
+
+ (if (equal? old-name 'TremoloRepeatedMusic)
(let* ((seq-arg? (memq 'sequential-music
(ly:music-property e 'types)))
(count (ly:music-property music 'repeat-count))
(ly:intlog2 count)) dot-shift)
(if seq-arg?
- (ly:music-compress e (ly:make-moment (length (ly:music-property e 'elements)) 1)))))
+ (ly:music-compress e (ly:make-moment (length (ly:music-property
+ e 'elements)) 1)))))))
- (set! (ly:music-property music 'length-callback)
- Repeated_music::unfolded_music_length)
- (set! (ly:music-property music 'start-callback)
- Repeated_music::first_start)
- (set! (ly:music-property music 'iterator-ctor)
- Unfolded_repeat_iterator::constructor)))
(if (pair? es)
(set! (ly:music-property music 'elements)
(define-public (make-grob-property-revert grob gprop)
"Revert the grob property GPROP for GROB."
- (make-music 'OverrideProperty
+ (make-music 'RevertProperty
'symbol grob
'grob-property gprop))
(define direction-polyphonic-grobs
- '(Stem Tie Rest Slur Script TextScript Dots DotColumn Fingering))
+ '(Stem Tie Rest Slur PhrasingSlur Script TextScript Dots DotColumn Fingering))
(define-safe-public (make-voice-props-set n)
(make-sequential-music
"Check if we have R1*4-\\markup { .. }, and if applicable convert to
a property set for MultiMeasureRestNumber."
(define (script-to-mmrest-text script-music)
- "Extract 'direction and 'text from SCRIPT-MUSIC, and transform into property sets."
+ "Extract 'direction and 'text from SCRIPT-MUSIC, and transform MultiMeasureTextEvent"
(let ((dir (ly:music-property script-music 'direction))
(p (make-music 'MultiMeasureTextEvent
'text (ly:music-property script-music 'text))))
(if (ly:dir? dir)
(set! (ly:music-property p 'direction) dir))
p))
+
(if (eq? (ly:music-property music 'name) 'MultiMeasureRestMusicGroup)
(let* ((text? (lambda (x) (memq 'script-event (ly:music-property x 'types))))
- (es (ly:music-property music 'elements))
- (texts (map script-to-mmrest-text (filter text? es)))
- (others (remove text? es)))
- (if (pair? texts)
+ (event? (lambda (x) (memq 'event (ly:music-property x 'types))))
+ (group-elts (ly:music-property music 'elements))
+ (texts '())
+ (events '())
+ (others '()))
+
+ (set! texts
+ (map script-to-mmrest-text (filter text? group-elts)))
+ (set! group-elts
+ (remove text? group-elts))
+
+ (set! events (filter event? group-elts))
+ (set! others (remove event? group-elts))
+
+ (if (or (pair? texts) (pair? events))
(set! (ly:music-property music 'elements)
- (cons (make-event-chord texts) others)))))
+ (cons (make-event-chord
+ (append texts events))
+ others)))
+
+ ))
+
music)
(set! (ly:music-property m 'procedure) checker)
m))
+
+(define-public (skip->rest mus)
+
+ "Replace MUS by RestEvent of the same duration if it is a
+SkipEvent. Useful for extracting parts from crowded scores"
+
+ (if (equal? (ly:music-property mus 'name) 'SkipEvent)
+ (make-music 'RestEvent 'duration (ly:music-property mus 'duration))
+ mus))
+
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; warn for bare chords at start.
(equal? (ly:music-property x 'name) 'RequestChord))
elts)))
-(define (ly:music-message music msg)
+(define-public (ly:music-message music msg)
(let ((ip (ly:music-property music 'origin)))
(if (ly:input-location? ip)
(ly:input-message ip msg)
(ly:music-length music))
music)
+(define (skip-to-last music parser)
+
+ "Replace MUSIC by
+
+<< { \\set skipTypesetting = ##t
+ LENGTHOF(\\showLastLength)
+ \\set skipTypesetting = ##t }
+ MUSIC >>
+
+if appropriate.
+ "
+ (let*
+ ((show-last (ly:parser-lookup parser 'showLastLength)))
+
+ (if (ly:music? show-last)
+ (let*
+ ((orig-length (ly:music-length music))
+ (skip-length (ly:moment-sub orig-length (ly:music-length show-last))))
+
+ (make-simultaneous-music
+ (list
+ (make-sequential-music
+ (list
+ (context-spec-music (make-property-set 'skipTypesetting #t) 'Score)
+ (make-music 'SkipMusic 'duration
+ (ly:make-duration 0 0
+ (ly:moment-main-numerator skip-length)
+ (ly:moment-main-denominator skip-length)))
+ (context-spec-music (make-property-set 'skipTypesetting #f) 'Score)))
+ music)))
+ music)))
+
+
(define-public toplevel-music-functions
(list
(lambda (music parser) (voicify-music music))
;; switch-on-debugging
(lambda (x parser) (music-map cue-substitute x))
-; (lambda (x parser) (music-map display-scheme-music x))
-
- ))
+
+ (lambda (x parser)
+ (skip-to-last x parser)
+ )))
;;;;;;;;;;;;;;;;;
;; lyrics
(define-public ((add-balloon-text object-name text off) grob orig-context cur-context)
"Usage: see input/regression/balloon.ly "
(let* ((meta (ly:grob-property grob 'meta))
- (nm (if (pair? meta) (cdr (assoc 'name meta)) "nonexistant"))
- (cb (ly:grob-property grob 'print-function)))
- (if (equal? nm object-name)
+ (cb (ly:grob-property-data grob 'stencil))
+ (nm (if (pair? meta) (cdr (assoc 'name meta)) "nonexistant")))
+ (if (and (equal? nm object-name)
+ (procedure? cb))
(begin
- (set! (ly:grob-property grob 'print-function) Balloon_interface::print)
- (set! (ly:grob-property grob 'balloon-original-callback) cb)
+ (ly:grob-set-property! grob 'stencil ly:balloon-interface::print)
+ (set! (ly:grob-property grob 'original-stencil) cb)
(set! (ly:grob-property grob 'balloon-text) text)
(set! (ly:grob-property grob 'balloon-text-offset) off)
(set! (ly:grob-property grob 'balloon-text-props) '((font-family . roman)))))))
(ly:make-duration 0 0) '())))
(ly:music-compress skip (ly:music-length mus))
skip))
+
+(define-public (pitch-of-note event-chord)
+
+ (let*
+ ((evs (filter (lambda (x) (memq 'note-event (ly:music-property x 'types)))
+ (ly:music-property event-chord 'elements))))
+
+ (if (pair? evs)
+ (ly:music-property (car evs) 'pitch)
+ #f)))
+