1.3.4 Doubling a note with slurs (example) (Extending LilyPond)

#### 1.3.4 Doubling a note with slurs (example)

Suppose we want to create a function that translates input like `a` into `{ a( a) }`. We begin by examining the internal representation of the desired result.

    \displayMusic{ a'( a') }
    ===>
    (make-music
      'SequentialMusic
      'elements
      (list (make-music
              'NoteEvent
              'articulations
              (list (make-music
                      'SlurEvent
                      'span-direction
                      -1))
              'duration
              (ly:make-duration 2 0 1/1)
              'pitch
              (ly:make-pitch 0 5 0))
            (make-music
              'NoteEvent
              'articulations
              (list (make-music
                      'SlurEvent
                      'span-direction
                      1))
              'duration
              (ly:make-duration 2 0 1/1)
              'pitch
              (ly:make-pitch 0 5 0))))

The bad news is that the `SlurEvent` expressions must be added ‘inside’ the note (in its `articulations` property).

Now we examine the input.

    \displayMusic a'
    ===>
    (make-music
      'NoteEvent
      'duration
      (ly:make-duration 2 0 1/1)
      'pitch
      (ly:make-pitch 0 5 0))))

So in our function, we need to clone this expression (so that we have two notes to build the sequence), add a `SlurEvent` to the `'articulations` property of each one, and finally make a `SequentialMusic` with the two `NoteEvent` elements. For adding to a property, it is useful to know that an unset property is read out as `'()`, the empty list, so no special checks are required before we put another element at the front of the `articulations` property.

    doubleSlur = #(define-music-function (note) (ly:music?)
             "Return: { note ( note ) }.
             `note` is supposed to be a single note."
             (let ((note2 (ly:music-deep-copy note)))
               (set! (ly:music-property note 'articulations)
                     (cons (make-music 'SlurEvent 'span-direction -1)
                           (ly:music-property note 'articulations)))
               (set! (ly:music-property note2 'articulations)
                     (cons (make-music 'SlurEvent 'span-direction 1)
                           (ly:music-property note2 'articulations)))
               (make-music 'SequentialMusic 'elements (list note note2))))

#### Extending LilyPond v2.26.0 (stable-branch).

- 1 Scheme tutorial
  - 1.1 Introduction to Scheme
    - 1.1.1 Scheme sandbox
    - 1.1.2 Scheme variables
    - 1.1.3 Scheme simple data types
    - 1.1.4 Scheme compound data types
      - Pairs
      - Lists
      - Association lists (alists)
      - Hash tables
    - 1.1.5 Calculations in Scheme
    - 1.1.6 Scheme procedures
      - Defining procedures
      - Predicates
      - Return values
    - 1.1.7 Scheme conditionals
      - if
      - cond
  - 1.2 Scheme in LilyPond
    - 1.2.1 LilyPond Scheme syntax
    - 1.2.2 LilyPond variables
    - 1.2.3 Debugging Scheme code
    - 1.2.4 Input variables and Scheme
    - 1.2.5 Importing Scheme in LilyPond
    - 1.2.6 Object properties
    - 1.2.7 LilyPond compound variables
      - Offsets
      - Fractions
      - Extents
      - Property alists
      - Alist chains
    - 1.2.8 LilyPond’s box model
    - 1.2.9 Internal music representation
  - 1.3 Building complicated functions
    - 1.3.1 A first approach (example)
    - 1.3.2 Displaying music expressions
    - 1.3.3 Music properties
    - 1.3.4 Doubling a note with slurs (example)
    - 1.3.5 Adding articulation to notes (example)
- 2 Interfaces for programmers
  - 2.1 LilyPond code blocks
  - 2.2 Scheme functions
    - 2.2.1 Scheme function definitions
    - 2.2.2 Scheme function usage
    - 2.2.3 Void Scheme functions
  - 2.3 Music functions
    - 2.3.1 Music function definitions
    - 2.3.2 Music function usage
    - 2.3.3 Simple substitution functions
    - 2.3.4 Intermediate substitution functions
    - 2.3.5 Mathematics in functions
    - 2.3.6 Functions without arguments
    - 2.3.7 Void music functions
  - 2.4 Event functions
  - 2.5 Markup functions
    - 2.5.1 Markup construction in Scheme
    - 2.5.2 How markups work internally
    - 2.5.3 New markup command definition
      - Markup command definition syntax
      - On properties
      - A complete example
      - Adapting builtin commands
      - Converting markups to strings
    - 2.5.4 New markup list command definition
  - 2.6 Contexts for programmers
    - 2.6.1 Context evaluation
    - 2.6.2 Running a function on all layout objects
  - 2.7 Callback functions
  - 2.8 Unpure-pure containers
  - 2.9 Difficult tweaks
- 3 LilyPond Scheme interfaces
- Appendix A GNU Free Documentation License
- Appendix B Index