+propertyOverride =
+#(define-music-function (grob-property-path value)
+ (key-list? scheme?)
+ (_i "Set the grob property specified by @var{grob-property-path} to
+@var{value}. @var{grob-property-path} is a symbol list of the form
+@code{Context.GrobName.property} or @code{GrobName.property}, possibly
+with subproperties given as well. This music function is mostly intended
+for use from Scheme as a substitute for the built-in @code{\\override}
+command.")
+ (let ((p (check-grob-path grob-property-path (*location*)
+ #:default 'Bottom
+ #:min 3)))
+ (if p
+ (context-spec-music
+ (make-music 'OverrideProperty
+ 'symbol (cadr p)
+ 'origin (*location*)
+ 'grob-value value
+ 'grob-property-path (cddr p)
+ 'pop-first #t)
+ (car p))
+ (make-music 'Music))))
+
+propertyRevert =
+#(define-music-function (grob-property-path)
+ (key-list?)
+ (_i "Revert the grob property specified by @var{grob-property-path} to
+its previous value. @var{grob-property-path} is a symbol list of the form
+@code{Context.GrobName.property} or @code{GrobName.property}, possibly
+with subproperties given as well. This music function is mostly intended
+for use from Scheme as a substitute for the built-in @code{\\revert}
+command.")
+ (let ((p (check-grob-path grob-property-path (*location*)
+ #:default 'Bottom
+ #:min 3)))
+ (if p
+ (context-spec-music
+ (make-music 'RevertProperty
+ 'symbol (cadr p)
+ 'origin (*location*)
+ 'grob-property-path (cddr p))
+ (car p))
+ (make-music 'Music))))
+
+propertySet =
+#(define-music-function (property-path value)
+ (symbol-list-or-symbol? scheme?)
+ (_i "Set the context property specified by @var{property-path} to
+@var{value}. This music function is mostly intended for use from
+Scheme as a substitute for the built-in @code{\\set} command.")
+ (let ((p (check-context-path property-path (*location*))))
+ (if p
+ (context-spec-music
+ (make-music 'PropertySet
+ 'symbol (cadr p)
+ 'value value
+ 'origin (*location*))
+ (car p))
+ (make-music 'Music))))
+
+propertyTweak =
+#(define-music-function (prop value item)
+ (key-list-or-symbol? scheme? key-list-or-music?)
+ (_i "Add a tweak to the following @var{item}, usually music.
+This generally behaves like @code{\\tweak} but will turn into an
+@code{\\override} when @var{item} is a symbol list.
+
+In that case, @var{item} specifies the grob path to override. This is
+mainly useful when using @code{\\propertyTweak} as as a component for
+building other functions like @code{\\omit}. It is not the default
+behavior for @code{\\tweak} since many input strings in
+@code{\\lyricmode} can serve equally as music or as symbols which
+causes surprising behavior when tweaking lyrics using the less
+specific semantics of @code{\\propertyTweak}.
+
+@var{prop} can contain additional elements in which case a nested
+property (inside of an alist) is tweaked.")
+ ;; Why not instead make the parser treat strings preferably as
+ ;; music in lyrics mode rather than as symbol? Because then
+ ;;
+ ;; \tweak text "whatever" mylyrics
+ ;;
+ ;; will try putting a lyric event with text "whatever" in the text
+ ;; property of lyrics. So we want expressions allowing both
+ ;; strings and lyrics to deliver strings: more complex conversions
+ ;; should only be attempted when the simple uses don't match the
+ ;; given predicate.
+ (if (ly:music? item)
+ (if (music-is-of-type? item 'context-specification)
+ ;; This is essentially dealing with the case
+ ;; \propertyTweak color #red \propertyTweak font-size #3 NoteHead
+ ;; namely when stacked tweaks end in a symbol list
+ ;; rather than a music expression.
+ ;;
+ ;; We have a tweak here to convert into an override,
+ ;; so we need to know the grob to apply it to. That's
+ ;; easy if we have a directed tweak, and otherwise we
+ ;; need to find the symbol in the expression itself.
+ (let* ((p (check-grob-path prop (*location*)
+ #:start 1
+ #:default #t
+ #:min 2))
+ (elt (ly:music-property item 'element))
+ (seq (if (music-is-of-type? elt 'sequential-music)
+ elt
+ (make-sequential-music (list elt))))
+ (elts (ly:music-property seq 'elements))
+ (symbol (if (symbol? (car p))
+ (car p)
+ (and (pair? elts)
+ (ly:music-property (car elts)
+ 'symbol)))))
+ (if (symbol? symbol)
+ (begin
+ (set! (ly:music-property seq 'elements)
+ (cons (make-music 'OverrideProperty
+ 'symbol symbol
+ 'grob-property-path (cdr p)
+ 'pop-first #t
+ 'grob-value value
+ 'origin (*location*))
+ elts))
+ (set! (ly:music-property item 'element) seq))
+ (begin
+ (ly:parser-error (_ "Cannot \\propertyTweak")
+ (*location*))
+ (ly:music-message item (_ "untweakable"))))
+ item)
+ (tweak prop value item))
+ (propertyOverride (append item (if (symbol? prop) (list prop) prop))
+ value)))
+
+propertyUnset =
+#(define-music-function (property-path)
+ (symbol-list-or-symbol?)
+ (_i "Unset the context property specified by @var{property-path}.
+This music function is mostly intended for use from Scheme as a
+substitute for the built-in @code{\\unset} command.")
+ (let ((p (check-context-path property-path (*location*))))
+ (if p
+ (context-spec-music
+ (make-music 'PropertyUnset
+ 'symbol (cadr p)
+ 'origin (*location*))
+ (car p))
+ (make-music 'Music))))
+
+pushToTag =
+#(define-music-function (tag more music)
+ (symbol? ly:music? ly:music?)
+ (_i "Add @var{more} to the front of @code{elements} of all music
+expressions in @var{music} that are tagged with @var{tag}.")
+ (music-map (lambda (m)
+ (if (memq tag (ly:music-property m 'tags))
+ (set! (ly:music-property m 'elements)
+ (cons more (ly:music-property m 'elements))))
+ m)
+ music))
+
+quoteDuring =
+#(define-music-function (what main-music) (string? ly:music?)
+ (_i "Indicate a section of music to be quoted. @var{what} indicates the name
+of the quoted voice, as specified in an @code{\\addQuote} command.
+@var{main-music} is used to indicate the length of music to be quoted;
+usually contains spacers or multi-measure rests.")
+ (make-music 'QuoteMusic
+ 'element main-music
+ 'quoted-music-name what))
+
+reduceChords =
+#(define-music-function (music) (ly:music?)
+ (_i "Reduce chords contained in @var{music} to single notes,
+intended mainly for reusing music in RhythmicStaff. Does not
+reduce parallel music.")
+ (event-chord-reduce music))
+
+relative =
+#(define-music-function (pitch music)
+ ((ly:pitch?) ly:music?)
+ (_i "Make @var{music} relative to @var{pitch}. If @var{pitch} is
+omitted, the first note in @var{music} is given in absolute pitch.")
+ ;; When \relative has no clear decision (can only happen with
+ ;; scales with an even number of steps), it goes down (see
+ ;; pitch.cc). The following formula puts out f for both the normal
+ ;; 7-step scale as well as for a "shortened" scale missing the
+ ;; final b. In either case, a first note of c will end up as c,
+ ;; namely pitch (-1, 0, 0).
+ (ly:make-music-relative! music
+ (or pitch
+ (ly:make-pitch
+ -1
+ (quotient
+ ;; size of current scale:
+ (ly:pitch-steps (ly:make-pitch 1 0))
+ 2))))
+ (make-music 'RelativeOctaveMusic
+ 'element music))
+
+removeWithTag =
+#(define-music-function (tags music)
+ (symbol-list-or-symbol? ly:music?)
+ (_i "Remove elements of @var{music} that are tagged with one of the
+tags in @var{tags}. @var{tags} may be either a single symbol or a list
+of symbols.")
+ (music-filter
+ (tags-remove-predicate tags)
+ music))
+
+resetRelativeOctave =
+#(define-music-function (pitch) (ly:pitch?)
+ (_i "Set the octave inside a \\relative section.")
+
+ (make-music 'SequentialMusic
+ 'to-relative-callback
+ (lambda (music last-pitch) pitch)))
+
+retrograde =
+#(define-music-function (music)
+ (ly:music?)
+ (_i "Return @var{music} in reverse order.")
+ (retrograde-music
+ (expand-repeat-notes!
+ (expand-repeat-chords!
+ (cons 'rhythmic-event
+ (ly:parser-lookup '$chord-repeat-events))
+ music))))
+
+revertTimeSignatureSettings =
+#(define-music-function
+ (time-signature)
+ (pair?)