@menu
-* Bloques de código de Lilypond::
+* Bloques de código de LilyPond::
* Funciones de Scheme::
* Funciones musicales::
+* Funciones de eventos::
* Funciones de marcado::
* Contextos para programadores::
* Funciones de callback::
* Trucos difíciles::
@end menu
-@node Bloques de código de Lilypond
-@section Bloques de código de Lilypond
+@node Bloques de código de LilyPond
+@section Bloques de código de LilyPond
@translationof Lilypond code blocks
-Los bloques de código de Lilypond tienen el siguiente aspecto:
+Los bloques de código de LilyPond tienen el siguiente aspecto:
@example
- #@{ @var{código de Lilypond} #@}
+ #@{ @var{código de LilyPond} #@}
@end example
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. Mientras se está leyendo el
-bloque de código de Lilypond, se analiza sintácticamente de forma
+incorporar bloques de código de LilyPond. Mientras se está leyendo el
+bloque de código de LilyPond, se analiza sintácticamente de forma
superficial y se sustituye por una llamada al analizador sintáctico de
-Lilypond, que funciona en tiempo de ejecución para que interprete el
-bloque de código de Lilypond.
+LilyPond, que funciona en tiempo de ejecución para que interprete el
+bloque de código de LilyPond.
El objeto del análisis superficial es la interpretación de los
símbolos @code{$} que se pueden usar para aislar expresiones del
@table @code
@item $$
-simplemente pasa un único símbolo @code{$} al analizador de Lilypond.
+simplemente pasa un único símbolo @code{$} al analizador de LilyPond.
@item $@var{forma}
evalúa la forma Scheme en tiempo de ejecución y la analiza como un
-identificador @code{\forma} en el analizador de Lilypond. Dependiendo
+identificador @code{\forma} en el analizador de LilyPond. Dependiendo
del tipo del valor, se puede interpretar como varias entidades
sintácticas diferentes.
@item #$@var{forma}
@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
@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 la definición de una función de Scheme es:
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{@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}}
debe devolver @code{#t}. Algunos de estos predicados se reconocen de
-forma especial por parte del analizador, véase más abajo.
+forma especial por parte del analizador, véase más abajo. También
+existe una forma especial @code{(@emph{predicate?} @emph{default})}
+para especificar argumentos opcionales. Si el argumento actual no
+está presente cuando se llama 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
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
+@ref{Bloques de código de LilyPond}. Dentro de los bloques de código
de LilyPond, use el símbolo del dólar @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)}}).
+(p.ej. @w{@samp{$(cons arg1 arg2)}}). Si la función devuelve una
+expresión musical, se clona y se le da el @code{origin} correcto.
@end multitable
@noindent
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.
+seguido por sus argumentos. El último argumento no puede ser un
+argumento opcional. Si hay varios argumentos opcionales seguidos, se
+rellenan con valores de izquierda a derecha. Desde el momento en que
+un argumento opcional no corresponde con la entrada, éste y todos los
+argumentos opcionales inmediatamente siguientes se sustituyen por sus
+valores predeterminados, y la correspondencia continúa con el
+siguiente argumento no opcional.
Aparte de los lugares en que se requiere un valor de Scheme hay
ciertos sitios en que se aceptan expresiones de almohadilla @code{#} y
@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.
@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:
@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}.
+@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}.
especiales restricciones sobre la lista de argumentos.
@item
-Como un post-evento. Todos los argumentos añadidos al final de la
-función musical con el predicado @code{ly:music?} se analizan
-sintácticamente también como post-eventos. Observe que los
-post-eventos que se devuelven también serán aceptables por parte de
-las funciones musicales que se llamen desde el nivel superior, lo que
-lleva a un resultado aproximadamente equivalente a
+Como un post-evento, que comienza explícitamente con un indicador de
+dirección (a elegir entre @code{-}, @code{^} @w{y @code{_}}). Todos
+los argumentos añadidos al final de la función musical con el
+predicado @code{ly:music?} se analizan sintácticamente también como
+post-eventos (si el último argumento es una función de Scheme, éste
+contendrá en su lugar los argumentos @code{ly:music?} del final de la
+función de Scheme). Observe que se puede aceptar la devolución de un
+post-evento por parte de las funciones musicales que se llaman como
+música normal, lo que lleva a un resultado aproximadamente equivalente
+a
@example
s 1*0-\fun
@end example
escribir funciones polimórficas como @code{\tweak} que se pueden
aplicar a construcciones distintas.
-Hay otra regla que es de alguna manera especial: si tenemos un
-predicado @code{ly:music?} justo antes de un predicado
-@code{ly:duration?}, la expresión musical correspondiente debe ser un
-identificador musical, o bien música secuencial o paralela encerrada
-en @code{@{}@dots{}@code{@}} o en @code{<<}@dots{}@code{>>} de forma
-explícita. De lo contrario, LilyPond podría entrar en confusión
-acerca de dónde termina la música y dónde empieza la duración.
-
@node Funciones de sustitución sencillas
@subsection Funciones de sustitución sencillas
@translationof Simple substitution functions
hace posible.
+@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,raggedright]
+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
@section Funciones de marcado
@translationof Markup functions
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
\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)