(pair? markup-list?)
"Like @code{\\override}, for markup lists."
(interpret-markup-list layout (cons (list new-prop) props) args))
+
+(define-markup-list-command (map-markup-commands layout props compose args)
+ (procedure? markup-list?)
+ "This applies the function @var{compose} to every markup in
+@var{args} (including elements of markup list command calls) in order
+to produce a new markup list. Since the return value from a markup
+list command call is not a markup list but rather a list of stencils,
+this requires passing those stencils off as the results of individual
+markup calls. That way, the results should work out as long as no
+markups rely on side effects."
+ (let ((key (make-symbol "key")))
+ (catch
+ key
+ (lambda ()
+ ;; if `compose' does not actually interpret its markup
+ ;; argument, we still need to return a list of stencils,
+ ;; created from the single returned stencil
+ (list
+ (interpret-markup layout props
+ (compose
+ (make-on-the-fly-markup
+ (lambda (layout props m)
+ ;; here all effects of `compose' on the
+ ;; properties should be visible, so we
+ ;; call interpret-markup-list at this
+ ;; point of time and harvest its
+ ;; stencils
+ (throw key
+ (interpret-markup-list
+ layout props args)))
+ (make-null-markup))))))
+ (lambda (key stencils)
+ (map
+ (lambda (sten)
+ (interpret-markup layout props
+ (compose (make-stencil-markup sten))))
+ stencils)))))
;; TODO: use separate module for syntax
;; constructors. Also create wrapper around the constructor?
(defmacro define-ly-syntax (args . body)
- `(define-public ,args ,(cons 'begin body)))
+ `(define-public ,args ,@body))
;; A ly-syntax constructor takes two extra parameters, parser and
;; location. These are mainly used for reporting errors and
;; (bold (raise 4 (italic markup2)))
;; (bold (raise 4 (italic markup3))))
- (map (lambda (arg)
- (fold
- (lambda (cmd prev) (append cmd (list prev)))
- arg
- commands))
- (if (every markup? markups)
- markups
- (begin
- (ly:parser-error parser
- (format #f
- (_ "uncomposable markup list elements ~a")
- (remove markup? markups))
- location)
- (filter markup? markups)))))
+ (define (compose arg)
+ (fold
+ (lambda (cmd prev) (append cmd (list prev)))
+ arg
+ commands))
+ (let loop ((markups markups) (completed '()))
+ (cond ((null? markups) (reverse! completed))
+ ((markup? (car markups))
+ (loop (cdr markups)
+ (cons (compose (car markups)) completed)))
+ (else
+ (call-with-values
+ (lambda () (break! markup? markups))
+ (lambda (complex rest)
+ (loop rest
+ (reverse!
+ (make-map-markup-commands-markup-list
+ compose complex) completed))))))))
(define-ly-syntax (property-operation parser location ctx music-type symbol . args)
(let* ((props (case music-type