2.9 Difficult tweaks (Extending LilyPond)

### 2.9 Difficult tweaks

There are a few classes of difficult adjustments.

- One type of difficult adjustment involves the appearance of spanner objects, such as slurs and ties. Usually, only one spanner object is created at a time, and it can be adjusted with the normal mechanism. However, occasionally a spanner crosses a line break. When this happens, the object is cloned. A separate object is created for every system in which the spanner appears. The new objects are clones of the original object and inherit all properties, including `\override`s.

  In other words, an `\override` always affects all pieces of a broken spanner. To change only one part of a spanner at a line break, it is necessary to hook into the formatting process. The `after-line-breaking` callback contains the Scheme procedure that is called after the line breaks have been determined and layout objects have been split over different systems.

  In the following example, we define a procedure `my-callback`. This procedure

  - − determines if the spanner has been split across line breaks
  - − if yes, retrieves all the split objects
  - − checks if this grob is the last of the split objects
  - − if yes, it sets `extra-offset`.

  This procedure is installed into Tie, so the last part of the broken tie is repositioned.

  >     #(define (my-callback grob)
  >        (let* (
  >               ;; have we been split?
  >               (orig (ly:grob-original grob))

  >               ;; if yes, get the split pieces (our siblings)
  >               (siblings (if (ly:grob? orig)
  >                             (ly:spanner-broken-into orig)
  >                             '())))

  >          (if (and (>= (length siblings) 2)
  >                   (eq? (car (last-pair siblings)) grob))
  >              (ly:grob-set-property! grob 'extra-offset '(1 . -4)))))

  >     \relative {
  >       \override Tie.after-line-breaking =
  >       #my-callback
  >       c''1 ~ \break
  >       c2 ~ 2
  >     }

  When applying this trick, the new `after-line-breaking` callback should also call the old one, if such a default exists. For example, if using this with `Hairpin`, `ly:spanner::kill-zero-spanned-time` should also be called.

- Some objects cannot be changed with `\override` for technical reasons. They can be changed with the `\overrideProperty` function, which works similar to `\once \override`, but uses a different syntax.2

      \overrideProperty [ContextName].GrobName.property-name[.subproperty-name] value

#### Footnotes

##### (2)

Over time, `\overrideProperty` is being replaced with the more usual `\once \override` command. If you still find yourself needing `\overrideProperty`, a bug report would be appreciated.

#### 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