- (let* ((elements (ly:music-property chord 'elements))
- (simple-elements (filter (make-music-type-predicate
- 'NoteEvent 'ClusterNoteEvent 'RestEvent
- 'MultiMeasureRestEvent 'SkipEvent 'LyricEvent)
- elements)))
- (if ((make-music-type-predicate 'StaffSpanEvent 'BreathingEvent) (car elements))
- ;; first, a special case: StaffSpanEvent (\startStaff, \stopStaff)
- ;; and BreathingEvent (\breathe)
- (music->lily-string (car elements) parser)
- (if (and (not (null? simple-elements))
- (null? (cdr simple-elements))
- ;; special case: if this simple_element has a HarmonicEvent in its
- ;; 'articulations list, it should be interpreted instead as a
- ;; note_chord_element, since \harmonic only works inside chords,
- ;; even for single notes, e.g., < c\harmonic >
- (null? (filter (make-music-type-predicate 'HarmonicEvent)
- (ly:music-property (car simple-elements) 'articulations))))
- ;; simple_element : note | figure | rest | mmrest | lyric_element | skip
- (let* ((simple-element (car simple-elements))
- (duration (ly:music-property simple-element 'duration))
- (lily-string (format #f "~a~a~a~{~a ~}"
- (music->lily-string simple-element parser)
- (duration->lily-string duration)
- (if (and ((make-music-type-predicate 'RestEvent) simple-element)
- (ly:pitch? (ly:music-property simple-element 'pitch)))
- "\\rest"
- "")
- (map-in-order (lambda (music)
- (music->lily-string music parser))
- (filter post-event? elements)))))
- (*previous-duration* duration)
- lily-string)
- (let ((chord-elements (filter (make-music-type-predicate
- 'NoteEvent 'ClusterNoteEvent 'BassFigureEvent)
- elements))
- (post-events (filter post-event? elements)))
- (if (not (null? chord-elements))
- ;; note_chord_element : '<' (notepitch | drumpitch)* '>" duration post_events
- (let ((lily-string (format #f "< ~{~a ~}>~a~{~a ~}"
- (map-in-order (lambda (music)
- (music->lily-string music parser))
- chord-elements)
- (duration->lily-string (ly:music-property (car chord-elements)
- 'duration))
- (map-in-order (lambda (music)
- (music->lily-string music parser))
- post-events))))
- (*previous-duration* (ly:music-property (car chord-elements) 'duration))
- lily-string)
- ;; command_element
- (format #f "~{~a ~}" (map-in-order (lambda (music)
- (music->lily-string music parser))
- elements))))))))
+ (let* ((elements (append (ly:music-property chord 'elements)
+ (ly:music-property chord 'articulations)))
+ (chord-repeat (ly:music-property chord 'duration)))
+ (call-with-values
+ (lambda ()
+ (partition (lambda (m) (music-is-of-type? m 'rhythmic-event))
+ elements))
+ (lambda (chord-elements other-elements)
+ (cond ((pair? chord-elements)
+ ;; note_chord_element :
+ ;; '<' (notepitch | drumpitch)* '>" duration post_events
+ (let ((duration (duration->lily-string (ly:music-property
+ (car chord-elements)
+ 'duration)
+ #:remember #t)))
+ ;; Format duration first so that it does not appear on
+ ;; chord elements
+ (format #f "< ~{~a ~}>~a~:{~:[-~;~]~a~^ ~}"
+ (map-in-order (lambda (music)
+ (music->lily-string music parser))
+ chord-elements)
+ duration
+ (map-in-order (lambda (music)
+ (list
+ (post-event? music)
+ (music->lily-string music parser)))
+ other-elements))))
+ ((ly:duration? chord-repeat)
+ (let ((duration (duration->lily-string chord-repeat
+ #:remember #t)))
+ (format #f "q~a~:{~:[-~;~]~a~^ ~}"
+ duration
+ (map-in-order (lambda (music)
+ (list
+ (post-event? music)
+ (music->lily-string music parser)))
+ other-elements))))
+
+ ((and (= 1 (length other-elements))
+ (not (post-event? (car other-elements))))
+ (format #f (music->lily-string (car other-elements) parser)))
+ (else
+ (format #f "< >~:{~:[-~;~]~a~^ ~}"
+ (map-in-order (lambda (music)
+ (list
+ (post-event? music)
+ (music->lily-string music parser)))
+ other-elements))))))))