| [ << Interfaces for programmers ] | [Top][Contents][Index] | [ LilyPond Scheme interfaces >> ] |
| [ < Adapting builtin commands ] | [ Up: New markup command definition ] | [ New markup list command definition > ] |
Converting markups to strings
Markups are occasionally converted to plain strings, such as when
outputting PDF metadata based on the title header field or
for converting lyrics to MIDI. This conversion is inherently
lossy, but tries to as accurate as feasible. The function used
for this is markup->string.
composerName = \markup \box "Arnold Schönberg" \markup \composerName \markup \typewriter #(markup->string composerName)![]()
For custom markup commands, the default behavior is to convert all markup or markup list arguments first, and join the results by spaces.
#(define-markup-command (authors-and layout props authorA authorB) (markup? markup?) (interpret-markup layout props #{ \markup \fill-line { \box #authorA and \box #authorB } #})) defaultBehavior = \markup \authors-and "Bertolt Brecht" "Kurt Weill" \markup \defaultBehavior \markup \typewriter #(markup->string defaultBehavior)![]()
markup->string can also receive the named arguments
#:layout layout and #:props props, with
the same meaning as in the definition of a markup command.
However, they are optional because they cannot always be provided
(such as the layout argument when converting to MIDI).
To support special conversions in custom markup commands, the
#:as-string parameter can be given to
define-markup-command. It expects an expression, which is
evaluated by markup->string in order to yield the string
result.
#(define-markup-command (authors-and layout props authorA authorB) (markup? markup?) #:as-string (format #f "~a and ~a" (markup->string authorA #:layout layout #:props props) (markup->string authorB #:layout layout #:props props)) (interpret-markup layout props #{ \markup \fill-line { \box #authorA and \box #authorB } #})) customized = \markup \authors-and "Bertolt Brecht" "Kurt Weill" \markup \customized \markup \typewriter #(markup->string customized)![]()
Within the expression, the same bindings are available as in the
main markup command body, namely layout and props,
the command argument, and optionally the properties.
#(define-markup-command (authors-and layout props authorA authorB) (markup? markup?) #:properties ((author-separator " and ")) #:as-string (format #f "~a~a~a" (markup->string authorA #:layout layout #:props props) (markup->string author-separator #:layout layout #:props props) (markup->string authorB #:layout layout #:props props)) (interpret-markup layout props #{ \markup { \box #authorA #author-separator \box #authorB } #})) customized = \markup \override #'(author-separator . ", ") \authors-and "Bertolt Brecht" "Kurt Weill" \markup \customized \markup \typewriter #(markup->string customized)![]()
Most often, a custom handler only needs to call
markup->string recursively on certain arguments, as
demonstrated above. However, it can also make use of the
layout and props directly, in the same way as in the
main body. Care must be taken that the layout argument is
#f if no #:layout has been given to
markup->string. The props argument defaults to the
empty list.
| [ << Interfaces for programmers ] | [Top][Contents][Index] | [ LilyPond Scheme interfaces >> ] |
| [ < Adapting builtin commands ] | [ Up: New markup command definition ] | [ New markup list command definition > ] |
![[image of music]](../a8/lily-af8467fa.png)
![[image of music]](../b2/lily-ba237c2c.png)
![[image of music]](../5a/lily-9af01667.png)
![[image of music]](../3e/lily-27fb5135.png)