-(define-ly-syntax (property-operation parser location ctx music-type symbol . args)
- (let* ((props (case music-type
- ((PropertySet) (list 'value (car args)))
- ((PropertyUnset) '())
- ((OverrideProperty) (list 'grob-value (car args)
- 'grob-property-path (if (list? (cadr args))
- (cadr args)
- (cdr args))
- 'pop-first #t))
- ((RevertProperty)
- (if (list? (car args))
- (list 'grob-property-path (car args))
- (list 'grob-property-path args)))
- (else (ly:error (_ "Invalid property operation ~a") music-type))))
- (m (apply make-music music-type
- 'symbol symbol
- 'origin location
- props)))
- (make-music 'ContextSpeccedMusic
- 'element m
- 'context-type ctx
- 'origin location)))
-
-;; TODO: It seems that this function rarely returns anything useful.
-(define (get-first-context-id type mus)
- "Find the name of a ContextSpeccedMusic with given type"
+(define-public (partial-markup commands)
+ ;; Like composed-markup-list, except that the result is a single
+ ;; markup command that can be applied to one markup
+ (define (compose rest)
+ (fold
+ (lambda (cmd prev) (append cmd (list prev)))
+ (append (car commands) rest)
+ (cdr commands)))
+ (let ((chain (lambda (layout props . rest)
+ (interpret-markup layout props (compose rest)))))
+ (set! (markup-command-signature chain)
+ (list-tail
+ (markup-command-signature (caar commands))
+ (length (cdar commands))))
+ chain))
+
+(define-public (property-set context property value)
+ (ly:set-origin! (context-spec-music
+ (ly:set-origin!
+ (make-music 'PropertySet
+ 'symbol property
+ 'value value))
+ context)))
+
+(define-public (property-unset context property)
+ (ly:set-origin! (context-spec-music
+ (ly:set-origin!
+ (make-music 'PropertyUnset
+ 'symbol property))
+ context)))
+
+(define-public (property-override context path value)
+ (ly:set-origin! (context-spec-music
+ (ly:set-origin!
+ (make-music 'OverrideProperty
+ 'symbol (car path)
+ 'grob-property-path (cdr path)
+ 'grob-value value
+ 'pop-first #t))
+ context)))
+
+(define-public (property-revert context path)
+ (ly:set-origin! (context-spec-music
+ (ly:set-origin!
+ (make-music 'RevertProperty
+ 'symbol (car path)
+ 'grob-property-path (cdr path)))
+ context)))
+
+;; The signature here is slightly fishy since the "fallback return
+;; value" is not actually music but #f. This used to be (void-music)
+;; but triggered "Parsed object should be dead" warnings for music
+;; objects outside of the current parser session/module. The called
+;; functions always deliver music and are used from the parser in a
+;; manner where only the last argument is provided from outside the
+;; parser, and its predicate "scheme?" is always true. So the
+;; fallback value will never get used and its improper type is no
+;; issue.
+(define-public property-override-function
+ (ly:make-music-function
+ (list (cons ly:music? #f) symbol? symbol-list? scheme?)
+ property-override))
+
+(define-public property-set-function
+ (ly:make-music-function
+ (list (cons ly:music? #f) symbol? symbol? scheme?)
+ property-set))
+
+(define (get-first-context-id! mus)
+ "Find the name of a ContextSpeccedMusic, possibly naming it"