#### C.2.2 Markup command definition

New markup commands can be defined with the `def-markup-command` scheme macro.

         (def-markup-command (command-name paper props arg1 arg2 ...)
                     (arg1-type? arg2-type? ...)
           ..command body..)

The arguments signify

argi
  ith command argument
argi-type?
  a type predicate for the ith argument
paper
  the `paper' definition
props
  a list of alists, containing all active properties.

As a simple example, we show how to add a `\smallcaps` command, which selects TeX's small caps font. Normally, we could select the small caps font as follows:

      \markup { \override #'(font-shape . caps)  Text-in-caps }

This selects the caps font by setting the `font-shape` property to `#'caps` for interpreting `Text-in-caps`.

To make the above available as `\smallcaps` command, we have to define a function using `def-markup-command`. The command should take a single argument, of markup type. Therefore, the start of the definition should read

           (def-markup-command (smallcaps paper props argument) (markup?)

What follows is the content of the command: we should interpret the `argument` as a markup, i.e.

             (interpret-markup paper  ... argument)

This interpretation should add `'(font-shape . caps)` to the active properties, so we substitute the following for the ... in the above example:

          (cons (list '(font-shape . caps) ) props)

The variable `props` is a list of alists, and we prepend to it by consing a list with the extra setting.

Suppose that we are typesetting a recitative in an opera, and we would like to define a command that will show character names in a custom manner. Names should be printed with small caps and translated a bit to the left and top. We will define a `\character` command that takes into account the needed translation, and uses the newly defined `\smallcaps` command:

    #(def-markup-command (character paper props name) (string?)
       "Print the character name in small caps, translated to the left and
       top. Syntax: \\character #\"name\""
       (interpret-markup paper props
        (markup "" #:translate (cons -4 2) #:smallcaps name)))

There is one complication that needs explanation: texts above and below the staff are moved vertically to be at a certain distance (the `padding` property) from the staff and the notes. To make sure that this mechanism does not annihilate the vertical effect of our `#:translate`, we add an empty string (`""`) before the translated text. Now the `""` will be put above the notes, and the `name` is moved in relation to that empty string. The net effect is that the text is moved to the upper left.

The final result is as follows:

    \score {
        \notes { \fatText
            c''^\markup \character #"Cleopatra"
            e'^\markup \character #"Giulio Cesare"
        }
    }

We have used the `caps` font shape, but suppose that our font that does not have a small-caps variant. In that case, we have to fake the small caps font, by setting a string in upcase, with the first letter a little larger:

         #(def-markup-command (smallcaps paper props str) (string?)
            "Print the string argument in small caps."
            (interpret-markup paper props
             (make-line-markup
              (map (lambda (s)
                     (if (= (string-length s) 0)
                         s
                         (markup #:large (string-upcase (substring s 0 1))
                                 #:translate (cons -0.6 0)
                                 #:tiny (string-upcase (substring s 1)))))
                   (string-split str #\Space)))))

The `smallcaps` command first splits its string argument into tokens separated by spaces (`(string-split str #\Space)`); for each token, a markup is built with the first letter made large and upcased (`#:large (string-upcase (substring s 0 1))`), and a second markup built with the following letters made tiny and upcased (`#:tiny (string-upcase (substring s 1))`). As LilyPond introduces a space between markups on a line, the second markup is translated to the left (`#:translate (cons -0.6 0) ...`). Then, the markups built for each token are put in a line by `(make-line-markup ...)`. Finally, the resulting markup is passed to the `interpret-markup` function, with the `paper` and `props` arguments.

Read comments on this page, or add one. This page is for LilyPond-2.2.2 (stable-branch).