B.3.4 Funciones de sustitución intermedias (Extender LilyPond)

#### B.3.4 Funciones de sustitución intermedias

Las funciones de sustitución intermedias contienen una mezcla de código de Scheme y de LilyPond dentro de la expresión musical que se devuelve.

Algunas instrucciones `\override` requieren un argumento que consiste en una pareja de números (llamada una célula cons en Scheme).

La pareja se puede pasar directamente dentro de la función musical, usando una variable `pair?`:

    barraManual =
    #(define-music-function
         (principio-final)
         (pair?)
       #{
         \once \override Beam.positions = #principio-final
       #})

    \relative c' {
      \barraManual #'(3 . 6) c8 d e f
    }

De forma alternativa, los números que componen la pareja se pueden pasar como argumentos separados, y el código de Scheme que se ha usado para crear la pareja se puede incluir dentro de la expresión musical:

>     manualBeam =
>     #(define-music-function
>          (beg end)
>          (number? number?)
>        #{
>          \once \override Beam.positions = #(cons beg end)
>        #})

>     \relative c' {
>       \manualBeam #3 #6 c8 d e f
>     }

Las propiedades se mantienen conceptualmente utilizando una pila por cada propiedad, por cada grob y por cada contexto. Las funciones musicales pueden requerir la sobreescritura de una o varias propiedades durante el tiempo de duración de la función, restaurándolas a sus valores previos antes de salir. Sin embargo, las sobreescrituras normales extraen y descartan la cima de la pila de propiedades actual antes de introducir un valor en ella, de manera que el valor anterior de la propiedad se pierde cuando se sobreescribe. Si se quiere preservar el valor anterior, hay que preceder la instrucción `\override` con la palabra clave `\temporary`, así:

    \temporary \override …

El uso de `\temporary` hace que se borre la propiedad (normalmente fijada a un cierto valor) `pop-first` de la sobreescritura, de forma que el valor anterior no se extrae de la pila de propiedades antes de poner en ella el valor nuevo. Cuando una instrucción `\revert` posterior extrae el valor sobreescrito temporalmente, volverá a emerger el valor anterior.

En otras palabras, una llamada a `\temporary \override` y a continuación otra a `\revert` sobre la misma propiedad, tiene un valor neto que es nulo. De forma similar, la combinación en secuencia de `\temporary` y `\undo` sobre la misma música que contiene las sobreescrituras, tiene un efecto neto nulo.

He aquí un ejemplo de una función musical que utiliza lo expuesto anteriormente. El uso de `\temporary` asegura que los valores de las propiedades `cross-staff` y `style` se restauran a la salida a los valores que tenían cuando se llamó a la función `crossStaff`. Sin `\temporary`, a la salida se habrían fijado los valores predeterminados.

    crossStaff =
    #(define-music-function (notes) (ly:music?)
      (_i "Create cross-staff stems")
      #{
      \temporary \override Stem.cross-staff = #cross-staff-connect
      \temporary \override Flag.style = #'no-flag
      #notes
      \revert Stem.cross-staff
      \revert Flag.style
    #})

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

- Appendix A Tutorial de Scheme
  - A.1 Introducción a Scheme
    - A.1.1 Cajón de arena de Scheme
    - A.1.2 Variables de Scheme
    - A.1.3 Tipos de datos simples de Scheme
    - A.1.4 Tipos de datos compuestos de Scheme
      - Parejas
      - Listas
      - Listas asociativas (listas-A)
      - Tablas de hash
    - A.1.5 Cálculos en Scheme
    - A.1.6 Procedimientos de Scheme
      - Definir procedimientos
      - Predicados
      - Valores de retorno
    - A.1.7 Condicionales de Scheme
      - if
      - cond
  - A.2 Scheme dentro de LilyPond
    - A.2.1 Sintaxis del Scheme de LilyPond
    - A.2.2 Variables de LilyPond
    - A.2.3 Depuración del código de Scheme
    - A.2.4 Variables de entrada y Scheme
    - A.2.5 Importación de Scheme dentro de LilyPond
    - A.2.6 Propiedades de los objetos
    - A.2.7 Variables de LilyPond compuestas
      - Desplazamientos
      - Fracciones
      - Dimensiones
      - Listas-A de propiedades
      - Cadenas de listas-A
    - A.2.8 El modelo de caja de LilyPond
    - A.2.9 Representación interna de la música
  - A.3 Construir funciones complicadas
    - A.3.1 Una primera aproximación (ejemplo)
    - A.3.2 Presentación de las expresiones musicales
    - A.3.3 Propiedades musicales
    - A.3.4 Duplicar una nota con ligaduras (ejemplo)
    - A.3.5 Añadir articulaciones a las notas (ejemplo)
- B Interfaces para programadores
  - B.1 Bloques de código de LilyPond
  - B.2 Funciones de Scheme
    - B.2.1 Definición de funciones de Scheme
    - B.2.2 Uso de las funciones de Scheme
    - B.2.3 Funciones de Scheme vacías
  - B.3 Funciones musicales
    - B.3.1 Definiciones de funciones musicales
    - B.3.2 Uso de las funciones musicales
    - B.3.3 Funciones de sustitución sencillas
    - B.3.4 Funciones de sustitución intermedias
    - B.3.5 Matemáticas dentro de las funciones
    - B.3.6 Funciones sin argumentos
    - B.3.7 Funciones musicales vacías
  - B.4 Funciones de eventos
  - B.5 Funciones de marcado
    - B.5.1 Construcción de elementos de marcado en Scheme
    - B.5.2 Cómo funcionan internamente los elementos de marcado
    - B.5.3 Definición de una instrucción de marcado nueva
      - Sintaxis de la definición de instrucciones de marcado
      - Acerca de las propiedades
      - Un ejemplo completo
      - Adaptación de instrucciones incorporadas
      - Convertir elementos de marcado en cadenas
    - B.5.4 Definición de nuevas instrucciones de lista de marcado
  - B.6 Contextos para programadores
    - B.6.1 Evaluación de contextos
    - B.6.2 Ejecutar una función sobre todos los objetos de la presentación
  - B.7 Funciones de callback
  - B.8 Contenedores Unpure-pure
  - B.9 Trucos difíciles
- C Interfaces de Scheme de LilyPond
- Appendix D GNU Free Documentation License
- Appendix E Índice