1 @c -*- coding: utf-8; mode: texinfo; documentlanguage: es -*-
4 Translation of GIT committish: e18567dccce0f16b680e6b7e562329e5f8bcae59
6 When revising a translation, copy the HEAD committish of the
7 version that you are working on. For details, see the Contributors'
8 Guide, node Updating translation committishes..
13 @node Tutorial de Scheme
14 @appendix Tutorial de Scheme
15 @translationof Scheme tutorial
20 @cindex Scheme, código en línea
21 @cindex acceder a Scheme
22 @cindex evaluar Scheme
25 LilyPond utiliza el lenguaje de programación Scheme, tanto como parte
26 de la sintaxis del código de entrada, como para servir de mecanismo
27 interno que une los módulos del programa entre sí. Esta sección es
28 una panorámica muy breve sobre cómo introducir datos en Scheme. Si
29 quiere saber más sobre Scheme, consulte
30 @uref{http://@/www@/.schemers@/.org}.
32 LilyPond utiliza la implementación GNU Guile de Scheme, que está
33 basada en el estándar @qq{R5RS} del lenguaje. Si está aprendiendo
34 Scheme para usarlo con LilyPond, no se recomienda trabajar con una
35 implementación distinta (o que se refiera a un estándar diferente).
36 Hay información sobre Guile en
37 @uref{http://www.gnu.org/software/guile/}. El estándar de Scheme
38 @qq{R5RS} se encuentra en
39 @uref{http://www.schemers.org/Documents/Standards/R5RS/}.
42 * Introducción a Scheme::
43 * Scheme dentro de LilyPond::
44 * Construir funciones complicadas::
47 @node Introducción a Scheme
48 @section Introducción a Scheme
49 @translationof Introduction to Scheme
51 Comenzaremos con una introducción a Scheme. Para esta breve
52 introducción utilizaremos el intérprete GUILE para explorar la manera
53 en que el lenguaje funciona. Una vez nos hayamos familiarizado con
54 Scheme, mostraremos cómo se puede integrar el lenguaje en los archivos
59 * Cajón de arena de Scheme::
60 * Variables de Scheme::
61 * Tipos de datos simples de Scheme::
62 * Tipos de datos compuestos de Scheme::
63 * Cálculos en Scheme::
64 * Procedimientos de Scheme::
65 * Condicionales de Scheme::
68 @node Cajón de arena de Scheme
69 @subsection Cajón de arena de Scheme
70 @translationof Scheme sandbox
72 La instalación de LilyPond incluye también la de la implementación
73 Guile de Scheme. Sobre casi todos los sistemas puede experimentar en
74 una @qq{caja de arena} de Scheme abriendo una ventana del terminal y
75 tecleando @q{guile}. En algunos sistemas, sobre todo en Windows,
76 podría necesitar ajustar la variable de entorno @code{GUILE_LOAD_PATH}
77 a la carpeta @code{../usr/shr/guile/1.8} dentro de la instalación de
78 LilyPond (para conocer la ruta completa a esta carpeta, consulte
79 @rlearning{Otras fuentes de información}). Como alternativa, los
80 usuarios de Windows pueden seleccionar simplemente @q{Ejecutar} del
81 menú Inicio e introducir @q{guile}.
83 Una vez está funcionando el cajón de arena de Guile, verá un indicador
90 Podemos introducir expresiones de Scheme en este indicador para
91 experimentar con Scheme.
93 @node Variables de Scheme
94 @subsection Variables de Scheme
95 @translationof Scheme variables
97 Las variables de Scheme pueden tener cualquier valor válido de Scheme,
98 incluso un procedimiento de Scheme.
100 Las variables de Scheme se crean con @code{define}:
107 Las variables de Scheme se pueden evaluar en el indicador del sistema
108 de guile, simplemente tecleando el nombre de la variable:
116 Las variables de Scheme se pueden imprimir en la pantalla utilizando
125 Observe que el valor @code{2} y el indicador del sistema @code{guile}
126 se muestran en la misma línea. Esto se puede evitar llamando al
127 procedimiento de nueva línea o imprimiendo un carácter de nueva línea.
130 guile> (display a)(newline)
132 guile> (display a)(display "\n")
137 Una vez que se ha creado una variable, su valor se puede modificar con
141 guile> (set! a 12345)
147 @node Tipos de datos simples de Scheme
148 @subsection Tipos de datos simples de Scheme
149 @translationof Scheme simple data types
151 El concepto más básico de un lenguaje son sus tipos de datos: números,
152 cadenas de caracteres, listas, etc. He aquí una lista de los tipos de
153 datos que son de relevancia respecto de la entrada de LilyPond.
157 Los valores Booleanos son Verdadero y Falso. Verdadero en Scheme es
158 @code{#t} y Falso es @code{#f}.
163 Los números se escriben de la forma normal, @code{1} es el número
164 (entero) uno, mientras que @code{-1.5} es un número en coma flotante
165 (un número no entero).
168 Las cadenas se encierran entre comillas:
174 Las cadenas pueden abarcar varias líneas:
183 y los caracteres de nueva línea al final de cada línea se incluirán
186 Los caracteres de nueva línea también se pueden añadir mediante la
187 inclusión de @code{\n} en la cadena.
190 "esto\nes una\ncadena de varias líneas"
194 Las comillas dobles y barras invertidas se añaden a las cadenas
195 precediéndolas de una barra invertida. La cadena @code{\a dijo "b"}
204 Existen más tipos de datos de Scheme que no se estudian aquí. Para
205 ver un listado completo, consulte la guía de referencia de Guile,
206 @uref{http://www.gnu.org/software/guile/manual/html_node/Simple-Data-Types.html}.
208 @node Tipos de datos compuestos de Scheme
209 @subsection Tipos de datos compuestos de Scheme
210 @translationof Scheme compound data types
212 También existen tipos de datos compuestos en Scheme. Entre los tipos
213 más usados en la programación de LilyPond se encuentran las parejas,
214 las listas, las listas-A y las tablas de hash.
218 El tipo fundacional de datos compuestos de Scheme es la @code{pareja}.
219 Como se espera por su nombre, una pareja son dos valores unidos en uno
220 solo. El operador que se usa para formar una pareja se llama
229 Observe que la pareja se imprime como dos elementos rodeados por
230 paréntesis y separados por un espacio, un punto (@code{.}) y otro
231 espacio. El punto @emph{no es} un punto decimal, sino más bien un
234 Las parejas también se pueden introducir como valores literales
235 precediéndolos de un carácter de comilla simple o apóstrofo.
243 Los dos elementos de una pareja pueden ser cualquier valor válido de
249 guile> '("bla-bla" . 3.1415926535)
250 ("bla-bla" . 3.1415926535)
254 Se puede accede al primero y segundo elementos de la pareja mediante
255 los procedimientos de Scheme @code{car} y @code{cdr}, respectivamente.
258 guile> (define mipareja (cons 123 "Hola")
260 guile> (car mipareja)
262 guile> (cdr mipareja)
269 Nota: @code{cdr} se pronuncia "could-er", según Sussman y Abelson,
271 @uref{http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-14.html#footnote_Temp_133}
276 Una estructura de datos muy común en Scheme es la @emph{lista}.
277 Formalmente, una lista se define como la lista vacía (representada
278 como @code{'()}, o bien como una pareja cuyo @code{cdr} es una lista.
280 Existen muchas formas de crear listas. Quizá la más común es con el
281 procedimiento @code{list}:
284 guile> (list 1 2 3 "abc" 17.5)
288 Como se ve, una lista se imprime en la forma de elementos individuales
289 separados por espacios y encerradas entre paréntesis. A diferencia de
290 las parejas, no hay ningún punto entre los elementos.
292 También se puede escribir una lista como una lista literal encerrando
293 sus elementos entre paréntesis y añadiendo un apóstrofo:
296 guile> '(17 23 "fulano" "mengano" "zutano")
297 (17 23 "fulano" "mengano" "zutano")
300 Las listas son una parte fundamental de Scheme. De hecho, Scheme se
301 considera un dialecto de Lisp, donde @q{lisp} es una abreviatura de
302 @q{List Processing} (proceso de listas). Todas las expresiones de
305 @subheading Listas asociativas (listas-A)
307 Un tipo especial de listas son las @emph{listas asociativas} o
308 @emph{listas-A}. Se puede usar una lista-A para almacenar datos para
309 su fácil recuperación posterior.
311 Las listas-A son listas cuyos elementos son parejas. El @code{car} de
312 cada elemento se llama @emph{clave}, y el @code{cdr} de cada elemento
313 se llama @emph{valor}. El procedimiento de Scheme @code{assoc} se usa
314 para recuperar un elemento de la lista-A, y @code{cdr} se usa para
318 guile> (define mi-lista-a '((1 . "A") (2 . "B") (3 . "C")))
320 ((1 . "A") (2 . "B") (3 . "C"))
321 guile> (assoc 2 mi-lista-a)
323 guile> (cdr (assoc 2 mi-lista-a))
328 Las listas-A se usan mucho en LilyPond para almacenar propiedades y
331 @subheading Tablas de hash
333 Estructuras de datos que se utilizan en LilyPond de forma ocasional.
334 Una tabla de hash es similar a una matriz, pero los índices de la
335 matriz pueden ser cualquier tipo de valor de Scheme, no sólo enteros.
337 Las tablas de hash son más eficientes que las listas-A si hay una gran
338 cantidad de datos que almacenar y los datos cambian con muy poca
341 La sintaxis para crear tablas de hash es un poco compleja, pero
342 veremos ejemplos de ello en el código fuente de LilyPond.
345 guile> (define h (make-hash-table 10))
348 guile> (hashq-set! h 'key1 "val1")
350 guile> (hashq-set! h 'key2 "val2")
352 guile> (hashq-set! h 3 "val3")
356 Los valores se recuperan de las tablas de hash mediante
360 guile> (hashq-ref h 3)
362 guile> (hashq-ref h 'key2)
367 Las claves y los valores se recuperan como una pareja con
368 @code{hashq-get-handle}. Ésta es la forma preferida, porque devuelve
369 @code{#f} si no se encuentra la clave.
372 guile> (hashq-get-handle h 'key1)
374 guile> (hashq-get-handle h 'frob)
379 @node Cálculos en Scheme
380 @subsection Cálculos en Scheme
381 @translationof Calculations in Scheme
384 Todo el tiempo hemos estado usando listas. Un cálculo, como @code{(+
385 1 2)} también es una lista (que contiene el símbolo @code{+} y los
386 números 1 y@tie{}2). Normalmente, las listas se interpretan como
387 cálculos, y el intérprete de Scheme sustituye el resultado del
388 cálculo. Para escribir una lista, detenemos la evaluación. Esto se
389 hace precediendo la lista por un apóstrofo @code{'}. Así, para los
390 cálculos no usamos ningún apóstrofo.
392 Dentro de una lista o pareja precedida de apóstrofo, no hay necesidad
393 de escribir ningún apóstrofo más. Lo siguiente es una pareja de
394 símbolos, una lista de símbolos y una lista de listas respectivamente:
398 #'(staff clef key-signature)
403 Scheme se puede usar para hacer cálculos. Utiliza sintaxis
404 @emph{prefija}. Sumar 1 y@tie{}2 se escribe como @code{(+ 1 2)} y no
405 como el tradicional @math{1+2}.
412 Los cálculos se pueden anidar; el resultado de una función se puede
413 usar para otro cálculo.
420 Estos cálculos son ejemplos de evaluaciones; una expresión como
421 @code{(* 3 4)} se sustituye por su valor @code{12}.
423 Los cálculos de Scheme son sensibles a las diferencias entre enteros y
424 no enteros. Los cálculos enteros son exactos, mientras que los no
425 enteros se calculan con los límites de precisión adecuados:
434 Cuando el intérprete de Scheme encuentra una expresión que es una
435 lista, el primer elemento de la lista se trata como un procedimiento a
436 evaluar con los argumentos del resto de la lista. Por tanto, todos
437 los operadores en Scheme son operadores prefijos.
439 Si el primer elemento de una expresión de Scheme que es una lista que
440 se pasa al intérprete @emph{no es} un operador o un procedimiento, se
450 <unnamed port>:52:1: In expression (1 2 3):
451 <unnamed port>:52:1: Wrong type to apply: 1
456 Aquí podemos ver que el intérprete estaba intentando tratar el 1 como
457 un operador o procedimiento, y no pudo hacerlo. De aquí que el error
458 sea "Wrong type to apply: 1".
460 Así pues, para crear una lista debemos usar el operador de lista, o
461 podemos precederla de un apóstrofo para que el intérprete no trate de
472 Esto es un error que puede aparecer cuando trabaje con Scheme dentro
476 La misma asignación se puede hacer también completamente en Scheme,
479 #(define veintiCuatro (* 2 doce))
482 @c this next section is confusing -- need to rewrite
484 El @emph{nombre} de una variable también es una expresión, similar a
485 un número o una cadena. Se introduce como
492 @cindex comillas en Scheme
494 El apóstrofo @code{'} evita que el intérprete de Scheme sustituya
495 @code{veintiCuatro} por @code{24}. En vez de esto, obtenemos el
496 nombre @code{veintiCuatro}.
500 @node Procedimientos de Scheme
501 @subsection Procedimientos de Scheme
502 @translationof Scheme procedures
504 Los procedimientos de Scheme son expresiones de Scheme ejecutables que
505 devuelven un valor resultante de su ejecución. También pueden
506 manipular variables definidas fuera del procedimiento.
508 @subheading Definir procedimientos
510 Los procedimientos se definen en Scheme con @code{define}:
513 (define (nombre-de-la-función arg1 arg2 ... argn)
514 expresión-de-scheme-que-devuelve-un-valor)
517 Por ejemplo, podemos definir un procedimiento para calcular la media:
520 guile> (define (media x y) (/ (+ x y) 2))
522 #<procedure media (x y)>
525 Una vez se ha definido un procedimiento, se llama poniendo el nombre
526 del procedimiento dentro de una lista. Por ejemplo, podemos calcular
534 @subheading Predicados
536 Los procedimientos de Scheme que devuelven valores booleanos se suelen
537 llamar @emph{predicados}. Por convenio (pero no por necesidad),
538 los nombres de predicados acaban en un signo de interrogación:
541 guile> (define (menor-que-diez? x) (< x 10))
542 guile> (menor-que-diez? 9)
544 guile> (menor-que-diez? 15)
548 @subheading Valores de retorno
550 A veces, el usuario quiere tener varias expresiones de Scheme dentro
551 de un procedimiento. Existen dos formas en que se pueden combinar
552 distintas expresiones. La primera es el procedimiento @code{begin},
553 que permite evaluar varias expresiones, y devuelve el valor de la
557 guile> (begin (+ 1 2) (- 5 8) (* 2 2))
561 La segunda forma de combinar varias expresiones es dentro de un bloque
562 @code{let}. Dentro de un bloque let, se crean una serie de ligaduras
563 o asignaciones, y después se evalúa una secuencia de expresiones que
564 pueden incluir esas ligaduras o asignaciones. El valor de retorno del
565 bloque let es el valor de retorno de la última sentencia del bloque
569 guile> (let ((x 2) (y 3) (z 4)) (display (+ x y)) (display (- z 4))
570 ... (+ (* x y) (/ z x)))
574 @node Condicionales de Scheme
575 @subsection Condicionales de Scheme
576 @translationof Scheme conditionals
580 Scheme tiene un procedimiento @code{if}:
583 (if expresión-de-prueba expresión-de-cierto expresión-de-falso)
586 @var{expresión-de-prueba} es una expresión que devuelve un valor
587 booleano. Si @var{expresión-de-prueba} devuelve @code{#t}, el
588 procedimiento @code{if} devuelve el valor de la
589 @var{expresión-de-cierto}, en caso contrario devuelve el valor de la
590 @var{expresión-de-falso}.
595 guile> (if (> a b) "a es mayor que b" "a no es mayor que b")
596 "a no es mayor que b"
601 Otro procedimiento condicional en scheme es @code{cond}:
604 (cond (expresión-de-prueba-1 secuencia-de-expresiones-resultante-1)
605 (expresión-de-prueba-2 secuencia-de-expresiones-resultante-2)
607 (expresión-de-prueba-n secuencia-de-expresiones-resultante-n))
615 guile> (cond ((< a b) "a es menor que b")
616 ... ((= a b) "a es igual a b")
617 ... ((> a b) "a es mayor que b"))
621 @node Scheme dentro de LilyPond
622 @section Scheme dentro de LilyPond
623 @translationof Scheme in LilyPond
626 * Sintaxis del Scheme de LilyPond::
627 * Variables de LilyPond::
628 * Variables de entrada y Scheme::
629 * Propiedades de los objetos::
630 * Variables de LilyPond compuestas::
631 * Representación interna de la música::
634 @node Sintaxis del Scheme de LilyPond
635 @subsection Sintaxis del Scheme de LilyPond
636 @translationof LilyPond Scheme syntax
638 En un archivo de música, los fragmentos de código de Scheme se
639 escriben con el signo de almohadilla @code{#}. Así, los ejemplos
640 anteriores traducidos a LilyPond son:
645 #"esto es una cadena"
651 Observe que los comentarios de LilyPond (@code{%} y @code{%@{ %@}}) no
652 se pueden utilizar dentro del código de Scheme. Los comentarios en
653 el Scheme de Guile se introducen como sigue:
656 ; esto es un comentario de una línea
659 Esto es un comentario de bloque (no anidable) estilo Guile
660 Pero se usan rara vez por parte de los Schemers y nunca dentro del
661 código fuente de LilyPond
665 Se pueden combinar en un mismo archivo de música varias expresiones de
666 Scheme consecutivas mediante la utilización del operador @code{begin}.
667 Ello permite que el número de marcas de cuadradillo se reduzca a una.
672 (define menganito 1))
675 Si el @code{#} va seguido de un paréntesis de apertura, @code{(}, como
676 en el ejemplo anterior, el analizador sintáctico permanece dentro del
677 modo de Scheme hasta que encuentra el paréntesis de cierre
678 correspondiente, @code{)}, por lo que no son necesarios más símbolos
679 de @code{#} para introducir una sección de Scheme.
681 Durante el resto de esta sección, supondremos que los datos se
682 introducen en un archivo de música, por lo que añadiremos almohadillas
683 @code{#} en todas partes.
685 @node Variables de LilyPond
686 @subsection Variables de LilyPond
687 @translationof LilyPond variables
689 @c TODO -- make this read right
691 Algo similar ocurre con las variables. Después de definir una
699 las variables se pueden usar también dentro de expresiones, aquí
702 veintiCuatro = (* 2 doce)
706 el número 24 se almacena dentro de la variable @code{veintiCuatro}.
708 @node Variables de entrada y Scheme
709 @subsection Variables de entrada y Scheme
710 @translationof Input variables and Scheme
712 El formato de entrada contempla la noción de variables: en el
713 siguiente ejemplo, se asigna una expresión musical a una variable con
714 el nombre @code{traLaLa}.
717 traLaLa = @{ c'4 d'4 @}
722 También hay una forma de ámbito: en el ejemplo siguiente, el bloque
723 @code{\layout} también contiene una variable @code{traLaLa}, que es
724 independiente de la @code{\traLaLa} externa.
727 traLaLa = @{ c'4 d'4 @}
728 \layout @{ traLaLa = 1.0 @}
731 En efecto, cada archivo de entrada constituye un ámbito, y cada bloque
732 @code{\header}, @code{\midi} y @code{\layout} son ámbitos anidados
733 dentro del ámbito de nivel superior.
735 Tanto las variables como los ámbitos están implementados en el sistema
736 de módulos de GUILE. A cada ámbito se adjunta un módulo anónimo de
737 Scheme. Una asignación de la forma
740 traLaLa = @{ c'4 d'4 @}
744 se convierte internamente en una definición de Scheme
747 (define traLaLa @var{Valor Scheme de `@code{... }'})
750 Esto significa que las variables de entrada y las variables de Scheme
751 se pueden mezclar con libertad. En el ejemplo siguiente, se almacena
752 un fragmento de música en la variable @code{traLaLa}, y se duplica
753 usando Scheme. El resultado se importa dentro de un bloque
754 @code{\score} por medio de una segunda variable @code{twice}:
757 traLaLa = { c'4 d'4 }
759 %% dummy action to deal with parser lookahead
760 #(display "this needs to be here, sorry!")
762 #(define newLa (map ly:music-deep-copy
763 (list traLaLa traLaLa)))
765 (make-sequential-music newLa))
770 @c Due to parser lookahead
772 En este ejemplo, la asignación se produce después de que el analizador
773 sintáctico ha verificado que no ocurre nada interesante después de
774 @code{traLaLa = @{ ... @}}. Sin la sentencia muda del ejemplo
775 anterior, la definición de @code{newLa} se ejecuta antes de que se
776 defina @code{traLaLa}, produciendo un error de sintaxis.
778 El ejemplo anterior muestra cómo @q{exportar} expresiones musicales
779 desde la entrada al intérprete de Scheme. Lo contrario también es
780 posible. Envolviendo un valor de Scheme en la función
781 @code{ly:export}, se interpreta un valor de Scheme como si hubiera
782 sido introducido en la sintaxis de LilyPond. En lugar de definir
783 @code{\twice}, el ejemplo anterior podría también haberse escrito como
787 @{ #(ly:export (make-sequential-music (list newLa))) @}
790 El código de Scheme se evalúa tan pronto como el analizador sintáctico
791 lo encuentra. Para definir código de Scheme dentro de un macro (para
792 llamarse más tarde), utilice @ref{Funciones vacías}, o bien
796 (ly:set-option 'point-and-click #f))
805 No es posible mezclar variables de Scheme y de LilyPond con la opción
811 @node Propiedades de los objetos
812 @subsection Propiedades de los objetos
813 @translationof Object properties
815 Esta sintaxis se usará con mucha frecuencia, pues muchos de los trucos
816 de presentación consisten en asignar valores (de Scheme) a variables
817 internas, por ejemplo
820 \override Stem #'thickness = #2.6
823 Esta instrucción ajusta el aspecto de las plicas. El valor @code{2.6}
824 se pone dentro de la variable @code{thickness} de un objeto
825 @code{Stem}. @code{thickness} se mide a partir del grosor de las
826 líneas del pentagrama, y así estas plicas serán @code{2.6} veces el
827 grosor de las líneas del pentagrama. Esto hace que las plicas sean
828 casi el doble de gruesas de lo normal. Para distinguir entre las
829 variables que se definen en los archivos de entrada (como
830 @code{veintiCuatro} en el ejemplo anterior) y las variables de los
831 objetos internos, llamaremos a las últimas @q{propiedades} y a las
832 primeras @q{variables.} Así, el objeto plica tiene una propiedad
833 @code{thickness} (grosor), mientras que @code{veintiCuatro} es una
836 @cindex propiedades frente a variables
837 @cindex variables frente a propiedades
839 @c todo -- here we're getting interesting. We're now introducing
840 @c LilyPond variable types. I think this deserves a section all
843 @node Variables de LilyPond compuestas
844 @subsection Variables de LilyPond compuestas
845 @translationof LilyPond compound variables
847 @subheading Desplazamientos
849 Los desplazamientos bidimensionales (coordenadas X e Y) así como los
850 tamaños de los objetos (intervalos con un punto izquierdo y otro
851 derecho) se introducen como @code{parejas}. Una pareja@footnote{En la
852 terminología de Scheme, la pareja se llama @code{cons}, y sus dos
853 elementos se llaman @code{car} y @code{cdr} respectivamente.} se
854 introduce como @code{(primero . segundo)} y, como los símbolos, se deben
855 preceder de un apóstrofo:
858 \override TextScript #'extra-offset = #'(1 . 2)
861 Esto asigna la pareja (1, 2) a la propiedad @code{extra-offset} del
862 objeto TextScript. Estos números se miden en espacios de pentagrama,
863 y así esta instrucción mueve el objeto un espacio de pentagrama a la
864 derecha, y dos espacios hacia arriba.
866 @subheading Dimensiones
868 HACER @c todo -- write something about extents
870 @subheading Listas-A de propiedades
872 HACER @c todo -- write something about property alists
874 @subheading Cadenas de listas-A
876 HACER @c todo -- write something about alist chains
878 @node Representación interna de la música
879 @subsection Representación interna de la música
880 @translationof Internal music representation
882 Cuando se analiza una expresión musical, se convierte en un conjunto
883 de objetos musicales de Scheme. La propiedad definitoria de un objeto
884 musical es que ocupa un tiempo. El tiempo es un número racional que
885 mide la longitud de una pieza de música en redondas.
887 Un objeto musical tiene tres clases de tipos:
890 nombre musical: Cada expresión musical tiene un nombre. Por ejemplo,
891 una nota lleva a un @rinternals{NoteEvent}, y @code{\simultaneous}
892 lleva a una @rinternals{SimultaneousMusic}. Hay una lista de todas
893 las expresiones disponibles en el manual de Referencia de
894 funcionamiento interno, bajo el epígrafe @rinternals{Music
898 @q{type} (tipo) o interface: Cada nombre musical tiene varios
899 @q{tipos} o interfaces, por ejemplo, una nota es un @code{event}, pero
900 también es un @code{note-event}, un @code{rhythmic-event}, y un
901 @code{melodic-event}. Todas las clases de música están listadas en el
902 manual de Referencia de funcionamiento interno, bajo el epígrafe
903 @rinternals{Music classes}.
906 objeto de C++: Cada objeto musical está representado por un objeto de
907 la clase @code{Music} de C++.
910 La información real de una expresión musical se almacena en
911 propiedades. Por ejemplo, un @rinternals{NoteEvent} tiene propiedades
912 @code{pitch} y @code{duration} que almacenan la altura y la duración
913 de esa nota. Hay una lista de todas la propiedades disponibles en el
914 manual de Referencia de funcionamiento interno, bajo el epígrafe
915 @rinternals{Music properties}.
917 Una expresión musical compuesta es un objeto musical que contiene
918 otros objetos musicales dentro de sus propiedades. Se puede almacenar
919 una lista de objetos dentro de la propiedad @code{elements} de un
920 objeto musical, o un único objeto musical @q{hijo} dentro de la
921 propiedad @code{element}. Por ejemplo, @rinternals{SequentialMusic}
922 tiene su hijo dentro de @code{elements}, y @rinternals{GraceMusic}
923 tiene su argumento único dentro de @code{element}. El cuerpo de una
924 repetición se almacena dentro de la propiedad @code{element} de
925 @rinternals{RepeatedMusic}, y las alternativas dentro de
928 @node Construir funciones complicadas
929 @section Construir funciones complicadas
930 @translationof Building complicated functions
932 Esta sección explica cómo reunir la información necesaria para crear
933 funciones musicales complicadas.
936 * Presentación de las expresiones musicales::
937 * Propiedades musicales::
938 * Duplicar una nota con ligaduras (ejemplo)::
939 * Añadir articulaciones a las notas (ejemplo)::
943 @node Presentación de las expresiones musicales
944 @subsection Presentación de las expresiones musicales
945 @translationof Displaying music expressions
947 @cindex almacenamiento interno
948 @cindex imprimir expresiones musicales
949 @cindex representación interna, impresión de
951 @funindex \displayMusic
953 Si se está escribiendo una función musical, puede ser muy instructivo
954 examinar cómo se almacena internamente una expresión musical. Esto se
955 puede hacer con la función musical @code{\displayMusic}
959 \displayMusic @{ c'4\f @}
964 imprime lo siguiente:
976 (ly:make-duration 2 0 1 1)
978 (ly:make-pitch 0 0 0))
980 'AbsoluteDynamicEvent
985 De forma predeterminada, LilyPond imprime estos mensajes sobre la
986 consola junto al resto de los mensajes. Para separar estos mensajes y
987 guardar el resultado de @code{\display@{LOQUESEA@}}, redirija la
991 lilypond archivo.ly >salida.txt
994 Con la aplicación de un poco de formateo, la información anterior es
998 (make-music 'SequentialMusic
999 'elements (list (make-music 'EventChord
1000 'elements (list (make-music 'NoteEvent
1001 'duration (ly:make-duration 2 0 1 1)
1002 'pitch (ly:make-pitch 0 0 0))
1003 (make-music 'AbsoluteDynamicEvent
1007 Una secuencia musical @code{@{ ... @}} tiene el nombre
1008 @code{SequentialMusic}, y sus expresiones internas se almacenan coma
1009 una lista dentro de su propiedad @code{'elements}. Una nota se
1010 representa como una expresión @code{EventChord} que contiene un objeto
1011 @code{NoteEvent} (que almacena las propiedades de duración y altura) y
1012 cualquier información adicional (en este caso, un evento
1013 @code{AbsoluteDynamicEvent} con una propiedad @code{"f"} de texto.
1016 @node Propiedades musicales
1017 @subsection Propiedades musicales
1018 @translationof Music properties
1020 El objeto @code{NoteEvent} es el primer objeto de la propiedad
1021 @code{'elements} de @code{someNote}.
1025 \displayMusic \someNote
1033 (ly:make-duration 2 0 1 1)
1035 (ly:make-pitch 0 0 0))))
1038 La función @code{display-scheme-music} es la función que se usa por
1039 parte de @code{\displayMusic} para imprimir la representación de
1040 Scheme de una expresión musical.
1043 #(display-scheme-music (first (ly:music-property someNote 'elements)))
1048 (ly:make-duration 2 0 1 1)
1050 (ly:make-pitch 0 0 0))
1053 Después se accede a la altura de la nota a través de la propiedad
1054 @code{'pitch} del objeto @code{NoteEvent}:
1057 #(display-scheme-music
1058 (ly:music-property (first (ly:music-property someNote 'elements))
1061 (ly:make-pitch 0 0 0)
1064 La altura de la nota se puede cambiar estableciendo el valor de esta
1065 propiedad @code{'pitch},
1067 @funindex \displayLilyMusic
1070 #(set! (ly:music-property (first (ly:music-property someNote 'elements))
1072 (ly:make-pitch 0 1 0)) ;; establecer la altura a d'.
1073 \displayLilyMusic \someNote
1079 @node Duplicar una nota con ligaduras (ejemplo)
1080 @subsection Duplicar una nota con ligaduras (ejemplo)
1081 @translationof Doubling a note with slurs (example)
1083 Supongamos que queremos crear una función que convierte una entrada
1084 como @code{a} en @code{a( a)}. Comenzamos examinando la
1085 representación interna de la música con la que queremos terminar.
1088 \displayMusic@{ a'( a') @}
1099 (ly:make-duration 2 0 1 1)
1101 (ly:make-pitch 0 5 0))
1112 (ly:make-duration 2 0 1 1)
1114 (ly:make-pitch 0 5 0))
1121 Las malas noticias son que las expresiones @code{SlurEvent} se deben
1122 añadir @q{dentro} de la nota (o para ser más exactos, dentro de la
1123 expresión @code{EventChord}).
1125 Ahora examinamos la entrada,
1137 (ly:make-duration 2 0 1 1)
1139 (ly:make-pitch 0 5 0))))))
1142 Así pues, en nuestra función, tenemos que clonar esta expresión (de
1143 forma que tengamos dos notas para construir la secuencia), añadir
1144 @code{SlurEvents} a la propiedad @code{'elements} de cada una de
1145 ellas, y por último hacer una secuencia @code{SequentialMusic} con los
1146 dos @code{EventChords}.
1149 doubleSlur = #(define-music-function (parser location note) (ly:music?)
1150 "Return: @{ note ( note ) @}.
1151 `note' is supposed to be an EventChord."
1152 (let ((note2 (ly:music-deep-copy note)))
1153 (set! (ly:music-property note 'elements)
1154 (cons (make-music 'SlurEvent 'span-direction -1)
1155 (ly:music-property note 'elements)))
1156 (set! (ly:music-property note2 'elements)
1157 (cons (make-music 'SlurEvent 'span-direction 1)
1158 (ly:music-property note2 'elements)))
1159 (make-music 'SequentialMusic 'elements (list note note2))))
1163 @node Añadir articulaciones a las notas (ejemplo)
1164 @subsection Añadir articulaciones a las notas (ejemplo)
1165 @translationof Adding articulation to notes (example)
1167 La manera fácil de añadir articulación a las notas es mezclar dos
1168 expresiones musicales en un solo contexto, como se explica en
1169 @ruser{Crear contextos}. Sin embargo, supongamos que queremos
1170 escribir una función musical que lo haga.
1172 Una @code{$variable} dentro de la notación @code{#@{...#@}} es como
1173 una @code{\variable} normal en la notación clásica de LilyPond.
1181 no funciona en LilyPond. Podríamos evitar este problema adjuntando la
1182 articulación a una nota falsa,
1185 @{ << \music s1*0-.-> @}
1189 pero a los efectos de este ejemplo, aprenderemos ahora cómo hacerlo en
1190 Scheme. Empezamos examinando nuestra entrada y la salida deseada,
1202 (ly:make-duration 2 0 1 1)
1204 (ly:make-pitch -1 0 0))))
1215 (ly:make-duration 2 0 1 1)
1217 (ly:make-pitch -1 0 0))
1224 Vemos que una nota (@code{c4}) se representa como una expresión
1225 @code{EventChord}, con una expresión @code{NoteEvent} en su lista de
1226 elementos. Para añadir una articulación de marcato, se debe añadir
1227 una expresión @code{ArticulationEvent} a la propiedad elements de la
1228 expresión @code{EventChord}.
1230 Para construir esta función, empezamos con
1233 (define (add-marcato event-chord)
1234 "Add a marcato ArticulationEvent to the elements of `event-chord',
1235 which is supposed to be an EventChord expression."
1236 (let ((result-event-chord (ly:music-deep-copy event-chord)))
1237 (set! (ly:music-property result-event-chord 'elements)
1238 (cons (make-music 'ArticulationEvent
1239 'articulation-type "marcato")
1240 (ly:music-property result-event-chord 'elements)))
1241 result-event-chord))
1244 La primera línea es la forma de definir una función en Scheme: el
1245 nombre de la función es @code{add-marcato}, y tiene una variable
1246 llamada @code{event-chord}. En Scheme, el tipo de variable suele
1247 quedar claro a partir de su nombre (¡esto también es una buena
1248 práctica en otros lenguajes de programación!)
1255 es una descripción de lo que hace la función. No es estrictamente
1256 necesaria, pero de igual forma que los nombres claros de variable, es
1260 (let ((result-event-chord (ly:music-deep-copy event-chord)))
1263 Se usa @code{let} para declarar las variables locales. Aquí usamos
1264 una variable local, llamada @code{result-event-chord}, a la que le
1265 damos el valor @code{(ly:music-deep-copy event-chord)}.
1266 @code{ly:music-deep-copy} es una función específica de LilyPond, como
1267 todas las funciones que comienzan por @code{ly:}. Se usa para hacer
1268 una copia de una expresión musical. Aquí, copiamos @code{event-chord}
1269 (el parámetro de la función). Recuerde que nuestro propósito es
1270 añadir un marcato a una expresión @code{EventChord}. Es mejor no
1271 modificar el @code{EventChord} que se ha dado como argumento, porque
1272 podría utilizarse en algún otro lugar.
1274 Ahora tenemos un @code{result-event-chord}, que es una expresión
1275 @code{NoteEventChord} y es una copia de @code{event-chord}. Añadimos
1276 el marcato a su propiedad de la lista de @code{'elements}.
1279 (set! lugar valor-nuevo)
1282 Aquí, lo que queremos establecer (el @q{lugar}) es la propiedad
1283 @code{'elements} de la expresión @code{result-event-chord}.
1286 (ly:music-property result-event-chord 'elements)
1289 @code{ly:music-property} es la función que se usa para acceder a las
1290 propiedades musicales (los @code{'elements}, @code{'duration},
1291 @code{'pitch}, etc, que vimos en la salida de @code{\displayMusic}
1292 anterior). El nuevo valor es la antigua propiedad @code{'elements},
1293 con un elemento adicional: la expresión @code{ArticulationEvent}, que
1294 copiamos a partir de la salida de @code{\displayMusic},
1297 (cons (make-music 'ArticulationEvent
1298 'articulation-type "marcato")
1299 (ly:music-property result-event-chord 'elements))
1302 @code{cons} se usa para añadir un elemento a una lista sin modificar
1303 la lista original. Esto es lo que queremos: la misma lista que antes,
1304 más la expresión @code{ArticulationEvent} nueva. El orden dentro de
1305 la propiedad @code{'elements} no es importante aquí.
1307 Finalmente, una vez hemos añadido la articulación marcato a su
1308 propiedad @code{elements}, podemos devolver @code{result-event-chord},
1309 de ahí la última línea de la función.
1311 Ahora transformamos la función @code{add-marcato} en una función
1315 addMarcato = #(define-music-function (parser location event-chord)
1317 "Add a marcato ArticulationEvent to the elements of `event-chord',
1318 which is supposed to be an EventChord expression."
1319 (let ((result-event-chord (ly:music-deep-copy event-chord)))
1320 (set! (ly:music-property result-event-chord 'elements)
1321 (cons (make-music 'ArticulationEvent
1322 'articulation-type "marcato")
1323 (ly:music-property result-event-chord 'elements)))
1324 result-event-chord))
1327 Podemos verificar que esta función musical funciona correctamente:
1330 \displayMusic \addMarcato c4
1340 * Trucos con Scheme::
1343 @node Trucos con Scheme
1344 @c @section Trucos con Scheme
1345 @translationof Tweaking with Scheme
1347 Hemos visto cómo la salida de LilyPond se puede modificar
1348 profundamente usando instrucciones como @code{\override TextScript
1349 #'extra-offset = ( 1 . -1)}. Pero tenemos incluso mucho más poder si
1350 utilizamos Scheme. Para ver una explicación completa de esto,
1351 consulte el @ref{Tutorial de Scheme}, y @ruser{Interfaces para programadores}.
1353 Podemos usar Scheme simplemente para sobreescribir instrucciones con
1356 TODO Find a simple example
1357 @c This isn't a valid example with skylining
1358 @c It works fine without padText -td
1362 @lilypond[quote,verbatim,ragged-right]
1363 padText = #(define-music-function (parser location padding) (number?)
1365 \once \override TextScript #'padding = #$padding
1369 c4^"piu mosso" b a b
1371 c4^"piu mosso" d e f
1373 c4^"piu mosso" fis a g
1379 Lo podemos usar para crear instrucciones nuevas:
1381 @c Check this is a valid example with skylining
1382 @c It is - 'padding still works
1385 @lilypond[quote,verbatim,ragged-right]
1386 tempoPadded = #(define-music-function (parser location padding tempotext)
1389 \once \override Score.MetronomeMark #'padding = $padding
1390 \tempo \markup { \bold $tempotext }
1394 \tempo \markup { "Low tempo" }
1396 \tempoPadded #4.0 #"High tempo"
1402 Incluso se le pueden pasar expresiones musicales:
1404 @lilypond[quote,verbatim,ragged-right]
1405 pattern = #(define-music-function (parser location x y) (ly:music? ly:music?)
1412 \pattern {d16 dis} { ais16-> b\p }