;; TODO: use separate module for syntax
;; constructors. Also create wrapper around the constructor?
-(define define-ly-syntax define-public)
+(defmacro define-ly-syntax (args . body)
+ `(define-public ,args ,(cons 'begin body)))
;; A ly-syntax constructor takes two extra parameters, parser and
;; location. These are mainly used for reporting errors and
;; location arg to set the origin of the returned music object; this
;; behaviour is usually desired
(defmacro define-ly-syntax-loc (args . body)
- (primitive-eval `(define-ly-syntax ,args
- (let ((m ,(cons 'begin body)))
- (set! (ly:music-property m 'origin) ,(third args))
- m))))
-
+ `(define-public ,args
+ (let ((m ,(cons 'begin body)))
+ (set! (ly:music-property m 'origin) ,(third args))
+ m)))
;; Like define-ly-syntax-loc, but adds parser and location
;; parameters. Useful for simple constructors that don't need to
;; report errors.
(defmacro define-ly-syntax-simple (args . body)
- (primitive-eval `(define-ly-syntax ,(cons* (car args)
- 'parser
- 'location
- (cdr args))
- (let ((m ,(cons 'begin body)))
- (set! (ly:music-property m 'origin) location)
- m))))
+ `(define-public ,(cons* (car args)
+ 'parser
+ 'location
+ (cdr args))
+ (let ((m ,(cons 'begin body)))
+ (set! (ly:music-property m 'origin) location)
+ m)))
;; Music function: Apply function and check return value.
(define-ly-syntax-loc (music-function parser loc fun args)
'element (ly:music-transpose music pitch)))
(define-ly-syntax-simple (tempo text duration tempo)
- (let ((props (list
- (make-property-set 'tempoWholesPerMinute
- (ly:moment-mul (ly:make-moment tempo 1)
- (ly:duration-length duration)))
- (make-property-set 'tempoUnitDuration duration)
- (make-property-set 'tempoUnitCount tempo))))
- (set! props (cons
- (if text (make-property-set 'tempoText text)
- (make-property-unset 'tempoText))
- props))
+ (let* ((range-tempo? (pair? tempo))
+ (tempo-count (if range-tempo?
+ (round (/ (+ (car tempo) (cdr tempo)) 2))
+ tempo))
+ (props (list
+ (make-property-set 'tempoWholesPerMinute
+ (ly:moment-mul (ly:make-moment tempo-count 1)
+ (ly:duration-length duration)))
+ (make-property-set 'tempoUnitDuration duration)
+ (make-property-set 'tempoUnitCount tempo))))
+ (set! props (cons
+ (if text (make-property-set 'tempoText text)
+ (make-property-unset 'tempoText))
+ props))
(context-spec-music
- (make-sequential-music props)
- 'Score)))
+ (make-sequential-music props)
+ 'Score)))
(define-ly-syntax-simple (tempoText text)
(context-spec-music
'origin loc)))
addlyrics-list)))
(make-simultaneous-music (cons voice lyricstos))))
+
+(define-ly-syntax (make-mark-set parser location label)
+ "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))
+ (ch (make-event-chord (list ev))))
+
+ (set! (ly:music-property ev 'origin) location)
+ (if set
+ (make-sequential-music (list set ch))
+ (begin
+ (set! (ly:music-property ev 'label) label)
+ ch))))
+
+(define-ly-syntax (partial parser location dur)
+ "Make a partial measure."
+
+ ;; We use `descend-to-context' here instead of `context-spec-music' to
+ ;; ensure \partial still works if the Timing_translator is moved
+ (descend-to-context
+ (context-spec-music (make-music 'PartialSet
+ 'origin location
+ 'partial-duration dur)
+ 'Timing)
+ 'Score))