]> git.donarmstrong.com Git - lilypond.git/blobdiff - Documentation/es/extending/programming-interface.itely
Merge remote-tracking branch 'origin/translation' into staging
[lilypond.git] / Documentation / es / extending / programming-interface.itely
index f71652981391362470e350e2179050e882fe04e4..0f5a87038598d4d7b5a75e02e72345772d17b6d8 100644 (file)
@@ -1,13 +1,13 @@
 @c -*- coding: utf-8; mode: texinfo; documentlanguage: es -*-
 @c This file is part of extending.tely
 @ignore
-    Translation of GIT committish: 10bd5cc93870ac4b884b8cb938cfc6a19c768097
+    Translation of GIT committish: 6bbc01872dd4e9cced2524c378628d9219ac08ae
 
     When revising a translation, copy the HEAD committish of the
     version that you are working on.  See TRANSLATION for details.
 @end ignore
 
-@c \version "2.13.36"
+@c \version "2.19.2"
 
 @node Interfaces para programadores
 @chapter Interfaces para programadores
@@ -19,7 +19,10 @@ Scheme, @ref{Tutorial de Scheme}.
 
 
 @menu
+* Bloques de código de LilyPond::
+* Funciones de Scheme::
 * Funciones musicales::
+* Funciones de eventos::
 * Funciones de marcado::
 * Contextos para programadores::
 * Funciones de callback::
@@ -27,67 +30,347 @@ Scheme, @ref{Tutorial de Scheme}.
 * Trucos difíciles::
 @end menu
 
-@node Funciones musicales
-@section Funciones musicales
-@translationof Music functions
+@node Bloques de código de LilyPond
+@section Bloques de código de LilyPond
+@translationof LilyPond code blocks
+
+@cindex Bloques de código de LilyPond
+@cindex LilyPond, bloques de código de
+@funindex #@{ @dots{} #@}
+@funindex $
+@funindex #
+
+La creación de expresiones musicales en Scheme puede ser una tarea
+tediosa porque a veces presentan muchos niveles de profundidad de
+anidamiento y el código resultante es grande.  Para algunas tareas
+sencillas, esto puede evitarse utilizando bloques de código de
+LilyPond, que permiten usar la sintaxis ordinaria de LilyPond
+dentro de Scheme.
+
+Los bloques de código de LilyPond tienen el siguiente aspecto:
+@example
+  #@{ @var{código de LilyPond} #@}
+@end example
+
+He aquí un ejemplo trivial:
 
