%% Lyrics
\test ##[ \lyrics { a b } #]
-\test ##[ \lyricmode { a -- b } #] % HyphenEvent
-\test ##[ \lyricmode { a __ b } #] % ExtenderEvent
+\test ##[ \lyricmode { a -- b } #] % HyphenEvent
+\test ##[ \lyricmode { a __ b } #] % ExtenderEvent
\test ##[ \lyricmode { "a " } #] % LyricEvent
\test ##[ \lyricsto "foo" { bla bla } #] % LyricCombineMusic
\test ##[ { { c d }
\test ##[ c4 ~ #] % TieEvent
\test ##[ c\noBeam #] % BeamForbidEvent
\test ##[ c\1 #] % StringNumberEvent
-\test ##[ { c: c:1 } #] % TremoloEvent
-\test ##[ { c-^ c^^ c_^ } #] % ArticulationEvent
-\test ##[ { c-+ c^+ c_+ } #]
-\test ##[ { c-- c^- c_- } #]
-\test ##[ { c-| c^| c_| } #]
-\test ##[ { c-> c^> c_> } #]
-\test ##[ { c-. c^. c_. } #]
-\test ##[ { c-_ c^_ c__ } #]
-\test ##[ { c-\trill c^\trill c_\trill } #]
-\test ##[ { c-1 c^2 c_3 } #] % FingerEvent
-\test ##[ { c-"foo" c^"foo" c_"foo" } #] % TextScriptEvent
-\test ##[ { R1*4-"foo" R^"foo" R_"foo" } #] % MultiMeasureTextEvent
+\test ##[ { c: c:1 } #] % TremoloEvent
+\test ##[ { c-^ c^^ c_^ } #] % ArticulationEvent
+\test ##[ { c-+ c^+ c_+ } #]
+\test ##[ { c-- c^- c_- } #]
+\test ##[ { c-| c^| c_| } #]
+\test ##[ { c-> c^> c_> } #]
+\test ##[ { c-. c^. c_. } #]
+\test ##[ { c-_ c^_ c__ } #]
+\test ##[ { c-\trill c^\trill c_\trill } #]
+\test ##[ { c-1 c^2 c_3 } #] % FingerEvent
+\test ##[ { c-"foo" c^"foo" c_"foo" } #] % TextScriptEvent
+\test ##[ { R1*4-"foo" R^"foo" R_"foo" } #] % MultiMeasureTextEvent
\test ##[ { < c\harmonic >4 < c e\harmonic > } #] % HarmonicEvent
-\test ##[ { c-\glissando c^\glissando c_\glissando } #] % GlissandoEvent
-\test ##[ { c-\arpeggio c^\arpeggio c_\arpeggio } #] % ArpeggioEvent
-\test ##[ { c\p c^\ff c_\sfz } #] % AbsoluteDynamicEvent
-\test ##[ { c[ c] c^[ c^] c_[ c_] } #] % BeamEvent
-\test ##[ { c( c) c^( c^) c_( c_) } #] % SlurEvent
-\test ##[ { c\< c\! c^\< c^\! c_\< c_\! } #] % CrescendoEvent
-\test ##[ { c\> c\! c^\> c^\! c_\> c_\! } #] % DecrescendoEvent
-\test ##[ { c\episemInitium c\episemFinis } #] % EpisemaEvent
-\test ##[ { c\( c\) c^\( c^\) c_\( c_\) } #] % PhrasingSlurEvent
-\test ##[ { c\sustainOn c\sustainOff } #] % SustainEvent
-\test ##[ { c\sostenutoOn c\sostenutoOff } #] % SostenutoEvent
+\test ##[ { c-\glissando c^\glissando c_\glissando } #] % GlissandoEvent
+\test ##[ { c-\arpeggio c^\arpeggio c_\arpeggio } #] % ArpeggioEvent
+\test ##[ { c\p c^\ff c_\sfz } #] % AbsoluteDynamicEvent
+\test ##[ { c[ c] c^[ c^] c_[ c_] } #] % BeamEvent
+\test ##[ { c( c) c^( c^) c_( c_) } #] % SlurEvent
+\test ##[ { c\< c\! c^\< c^\! c_\< c_\! } #] % CrescendoEvent
+\test ##[ { c\> c\! c^\> c^\! c_\> c_\! } #] % DecrescendoEvent
+\test ##[ { c\episemInitium c\episemFinis } #] % EpisemaEvent
+\test ##[ { c\( c\) c^\( c^\) c_\( c_\) } #] % PhrasingSlurEvent
+\test ##[ { c\sustainOn c\sustainOff } #] % SustainEvent
+\test ##[ { c\sostenutoOn c\sostenutoOff } #] % SostenutoEvent
\test ##[ \melisma #]
\test ##[ \melismaEnd #]
-\test ##[ { c\startTextSpan c\stopTextSpan } #] % TextSpanEvent
-\test ##[ { c\startTrillSpan c\stopTrillSpan } #] % TrillSpanEvent
-\test ##[ { c \startStaff c \stopStaff } #] % StaffSpanEvent
-\test ##[ { c\startGroup c\stopGroup c^\startGroup c^\stopGroup c_\startGroup c_\stopGroup } #] % NoteGroupingEvent
-\test ##[ { c\unaCorda c\treCorde } #] % UnaCordaEvent
+\test ##[ { c\startTextSpan c\stopTextSpan } #] % TextSpanEvent
+\test ##[ { c\startTrillSpan c\stopTrillSpan } #] % TrillSpanEvent
+\test ##[ { c \startStaff c \stopStaff } #] % StaffSpanEvent
+\test ##[ { c\startGroup c\stopGroup c^\startGroup c^\stopGroup c_\startGroup c_\stopGroup } #] % NoteGroupingEvent
+\test ##[ { c\unaCorda c\treCorde } #] % UnaCordaEvent
\test ##[ \breathe #]
\test ##[ { c \[ c \] } #] % LigatureEvent
\test ##[ \~ #] % PesOrFlexaEvent
-\test ##[ { c-\bendAfter #3 } #] % BendAfterEvent
+\test ##[ { c-\bendAfter #3 } #] % BendAfterEvent
\test ##[ < c-\rightHandFinger #1 > #] % StrokeFingerEvent
\test ##[ \break #]
" containing either @code{ly:music?} predicates or other type"
" predicates. Its car is the syntax function to call.")
{
- LY_ASSERT_TYPE (ly_is_procedure, func, 1);
+ LY_ASSERT_TYPE (ly_is_list, signature, 1);
+ LY_ASSERT_TYPE (ly_is_procedure, func, 2);
+ int n=0;
+ for (SCM p = signature; scm_is_pair (p); p = scm_cdr (p), ++n)
+ {
+ SCM proc = scm_car (p);
+ if (scm_is_pair (proc))
+ proc = scm_car (proc);
+ if (scm_is_false (scm_procedure_p (proc)))
+ {
+ scm_wrong_type_arg_msg ("music-function", n, p,
+ "music function predicate");
+ }
+ }
+
return make_music_function (signature, func);
}
(chord? (make-music-type-predicate 'EventChord))
(cluster? (make-music-type-predicate 'ClusterNoteEvent))
(note? (make-music-type-predicate 'NoteEvent)))
- (format #f "~a~a{~v%~v_~{~a ~}~v%~v_}"
+ (format #f "~a~a{~v%~v_~{~a~^ ~}~v%~v_}"
(if (any (lambda (e)
(and (chord? e)
(any cluster? (ly:music-property e 'elements))))
(music->lily-string music parser))
elements))
(if force-line-break 1 0)
- (if force-line-break (*indent*) 0))))
+ (if force-line-break (*indent*) 1))))
(define-display-method SimultaneousMusic (sim parser)
(parameterize ((*indent* (+ 3 (*indent*))))
;; 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 ~}"
+ (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)
(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 ~}"
+ (let ((lily-string (format #f "< ~{~a ~}>~a~{~a~^ ~}"
(map-in-order (lambda (music)
(music->lily-string music parser))
chord-elements)
(*previous-duration* (ly:music-property (car chord-elements) 'duration))
lily-string)
;; command_element
- (format #f "~{~a ~}" (map-in-order (lambda (music)
+ (format #f "~{~a~^ ~}" (map-in-order (lambda (music)
(music->lily-string music parser))
elements))))))))
(define-display-method MultiMeasureRestMusic (mmrest parser)
(let* ((dur (ly:music-property mmrest 'duration))
- (ly (format #f "R~a~{~a ~}"
+ (ly (format #f "R~a~{~a~^ ~}"
(duration->lily-string dur)
(map-in-order (lambda (music)
(music->lily-string music parser))
(write-char x out)
x)) #f)
"r")))
+ (set-port-filename! copycat filename)
(do ((c (read-char port) (read-char port)))
((and (char=? c #\#)
(char=? (peek-char port) #\}))
;; a #scheme or $scheme expression
(if (or (char=? c #\#) (char=? c #\$))
(let* ((p (ftell out))
- (expr (read copycat)))
+ (expr
+ (begin
+ (set-port-line! copycat
+ (port-line port))
+ (set-port-column! copycat
+ (port-column port))
+ (read copycat))))
+ ;; kill unused lookahead, it has been
+ ;; written out already
+ (drain-input copycat)
;; only put symbols and non-quote
;; lists into closures -- constants
;; don't need lexical environments
(set! closures
(cons `(cons ,p (lambda () ,expr))
closures)))))))))))
- `(let* ((clone
- (ly:parser-clone parser (list ,@closures)))
- (result (ly:parse-string-expression clone ,lily-string
- ,filename
- ,line)))
- (if (ly:parser-has-error? clone)
- (ly:parser-error parser (_ "error in #{ ... #}")))
- result)))
+ (define (embedded-lilypond parser lily-string filename line closures)
+ (let* ((clone (ly:parser-clone parser closures))
+ (result (ly:parse-string-expression clone lily-string
+ filename line)))
+ (if (ly:parser-has-error? clone)
+ (ly:parser-error parser (_ "error in #{ ... #}")))
+ result))
+ (list embedded-lilypond 'parser lily-string filename line (cons 'list (reverse! closures)))))
(read-hash-extend #\{ read-lily-expression)