@c -*- coding: utf-8; mode: texinfo; documentlanguage: es -*-
@ignore
- Translation of GIT committish: c1eb9d63bb22ba4a9243942599f68768f5631e34
+ Translation of GIT committish: cccd2bf82ebfb55b6423346037fa4d2793fc4c3b
When revising a translation, copy the HEAD committish of the
version that you are working on. For details, see the Contributors'
Guide, node Updating translation committishes..
@end ignore
-@c \version "2.12.0"
+@c \version "2.17.11"
@node Tutorial de Scheme
@appendix Tutorial de Scheme
@translationof Scheme tutorial
-@funindex #
@cindex Scheme
@cindex GUILE
@cindex Scheme, código en línea
@subsection Cajón de arena de Scheme
@translationof Scheme sandbox
-La instalación de LilyPond inclute también la de la implementación
+La instalación de LilyPond incluye también la de la implementación
Guile de Scheme. Sobre casi todos los sistemas puede experimentar en
una @qq{caja de arena} de Scheme abriendo una ventana del terminal y
tecleando @q{guile}. En algunos sistemas, sobre todo en Windows,
podría necesitar ajustar la variable de entorno @code{GUILE_LOAD_PATH}
-a la carpeta @code{../usr/shr/guile/1.8} dentro de la instalación de
+a la carpeta @code{../usr/share/guile/1.8} dentro de la instalación de
LilyPond (para conocer la ruta completa a esta carpeta, consulte
-@ref{Otras fuentes de información}). Como alternativa, los usuarios
-de Windows pueden seleccionar simplemente @q{Ejecutar} del menú Inicio
-e introducir @q{guile}.
+@rlearning{Otras fuentes de información}). Como alternativa, los
+usuarios de Windows pueden seleccionar simplemente @q{Ejecutar} del
+menú Inicio e introducir @q{guile}.
-Una vez está funcionando el cajón de arena de Guile, verá un indicador
+Sin embargo, está disponible un cajón de arena de Scheme listo para
+funcionar con todo LilyPond cargado, con esta instrucción de la línea
+de órdenes:
+@example
+lilypond scheme-sandbox
+@end example
+
+@noindent
+Una vez está funcionando el cajón de arena, verá un indicador
del sistema de Guile:
@lisp
@end lisp
Podemos introducir expresiones de Scheme en este indicador para
-experimentar con Scheme.
+experimentar con Scheme. Si quiere usar la biblioteca readline de GNU
+para una más cómoda edición de la línea de órdenes de Scheme, consulte
+el archivo @file{ly/scheme-sandbox.ly} para más información. Si ya ha
+activado la biblioteca readline para las sesiones de Guile
+interactivas fuera de LilyPond, debería funcionar también en el cajón
+de arena.
@node Variables de Scheme
@subsection Variables de Scheme
@translationof Scheme variables
-Las variables de Scheme pueden tener cualquier valor válido de scheme,
+Las variables de Scheme pueden tener cualquier valor válido de Scheme,
incluso un procedimiento de Scheme.
Las variables de Scheme se crean con @code{define}:
@item Números
Los números se escriben de la forma normal, @code{1} es el número
-(entero) uno, mientras que @code{-1.5} es un número en coma flotante
+(entero) uno, mientras que @w{@code{-1.5}} es un número en coma flotante
(un número no entero).
@item Cadenas
@end example
@noindent
-y los caracterres de nueva línea al final de cada línea se incluirán
+y los caracteres de nueva línea al final de cada línea se incluirán
dentro de la cadena.
Los caracteres de nueva línea también se pueden añadir mediante la
@end example
-Las comillas dobres y barras invertidas se añaden a las cadenas
-precediéndolas mediante una barra invertida. La cadena @code{\a dijo
-"b"} se introduce como
+Las comillas dobles y barras invertidas se añaden a las cadenas
+precediéndolas de una barra invertida. La cadena @code{\a dijo "b"}
+se introduce como
@example
"\\a dijo \"b\""
más usados en la programación de LilyPond se encuentran las parejas,
las listas, las listas-A y las tablas de hash.
+@menu
+* Parejas::
+* Listas::
+* Listas asociativas (listas-A)::
+* Tablas de hash::
+@end menu
+
+@node Parejas
@unnumberedsubsubsec Parejas
+@translationof Pairs
El tipo fundacional de datos compuestos de Scheme es la @code{pareja}.
Como se espera por su nombre, una pareja son dos valores unidos en uno
@end lisp
Observe que la pareja se imprime como dos elementos rodeados por
-paréntesis y separados por un espacio, un punto (@code{.}), y más
-espacios en blanco. El punto @emph{no es} un punto decimal, sino más
-bien un indicador de la pareja.
+paréntesis y separados por un espacio, un punto (@code{.}) y otro
+espacio. El punto @emph{no es} un punto decimal, sino más bien un
+indicador de pareja.
Las parejas también se pueden introducir como valores literales
precediéndolos de un carácter de comilla simple o apóstrofo.
@lisp
guile> (cons #t #f)
(#t . #f)
-guile> '("blah-blah" . 3.1415926535)
-("blah-blah" . 3.1415926535)
+guile> '("bla-bla" . 3.1415926535)
+("bla-bla" . 3.1415926535)
guile>
@end lisp
los procedimientos de Scheme @code{car} y @code{cdr}, respectivamente.
@lisp
-guile> (define mypair (cons 123 "Hola")
+guile> (define mipareja (cons 123 "Hola")
... )
-guile> (car mypair)
+guile> (car mipareja)
123
-guile> (cdr mypair)
+guile> (cdr mipareja)
"Hola"
guile>
@end lisp
véase
@uref{http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-14.html#footnote_Temp_133}
-
+@node Listas
@unnumberedsubsubsec Listas
+@translationof Lists
-Una estrucgtura de datos muy común en Scheme es la @emph{lista}.
+Una estructura de datos muy común en Scheme es la @emph{lista}.
Formalmente, una lista se define como la lista vacía (representada
como @code{'()}, o bien como una pareja cuyo @code{cdr} es una lista.
las parejas, no hay ningún punto entre los elementos.
También se puede escribir una lista como una lista literal encerrando
-sus elementos entre paréntesism y añadiendo un apóstrofo:
+sus elementos entre paréntesis y añadiendo un apóstrofo:
@lisp
guile> '(17 23 "fulano" "mengano" "zutano")
@q{List Processing} (proceso de listas). Todas las expresiones de
Scheme son listas.
+
+@node Listas asociativas (listas-A)
@unnumberedsubsubsec Listas asociativas (listas-A)
+@translationof Association lists (alists)
Un tipo especial de listas son las @emph{listas asociativas} o
@emph{listas-A}. Se puede usar una lista-A para almacenar datos para
Las listas-A se usan mucho en LilyPond para almacenar propiedades y
otros datos.
+
+@node Tablas de hash
@unnumberedsubsubsec Tablas de hash
+@translationof Hash tables
Estructuras de datos que se utilizan en LilyPond de forma ocasional.
Una tabla de hash es similar a una matriz, pero los índices de la
-matriz pueden ser cualquier tipo de valor de Scheme value, no sólo
-enteros.
+matriz pueden ser cualquier tipo de valor de Scheme, no sólo enteros.
Las tablas de hash son más eficientes que las listas-A si hay una gran
cantidad de datos que almacenar y los datos cambian con muy poca
13
@end lisp
-Eestos cálculos son ejemplos de evaluaciones; una expresión como
+Estos cálculos son ejemplos de evaluaciones; una expresión como
@code{(* 3 4)} se sustituye por su valor @code{12}.
Los cálculos de Scheme son sensibles a las diferencias entre enteros y
2.33333333333333
@end lisp
-CUando el intérprete de Scheme encuentra una expresión que es una
+Cuando el intérprete de Scheme encuentra una expresión que es una
lista, el primer elemento de la lista se trata como un procedimiento a
evaluar con los argumentos del resto de la lista. Por tanto, todos
los operadores en Scheme son operadores prefijos.
@subsection Procedimientos de Scheme
@translationof Scheme procedures
-Los procedimientos de Scheme son expresiones de scheme ejecutables que
+Los procedimientos de Scheme son expresiones de Scheme ejecutables que
devuelven un valor resultante de su ejecución. También pueden
-manipular variables definidas fuera del proceimiento.
+manipular variables definidas fuera del procedimiento.
+
+@menu
+* Definir procedimientos::
+* Predicados::
+* Valores de retorno::
+@end menu
+@node Definir procedimientos
@unnumberedsubsubsec Definir procedimientos
+@translationof Defining procedures
Los procedimientos se definen en Scheme con @code{define}:
15/2
@end lisp
+
+@node Predicados
@unnumberedsubsubsec Predicados
+@translationof Predicates
Los procedimientos de Scheme que devuelven valores booleanos se suelen
llamar @emph{predicados}. Por convenio (pero no por necesidad),
#f
@end lisp
+
+@node Valores de retorno
@unnumberedsubsubsec Valores de retorno
+@translationof Return values
+
+Los procedimientos de Scheme siempre devuelven un valor de retorno,
+que es el valor de la última expresión ejecutada en el procedimiento.
+El valor de retorno puede ser cualquier valor de Scheme válido,
+incluso una estructura de datos compleja o un procedimiento.
-A veces, el usuario quiere tener varias espresiones de Scheme dentro
+A veces, el usuario quiere tener varias expresiones de Scheme dentro
de un procedimiento. Existen dos formas en que se pueden combinar
distintas expresiones. La primera es el procedimiento @code{begin},
que permite evaluar varias expresiones, y devuelve el valor de la
508
@end lisp
+
@node Condicionales de Scheme
@subsection Condicionales de Scheme
@translationof Scheme conditionals
+@menu
+* if::
+* cond::
+@end menu
+
+@node if
@unnumberedsubsubsec if
+@translationof if
Scheme tiene un procedimiento @code{if}:
"a no es mayor que b"
@end lisp
+
+@node cond
@unnumberedsubsubsec cond
+@translationof cond
-Otro procedimiento condicional en scheme es @code{cond}:
+Otro procedimiento condicional en Scheme es @code{cond}:
@example
(cond (expresión-de-prueba-1 secuencia-de-expresiones-resultante-1)
* Sintaxis del Scheme de LilyPond::
* Variables de LilyPond::
* Variables de entrada y Scheme::
+* Importación de Scheme dentro de LilyPond::
* Propiedades de los objetos::
* Variables de LilyPond compuestas::
* Representación interna de la música::
@node Sintaxis del Scheme de LilyPond
@subsection Sintaxis del Scheme de LilyPond
@translationof LilyPond Scheme syntax
+@funindex $
+@funindex #
-En un archivo de música, los fragmentos de código de Scheme se
-escriben con el signo de almohadilla @code{#}. Así, los ejemplos
-anteriores traducidos a LilyPond son:
+El intérprete Guile forma parte de LilyPond, lo que significa que se
+puede incluir Scheme dentro de los archivos de entrada de LilyPond.
+Existen varios métodos para incluir Scheme dentro de LilyPond.
+
+La manera más sencilla es utilizar el símbolo de
+almohadilla@tie{}@code{#} antes de una expresión de Scheme.
+
+Ahora bien, el código de entrada de LilyPond se estructura en
+elementos y expresiones, de forma parecida a cómo el lenguaje humano
+se estructura en palabras y frases. LilyPond tiene un analizador
+léxico que reconoce elementos indivisibles (números literales, cadenas
+de texto, elementos de Scheme, nombres de nota, etc.), y un analizador
+que entiende la sintaxis, la Gramática de LilyPond (@rcontrib{LilyPond grammar}).
+Una vez que sabe que se aplica una regla sintáctica concreta, ejecuta
+las acciones asociadas con ella.
+
+El método del símbolo de almohadilla@tie{}@code{#} para incrustar
+Scheme se adapta de forma natural a este sistema. Una vez que el
+analizador léxico ve un símbolo de almohadilla, llama al lector de
+Scheme para que lea una expresión de Scheme completa (que puede ser un
+identificador, una expresión encerrada entre paréntesis, o algunas
+otras cosas). Después de que se ha leído la expresión de Scheme, se
+almacena como el valor de un elemento @code{SCM_TOKEN} de la
+gramática. Después de que el analizador sintáctico ya sabe cómo hacer
+uso de este elemento, llama a Guila para que evalúe la expresión de
+Scheme. Dado que el analizador sintáctico suele requerir un poco de
+lectura por delante por parte del analizador léxico para tomar sus
+decisiones de análisis sintáctico, esta separación de lectura y
+evaluación entre los analizadores léxico y sintáctico es justamente lo
+que se necesita para mantener sincronizadas las ejecuciones de
+expresiones de LilyPond y de Scheme. Por este motivo se debe usar el
+símbolo de almohadilla@tie{}@code{#} para llamar a Scheme siempre que
+sea posible.
+
+Otra forma de llamar al intérprete de Scheme desde lilyPond es el uso
+del símbolo de dólar@tie{}@code{$} en lugar de la almohadilla para
+introducir las expresiondes de Scheme. En este caso, LilyPond evalúa
+el código justo después de que el analizador léxico lo ha leído.
+Comprueba el tipo resultante de la expresión de Scheme y después
+selecciona un tipo de elemento (uno de los varios elementos
+@code{xxx_IDENTIFIER} dentro de la sintaxis) para él. Crea una
+@emph{copia} del valor y la usa como valor del elemento. Si el valor
+de la expresión es vacío (El valor de Guile de @code{*unspecified*}),
+no se pasa nada en absoluto al analizador sintáctico.
+
+Éste es, de hecho, el mismo mecanismo exactamente que LilyPond emplea
+cuando llamamos a cualquier variable o función musical por su nombre,
+como @code{\nombre}, con la única diferencia de que el nombre viene
+determinado por el analizador léxico de LilyPond sin consultar al
+lector de Scheme, y así solamente se aceptan los nombres de variable
+consistentes con el modo actual de LilyPond.
+
+La acción inmediata de @code{$} puede llevar a alguna que otra
+sorpresa, véase @ref{Variables de entrada y Scheme}. La utilización
+de @code{#} donde el analizador sintáctico lo contempla es normalmente
+preferible. Dentro de las expresiones musicales, aquellas que se
+crean utilizando @code{#} @emph{se interprentan} como música. Sin
+embargo, @emph{no se copian} antes de ser utilizadas. Si forman parte
+de alguna estructura que aún podría tener algún uso, quizá tenga que
+utilizar explícitamente @code{ly:music-deep-copy}.
+
+@funindex $@@
+@funindex #@@
+También existen los operadores de @q{división de listas} @code{$@@} y
+@code{#@@} que insertan todos los elementos de una lista dentro del
+contexto circundante.
+
+Ahora echemos un vistazo a algo de código de Scheme real. Los
+procedimientos de Scheme se pueden definir dentro de los archivos de
+entrada de LilyPond:
@example
-##t ##f
-#1 #-1.5
-#"esto es una cadena"
-#"esto
-es
-una cadena"
+#(define (media a b c) (/ (+ a b c) 3))
@end example
Observe que los comentarios de LilyPond (@code{%} y @code{%@{ %@}}) no
-se puedden utilizar dentro del código de Scheme. Los comentarios en
-el Scheme de Guile se introducen como sigue:
+se pueden utilizar dentro del código de Scheme, ni siquiera dentro de
+un archivo de entrada de LilyPond, porque es el intérprete Guile, y no
+el analizador léxico de LilyPond, el que está leyendo la expresión de
+Scheme. Los comentarios en el Scheme de Guile se introducen como
+sigue:
@example
; esto es un comentario de una línea
!#
@end example
-Se pueden combinar en un mismo archivo de música varias expresiones de
-Scheme consecutivas mediante la utilización del operador @code{begin}.
-Ello permite que el número de marcas de cuadradillo se redizca a una.
+Durante el resto de esta sección, supondremos que los datos se
+introducen en un archivo de música, por lo que añadiremos
+almohadillas@tie{}@code{#} al principio de todas las expresiones de Scheme.
+
+Todas las expresiones de Scheme del nivel jerárquico superior dentro
+de un archivo de entrada de LilyPond se pueden combinar en una sola
+expresión de Scheme mediante la utilización del operador @code{begin}:
@example
#(begin
(define menganito 1))
@end example
-Si el @code{#} va seguido de un paréntesis de apertura, @code{(}, como
-en el ejemplo anterior, el analizador sintáctico permanece dentro del
-modo de Scheme hasta que encuentra el paréntesis de cierre
-correspondiente, @code{)}, por lo que no son necesarios más símbolos
-de @code{#} para introducir una sección de Scheme.
-
-Durante el resto de esta sección, supondremos que los datos se
-introducen en un archivo de música, por lo que añadiremos almohadillas
-@code{#} en todas partes.
@node Variables de LilyPond
@subsection Variables de LilyPond
@translationof LilyPond variables
-@c TODO -- make this read right
-
-Algo simiar ocurre con las variables. Después de definir una
-variable,
+Las variables de LilyPond se almacenan internamente en la forma de
+variables de Scheme. Así,
@example
doce = 12
@end example
@noindent
-las variables se pueden usar también dentro de expresiones, aquí
+equivale a
+
+@example
+#(define doce 12)
+@end example
+
+Esto significa que las variables de LilyPond están disponibles para su
+uso dentro de expresiones de Scheme. Por ejemplo, podríamos usar
@example
veintiCuatro = (* 2 doce)
@end example
@noindent
-el número 24 se almacena dentro de la variable @code{veintiCuatro}.
+lo que daría lugar a que el número 24 se almacenase dentro de la
+variable @code{veintiCuatro} de LilyPond (y de Scheme).
+
+La forma usual de referirse a las variables de LilyPond,
+@ref{Sintaxis del Scheme de LilyPond},
+
+es llamarlas usando una barra invertida, es decir
+@code{\veintiCuatro}. Dado que esto crea una copia para la mayor
+parte de los tipos internos de LilyPond, concretamente las expresiones
+musicales, las funciones musicales no sueln crear copias del material
+que ellas mismas modifican. Por este motivo, las expresiones
+musicales dadas con @code{#} no deberían, por lo general, contener
+material que no se haya creado partiendo de cero o copiado
+explícitamente en lugar de estar referenciado directamente.
@node Variables de entrada y Scheme
@subsection Variables de entrada y Scheme
traLaLa = @{ c'4 d'4 @}
\layout @{ traLaLa = 1.0 @}
@end example
+
@c
En efecto, cada archivo de entrada constituye un ámbito, y cada bloque
@code{\header}, @code{\midi} y @code{\layout} son ámbitos anidados
Tanto las variables como los ámbitos están implementados en el sistema
de módulos de GUILE. A cada ámbito se adjunta un módulo anónimo de
-Scheme. Una asignación de la forma
+Scheme. Una asignación de la forma:
@example
traLaLa = @{ c'4 d'4 @}
@end example
@noindent
-se convierte internamente en una definición de Scheme
+se convierte internamente en una definición de Scheme:
@example
(define traLaLa @var{Valor Scheme de `@code{... }'})
@end example
-Esto significa que las variables de entrada y las variables de Scheme
+Esto significa que las variables de LilyPond y las variables de Scheme
se pueden mezclar con libertad. En el ejemplo siguiente, se almacena
un fragmento de música en la variable @code{traLaLa}, y se duplica
usando Scheme. El resultado se importa dentro de un bloque
@lilypond[verbatim]
traLaLa = { c'4 d'4 }
-%% dummy action to deal with parser lookahead
-#(display "this needs to be here, sorry!")
-
#(define newLa (map ly:music-deep-copy
(list traLaLa traLaLa)))
#(define twice
(make-sequential-music newLa))
-{ \twice }
+\twice
@end lilypond
@c Due to parser lookahead
-En este ejemplo, la asignación se produce después de que el analizador
-sintáctico ha verificado que no ocurre nada interesante después de
-@code{traLaLa = @{ ... @}}. Sin la sentencia muda del ejemplo
-anterior, la definición de @code{newLa} se ejecuta antes de que se
-defina @code{traLaLa}, produciendo un error de sintaxis.
+En realidad, éste es un ejemplo bastante interesante. La asignación
+solo tiene lugar después de que el analizador sintáctico se ha
+asegurado de que no sigue nada parecido a @code{\addlyrics}, de manera
+que necesita comprobar lo que viene a continuación. Lee el símbolo
+@code{#} y la expresión de Scheme siguiente @emph{sin} evaluarla, de
+forma que puede proceder a la asignación, y @emph{posteriormente}
+ejecutar el código de Scheme sin problema.
+
+@node Importación de Scheme dentro de LilyPond
+@subsection Importación de Scheme dentro de LilyPond
+@translationof Importing Scheme in LilyPond
+@funindex $
+@funindex #
El ejemplo anterior muestra cómo @q{exportar} expresiones musicales
desde la entrada al intérprete de Scheme. Lo contrario también es
-posible. Envolviendo un valor de Scheme en la función
-@code{ly:export}, se interpreta un valor de Scheme como si hubiera
-sido introducido en la sintaxis de LilyPond. En lugar de definir
-@code{\twice}, el ejemplo anterior podría también haberse escrito como
+posible. Colocándolo después de @code{$}, un valor de Scheme se
+interpreta como si hubiera sido introducido en la sintaxis de
+LilyPond. En lugar de definir @code{\twice}, el ejemplo anterior
+podría también haberse escrito como
@example
...
-@{ #(ly:export (make-sequential-music (list newLa))) @}
+$(make-sequential-music newLa)
@end example
-El código de Scheme se evalúa tan pronto como el analizador sintáctico
-lo encuentra. Para definir código de Scheme dentro de un macro (para
-llamarse más tarde), utilice @ref{Void functions}, o bien
+Podemos utilizar @code{$} con una expresión de Scheme en cualquier
+lugar en el que usaríamos @code{\@var{nombre}} después de haber
+asignado la expresión de Scheme a una variable @var{nombre}. Esta
+sustitución se produce dentro del @q{analizador léxico}, de manera que
+LilyPond no llega a darse cuenta de la diferencia.
+
+Sin embargo, existe un inconveniente, el de la medida del tiempo. Si
+hubiésemos estado usando @code{$} en vez de @code{#} para definir
+@code{newLa} en el ejemplo anterior, la siguiente definición de Scheme
+habría fracasado porque @code{traLaLa} no habría sido definida aún.
+Para ver una explicación de este problema de momento temporal, véase
+@ref{Sintaxis del Scheme de LilyPond}.
+
+@funindex $@@
+@funindex #@@
+Un conveniente aspecto posterior pueden ser los operadores de
+@q{división de listas} @code{$@@} y @code{#@@} para la inserción de
+los elementos de una lista dentro del contexto circundante.
+Utilizándolos, la última parte del ejemplo se podría haber escrito
+como
+
+@example
+...
+@{ #@@newLa @}
+@end example
+
+Aquí, cada elemento de la lista que está almacenado en @code{newLa} se
+toma en secuencia y se inserta en la lista, como si hubiésemos escrito
+
+@example
+@{ #(first newLa) #(second newLa) @}
+@end example
+
+Ahora bien, en todas esas formas, el código de Scheme se evalúa en el
+momento en que el código de entrada aún se está procesando, ya sea en
+el analizador léxico o en el analizador sintáctico. Si necesitamos
+que se ejecute en un momento posterior, debemos consultar
+@ref{Funciones de Scheme vacías}, o almacenarlo dentro de un
+procedimiento:
@example
#(define (nopc)
@knownissues
No es posible mezclar variables de Scheme y de LilyPond con la opción
-@code{--safe}.
-
-
+@option{--safe}.
@node Propiedades de los objetos
@subsection Propiedades de los objetos
@translationof Object properties
-Esta sintaxis se usará con mucha frecuencia, pues muchos de los trucos
-de presentación consisten en asignar valores (de Scheme) a variables
-internas, por ejemplo
+Las propiedades de los objetos se almacenan en LilyPond en forma de
+cadenas de listas-A, que son listas de listas-A. Las propiedades se
+establecen añadiendo valores al principio de la lista de propiedades.
+Las propiedades se leen extrayendo valores de las listas-A.
+
+El establecimiento de un valor nuevo para una propiedad requiere la
+asignación de un valor a la lista-A con una clave y un valor. La
+sintaxis de LilyPond para hacer esto es la siguiente:
@example
-\override Stem #'thickness = #2.6
+\override Stem.thickness = #2.6
@end example
-Esta instrucción ajusta el aspecto de las plicas. El valor @code{2.6}
-se pone dentro de la variable @code{thickness} de un objeto
-@code{Stem}. @code{thickness} se mide a partir del grosor de las
-líneas del pentagrama, y así estas plicas serán @code{2.6} veces el
-grosor de las líneas del pentagrama. Esto hace que las plicas sean
-casi el doble de gruesas de lo normal. Para distinguir entre las
-variables que se definen en los archivos de entrada (como
-@code{veintiCuatro} en el ejemplo anterior) y las variables de los
-objetos internos, llamaremos a las últimas @q{propiedades} y a las
-primeras @q{variables.} Así, el objeto plica tiene una propiedad
-@code{thickness} (grosor), mientras que @code{veintiCuatro} es una
-variable.
+Esta instrucción ajusta el aspecto de las plicas. Se añade una
+entrada de lista-A @code{'(thickness . 2.6)} a la lista de propiedades
+de un objeto @code{Stem}. @code{thickness} se mide a partir del
+grosor de las líneas del pentagrama, y así estas plicas serán
+@code{2.6} veces el grosor de las líneas del pentagrama. Esto hace
+que las plicas sean casi el doble de gruesas de lo normal. Para
+distinguir entre las variables que se definen en los archivos de
+entrada (como @code{veintiCuatro} en el ejemplo anterior) y las
+variables de los objetos internos, llamaremos a las últimas
+@q{propiedades} y a las primeras @q{variables.} Así, el objeto plica
+tiene una propiedad @code{thickness} (grosor), mientras que
+@code{veintiCuatro} es una variable.
@cindex propiedades frente a variables
@cindex variables frente a propiedades
@subsection Variables de LilyPond compuestas
@translationof LilyPond compound variables
+@menu
+* Desplazamientos::
+* Fracciones::
+* Dimensiones::
+* Listas-A de propiedades::
+* Cadenas de listas-A::
+@end menu
+
+
+@node Desplazamientos
@unnumberedsubsubsec Desplazamientos
+@translationof Offsets
-Los desplazamientos bidimensionales (coordenadas X e Y) así como los
-tamaños de los objetos (intervalos con un punto izquierdo y otro
-derecho) se introducen como @code{parejas}. Una pareja@footnote{En la
-terminología de Scheme, la pareja se llama @code{cons}, y sus dos
-elementos se llaman @code{car} y @code{cdr} respectivamente.} se
-introduce como @code{(primero . segundo)} y, como los símbolos, se deben
-preceder de un apóstrofo:
+Los desplazamientos bidimensionales (coordenadas X e Y) se almacenan
+como @emph{parejas}. El @code{car} del desplazamiento es la
+coordenada X, y el @code{cdr} es la coordenada Y.
@example
-\override TextScript #'extra-offset = #'(1 . 2)
+\override TextScript.extra-offset = #'(1 . 2)
@end example
-Esto asigna la pareja (1, 2) a la propiedad @code{extra-offset} del
-objeto TextScript. Estos números se miden en espacios de pentagrama,
-y así esta instrucción mueve el objeto un espacio de pentagrama a la
-derecha, y dos espacios hacia arriba.
+Esto asigna la pareja @code{(1 . 2)} a la propiedad
+@code{extra-offset} del objeto TextScript. Estos números se miden en
+espacios de pentagrama, y así esta instrucción mueve el objeto un
+espacio de pentagrama a la derecha, y dos espacios hacia arriba.
+
+Los procedimientos para trabajar con desplazamientos están en
+@file{scm/lily-library.scm}.
+
+@node Fracciones
+@unnumberedsubsubsec Fracciones
+@subheading Fractions
+
+Las fracciones tal y como se utilizan por parte de LilyPond
+se almacenan, de nuevo, como @emph{parejas}, esta
+vez de enteros sin signo. Mientras que Scheme es capaz de representar números racionaes
+como un tipo nativo, musicalmente @samp{2/4} y @samp{1/2} no son lo mismo,
+y necesitamos poder distinguir entre ellos. De igual forma, no existe el concepto
+de @q{fracciones} negativas en LilyPond. Así pues, @code{2/4} en LilyPond
+significa @code{(2 . 4)} en Scheme, y @code{#2/4} en LilyPond significa
+@code{1/2} en Scheme.
+
+@node Dimensiones
@unnumberedsubsubsec Dimensiones
+@translationof Extents
+
+Las parejas se usan también para almacenar intervalos, que representan
+un rango de números desde el mínimo (el @code{car}) hasta el máximo
+(el @code{cdr}). Los intervalos se usan para almacenar las
+dimensiones en X y en Y de los objetos imprimibles. Para dimensiones
+en X, el @code{car} es la coordenada X de la parte izquierda, y el
+@code{cdr} es la coordenada X de la parte derecha. Para las
+dimensiones en Y, el @code{car} es la coordenada inferior, y el
+@code{cdr} es la coordenada superior.
-HACER @c todo -- write something about extents
+Los procedimientos para trabajar con intervalos están en
+@file{scm/lily-library.scm}. Se deben usar estos procedimientos
+siempre que sea posible, para asegurar la consistencia del código.
+
+@node Listas-A de propiedades
@unnumberedsubsubsec Listas-A de propiedades
+@translationof Property alists
+
+Una lista-A de propiedades es una estructura de datos de LilyPond que
+es una lista-A cuyas claves son propiedades y cuyos valores son
+expresiones de Scheme que dan el valor deseado de la propiedad.
-HACER @c todo -- write something about property alists
+Las propiedades de LilyPond son símbolos de Scheme, como por ejemplo
+@code{'thickness}.
+
+@node Cadenas de listas-A
@unnumberedsubsubsec Cadenas de listas-A
+@translationof Alist chains
+
+Una cadena de listas-A es una lista que contiene listas-A de
+propiedades.
-HACER @c todo -- write something about alist chains
+El conjunto de todas las propiedades que se aplican a un grob se
+almacena por lo general como una cadena de listas-A. Para poder
+encontrar el valor de una propiedad determinada que debería tener un
+grob, se busca por todas las listas-A de la cadena, una a una,
+tratando de encontrar una entrada que contenga la clave de la
+propiedad. Se devuelve la primera entrada de lista-A que se
+encuentre, y el valor es el valor de la propiedad.
+
+El procedimiento de Scheme @code{chain-assoc-get} se usa normalmente
+para obtener los valores de propiedades.
@node Representación interna de la música
@subsection Representación interna de la música
@translationof Internal music representation
+Internamente, la música se representa como una lista de Scheme. La
+lista contiene varios elementos que afectan a la salida impresa. El
+análisis sintáctico es el proceso de convertir la música de la
+representación de entrada de LilyPond a la representación interna de
+Scheme.
+
Cuando se analiza una expresión musical, se convierte en un conjunto
de objetos musicales de Scheme. La propiedad definitoria de un objeto
-musical es que ocupa un tiempo. El tiempo es un número racional que
-mide la longitud de una pieza de música en redondas.
+musical es que ocupa un tiempo. El tiempo que ocupa se llama
+@emph{duración}. Las duraciones se expresan como un número racional
+que mide la longitud del objeto musical en redondas.
Un objeto musical tiene tres clases de tipos:
@itemize
@q{tipos} o interfaces, por ejemplo, una nota es un @code{event}, pero
también es un @code{note-event}, un @code{rhythmic-event}, y un
@code{melodic-event}. Todas las clases de música están listadas en el
-manual de REferencia de funcionamiento interno, bajo el epígrafe
+manual de Referencia de funcionamiento interno, bajo el epígrafe
@rinternals{Music classes}.
@item
@section Construir funciones complicadas
@translationof Building complicated functions
-Esta sección explica cómo recolectar la información necesaria para
-crear funciones musicales complicadas.
+Esta sección explica cómo reunir la información necesaria para crear
+funciones musicales complicadas.
@menu
* Presentación de las expresiones musicales::
@cindex displayMusic
@funindex \displayMusic
-Cuando se escribe una función musical, suele ser instructivo
-inspeccionar cómo se almacena internamente una expresión musical.
-Esto puede hacerse con la función musical @code{\displayMusic}
+Si se está escribiendo una función musical, puede ser muy instructivo
+examinar cómo se almacena internamente una expresión musical. Esto se
+puede hacer con la función musical @code{\displayMusic}
@example
@{
@end example
@noindent
-imprime
+imprime lo siguiente:
@example
(make-music
'SequentialMusic
'elements
(list (make-music
- 'EventChord
- 'elements
+ 'NoteEvent
+ 'articulations
(list (make-music
- 'NoteEvent
- 'duration
- (ly:make-duration 2 0 1 1)
- 'pitch
- (ly:make-pitch 0 0 0))
- (make-music
'AbsoluteDynamicEvent
'text
- "f")))))
+ "f"))
+ 'duration
+ (ly:make-duration 2 0 1/1)
+ 'pitch
+ (ly:make-pitch 0 0 0))))
@end example
De forma predeterminada, LilyPond imprime estos mensajes sobre la
-conola junto a todos los tros mensajes. Para separar estos mensajes y
-guardar los resultados de @code{\display@{LOQUESEA@}}, redirija la
+consola junto al resto de los mensajes. Para separar estos mensajes y
+guardar el resultado de @code{\display@{LOQUESEA@}}, redirija la
salida a un archivo.
@example
lilypond archivo.ly >salida.txt
@end example
-Con un poco de formateo, la información anterior es fácil de leer,
+Con un poco de magia combinada de LilyPond y Scheme, podemos realmente
+hacer que LilyPond dirija solamente esta salida a su propio archivo:
+
+@example
+@{
+ #(with-output-to-file "display.txt"
+ (lambda () #@{ \displayMusic @{ c'4\f @} #@}))
+@}
+@end example
+
+
+Un poco de reformateo hace a la información anterior más fácil de
+leer:
@example
(make-music 'SequentialMusic
- 'elements (list (make-music 'EventChord
- 'elements (list (make-music 'NoteEvent
- 'duration (ly:make-duration 2 0 1 1)
- 'pitch (ly:make-pitch 0 0 0))
- (make-music 'AbsoluteDynamicEvent
- 'text "f")))))
+ 'elements (list
+ (make-music 'NoteEvent
+ 'articulations (list
+ (make-music 'AbsoluteDynamicEvent
+ 'text
+ "f"))
+ 'duration (ly:make-duration 2 0 1/1)
+ 'pitch (ly:make-pitch 0 0 0))))
@end example
Una secuencia musical @code{@{ ... @}} tiene el nombre
@code{SequentialMusic}, y sus expresiones internas se almacenan coma
-una lista dentro de su propiedad @code{'elements}. Se representa una
-nota como una expresión @code{EventChord} que contiene un objeto
-@code{NoteEvent} (que almacena las propiedades de duración y altura) y
-cualquier información adicional (en este caso, un
-@code{AbsoluteDynamicEvent} con una propiedad @code{"f"} de texto.
-
+una lista dentro de su propiedad @code{'elements}. Una nota se
+representa como un objeto @code{NoteEvent} (que almacena las
+propiedades de duración y altura) con información adjunta (en este
+caso, un evento @code{AbsoluteDynamicEvent} con una propiedad
+@code{"f"} de texto) almacenada en su propiedad @code{articulations}.
+
+@funindex{\void}
+@code{\displayMusic} devuelve la música que imprime en la consola, y
+por ello se interpretará al tiempo que se imprime en la consola. Para
+evitar la interpretación, escriba @code{\void} antes de
+@code{\displayMusic}.
@node Propiedades musicales
@subsection Propiedades musicales
@translationof Music properties
-El objeto @code{NoteEvent} es el primer objeto de la propiedad
-@code{'elements} de @code{someNote}.
+@c TODO -- make sure we delineate between @emph{music} properties,
+@c @emph{context} properties, and @emph{layout} properties. These
+@c are potentially confusing.
+
+Veamos un ejemplo:
@example
someNote = c'
\displayMusic \someNote
===>
+(make-music
+ 'NoteEvent
+ 'duration
+ (ly:make-duration 2 0 1/1)
+ 'pitch
+ (ly:make-pitch 0 0 0))
+@end example
+
+The @code{NoteEvent} object is the representation of @code{someNote}.
+Straightforward. How about putting c' in a chord?
+
+@example
+someNote = <c'>
+\displayMusic \someNote
+===>
(make-music
'EventChord
'elements
(list (make-music
'NoteEvent
'duration
- (ly:make-duration 2 0 1 1)
+ (ly:make-duration 2 0 1/1)
'pitch
(ly:make-pitch 0 0 0))))
@end example
+Ahora el objeto @code{NoteEvent} es el primer objeto
+de la propiedad @code{'elements} de @code{someNote}.
+
La función @code{display-scheme-music} es la función que se usa por
parte de @code{\displayMusic} para imprimir la representación de
Scheme de una expresión musical.
(make-music
'NoteEvent
'duration
- (ly:make-duration 2 0 1 1)
+ (ly:make-duration 2 0 1/1)
'pitch
(ly:make-pitch 0 0 0))
@end example
Después se accede a la altura de la nota a través de la propiedad
-@code{'pitch} del objeto @code{NoteEvent},
+@code{'pitch} del objeto @code{NoteEvent}:
@example
#(display-scheme-music
(ly:make-pitch 0 0 0)
@end example
-La altura de la nota se puede cambiar estableciendo su propiedad
-@code{'pitch},
+La altura de la nota se puede cambiar estableciendo el valor de esta
+propiedad @code{'pitch},
@funindex \displayLilyMusic
@translationof Doubling a note with slurs (example)
Supongamos que queremos crear una función que convierte una entrada
-como @code{a} en @code{a( a)}. Comenzamos examinando la
-representación interna del resultado deseado.
+como @code{a} en @code{@{ a( a) @}}. Comenzamos examinando la
+representación interna de la música con la que queremos terminar.
@example
\displayMusic@{ a'( a') @}
'SequentialMusic
'elements
(list (make-music
- 'EventChord
- 'elements
+ 'NoteEvent
+ 'articulations
(list (make-music
- 'NoteEvent
- 'duration
- (ly:make-duration 2 0 1 1)
- 'pitch
- (ly:make-pitch 0 5 0))
- (make-music
'SlurEvent
'span-direction
- -1)))
+ -1))
+ 'duration
+ (ly:make-duration 2 0 1/1)
+ 'pitch
+ (ly:make-pitch 0 5 0))
(make-music
- 'EventChord
- 'elements
+ 'NoteEvent
+ 'articulations
(list (make-music
- 'NoteEvent
- 'duration
- (ly:make-duration 2 0 1 1)
- 'pitch
- (ly:make-pitch 0 5 0))
- (make-music
'SlurEvent
'span-direction
- 1)))))
+ 1))
+ 'duration
+ (ly:make-duration 2 0 1/1)
+ 'pitch
+ (ly:make-pitch 0 5 0))))
@end example
-Las malas noticias son que las expresiones @code{SlurEvent} se deben
-añadir @q{dentro} de la nota (o para ser más exactos, dentro de la
-expresión @code{EventChord}).
+La mala noticia es que las expresiones @code{SlurEvent} se deben
+añadir @q{dentro} de la nota (dentro de la
+propiedad @code{articulations}).
Ahora examinamos la entrada,
@example
+\displayMusic a'
+===>
(make-music
- 'SequentialMusic
- 'elements
- (list (make-music
- 'EventChord
- 'elements
- (list (make-music
- 'NoteEvent
- 'duration
- (ly:make-duration 2 0 1 1)
- 'pitch
- (ly:make-pitch 0 5 0))))))
+ 'NoteEvent
+ 'duration
+ (ly:make-duration 2 0 1/1)
+ 'pitch
+ (ly:make-pitch 0 5 0))))
@end example
-Así que en nuestra función, tenemos que clonar esta expresión (de
+Así pues, en nuestra función, tenemos que clonar esta expresión (de
forma que tengamos dos notas para construir la secuencia), añadir
-@code{SlurEvents} a la propiedad @code{'elements} de cada una, y
-finalmente hacer una secuencia @code{SequentialMusic} con los dos
-@code{EventChords}.
+@code{SlurEvent} a la propiedad @code{'articulations} de cada una de
+ellas, y por último hacer una secuencia @code{SequentialMusic} con los
+dos @code{EventChords}. Para añadir a una propiedad, es útil saber
+que una propiedad no establecida se lee como @code{'()}, la lista
+vacía, así que no se requiere ninguna comprobación especial antes de
+que pongamos otro elemento delante de la propiedad
+@code{articulations}.
+
@example
doubleSlur = #(define-music-function (parser location note) (ly:music?)
"Return: @{ note ( note ) @}.
- `note' is supposed to be an EventChord."
+ `note' is supposed to be a single note."
(let ((note2 (ly:music-deep-copy note)))
- (set! (ly:music-property note 'elements)
+ (set! (ly:music-property note 'articulations)
(cons (make-music 'SlurEvent 'span-direction -1)
- (ly:music-property note 'elements)))
- (set! (ly:music-property note2 'elements)
+ (ly:music-property note 'articulations)))
+ (set! (ly:music-property note2 'articulations)
(cons (make-music 'SlurEvent 'span-direction 1)
- (ly:music-property note2 'elements)))
+ (ly:music-property note2 'articulations)))
(make-music 'SequentialMusic 'elements (list note note2))))
@end example
@translationof Adding articulation to notes (example)
La manera fácil de añadir articulación a las notas es mezclar dos
-expresiones musicales en un solo contexto, como se explica en
-@ruser{Crear contextos}. Sin embargo, supongamos que queremos
-escribir una función musical que lo haga.
+expresiones musicales en un solo contexto.
+Sin embargo, supongamos que queremos
+escribir una función musical que lo haga. Esto tiene la ventaja
+adicional de que podemos usar esa función musical para añadir una
+articulación (como una instrucción de digitación) a una nota única
+dentro de un acorde, lo cual no es posible si nos limitamos a mezclar
+fragmentos de música independientes.
Una @code{$variable} dentro de la notación @code{#@{...#@}} es como
una @code{\variable} normal en la notación clásica de LilyPond.
@noindent
no funciona en LilyPond. Podríamos evitar este problema adjuntando la
-articulación a una nota falsa,
+articulación a un acorde vacío,
@example
-@{ << \music s1*0-.-> @}
+@{ << \music <> -. -> >> @}
@end example
@noindent
-pero para los propósitos de este ejemplo, aprenderemos cómo hacerlo en
-Scheme. Empezamos examinando nuesta entrada y la salida deseada,
+pero a los efectos de este ejemplo, aprenderemos ahora cómo hacerlo en
+Scheme. Empezamos examinando nuestra entrada y la salida deseada,
@example
% input
\displayMusic c4
===>
(make-music
- 'EventChord
- 'elements
- (list (make-music
- 'NoteEvent
- 'duration
- (ly:make-duration 2 0 1 1)
- 'pitch
- (ly:make-pitch -1 0 0))))
+ 'NoteEvent
+ 'duration
+ (ly:make-duration 2 0 1/1)
+ 'pitch
+ (ly:make-pitch -1 0 0))))
=====
% desired output
\displayMusic c4->
===>
(make-music
- 'EventChord
- 'elements
+ 'NoteEvent
+ 'articulations
(list (make-music
- 'NoteEvent
- 'duration
- (ly:make-duration 2 0 1 1)
- 'pitch
- (ly:make-pitch -1 0 0))
- (make-music
'ArticulationEvent
'articulation-type
- "marcato")))
+ "accent"))
+ 'duration
+ (ly:make-duration 2 0 1/1)
+ 'pitch
+ (ly:make-pitch -1 0 0))
@end example
-Vemos que una nota (@code{c4}) se representa omo una expresión
-@code{EventChord}, con una expresión @code{NoteEvent} en su lista de
-elementos. Para añadir una articulación de marcato, se debe añadir
-una expresión @code{ArticulationEvent} a la propiedad elements de la
-expresión @code{EventChord}.
+Vemos que una nota (@code{c4}) se representa como una expresión
+@code{NoteEvent}. Para añadir una articulación de acento, se debe
+añadir una expresión @code{ArticulationEvent} a la propiedad
+@code{articulations} de la expresión @code{NoteEvent}.
-Para construir esta función, comenzamos por
+Para construir esta función, empezamos con
@example
-(define (add-marcato event-chord)
- "Add a marcato ArticulationEvent to the elements of `event-chord',
- which is supposed to be an EventChord expression."
- (let ((result-event-chord (ly:music-deep-copy event-chord)))
- (set! (ly:music-property result-event-chord 'elements)
- (cons (make-music 'ArticulationEvent
- 'articulation-type "marcato")
- (ly:music-property result-event-chord 'elements)))
- result-event-chord))
+(define (add-accent note-event)
+ "Add an accent ArticulationEvent to the articulations of `note-event',
+ which is supposed to be a NoteEvent expression."
+ (set! (ly:music-property note-event 'articulations)
+ (cons (make-music 'ArticulationEvent
+ 'articulation-type "accent")
+ (ly:music-property note-event 'articulations)))
+ note-event)
@end example
La primera línea es la forma de definir una función en Scheme: el
-nombre de la función es @code{add-marcato}, y tiene una variable
-llamada @code{event-chord}. En Scheme, el tipo de variable suele ser
-evidente a partir de su nombre (¡ésta es una buena práctica también en
-otros lenguajes de programación!!)
+nombre de la función es @code{add-accent}, y tiene una variable
+llamada @code{note-event}. En Scheme, el tipo de variable suele
+quedar claro a partir de su nombre (¡esto también es una buena
+práctica en otros lenguajes de programación!)
@example
-"Add a marcato..."
+"Add an accent..."
@end example
@noindent
necesaria, pero de igual forma que los nombres claros de variable, es
una buena práctica.
-@example
-(let ((result-event-chord (ly:music-deep-copy event-chord)))
-@end example
-
-Se usa @code{let} para declarar las variables locales. Aquí, usamos
-una variable local, llamada @code{result-event-chord}, a la que le
-damos el valor @code{(ly:music-deep-copy event-chord)}.
-@code{ly:music-deep-copy} Es una función específica de LilyPond, como
-todas las funciones predecidas de @code{ly:}. Se usa para hacer una
-copia de una expresión musical. Aquí, copiamos @code{event-chord} (el
-parámetro de la función). Recuerde que nuestro propósito es añadir un
-marcato a una expresión @code{EventChord}. Es mejor no mdoficar el
-@code{EventChord} que se ha dado como argumento, porque se puede usar
-en algún otro lugar.
-
-Ahora tenemos un @code{result-event-chord}, que es una expresión
-@code{NoteEventChord} y es una copia de @code{event-chord}. Añadimos
-el marcato a su propiedad de la lista de @code{'elements}.
+Se preguntará porqué modificamos el evento de nota directamente en
+lugar de trabajar sobre una copia (se puede usar
+@code{ly:music-deep-copy} para ello). La razón es un contrato
+silencioso: se permite que las funciones musicales modifiquen sus
+argumentos; o bien se generan partiendo de cero (como la entrada del
+usuario) o están ya copiadas (referenciar una variable de música con
+@samp{\name} o la música procedente de expresiones de Scheme
+inmediatas @samp{$(@dots{})} proporcionan una copia). Dado que sería
+ineficiente crear copias innecesarias, el valor devuelto de una
+función musical @emph{no} se copia. Así pues, para cumplir dicho
+contrato, no debemos usar ningún argumento más de una vez, y
+devolverlo cuenta como una vez.
+
+En un ejemplo anterior, hemos construido música mediante la repetición
+de un argumento musical dado. En tal caso, al menos una repetidión
+tuvo que ser una copia de sí misma. Si no lo fuese, podrían ocurrir
+cosas muy extrañas. Por ejemplo, si usamos @code{\relative} o
+@code{\transpose} sobre la música resultante que contiene los mismos
+elementos varias veces, estarían sujetos varias veces a la
+relativización o al transporte. Si los asignamos a una variable de
+música, se rompe el curso porque hacer referencia a @samp{\name}
+creará de nuevo una copia que no retiene la identidad de los elementos
+repetidos.
+
+Ahora bien, aun cuando la función anterior no es una función musical,
+se usará normalmente dentro de funciones musicales. Así pues, tiene
+sentido obedecer el mismo convenio que usamos para las funciones
+musicales: la entrada puede modificarse para producir la salida, y el
+código que llama es responsable de crear las copias si aún necesita el
+propio argumento sin modificar. Si observamos las propias funciones
+de LilyPond como @code{music-map}, veremos que se atienen a los mismos
+principios.
+
+¿En qué punto nos encontramos? Ahora tenemos un @code{note-event} que
+podemos modificar, no a causa de la utilización de
+@code{ly:music-deep-copy} sino por una explicación muy desarrollada.
+Añadimos el acento a su propiedad de lista @code{'articulations}.
@example
-(set! lugar nuevo-valor)
+(set! place new-value)
@end example
-Aquí, lo que queremos establecer (el @q{lugar}) es la propiedad
-@code{'elements} de la expresión @code{result-event-chord}.
+Aquí, lo que queremos establecer (el @q{place}) es la propiedad
+@code{'articulations} de la expresión @code{note-event}.
@example
-(ly:music-property result-event-chord 'elements)
+(ly:music-property note-event 'articulations)
@end example
-@code{ly:music-property} es la función que se usa para acceder a las
-propiedades musicales (los @code{'elements}, @code{'duration},
-@code{'pitch}, etc, que vimos en la salida de @code{\displayMusic}
-anterior). El nuevo valor es la antigua propiedad @code{'elements},
-con un elemento adicional: la expresión @code{ArticulationEvent}, que
-copiamos de la salida de @code{\displayMusic},
+@code{ly:music-property} es la función ustilizada para acceder a las
+propiedades musicales (las @code{'articulations}, @code{'duration},
+@code{'pitch}, etc, que vemos arriba en la salida de
+@code{\displayMusic}). El nuevo valor es la antigua propiedad
+@code{'articulations}, con un elemento adicional: la expresión
+@code{ArticulationEvent}, que copiamos a partir de la salida de
+@code{\displayMusic},
@example
(cons (make-music 'ArticulationEvent
- 'articulation-type "marcato")
- (ly:music-property result-event-chord 'elements))
+ 'articulation-type "accent")
+ (ly:music-property result-event-chord 'articulations))
@end example
-@code{cons} se usa para añadir un elemento a una lista sin modificar
-la lista original. Esto es lo que queremos: la misma lista que antes,
-más la expresión @code{ArticulationEvent} nueva. El orden dentro de
-la propiedad @code{'elements} no es importante aquí.
+Se usa @code{cons} para añadir un elemento a la parte delantera de una
+lista sin modificar la lista original. Esto es lo que queremos: la
+misma lista de antes, más la nueva expresión @code{ArticulationEvent}.
+El orden dentro de la propiedad @code{'articulations} no tiene
+importancia aquí.
-Finalmente, una vez hemos añadido la articulación marcato a su
-propiedad @code{elements}, podemos devolver @code{result-event-chord},
-de ahí la última línea de la función.
+Finalmente, una vez hemos añadido la articulación de acento a su
+propiedad @code{articulations}, podemos devolver @code{note-event}, de
+aquí la última línea de la función.
-Ahora transformamos la función @code{add-marcato} en una función
-musical,
+Ahora transformamos la función @code{add-accent} en una función
+musical (es cuestión de un poco de aderezo sintáctico y una
+declaración del tipo de su único argumento @q{real}).
@example
-addMarcato = #(define-music-function (parser location event-chord)
+addAccent = #(define-music-function (parser location note-event)
(ly:music?)
- "Add a marcato ArticulationEvent to the elements of `event-chord',
- which is supposed to be an EventChord expression."
- (let ((result-event-chord (ly:music-deep-copy event-chord)))
- (set! (ly:music-property result-event-chord 'elements)
- (cons (make-music 'ArticulationEvent
- 'articulation-type "marcato")
- (ly:music-property result-event-chord 'elements)))
- result-event-chord))
+ "Add an accent ArticulationEvent to the articulations of `note-event',
+ which is supposed to be a NoteEvent expression."
+ (set! (ly:music-property note-event 'articulations)
+ (cons (make-music 'ArticulationEvent
+ 'articulation-type "accent")
+ (ly:music-property note-event 'articulations)))
+ note-event)
@end example
-Podemos verificar que esta función musical funciona correctamente,
+Podemos verificar que esta función musical funciona correctamente:
@example
-\displayMusic \addMarcato c4
+\displayMusic \addAccent c4
@end example
-
-
-
-
@ignore
@menu
* Trucos con Scheme::
@end menu
-@node Trucos con Scheme
-@c @section Trucos con Scheme
-@translationof Tweaking with Scheme
+@c @nod e Trucos con Scheme
+@c @sectio n Trucos con Scheme
+@c @transl ationof Tweaking with Scheme
Hemos visto cómo la salida de LilyPond se puede modificar
-profundamente usando instrucciones como @code{\override TextScript
-#'extra-offset = ( 1 . -1)}. Pero tenemos incluso mucho más poder si
+profundamente usando instrucciones como
+@code{\override TextScript.extra-offset = ( 1 . -1)}.
+Pero tenemos incluso mucho más poder si
utilizamos Scheme. Para ver una explicación completa de esto,
consulte el @ref{Tutorial de Scheme}, y @ruser{Interfaces para programadores}.
@lilypond[quote,verbatim,ragged-right]
padText = #(define-music-function (parser location padding) (number?)
#{
- \once \override TextScript #'padding = #$padding
+ \once \override TextScript.padding = #padding
#})
\relative c''' {
@lilypond[quote,verbatim,ragged-right]
tempoPadded = #(define-music-function (parser location padding tempotext)
- (number? string?)
+ (number? markup?)
#{
- \once \override Score.MetronomeMark #'padding = $padding
- \tempo \markup { \bold $tempotext }
+ \once \override Score.MetronomeMark.padding = #padding
+ \tempo \markup { \bold #tempotext }
#})
\relative c'' {
\tempo \markup { "Low tempo" }
c4 d e f g1
- \tempoPadded #4.0 #"High tempo"
+ \tempoPadded #4.0 "High tempo"
g4 f e d c1
}
@end lilypond
@lilypond[quote,verbatim,ragged-right]
pattern = #(define-music-function (parser location x y) (ly:music? ly:music?)
#{
- $x e8 a b $y b a e
+ #x e8 a b #y b a e
#})
\relative c''{