-Las @emph{funciones musicales} son procedimientos de Scheme
-que pueden crear automáticamente expresiones musicales, y se
-pueden usar para simplificar enormemente el archivo de entrada.
+@lilypond[verbatim,quote]
+ritpp = #(define-event-function (parser location) ()
+  #{ ^"rit." \pp #}
+)
+
+{ c'4 e'4\ritpp g'2 }
+@end lilypond
+
+Los bloques de código de LilyPond se pueden usar en cualquier
+lugar en el que se pueda escribir código de Scheme.  El lector de
+Scheme en efecto se modifica para que pueda incorporar bloques de
+código de LilyPond y pueda ocuparse de las expresiones de Scheme
+incrustadas que comienzan por @code{$} y@w{ }@code{#}.
+
+@cindex parser (function argument)
+@cindex location
+
+El lector extrae el bloque de código de LilyPond y genera una
+llamada en tiempo de ejecución al analizador sintáctico para que
+interprete el código de LilyPond.  Las expresiones de Scheme
+incrustadas en el código de LilyPond se evalúan dentro del entorno
+lóexico del bloque de código de LilyPond, de manera que puede
+accederse a todas las variables locales y los parámetros de
+función que están disponibles en el punto en que se escribe el
+bloque de código de LilyPond.  Las variables definidas en otros
+módulos de Scheme, como los módulos que contienen bloques
+@code{\header} y @code{\layout}, no están accesibles como
+variables de Scheme, es decir, precedidas de@tie{}@code{#}, pero
+se puede acceder a ellas como variables de LilyPond, es decir,
+precedidas de@tie{}@code{\}.
+
+Si @code{location} (véase @ref{Funciones de Scheme}) se refiere a una
+posición de entrada válida (como lo hace normalmente dentro de las
+funciones musicales o de Scheme), toda la música generada dentro
+del bloque de código tiene su @samp{origin} establecido a
+@code{location}.
+
+Un bloque de código de LilyPond puede contener cualquier cosa que
+podríamos utilizar en la parte derecha de una asignación.  Además, un
+bloque de LilyPond vacío corresponde a una expresión musical vacía, y
+un bloque de LilyPond que contiene varios eventos musicales se
+convierte en una expresión de música secuencial.
+
+@node Funciones de Scheme
+@section Funciones de Scheme
+@translationof Scheme functions
+@cindex Scheme, funciones de (sintaxis de LilyPond)
+
+Las @emph{funciones de Scheme} son procedimientos de Scheme que pueden
+crear expresiones de Scheme a partir de código de entrada escrito en
+la sintaxis de LilyPond.  Se pueden llamar desde prácticamente
+cualquier lugar en el que se permita el uso de @code{#} para la
+especificación de un valor en sintaxis de Scheme.  Mientras que Scheme
+tiene funciones propias, este capítulo se ocupa de las funciones
+@emph{sintácticas}, funciones que reciben argumentos especificados en
+la sintaxis de LilyPond.
 
 @menu
-* Sintaxis de las funciones musicales::
-* Funciones de sustitución sencillas::
-* Funciones de sustitución intermedias::
-* Matemáticas dentro de las funciones::
-* Funciones sin argumentos::
-* Funciones vacías::
+* Definición de funciones de Scheme::
+* Uso de las funciones de Scheme::
+* Funciones de Scheme vacías::
 @end menu
 
-@node Sintaxis de las funciones musicales
-@subsection Sintaxis de las funciones musicales
-@translationof Music function syntax
+@node Definición de funciones de Scheme
+@subsection Definición de funciones de Scheme
+@translationof Scheme function definitions
+@funindex define-scheme-function
 
-La forma general de una función musical es:
+La forma general de la definición de una función de Scheme es:
 
 @example
 funcion =
-#(define-music-function
+#(define-scheme-function
      (parser location @var{arg1} @var{arg2} @dots{})
-     (@var{type1?} @var{type2?} @dots{})
-   @var{música})
+     (@var{tipo1?} @var{tipo2?} @dots{})
+   @var{cuerpo})
 @end example
 
 @noindent
 donde
 
 @multitable @columnfractions .33 .66
+@item @code{parser}
+@tab tiene que ser literalmente @code{parser} para dar a los bloques de código
+de LilyPond (@code{#@{}@dots{}@code{#@}}) acceso al analizador
+sintáctico.
+
+@item @code{location}
+@tab tiene que ser literalmente @code{location} para ofrecer acceso al
+objeto de situación de la entrada, que se usa para ofrecer
+menssajes de error con nombres de archivo y números de línea.
+
 @item @code{@var{argN}}
 @tab @var{n}-ésimo argumento
 
 @item @code{@var{typeN?}}
 @tab un @emph{predicado de tipo} de Scheme para el que @code{@var{argN}}
-deve devolver @code{#t}.
-
-@item @code{@var{música}}
-@tab una expresión musical, opcionalmente escrita en Scheme, con
-el código de LilyPond que pudiera tener, encerrado entre llaves
-con almohadilla
-(@tie{}@w{@code{#@{@dots{}#@}}}@tie{}).  Dentro de los bloques
-de código de LilyPond, use @code{$} para referenciar a los argumentos
-de la función (p. ej. @samp{$arg1})
-o para iniciar una expresión en línea de Scheme
-que contenga argumentos de función
-(p.ej., @w{@samp{$(cons arg1 arg2)}}).
-
+debe devolver @code{#t}.
+
+También existe una forma especial @code{(@emph{predicate?}
+@emph{default})} para especificar argumentos opcionales.  Si el
+argumento actual no está presente cuando se ll ama a la función, el
+valor predeterminado se emplea en sustitución.  Los valores
+predeterminados se evalúan en tiempo de definición (¡incluyendo los
+bloques de código de LilyPond!), de manera que se necesitamos un valor
+por omisión calculado en tiempo de ejecución, debemos escribir en su
+lugar un valor especial que podamos reconocer fácilmente.  Si
+escribimos el predicado entre paréntesis pero no lo seguimos por el
+valor predeterminado, se usa @code{#f} como valor por omisión.  Los
+valores por omisión no se verifican con @emph{predicate?} en tiempo de
+definición ni en tiempo de ejecución: es nuestra responsabilidad
+tratar con los valores que especifiquemos.  Los valores por omisión
+que son expresiones musicales se copian mientras se establece
+@code{origin} al parámetro @code{location}.
+
+@item @code{@var{cuerpo}}
+@tab una secuencia de formas de Scheme que se evalúan ordenadamente; la
+última forma de la secuencia se usa como el valor de retorno de la
+función de Scheme. Puede contener bloques de código de LilyPond
+encerrados entre llaves con almohadillas
+(@tie{}@w{@code{#@{@dots{}#@}}}@tie{}), como se describe en
+@ref{Bloques de código de LilyPond}.  Dentro de los bloques de código
+de LilyPond, use el símbolo @code{#} para hacer referencia a
+argumentos de función (p.ej. @samp{#arg1}) o para iniciar una
+expresión en línea de Scheme que contenga argumentos de función
+(p.ej. @w{@samp{#(cons arg1 arg2)}}).  Donde las expresiones de Scheme
+normales que usan @code{#} no funcionan, podríamos necesitar volver a
+expresiones de Scheme inmediatas que usan @code{$}, como por ejemplo
+@samp{$music}.
+
+Si nuestra función devuelve una expresión musical, recibe un valor
+@code{origin} útil.
 @end multitable
 
 @noindent
+La idoneidad de los argumentos para los predicados viene determinada
+mediante llamadas reales al predicado después de que LilyPond ya las
+ha convertido en una expresión de Scheme.  Como consecuencia, el
+argumento se puede especificar en la sintaxis de Scheme si se desea
+(precedido de @code{#} o como resultado de haber llamado a una función
+de Scheme), pero LilyPond también convierte algunas construcciones de
+LilyPond en Scheme antes de hacer efectivamente la comprobación del
+predicado sobre ellas.  Actualmente se encuentran entre ellas la
+música, los post-eventos, las cadenas simples (entrecomilladas o no),
+los números, los elementos de marcado y de listas de marcado, score
+(partitura), book (libro), bookpart (parte de libro), las definiciones
+de contexto y los bloques de definición de salida.
+
+Para ciertos tipos de expresión (como la mayor parte de la música que
+no está encerrada entre llaves) LilyPond necesita más allá de la
+expresión misma para poder determinar su final.  Si tal expresión se
+considerase un argumento opcional mediante la evaluación de su
+predicado, LilyPond no podría recuperarse después de decidir que la
+expresión no se corresponde con el parámetro.  Así, ciertas formas de
+música necesitan ir encerradas entre llaves para poder considerarlas
+como aceptables bajo algunas circunstancias.  LilyPond resuelve
+algunas otras ambigüedades mediante la comprobación con funciones de
+predicado: ¿es @samp{-3} un post-evento de digitación o un número
+negativo?  ¿Es @code{"a" 4} en el modo de letra una cadena seguida por
+un número, o un evento de letra con la duración @code{4}?  LilyPond
+prueba el predicado del argumento sobre diversas interpretaciones
+sucesivas hasta que lo consigue, con un orden diseñado para minimizar
+las interpretaciones poco consistentes y la lectura por adelantado.
+
+Por ejemplo, un predicado que acepta tanto expresiones musicales como
+alturas consideraría que @code{c''} es una altura en lugar de una
+expresión musical.  Las duraciones o post-eventos que siguieran
+inmediatamente podrían no funcionar con dicha interpretación.  Así
+pues, es mejor evitar los predicados excesivamente permisivos como
+@code{scheme?} cuando la aplicación requeriría tipos de argumento más
+específicos.
+
 Para ver una lista de los predicados de tipo disponibles, consulte
 @ruser{Predicados de tipo predefinidos}.
-También se permiten predicados de tipo definidos por el usuario.
 
+@seealso
 
+Referencia de la notación:
+@ruser{Predicados de tipo predefinidos}.
+
+Archivos instalados:
+@file{lily/music-scheme.cc},
+@file{scm/c++.scm},
+@file{scm/lily.scm}.
+
+
+@node Uso de las funciones de Scheme
+@subsection Uso de las funciones de Scheme
+@translationof Scheme function usage
+
+Las funciones de Scheme se pueden llamar casi desde cualquier lugar en
+que puede escribirse una expresión de Scheme que comience con la
+almohadilla@tie{}@code{#}.  Llamamos a una función de Scheme
+escribiendo su nombre precedido de la barra invertida@tie{}@code{\}, y
+seguido por sus argumentos.  Una vez que un argumento opcional no
+corresponde a ningún argumento, LilyPond se salta este argumento y
+todos los que le siguen, sustituyéndolos por su valor por omisión
+especificado, y @q{recupera} el argumento que no correspondía al lugar
+del siguiente argumento obligatorio.  Dado que el argumento recuperado
+necesita ir a algún lugar, los argumentos opcionales no se consideran
+realmente opcionales a no ser que vayan seguidos de un argumento
+obligatorio.
+
+Existe una excepción: si escribimos @code{\default} en el lugar de un
+argumento opcional, este argumento y todos los argumentos opcionales
+que le siguen se saltan y se sustituyen por sus valores
+predeterminados.  Esto funciona incluso si no sigue ningún argumento
+obligatorio porque @code{\default} no necesita recuperarse.  Las
+instrucciones @code{mark} y @code{key} hacen uso de este truco para
+ofrecer su comportamiento predeterminado cuando van seguidas solamente
+por @code{\default}.
+
+Aparte de los lugares en que se requiere un valor de Scheme hay
+ciertos sitios en que se aceptan expresiones de almohadilla @code{#} y
+se evalúan por sus efectos secundarios, pero por lo demás se ignoran.
+Son, mayormente, los lugares en que también sería aceptable colocar
+una asignación.
+
+Dado que no es buena idea devolver valores que puedan malinterpretarse
+en algún contexto, debería usar funciones de Scheme normales solo para
+los casos en que siempre se devuelve un valor útil, y usar funciones
+de Scheme vacías (@pxref{Funciones de Scheme vacías}) en caso
+contrario.
+
+
+@node Funciones de Scheme vacías
+@subsection Funciones de Scheme vacías
+@translationof Void scheme functions
+@funindex define-void-function
+@funindex \void
+
+En ocasiones, un procedimiento se ejecuta con el objeto de llevar a
+cabo alguna acción más que para devolver un valor.  Algunos lenguajes
+de programación (como C y Scheme) usan las funciones para los dos
+conceptos y se limitan a descartar el valor devuelto (usualmente
+haciendo que cualquier expresión pueda actuar como instrucción,
+ignorando el resultado devuelto).  Esto puede parecer inteligente pero
+es propenso a errores: casi todos los compiladores de C de hoy en día
+emiten advertencias cuando se descarta una expresión no vacía.  Para
+muchas funciones que ejecutan una acción, los estándares de Scheme
+declaran que el valor de retorno sea no especificado.  Guile, el
+intérprete de Scheme de LilyPond, tiene un valor único
+@code{*unspecified*} que en tales casos devuelve de forma usual (como
+cuando se usa directamente @code{set!} sobre una variable), pero
+desgraciadamente no de forma consistente.
+
+Definir una función de LilyPond con @code{define-void-function}
+asegura que se devuelve este valor especial, el único valor que
+satisface el predicado @code{void?}.
+
+@example
+noApuntarYPulsar =
+#(define-void-function
+     (parser location)
+     ()
+   (ly:set-option 'point-and-click #f))
+@dots{}
+\noApuntarYPulsar   % desactivar la función de apuntar y pulsar
+@end example
+
+Si queremos evaluar una expresión sólo por su efecto colateral y no
+queremos que se interprete ningún valor que pueda devolver, podemos
+hacerlo anteponiendo el prefijo @code{\void}:
+
+@example
+\void #(hashq-set! some-table some-key some-value)
+@end example
+
+De esta forma podemos asegurar que LilyPond no asignará ningún
+significado al valor devuelto, independientemente de dónde lo
+encuentre.  También funciona para funciones musicales como
+@code{\displayMusic}.
+
+@node Funciones musicales
+@section Funciones musicales
+@translationof Music functions
+
+@cindex funciones musicales
+
+Las @emph{funciones musicales} son procedimientos de Scheme que pueden
+crear automáticamente expresiones musicales, y se pueden usar para
+simplificar enormemente el archivo de entrada.
+
+@menu
+* Definiciones de funciones musicales::
+* Uso de las funciones musicales::
+* Funciones de sustitución sencillas::
+* Funciones de sustitución intermedias::
+* Matemáticas dentro de las funciones::
+* Funciones sin argumentos::
+* Funciones musicales vacías::
+@end menu
+
+
+@node Definiciones de funciones musicales
+@subsection Definiciones de funciones musicales
+@translationof Music function definitions
+@cindex definición de funciones musicales
+@funindex define-music-function
+
+La forma general para definir funciones musicales es:
+
+@example
+funcion =
+#(define-music-function
+     (parser location @var{arg1} @var{arg2} @dots{})
+     (@var{tipo1?} @var{tipo2?} @dots{})
+   @var{cuerpo})
+@end example
+
+@noindent
+de forma bastante análoga a @ref{Definición de funciones de Scheme}.
+Lo más probable es que el @var{cuerpo} sea un
+@ref{Bloques de código de LilyPond,bloque de código de LilyPond}.
+
+Para ver una lista de los predicados de tipo disponibles, consulte
+@ruser{Predicados de tipo predefinidos}.
 
 @seealso
 
@@ -100,6 +383,39 @@ Archivos de inicio:
 @file{scm/lily.scm}.
 
 
+@node Uso de las funciones musicales
+@subsection Uso de las funciones musicales
+@translationof Music function usage
+
+Las funciones musicales se pueden actualmente utilizar en varios
+lugares.  Dependiendo de dónde se usan, son de aplicación ciertas
+restricciones para que sea posible su análisis sintáctico de forma
+no ambigua.  El resultado que devuelve una función musical debe ser
+compatible con el contexto desde el que se la llama.
+
+@itemize
+@item
+En el nivel superior dentro de una expresión musical.  Aquí
+no se aplica ninguna restricción.
+
+@item
+Como un post-evento, que comienza explícitamente con un indicador de
+dirección (a elegir entre @code{-}, @code{^} @w{y @code{_}}).
+
+En este caso, no podemos usar una expresión musical @emph{abierta}
+como último argumento, que terminaría en una expresión musical
+capaz de aceptar post-eventos adicionales.
+
+@item
+Como componente de un acorde.  La expresión devuelta debe ser
+del tipo @code{rhythmic-event}, probablemente un @code{NoteEvent}.
+@end itemize
+
+@noindent
+Las reglas especiales para los argumentos del final hacen posible
+escribir funciones polimórficas como @code{\tweak} que se pueden
+aplicar a construcciones distintas.
+
 @node Funciones de sustitución sencillas
 @subsection Funciones de sustitución sencillas
 @translationof Simple substitution functions
@@ -131,7 +447,7 @@ barraManual =
      (parser location principio-final)
      (pair?)
    #@{
-     \once \override Beam #'positions = $principio-final
+     \once \override Beam.positions = #principio-final
    #@})
 
 \relative c' @{
@@ -149,7 +465,7 @@ manualBeam =
      (parser location beg end)
      (number? number?)
    #{
-     \once \override Beam #'positions = $(cons beg end)
+     \once \override Beam.positions = #(cons beg end)
    #})
 
 \relative c' {
@@ -157,6 +473,61 @@ manualBeam =
 }
 @end lilypond
 
+@funindex \temporary
+@cindex sobreescrituras temporales
+@cindex temporales, sobreescrituras
+@cindex propiedades, recuperar valor anterior
+
+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 @code{\override} con la palabra clave
+@code{\temporary}, así:
+
+@example
+\temporary \override @dots{}
+@end example
+
+El uso de @code{\temporary} hace que se borre la propiedad
+(normalmente fijada a un cierto valor) @code{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 @code{\revert} posterior extrae el avlor
+sobreescrito temporalmente, volverá a emerger el valor anterior.
+
+En otras palabras, una llamada a @code{\temporary \override} y a
+continuación otra a @code{\revert} sobre la misma propiedad, tiene
+un valor neto que es nulo.  De forma similar, la combinación en
+secuencia de @code{\temporary} y @code{\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 @code{\temporary} asegura que los
+valores de las propiedades @code{cross-staff} y @code{style} se
+restauran a la salida a los valores que tenían cuando se llamó a
+la función @code{crossStaff}.  Sin @code{\temporary}, a la salida
+se habrían fijado los valores predeterminados.
+
+@example
+crossStaff =
+#(define-music-function (parser location 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
+#@})
+@end example
+
 
 @node Matemáticas dentro de las funciones
 @subsection Matemáticas dentro de las funciones
@@ -171,14 +542,14 @@ AltOn =
      (parser location mag)
      (number?)
    #{
-     \override Stem #'length = $(* 7.0 mag)
-     \override NoteHead #'font-size =
-       $(inexact->exact (* (/ 6.0 (log 2.0)) (log mag)))
+     \override Stem.length = #(* 7.0 mag)
+     \override NoteHead.font-size =
+       #(inexact->exact (* (/ 6.0 (log 2.0)) (log mag)))
    #})
 
 AltOff = {
-  \revert Stem #'length
-  \revert NoteHead #'font-size
+  \revert Stem.length
+  \revert NoteHead.font-size
 }
 
 \relative c' {
@@ -197,12 +568,12 @@ withAlt =
      (parser location mag music)
      (number? ly:music?)
    #{
-     \override Stem #'length = $(* 7.0 mag)
-     \override NoteHead #'font-size =
-       $(inexact->exact (* (/ 6.0 (log 2.0)) (log mag)))
-     $music
-     \revert Stem #'length
-     \revert NoteHead #'font-size
+     \override Stem.length = #(* 7.0 mag)
+     \override NoteHead.font-size =
+       #(inexact->exact (* (/ 6.0 (log 2.0)) (log mag)))
+     #music
+     \revert Stem.length
+     \revert NoteHead.font-size
    #})
 
 \relative c' {
@@ -232,7 +603,7 @@ mostrarNumeroDeCompas =
      (parser location)
      ()
    (if (eq? #t (ly:get-option 'display-bar-numbers))
-       #@{ \once \override Score.BarNumber #'break-visibility = ##f #@}
+       #@{ \once \override Score.BarNumber.break-visibility = ##f #@}
        #@{#@}))
 @end example
 
@@ -244,30 +615,42 @@ lilypond -d display-bar-numbers ARCHIVO.ly
 @end example
 
 
-@node Funciones vacías
-@subsection Funciones vacías
-@translationof Void functions
+@node Funciones musicales vacías
+@subsection Funciones musicales vacías
+@translationof Void music functions
 
-Una función musical debe devolver una expresión musical, pero a veces
-podemos necesitar una función en la que no hay música en juego (como
-la desactivación de la funcionalidad Apuntar y Pulsar).  Para hacerlo,
-devolvemos una expresión musical @code{void} (vacía).
+Una función musical debe devolver una expresión musical.  Si quiere
+ejecutar una función exclusivamente por sus efectos secundarios,
+debería usar @code{define-void-function}.  Pero
+puede haber casos en los que a veces queremos producir una expresión
+musical, y a veces no (como en el ejemplo anterior).  Devolver una
+expresión musical @code{void} (vacía) por medio de @code{#@{ #@}} lo
+hace posible.
 
-Este es el motivo por el que la forma que se devuelve es
-@code{(make-music ...)}.  Con el valor de la propiedad @code{'void}
-establecido a @code{#t}, le decimos al analizador que descarte la
-expresión musical devuelta.  así, la parte importante de la función
-musical vacía es el proceso realizado por la función, no la expresión
-musical que se devuelve.
 
-@example
-noApuntarYPulsar =
-#(define-music-function (parser location) ()
-   (ly:set-option 'point-and-click #f)
-   (make-music 'SequentialMusic 'void #t))
-...
-\noApuntarYPulsar   % desactivar la funcionalidad Apuntar y Pulsar.
-@end example
+@node Funciones de eventos
+@section Funciones de eventos
+@translationof Event functions
+@funindex define-event-function
+@cindex event functions
+
+Para usar una función musical en el lugar de un evento, tenemos que
+escribir un indicador de dirección antes de ella.  Pero a veces, ello
+hace que se pierda la correspondencia con la sintaxis de las
+construcciones que queremos sustituir.  Por ejemplo, si queremos
+escribir instrucciones de matiz dinámico, éstos se adjuntan
+habitualmente sin indicador de dirección, como @code{c'\pp}.  He aquí
+una forma de escribir indicaciones dinámicas arbitrarias:
+
+@lilypond[quote,verbatim,ragged-right]
+dyn=#(define-event-function (parser location arg) (markup?)
+         (make-dynamic-script arg))
+\relative c' { c\dyn pfsss }
+@end lilypond
+
+Podríamos hacer lo mismo usando una función musical, pero entonces
+tendríamos que escribir siempre un indicador de dirección antes de
+llamarla, como @code{@w{c-\dyn pfsss}}.
 
 
 @node Funciones de marcado
@@ -291,36 +674,67 @@ argumentos.
 @translationof Markup construction in Scheme
 
 @cindex marcado, definir instrucciones de
+@funindex \displayScheme
+
+Las expresiones de marcado se representan internamente en Scheme
+usando el macro @code{markup}:
+
+@example
+(markup @var{expr})
+@end example
 
-El macro @code{markup} construye expresiones de marcado en Scheme,
-proporcionando una sintaxis similar a la de LilyPond.  Por ejemplo:
+Para ver una expresión de marcado en su forma de Scheme, utilice
+la instrucción @code{\displayScheme}:
 
 @example
-(markup #:column (#:line (#:bold #:italic "hola" #:raise 0.4 "mundo")
-                  #:larger #:line ("fulano" "fulanito" "menganito")))
+\displayScheme
+\markup @{
+  \column @{
+    \line @{ \bold \italic "hola" \raise #0.4 "mundo" @}
+    \larger \line @{ fulano fulanito menganito @}
+  @}
+@}
 @end example
 
 @noindent
-equivale a:
+La compilación del código anterior envía a la consola lo
+siguiente:
+
 @example
-\markup \column @{ \line @{ \bold \italic "hola" \raise #0.4 "mundo" @}
-                  \larger \line @{ fulano fulanito menganito @} @}
+(markup
+  #:line
+  (#:column
+   (#:line
+    (#:bold (#:italic "hola") #:raise 0.4 "mundo")
+    #:larger
+    (#:line
+     (#:simple "fulano" #:simple "fulanito" #:simple "menganito")))))
 @end example
 
+Para evitar que el marcado se imprima en la página, use
+@w{@samp{\void \displayScheme @var{marcado}}}.  Asimismo, como
+ocurre con la instrucción @code{\displayMusic}, la salida de
+@code{\displayScheme} se puede guardar en un archivo externo.
+Véase @ref{Presentación de las expresiones musicales}.
+
 @noindent
 Este ejemplo muestra las principales reglas de traducción entre la
 sintaxis del marcado normal de LilyPond y la sintaxis del marcado de
-Scheme.
+Scheme.  La utilización de @code{#@{ @dots{} #@}} para escribir en la
+sintaxis de LilyPond será con frecuencia lo más conveniente, pero
+explicamos cómo usar la macro @code{markup} para obtener una solución
+sólo con Scheme.
 
 @quotation
 @multitable @columnfractions .3 .3
 @item @b{LilyPond} @tab @b{Scheme}
 @item @code{\markup marcado1} @tab @code{(markup marcado1)}
-@item @code{\markup @{ marcado1 marcado2 ... @}} @tab
-        @code{(markup marcado1 marcado2 ... )}
+@item @code{\markup @{ marcado1 marcado2 @dots{} @}} @tab
+        @code{(markup marcado1 marcado2 @dots{} )}
 @item @code{\instruccion} @tab @code{#:instruccion}
 @item @code{\variable} @tab @code{variable}
-@item @code{\center-column @{ ... @}} @tab @code{#:center-column ( ... )}
+@item @code{\center-column @{ @dots{} @}} @tab
+        @code{#:center-column ( @dots{} )}
 @item @code{cadena} @tab @code{"cadena"}
 @item @code{#argumento-de-scheme} @tab @code{argumento-de-scheme}
 @end multitable
@@ -329,7 +743,8 @@ Scheme.
 Todo el lenguaje Scheme está accesible dentro del macro @code{markup}.
 Por ejemplo, podemos usar llamadas a funciones dentro de @code{markup}
 para así manipular cadenas de caracteres.  Esto es útil si se están
-definiendo instrucciones de marcado nuevas (véase @ref{Definición de una instrucción de marcado nueva}).
+definiendo instrucciones de marcado nuevas (véase
+@ref{Definición de una instrucción de marcado nueva}).
 
 
 @knownissues
@@ -410,11 +825,11 @@ Se pueden definir instrucciones de marcado nuevas usando el macro de
 Scheme @code{define-markup-command}, en el nivel sintáctico superior.
 
 @lisp
-(define-markup-command (@var{nombre-de-la-instruccion} @var{layout} @var{props} @var{arg1} @var{arg2} ...)
-    (@var{tipo-de-arg1?} @var{tipo-de-arg2?} ...)
+(define-markup-command (@var{nombre-de-la-instruccion} @var{layout} @var{props} @var{arg1} @var{arg2} @dots{})
+    (@var{tipo-de-arg1?} @var{tipo-de-arg2?} @dots{})
     [ #:properties ((@var{propiedad1} @var{valor-predeterminado1})
-                    ...) ]
-  ..command body..)
+                    @dots{}) ]
+  @dots{}command body@dots{})
 @end lisp
 
 Los argumentos son
@@ -457,10 +872,33 @@ aplicado a todos los elementos de la lista de marcados original.
 Dado que la replicación de los argumentos precedentes para aplicar una
 función de marcado a una lista de marcados es poco costosa
 principalmente por los argumentos de Scheme, se evitan las caídas de
-reindimiento simplemente mediante la utilización de argumentos de
+rendimiento simplemente mediante la utilización de argumentos de
 Scheme para los argumentos antecedentes de las funciones de marcado
 que toman un marcado como su último argumento.
 
+@funindex \markup
+@cindex markup macro
+@funindex interpret-markup
+Las instrucciones de marcado tienen un ciclo de vida más bien
+complejo.  El cuerpo de la definición de una instrucción de marcado es
+responsable de la conversión de los argumentos de la instrucción de
+marcado en una expresión de sello que se devuelve.  Muy a menudo esto
+se lleva a cabo llamando a la función @code{interpret-markup} sobre
+una expresión de marcado, pasándole los argumentos @var{layout} y
+@var{props}.  Por lo general, estos argumentos se conocen solamente en
+una fase muy tardía de la composición tipográfica.  Las expresiones de
+marcado ya tienen sus componentes ensamblados dentro de expresiones de
+marcado cuando se expanden las instrucciones @code{\markup} (dentro de
+una expresión de LilyPond) o la macro @code{markup} (dentro de
+Scheme).  La evaluación y la comprobación de tipos de los argumentos
+de la instrucción de marcado tiene lugar en el momento en que se
+interpretan @code{\markup} o @code{markup}.
+
+Pero la conversión real de expresiones de marcado en expresiones de
+sello mediante la ejecución de los cuerpos de función de marcado solo
+tienen lugar cuando se llama a @code{interpret-markup} sobre una
+expresión de marcado.
+
 @node Acerca de las propiedades
 @unnumberedsubsubsec Acerca de las propiedades
 @translationof On properties
@@ -506,8 +944,8 @@ El ejemplo siguiente define una instrucción de marcado para trazar un
 rectángulo doble alrededor de un fragmento de texto.
 
 En primer lugar, necesitamos construir un resultado aproximado
-utilizando marcados.  Una consulta a @ruser{Text markup commands} nos
-muestra que es útil la instrucción @code{\box}:
+utilizando marcados.  Una consulta a @ruser{Instrucciones de marcado
+de texto} nos muestra que es útil la instrucción @code{\box}:
 
 @lilypond[quote,verbatim,ragged-right]
 \markup \box \box HELLO
@@ -527,7 +965,8 @@ Después, el relleno o separación entre los dos rectángulos nos parece
 muy pequeño, así que lo vamos a sobreescribir también:
 
 @lilypond[quote,verbatim,ragged-right]
-\markup \override #'(box-padding . 0.4) \box \override #'(box-padding . 0.6) \box A
+\markup \override #'(box-padding . 0.4) \box
+     \override #'(box-padding . 0.6) \box A
 @end lilypond
 
 Repetir esta extensa instrucción de marcado una y otra vez sería un
@@ -536,6 +975,16 @@ marcado.  Así pues, escribimos una instrucción de marcado
 @code{double-box}, que toma un argumento (el texto).  Dibuja los dos
 rectángulos y añade una separación.
 
+@lisp
+#(define-markup-command (double-box layout props text) (markup?)
+  "Trazar un rectángulo doble rodeando el texto."
+  (interpret-markup layout props
+    #@{\markup \override #'(box-padding . 0.4) \box
+            \override #'(box-padding . 0.6) \box @{ #text @}#@}))
+@end lisp
+
+o, de forma equivalente,
+
 @lisp
 #(define-markup-command (double-box layout props text) (markup?)
   "Trazar un rectángulo doble rodeando el texto."
@@ -548,10 +997,11 @@ rectángulos y añade una separación.
 @code{markup?} es el tipo: lo identifica como un elemento de marcado.
 La función @code{interpret-markup} se usa en casi todas las
 instrucciones de marcado: construye un sello, usando @code{layout},
-@code{props}, y un elemento de marcado.  Aquí, la marca se construye
-usando el macro de Scheme @code{markup}, véase @ref{Construcción de
-elementos de marcado en Scheme}.  La transformación de una expresión
-@code{\markup} en una expresión de marcado de Scheme es directa.
+@code{props}, y un elemento de marcado.  En el segundo caso, la marca
+se construye usando el macro de Scheme @code{markup}, véase
+@ref{Construcción de elementos de marcado en Scheme}.  La
+transformación de una expresión @code{\markup} en una expresión de
+marcado de Scheme es directa.
 
 La instrucción nueva se puede usar como sigue:
 
@@ -568,6 +1018,19 @@ nueva propiedad, @code{inter-box-padding}, para el relleno entre los
 rectángulos.  El @code{box-padding} se usará para el relleno interno.
 Ahora el código nuevo es como se ve a continuación:
 
+@lisp
+#(define-markup-command (double-box layout props text) (markup?)
+  #:properties ((inter-box-padding 0.4)
+                (box-padding 0.6))
+  "Trazar un rectángulo doble rodeando el texto."
+  (interpret-markup layout props
+    #@{\markup \override #`(box-padding . ,inter-box-padding) \box
+               \override #`(box-padding . ,box-padding) \box
+               @{ #text @} #@}))
+@end lisp
+
+De nuevo, la versión equivalente que utiliza la macro de marcado sería:
+
 @lisp
 #(define-markup-command (double-box layout props text) (markup?)
   #:properties ((inter-box-padding 0.4)
@@ -598,8 +1061,9 @@ y el relleno de los rectángulos se puede personalizar:
                 (box-padding 0.6))
   "Draw a double box around text."
   (interpret-markup layout props
-    (markup #:override `(box-padding . ,inter-box-padding) #:box
-            #:override `(box-padding . ,box-padding) #:box text)))
+    #{\markup \override #`(box-padding . ,inter-box-padding) \box
+              \override #`(box-padding . ,box-padding) \box
+              { #text } #}))
 
 \markup \double-box A
 \markup \override #'(inter-box-padding . 0.8) \double-box A
@@ -627,7 +1091,7 @@ documentación):
   (number-pair?)
   #:category graphic
   #:properties ((thickness 1))
-  "...documentación..."
+  "@dots{}documentación@dots{}"
   (let ((th (* (ly:output-def-lookup layout 'line-thickness)
                thickness))
         (x (car dest))
@@ -645,7 +1109,7 @@ instrucciones de marcado definidas por el usuario.
 (define-markup-command (draw-double-line layout props dest)
   (number-pair?)
   #:properties ((thickness 1))
-  "...documentación..."
+  "@dots{}documentación@dots{}"
   (let ((th (* (ly:output-def-lookup layout 'line-thickness)
                thickness))
         (x (car dest))
@@ -662,8 +1126,8 @@ predeterminado de p.ej. 0.6:
   (number-pair?)
   #:properties ((thickness 1)
                 (line-gap 0.6))
-  "...documentación..."
-  ...
+  "@dots{}documentación@dots{}"
+  @dots{}
 @end lisp
 
 Finalmente, se añade el código para trazar las dos líneas.  Se usan
@@ -700,6 +1164,9 @@ sellos resultantes se combinan usando @code{ly:stencil-add}:
 @subsection Definición de nuevas instrucciones de lista de marcado
 @translationof New markup list command definition
 
+@funindex define-markup-list-command
+@funindex interpret-markup-list
+
 Las instrucciones de listas de marcado se definen con el macro de
 Scheme @code{define-markup-list-command}, que es similar al macro
 @code{define-markup-command} descrito en @ref{Definición de una
@@ -711,6 +1178,15 @@ En el siguiente ejemplo se define una instrucción de lista de marcado
 estando la primera de ellas sangrada.  La anchura del sangrado se toma
 del argumento @code{props}.
 
+@example
+#(define-markup-list-command (paragraph layout props args) (markup-list?)
+   #:properties ((par-indent 2))
+   (interpret-markup-list layout props
+     #@{\markuplist \justified-lines @{ \hspace #par-indent #args @} #@}))
+@end example
+
+
+La versión que usa solamente Scheme es más compleja:
 @example
 #(define-markup-list-command (paragraph layout props args) (markup-list?)
    #:properties ((par-indent 2))
@@ -728,17 +1204,17 @@ En primer lugar, la función toma el ancho del sangrado, una propiedad
 llamada aquí @code{par-indent}, de la lista de propiedades
 @code{props}.  Si no se encuentra la propiedad, el valor
 predeterminado es @code{2}.  Después, se hace una lista de líneas
-justificadas usando la función
-@code{make-justified-lines-markup-list}, que está relacionada con la
-instrucción incorporada de lista de marcados @code{\justified-lines}.
-Se añade un espacio horizontal al principio usando la función
-@code{make-hspace-markup}.  Finalmente, la lista de marcados se
+justificadas usando la instrucción incorporada de lista de marcados
+@code{\justified-lines}, que está relacionada con la función
+@code{make-justified-lines-markup-list}.  Se añade un espacio
+horizontal al principio usando @code{\hspace} (o la función
+@code{make-hspace-markup}).  Finalmente, la lista de marcados se
 interpreta usando la función @code{interpret-markup-list}.
 
 Esta nueva instrucción de lista de marcados se puede usar como sigue:
 
 @example
-\markuplines @{
+\markuplist @{
   \paragraph @{
     El arte de la tipografía musical se llama  \italic @{grabado (en plancha).@}
     El término deriva del proceso tradicional de impresión de música.
@@ -805,14 +1281,14 @@ funciona insertando un evento dentro del contexto especificado
 (@rinternals{ApplyOutputEvent}).  Su sintaxis es
 
 @example
-\applyOutput @var{contexto} @var{proc}
+\applyOutput @var{Contexto} @var{proc}
 @end example
 
 @noindent
 donde @code{@var{proc}} es una función de Scheme que toma tres argumentos.
 
 Al interpretarse, la función @code{@var{proc}} se llama para cada objeto de
-presentación que se encuentra en el contexto @code{@var{contexto}}
+presentación que se encuentra en el contexto @code{@var{Contexto}}
 en el tiempo actual, con los siguientes argumentos:
 
 @itemize
@@ -842,6 +1318,14 @@ cabezas de las notas que están sobre la línea central y junto a ella:
 }
 @end lilypond
 
+Para que @var{función} se interprete en los niveles de @code{Score} o de @code{Staff}
+utilice estas formas:
+
+@example
+\applyOutput #'Score #@var{función}
+\applyOutput #'Staff #@var{función}
+@end example
+
 
 @node Funciones de callback
 @section Funciones de callback
@@ -852,13 +1336,13 @@ Las propiedades (como @code{thickness} (grosor), @code{direction}
 p. ej.:
 
 @example
-\override Stem #'thickness = #2.0
+\override Stem.thickness = #2.0
 @end example
 
-Las propiedades pueden fijarse también a un procedimiento de scheme,
+Las propiedades pueden fijarse también a un procedimiento de Scheme,
 
 @lilypond[fragment,verbatim,quote,relative=2]
-\override Stem #'thickness = #(lambda (grob)
+\override Stem.thickness = #(lambda (grob)
     (if (= UP (ly:grob-property grob 'direction))
         2.0
         7.0))
@@ -934,10 +1418,11 @@ mi-callback = #(lambda (grob)
 @translationof Inline Scheme code
 
 La principal desventaja de @code{\tweak} es su inflexibilidad
-sintáctica.  Por ejemplo, lo siguiente produce un error de sintaxis.
+sintáctica.  Por ejemplo, lo siguiente produce un error de sintaxis (o
+más bien: así lo hacía en algún momento del pasado):
 
 @example
-F = \tweak #'font-size #-3 -\flageolet
+F = \tweak font-size #-3 -\flageolet
 
 \relative c'' @{
   c4^\F c4_\F
@@ -945,10 +1430,6 @@ F = \tweak #'font-size #-3 -\flageolet
 @end example
 
 @noindent
-En otras palabras, @code{\tweak} no se comporta como una articulación
-en cuando a la sintaxis; concretamente, no se puede adjuntar con
-@code{^} y @code{_}.
-
 Usando Scheme, se puede dar un rodeo a este problema.  La ruta hacia
 el resultado se da en @ref{Añadir articulaciones a las notas
 (ejemplo)}, especialmente cómo usar @code{\displayMusic} como guía de
@@ -1039,10 +1520,10 @@ arriba.
          (ly:grob-set-property! grob 'extra-offset '(-2 . 5)))))
 
 \relative c'' {
-  \override Tie #'after-line-breaking =
+  \override Tie.after-line-breaking =
   #my-callback
   c1 ~ \break
-  c2 ~ c
+  c2 ~ 2
 }
 @end lilypond
 
@@ -1062,9 +1543,10 @@ razones técnicas.  Son ejemplos @code{NonMusicalPaperColumn} y
 
 @example
 \overrideProperty
-#"Score.NonMusicalPaperColumn"  % Nombre del grob
-#'line-break-system-details     % Nombre de la propiedad
-#'((next-padding . 20))         % Valor
+Score.NonMusicalPaperColumn      % Nombre del grob
+  . line-break-system-details    % Nombre de la propiedad
+  . next-padding                 % Nombre de la subpropiedad, opcional
+  #20                            % Valor
 @end example
 
 Observe, sin embargo, que @code{\override}, aplicado a