1 @c -*- coding: utf-8; mode: texinfo; documentlanguage: es -*-
2 @c This file is part of extending.tely
4 Translation of GIT committish: ca3b3c23ad44cb6b035c0dccf272cecf789d1029
6 When revising a translation, copy the HEAD committish of the
7 version that you are working on. See TRANSLATION for details.
12 @node Interfaces para programadores
13 @chapter Interfaces para programadores
14 @translationof Interfaces for programmers
16 Se pueden realizar trucos avanzados mediante el uso de Scheme. Si no
17 está familiarizado con Scheme, le conviene leer nuestro tutorial de
18 Scheme, @ref{Tutorial de Scheme}.
22 * Funciones musicales::
23 * Funciones de marcado::
24 * Contextos para programadores::
25 * Funciones de callback::
26 * Código de Scheme en línea::
30 @node Funciones musicales
31 @section Funciones musicales
32 @translationof Music functions
34 Las @emph{funciones musicales} son procedimientos de Scheme
35 que pueden crear automáticamente expresiones musicales, y se
36 pueden usar para simplificar enormemente el archivo de entrada.
39 * Sintaxis de las funciones musicales::
40 * Funciones de sustitución sencillas::
41 * Funciones de sustitución intermedias::
42 * Matemáticas dentro de las funciones::
43 * Funciones sin argumentos::
47 @node Sintaxis de las funciones musicales
48 @subsection Sintaxis de las funciones musicales
49 @translationof Music function syntax
51 La forma general de una función musical es:
55 #(define-music-function
56 (parser location @var{arg1} @var{arg2} @dots{})
57 (@var{type1?} @var{type2?} @dots{})
64 @multitable @columnfractions .33 .66
65 @item @code{@var{argN}}
66 @tab @var{n}-ésimo argumento
68 @item @code{@var{typeN?}}
69 @tab un @emph{predicado de tipo} de Scheme para el que @code{@var{argN}}
70 deve devolver @code{#t}.
72 @item @code{@var{música}}
73 @tab una expresión musical, opcionalmente escrita en Scheme, con
74 el código de LilyPond que pudiera tener, encerrado entre llaves
76 (@tie{}@w{@code{#@{@dots{}#@}}}@tie{}). Dentro de los bloques
77 de código de LilyPond, use @code{$} para referenciar a los argumentos
78 de la función (p. ej. @samp{$arg1})
79 o para iniciar una expresión en línea de Scheme
80 que contenga argumentos de función
81 (p.ej., @w{@samp{$(cons arg1 arg2)}}).
86 Para ver una lista de los predicados de tipo disponibles, consulte
87 @ruser{Predicados de tipo predefinidos}.
88 También se permiten predicados de tipo definidos por el usuario.
94 Referencia de la notación:
95 @ruser{Predicados de tipo predefinidos}.
98 @file{lily/music-scheme.cc},
103 @node Funciones de sustitución sencillas
104 @subsection Funciones de sustitución sencillas
105 @translationof Simple substitution functions
107 Una función de sustitución sencilla es una función musical cuya
108 expresión musical de salida está escrita en código de LilyPond
109 y contiene argumentos de la función en la expresión de salida.
110 Están descritas en @ruser{Ejemplos de funciones de sustitución}.
113 @node Funciones de sustitución intermedias
114 @subsection Funciones de sustitución intermedias
115 @translationof Intermediate substitution functions
117 Las funciones de sustitución intermedias contienen una
118 mezcla de código de Scheme y de LilyPond
119 dentro de la expresión musical que se devuelve.
121 Algunas instrucciones @code{\override} requieren un argumento que
122 consiste en una pareja de números (llamada una @code{célula cons} en
125 La pareja se puede pasar directamente dentro de la función musical,
126 usando una variable @code{pair?}:
130 #(define-music-function
131 (parser location principio-final)
134 \once \override Beam #'positions = $principio-final
138 \barraManual #'(3 . 6) c8 d e f
142 De forma alternativa, los números que componen la pareja se pueden
143 pasar como argumentos separados, y el código de Scheme que se ha usado
144 para crear la pareja se puede incluir dentro de la expresión musical:
146 @lilypond[quote,verbatim,ragged-right]
148 #(define-music-function
149 (parser location beg end)
152 \once \override Beam #'positions = $(cons beg end)
156 \manualBeam #3 #6 c8 d e f
161 @node Matemáticas dentro de las funciones
162 @subsection Matemáticas dentro de las funciones
163 @translationof Mathematics in functions
165 Las funciones musicales pueden contar con programación de Scheme
166 además de la simple sustitución:
168 @lilypond[quote,verbatim,ragged-right]
170 #(define-music-function
171 (parser location mag)
174 \override Stem #'length = $(* 7.0 mag)
175 \override NoteHead #'font-size =
176 $(inexact->exact (* (/ 6.0 (log 2.0)) (log mag)))
180 \revert Stem #'length
181 \revert NoteHead #'font-size
186 \AltOn #1.5 c c \AltOff c2
191 Este ejemplo se puede reescribir de forma que pase expresiones
194 @lilypond[quote,verbatim,ragged-right]
196 #(define-music-function
197 (parser location mag music)
200 \override Stem #'length = $(* 7.0 mag)
201 \override NoteHead #'font-size =
202 $(inexact->exact (* (/ 6.0 (log 2.0)) (log mag)))
204 \revert Stem #'length
205 \revert NoteHead #'font-size
209 c2 \withAlt #0.5 { c4 c }
210 \withAlt #1.5 { c c } c2
215 @node Funciones sin argumentos
216 @subsection Funciones sin argumentos
217 @translationof Functions without arguments
219 En casi todos los casos, una función sin argumentos se debe escribir
223 dolce = \markup@{ \italic \bold dolce @}
226 Sin embargo, en raras ocasiones puede ser de utilidad crear una
227 función musical sin argumentos:
230 mostrarNumeroDeCompas =
231 #(define-music-function
234 (if (eq? #t (ly:get-option 'display-bar-numbers))
235 #@{ \once \override Score.BarNumber #'break-visibility = ##f #@}
239 Para la impresión real de los números de compás donde se llama a esta
240 función, invoque a @command{lilypond} con
243 lilypond -d display-bar-numbers ARCHIVO.ly
247 @node Funciones vacías
248 @subsection Funciones vacías
249 @translationof Void functions
251 Una función musical debe devolver una expresión musical, pero a veces
252 podemos necesitar una función en la que no hay música en juego (como
253 la desactivación de la funcionalidad Apuntar y Pulsar). Para hacerlo,
254 devolvemos una expresión musical @code{void} (vacía).
256 Este es el motivo por el que la forma que se devuelve es
257 @code{(make-music ...)}. Con el valor de la propiedad @code{'void}
258 establecido a @code{#t}, le decimos al analizador que descarte la
259 expresión musical devuelta. así, la parte importante de la función
260 musical vacía es el proceso realizado por la función, no la expresión
261 musical que se devuelve.
265 #(define-music-function (parser location) ()
266 (ly:set-option 'point-and-click #f)
267 (make-music 'SequentialMusic 'void #t))
269 \noApuntarYPulsar % desactivar la funcionalidad Apuntar y Pulsar.
273 @node Funciones de marcado
274 @section Funciones de marcado
275 @translationof Markup functions
277 Los elementos de marcado están implementados como funciones de Scheme
278 especiales que producen un objeto @code{Stencil} dada una serie de
283 * Construcción de elementos de marcado en Scheme::
284 * Cómo funcionan internamente los elementos de marcado::
285 * Definición de una instrucción de marcado nueva::
286 * Definición de nuevas instrucciones de lista de marcado::
289 @node Construcción de elementos de marcado en Scheme
290 @subsection Construcción de elementos de marcado en Scheme
291 @translationof Markup construction in Scheme
293 @cindex marcado, definir instrucciones de
295 El macro @code{markup} construye expresiones de marcado en Scheme,
296 proporcionando una sintaxis similar a la de LilyPond. Por ejemplo:
299 (markup #:column (#:line (#:bold #:italic "hola" #:raise 0.4 "mundo")
300 #:larger #:line ("fulano" "fulanito" "menganito")))
306 \markup \column @{ \line @{ \bold \italic "hola" \raise #0.4 "mundo" @}
307 \larger \line @{ fulano fulanito menganito @} @}
311 Este ejemplo muestra las principales reglas de traducción entre la
312 sintaxis del marcado normal de LilyPond y la sintaxis del marcado de
316 @multitable @columnfractions .3 .3
317 @item @b{LilyPond} @tab @b{Scheme}
318 @item @code{\markup marcado1} @tab @code{(markup marcado1)}
319 @item @code{\markup @{ marcado1 marcado2 ... @}} @tab
320 @code{(markup marcado1 marcado2 ... )}
321 @item @code{\instruccion} @tab @code{#:instruccion}
322 @item @code{\variable} @tab @code{variable}
323 @item @code{\center-column @{ ... @}} @tab @code{#:center-column ( ... )}
324 @item @code{cadena} @tab @code{"cadena"}
325 @item @code{#argumento-de-scheme} @tab @code{argumento-de-scheme}
329 Todo el lenguaje Scheme está accesible dentro del macro @code{markup}.
330 Por ejemplo, podemos usar llamadas a funciones dentro de @code{markup}
331 para así manipular cadenas de caracteres. Esto es útil si se están
332 definiendo instrucciones de marcado nuevas (véase @ref{Definición de una instrucción de marcado nueva}).
337 El argumento markup-list de instrucciones como @code{#:line},
338 @code{#:center} y @code{#:column} no puede ser una variable ni el
339 resultado de la llamada a una función.
342 (markup #:line (funcion-que-devuelve-marcados))
346 no es válido. Hay que usar las funciones @code{make-line-markup},
347 @code{make-center-markup} o @code{make-column-markup} en su lugar:
350 (markup (make-line-markup (funcion-que-devuelve-marcados)))
354 @node Cómo funcionan internamente los elementos de marcado
355 @subsection Cómo funcionan internamente los elementos de marcado
356 @translationof How markups work internally
358 En un elemento de marcado como
361 \raise #0.5 "ejemplo de texto"
365 @code{\raise} se representa en realidad por medio de la función
366 @code{raise-markup}. La expresión de marcado se almacena como
369 (list raise-markup 0.5 (list simple-markup "ejemplo de texto"))
372 Cuando el marcado se convierte en objetos imprimibles (Stencils o
373 sellos), se llama la función @code{raise-markup} como
377 @var{\objeto de marcado}
378 @var{lista de listas asociativas de propiedades}
380 @var{el marcado "ejemplo de texto"})
383 Primero la función @code{raise-markup} crea el sello para la cadena
384 @code{ejemplo de texto}, y después eleva el sello Stencil en 0.5
385 espacios de pentagrama. Este es un ejemplo bastante simple; en el
386 resto de la sección podrán verse ejemplos más complejos, así como en
387 @file{scm/@/define@/-markup@/-commands@/.scm}.
390 @node Definición de una instrucción de marcado nueva
391 @subsection Definición de una instrucción de marcado nueva
392 @translationof New markup command definition
394 Esta sección trata sobre la definición de nuevas instrucciones de
399 * Sintaxis de la definición de instrucciones de marcado::
400 * Acerca de las propiedades::
401 * Un ejemplo completo::
402 * Adaptación de instrucciones incorporadas::
405 @node Sintaxis de la definición de instrucciones de marcado
406 @unnumberedsubsubsec Sintaxis de la definición de instrucciones de marcado
407 @translationof Markup command definition syntax
409 Se pueden definir instrucciones de marcado nuevas usando el macro de
410 Scheme @code{define-markup-command}, en el nivel sintáctico superior.
413 (define-markup-command (@var{nombre-de-la-instruccion} @var{layout} @var{props} @var{arg1} @var{arg2} ...)
414 (@var{tipo-de-arg1?} @var{tipo-de-arg2?} ...)
415 [ #:properties ((@var{propiedad1} @var{valor-predeterminado1})
423 @item nombre-de-la-instruccion
424 nombre de la instrucción de marcado
426 la definición de @q{layout} (disposición).
428 una lista de listas asociativas, que contienen todas las propiedades
431 argumento @var{i}-ésimo de la instrucción
433 predicado de tipo para el argumento @var{i}-ésimo
436 Si la instrucción utiliza propiedades de los argumentos @var{props},
437 se puede usar la palabra clave @code{#:properties} para especificar
438 qué propiedades se usan, así como sus valores predeterminados.
440 Los argumentos se distinguen según su tipo:
442 @item un marcado, que corresponde al predicado de tipo @code{markup?};
443 @item una lista de marcados, que corresponde al predicado de tipo
445 @item cualquier otro objeto de Scheme, que corresponde a predicados de tipo como
446 @code{list?}, @code{number?}, @code{boolean?}, etc.
449 No existe ninguna limitación en el orden de los argumentos (después de
450 los argumentos estándar @var{layout} y @var{props}). Sin embargo, las
451 funciones de marcado que toman un elemento de marcado como su último
452 argumento son un poco especiales porque podemos aplicarlas a una lista
453 de marcados y el resultado es una lista de marcados donde la función
454 de marcado (con los argumentos antecedentes especificados) se ha
455 aplicado a todos los elementos de la lista de marcados original.
457 Dado que la replicación de los argumentos precedentes para aplicar una
458 función de marcado a una lista de marcados es poco costosa
459 principalmente por los argumentos de Scheme, se evitan las caídas de
460 reindimiento simplemente mediante la utilización de argumentos de
461 Scheme para los argumentos antecedentes de las funciones de marcado
462 que toman un marcado como su último argumento.
464 @node Acerca de las propiedades
465 @unnumberedsubsubsec Acerca de las propiedades
466 @translationof On properties
468 Los argumentos @code{layout} y @code{props} de las instrucciones de
469 marcado traen a escena un contexto para la interpretación del marcado:
470 tamaño de la tipografía, grueso de línea, etc.
472 El argumento @code{layout} permite el acceso a las propiedades
473 definidas en los bloques @code{paper}, usando la función
474 @code{ly:output-def-lookup}. Por ejemplo, el grueso de línea (el
475 mismo que el que se usa en las partituras) se lee usando:
478 (ly:output-def-lookup layout 'line-width)
481 El argumento @code{props} hace accesibles algunas propiedades a las
482 instrucciones de marcado. Por ejemplo, cuando se interpreta el
483 marcado del título de un libro, todas las variables definidas dentro
484 del bloque @code{\header} se añaden automáticamente a @code{props}, de
485 manera que el marcado del título del libro puede acceder al título del
486 libro, el autor, etc. También es una forma de configurar el
487 comportamiento de una instrucción de marcado: por ejemplo, cuando una
488 instrucción utiliza tamaños de tipografía durante el procesado, el
489 tamaño se lee de @code{props} en vez de tener un argumento
490 @code{font-size}. El que llama a una instrucción de marcado puede
491 cambiar el valor de la propiedad del tamaño de la tipografía con el
492 objeto de modificar el comportamiento. Utilice la palabra clave
493 @code{#:properties} de @code{define-markup-command} para especificar
494 qué propiedades se deben leer a partir de los argumentos de
497 El ejemplo de la sección siguiente ilustra cómo acceder y
498 sobreescribir las propiedades de una instrucción de marcado.
501 @node Un ejemplo completo
502 @unnumberedsubsubsec Un ejemplo completo
503 @translationof A complete example
505 El ejemplo siguiente define una instrucción de marcado para trazar un
506 rectángulo doble alrededor de un fragmento de texto.
508 En primer lugar, necesitamos construir un resultado aproximado
509 utilizando marcados. Una consulta a @ruser{Text markup commands} nos
510 muestra que es útil la instrucción @code{\box}:
512 @lilypond[quote,verbatim,ragged-right]
513 \markup \box \box HELLO
516 Ahora, consideramos que es preferible tener más separación entre el
517 texto y los rectángulos. Según la documentación de @code{\box}, esta
518 instrucción usa una propiedad @code{box-padding}, cuyo valor
519 predeterminado es 0.2. La documentación también menciona cómo
520 sobreescribir este valor:
522 @lilypond[quote,verbatim,ragged-right]
523 \markup \box \override #'(box-padding . 0.6) \box A
526 Después, el relleno o separación entre los dos rectángulos nos parece
527 muy pequeño, así que lo vamos a sobreescribir también:
529 @lilypond[quote,verbatim,ragged-right]
530 \markup \override #'(box-padding . 0.4) \box \override #'(box-padding . 0.6) \box A
533 Repetir esta extensa instrucción de marcado una y otra vez sería un
534 quebradero de cabeza. Aquí es donde se necesita una instrucción de
535 marcado. Así pues, escribimos una instrucción de marcado
536 @code{double-box}, que toma un argumento (el texto). Dibuja los dos
537 rectángulos y añade una separación.
540 #(define-markup-command (double-box layout props text) (markup?)
541 "Trazar un rectángulo doble rodeando el texto."
542 (interpret-markup layout props
543 (markup #:override '(box-padding . 0.4) #:box
544 #:override '(box-padding . 0.6) #:box text)))
547 @code{text} es el nombre del argumento de la instrucción, y
548 @code{markup?} es el tipo: lo identifica como un elemento de marcado.
549 La función @code{interpret-markup} se usa en casi todas las
550 instrucciones de marcado: construye un sello, usando @code{layout},
551 @code{props}, y un elemento de marcado. Aquí, la marca se construye
552 usando el macro de Scheme @code{markup}, véase @ref{Construcción de
553 elementos de marcado en Scheme}. La transformación de una expresión
554 @code{\markup} en una expresión de marcado de Scheme es directa.
556 La instrucción nueva se puede usar como sigue:
559 \markup \double-box A
562 Sería buen hacer que la instrucción @code{double-box} fuera
563 personalizable: aquí, los valores de relleno @code{box-padding} son
564 fijos, y no se pueden cambiar por parte del usuario. Además, sería
565 mejor distinguir la separación entre los dos rectángulos, del relleno
566 entre el rectángulo interno y el texto. Así pues, introducimos una
567 nueva propiedad, @code{inter-box-padding}, para el relleno entre los
568 rectángulos. El @code{box-padding} se usará para el relleno interno.
569 Ahora el código nuevo es como se ve a continuación:
572 #(define-markup-command (double-box layout props text) (markup?)
573 #:properties ((inter-box-padding 0.4)
575 "Trazar un rectángulo doble rodeando el texto."
576 (interpret-markup layout props
577 (markup #:override `(box-padding . ,inter-box-padding) #:box
578 #:override `(box-padding . ,box-padding) #:box text)))
581 Aquí, la palabra clave @code{#:properties} se usa de manera que las
582 propiedades @code{inter-box-padding} y @code{box-padding} se leen a
583 partir del argumento @code{props}, y se les proporcionan unos valores
584 predeterminados si las propiedades no están definidas.
586 Después estos valores se usan para sobreescribir las propiedades
587 @code{box-padding} usadas por las dos instrucciones @code{\box}.
588 Observe el apóstrofo invertido y la coma en el argumento de
589 @code{\override}: nos permiten introducir un valor de variable dentro
590 de una expresión literal.
592 Ahora, la instrucción se puede usar dentro de un elemento de marcado,
593 y el relleno de los rectángulos se puede personalizar:
595 @lilypond[quote,verbatim,ragged-right]
596 #(define-markup-command (double-box layout props text) (markup?)
597 #:properties ((inter-box-padding 0.4)
599 "Draw a double box around text."
600 (interpret-markup layout props
601 (markup #:override `(box-padding . ,inter-box-padding) #:box
602 #:override `(box-padding . ,box-padding) #:box text)))
604 \markup \double-box A
605 \markup \override #'(inter-box-padding . 0.8) \double-box A
606 \markup \override #'(box-padding . 1.0) \double-box A
610 @node Adaptación de instrucciones incorporadas
611 @unnumberedsubsubsec Adaptación de instrucciones incorporadas
612 @translationof Adapting builtin commands
614 Una buena manera de comenzar a escribir una instrucción de marcado
615 nueva, es seguir el ejemplo de otra instrucción ya incorporada. Casi
616 todas las instrucciones de marcado que están incorporadas en LilyPond
617 se pueden encontrar en el archivo
618 @file{scm/@/define@/-markup@/-commands@/.scm}.
620 Por ejemplo, querríamos adaptar la instrucción @code{\draw-line}, para
621 que trace una línea doble. La instrucción @code{\draw-line} está
622 definida como sigue (se han suprimido los comentarios de
626 (define-markup-command (draw-line layout props dest)
629 #:properties ((thickness 1))
630 "...documentación..."
631 (let ((th (* (ly:output-def-lookup layout 'line-thickness)
635 (make-line-stencil th 0 0 x y)))
638 Para definir una instrucción nueva basada en otra existente, copie la
639 definición y cámbiele el nombre. La palabra clave @code{#:category}
640 se puede eliminar sin miedo, pues sólo se utiliza para generar
641 documentación de LilyPond, y no tiene ninguna utilidad para las
642 instrucciones de marcado definidas por el usuario.
645 (define-markup-command (draw-double-line layout props dest)
647 #:properties ((thickness 1))
648 "...documentación..."
649 (let ((th (* (ly:output-def-lookup layout 'line-thickness)
653 (make-line-stencil th 0 0 x y)))
656 A continuación se añade una propiedad para establecer la separación
657 entre las dos líneas, llamada @code{line-gap}, con un valor
658 predeterminado de p.ej. 0.6:
661 (define-markup-command (draw-double-line layout props dest)
663 #:properties ((thickness 1)
665 "...documentación..."
669 Finalmente, se añade el código para trazar las dos líneas. Se usan
670 dos llamadas a @code{make-line-stencil} para trazar las líneas, y los
671 sellos resultantes se combinan usando @code{ly:stencil-add}:
673 @lilypond[quote,verbatim,ragged-right]
674 #(define-markup-command (my-draw-line layout props dest)
676 #:properties ((thickness 1)
679 (let* ((th (* (ly:output-def-lookup layout 'line-thickness)
684 (x (cond ((= dx 0) w)
686 (else (/ w (sqrt (+ 1 (* (/ dx dy) (/ dx dy))))))))
687 (y (* (if (< (* dx dy) 0) 1 -1)
690 (else (/ w (sqrt (+ 1 (* (/ dy dx) (/ dy dx))))))))))
691 (ly:stencil-add (make-line-stencil th x y (+ dx x) (+ dy y))
692 (make-line-stencil th (- x) (- y) (- dx x) (- dy y)))))
694 \markup \my-draw-line #'(4 . 3)
695 \markup \override #'(line-gap . 1.2) \my-draw-line #'(4 . 3)
699 @node Definición de nuevas instrucciones de lista de marcado
700 @subsection Definición de nuevas instrucciones de lista de marcado
701 @translationof New markup list command definition
703 Las instrucciones de listas de marcado se definen con el macro de
704 Scheme @code{define-markup-list-command}, que es similar al macro
705 @code{define-markup-command} descrito en @ref{Definición de una
706 instrucción de marcado nueva}, excepto que donde éste devuelve un
707 sello único, aquél devuelve una lista de sellos.
709 En el siguiente ejemplo se define una instrucción de lista de marcado
710 @code{\paragraph}, que devuelve una lista de líneas justificadas,
711 estando la primera de ellas sangrada. La anchura del sangrado se toma
712 del argumento @code{props}.
715 #(define-markup-list-command (paragraph layout props args) (markup-list?)
716 #:properties ((par-indent 2))
717 (interpret-markup-list layout props
718 (make-justified-lines-markup-list (cons (make-hspace-markup par-indent)
722 Aparte de los argumentos usuales @code{layout} y @code{props}, la
723 instrucción de lista de marcados @code{paragraph} toma un argumento de
724 lista de marcados, llamado @code{args}. El predicado para listas de
725 marcados es @code{markup-list?}.
727 En primer lugar, la función toma el ancho del sangrado, una propiedad
728 llamada aquí @code{par-indent}, de la lista de propiedades
729 @code{props}. Si no se encuentra la propiedad, el valor
730 predeterminado es @code{2}. Después, se hace una lista de líneas
731 justificadas usando la función
732 @code{make-justified-lines-markup-list}, que está relacionada con la
733 instrucción incorporada de lista de marcados @code{\justified-lines}.
734 Se añade un espacio horizontal al principio usando la función
735 @code{make-hspace-markup}. Finalmente, la lista de marcados se
736 interpreta usando la función @code{interpret-markup-list}.
738 Esta nueva instrucción de lista de marcados se puede usar como sigue:
743 El arte de la tipografía musical se llama \italic @{grabado (en plancha).@}
744 El término deriva del proceso tradicional de impresión de música.
745 hace sólo algunas décadas, las partituras se hacían cortando y estampando
746 la música en una plancha de zinc o lata en una imagen invertida.
748 \override-lines #'(par-indent . 4) \paragraph @{
749 La plancha se tenía que entintar, y las depresiones causadas por los cortes
750 y estampados retienen la tinta. Se formaba una imagen presionando el papel
751 contra la plancha. El estampado y cortado se hacía completamente
758 @node Contextos para programadores
759 @section Contextos para programadores
760 @translationof Contexts for programmers
763 * Evaluación de contextos::
764 * Ejecutar una función sobre todos los objetos de la presentación::
767 @node Evaluación de contextos
768 @subsection Evaluación de contextos
769 @translationof Context evaluation
771 @cindex código, llamadas durante la interpretación
772 @funindex \applyContext
774 Se pueden modificar los contextos durante la interpretación con código
775 de Scheme. La sintaxis para esto es
778 \applyContext @var{función}
781 @var{función} debe ser una función de Scheme que toma un único
782 argumento, que es el contexto al que aplicarla. El código siguiente
783 imprime el número del compás actual sobre la salida estándar durante
789 (format #t "\nSe nos ha llamado en el compás número ~a.\n"
790 (ly:context-property x 'currentBarNumber)))
794 @node Ejecutar una función sobre todos los objetos de la presentación
795 @subsection Ejecutar una función sobre todos los objetos de la presentación
796 @translationof Running a function on all layout objects
798 @cindex código, llamar sobre objetos de presentación
799 @funindex \applyOutput
802 La manera más versátil de realizar el ajuste fino de un objeto es
803 @code{\applyOutput}. Su sintaxis es
806 \applyOutput @var{contexto} @var{proc}
810 donde @var{proc} es una función de Scheme, que toma tres argumentos.
812 Al interpretarse, la función @var{proc} se llama para cada objeto de
813 presentación que se encuentra en el contexto @var{contexto}, con los
814 siguientes argumentos:
817 @item el propio objeto de presentación,
818 @item el contexto en que se creó el objeto de presentación, y
819 @item el contexto en que se procesa @code{\applyOutput}.
823 Además, la causa del objeto de presentación, es decir el objeto o
824 expresión musical que es responsable de haberlo creado, está en la
825 propiedad @code{cause} del objeto. Por ejemplo, para la cabeza de una
826 nota, éste es un evento @rinternals{NoteHead}, y para un objeto
827 @rinternals{Stem} (plica), éste es un objeto @rinternals{Stem}.
828 @c Impossible - changed to Stem --FV
830 He aquí una función que usar para @code{\applyOutput}; borra las
831 cabezas de las notas que están sobre la línea central:
833 @lilypond[quote,verbatim,ragged-right]
834 #(define (blanker grob grob-origin context)
835 (if (and (memq 'note-head-interface (ly:grob-interfaces grob))
836 (eq? (ly:grob-property grob 'staff-position) 0))
837 (set! (ly:grob-property grob 'transparent) #t)))
840 e4 g8 \applyOutput #'Voice #blanker b d2
845 @node Funciones de callback
846 @section Funciones de callback
847 @translationof Callback functions
849 Las propiedades (como @code{thickness} (grosor), @code{direction}
850 (dirección), etc.) se pueden establecer a valores fijos con \override,
854 \override Stem #'thickness = #2.0
857 Las propiedades pueden fijarse también a un procedimiento de scheme,
859 @lilypond[fragment,verbatim,quote,relative=2]
860 \override Stem #'thickness = #(lambda (grob)
861 (if (= UP (ly:grob-property grob 'direction))
868 En este caso, el procedimiento se ejecuta tan pronto como el valor de
869 la propiedad se reclama durante el proceso de formateo.
871 Casi todo el motor de tipografiado está manejado por estos
872 @emph{callbacks}. Entre las propiedades que usan normalmente
873 @emph{callbacks} están
877 La rutina de impresión, que construye un dibujo para el símbolo
879 La rutina que establece la posición horizontal
881 La rutina que calcula la anchura de un objeto
884 El procedimiento siempre toma un argumento único, que es el grob (el
887 Si se deben llamar rutinas con varios argumentos, el grob actual se
888 puede insertar con una cerradura de grob. He aquí un ajuste
889 procedente de @code{AccidentalSuggestion},
893 ,(ly:make-simple-closure
895 ,(ly:make-simple-closure
896 (list ly:self-alignment-interface::centered-on-x-parent))
897 ,(ly:make-simple-closure
898 (list ly:self-alignment-interface::x-aligned-on-self)))))
902 En este ejemplo, tanto
903 @code{ly:self-alignment-interface::x-aligned-on-self} como
904 @code{ly:self-alignment-interface::centered-on-x-parent} se llaman con
905 el grob como argumento. El resultado se añade con la función
906 @code{+}. Para asegurar que esta adición se ejecuta adecuadamente,
907 todo ello se encierra dentro de @code{ly:make-simple-closure}.
909 De hecho, usar un solo procedimiento como valor de una propiedad
913 (ly:make-simple-closure (ly:make-simple-closure (list @var{proc})))
917 El @code{ly:make-simple-closure} interior aporta el grob como
918 argumento de @var{proc}, el exterior asegura que el resultado de la
919 función es lo que se devuelve, en lugar del objeto
920 @code{simple-closure}.
922 Desde dentro de un callback, el método más fácil para evaluar un
923 elemento de marcado es usar grob-interpret-markup. Por ejemplo:
926 mi-callback = #(lambda (grob)
927 (grob-interpret-markup grob (markup "fulanito")))
931 @node Código de Scheme en línea
932 @section Código de Scheme en línea
933 @translationof Inline Scheme code
935 La principal desventaja de @code{\tweak} es su inflexibilidad
936 sintáctica. Por ejemplo, lo siguiente produce un error de sintaxis.
939 F = \tweak #'font-size #-3 -\flageolet
947 En otras palabras, @code{\tweak} no se comporta como una articulación
948 en cuando a la sintaxis; concretamente, no se puede adjuntar con
951 Usando Scheme, se puede dar un rodeo a este problema. La ruta hacia
952 el resultado se da en @ref{Añadir articulaciones a las notas
953 (ejemplo)}, especialmente cómo usar @code{\displayMusic} como guía de
957 F = #(let ((m (make-music 'ArticulationEvent
958 'articulation-type "flageolet")))
959 (set! (ly:music-property m 'tweaks)
961 (ly:music-property m 'tweaks)))
970 Aquí, las propiedades @code{tweaks} del objeto flageolet @code{m}
971 (creado con @code{make-music}) se extraen con
972 @code{ly:music-property}, se antepone un nuevo par clave-valor para
973 cambiar el tamaño de la tipografía a la lista de propiedades con la
974 función de Scheme @code{acons}, y finalmente el resultado se escribe
975 de nuevo con @code{set!}. El último elemento del bloque @code{let} es
976 el valor de retorno, el propio @code{m}.
979 @node Trucos difíciles
980 @section Trucos difíciles
981 @translationof Difficult tweaks
983 Hay un cierto número de tipos de ajustes difíciles.
989 Un tipo de ajuste difícil es la apariencia de los objetos de
990 extensión, como las ligaduras de expresión y de unión. Inicialmente,
991 sólo se crea uno de estos objetos, y pueden ajustarse con el mecanismo
992 normal. Sin embargo, en ciertos casos los objetos extensores cruzan
993 los saltos de línea. Si esto ocurre, estos objetos se clonan. Se
994 crea un objeto distinto por cada sistema en que se encuentra. Éstos
995 son clones del objeto original y heredan todas sus propiedades,
996 incluidos los @code{\override}s.
998 En otras palabras, un @code{\override} siempre afecta a todas las
999 piezas de un objeto de extensión fragmentado. Para cambiar sólo una
1000 parte de un extensor en el salto de línea, es necesario inmiscuirse en
1001 el proceso de formateado. El @emph{callback}
1002 @code{after-line-breaking} contiene el procedimiento Scheme que se
1003 llama después de que se han determinado los saltos de línea, y los
1004 objetos de presentación han sido divididos sobre los distintos
1007 En el ejemplo siguiente, definimos un procedimiento
1008 @code{my-callback}. Este procedimiento
1012 determina si hemos sido divididos por los saltos de línea
1014 en caso afirmativo, reúne todos los objetos divididos
1016 comprueba si somos el último de los objetos divididos
1018 en caso afirmativo, establece @code{extra-offset}.
1021 Este procedimiento se instala en @rinternals{Tie} (ligadura de unión),
1022 de forma que la última parte de la ligadura dividida se traslada hacia
1025 @lilypond[quote,verbatim,ragged-right]
1026 #(define (my-callback grob)
1028 ;; have we been split?
1029 (orig (ly:grob-original grob))
1031 ;; if yes, get the split pieces (our siblings)
1032 (siblings (if (ly:grob? orig)
1033 (ly:spanner-broken-into orig)
1036 (if (and (>= (length siblings) 2)
1037 (eq? (car (last-pair siblings)) grob))
1038 (ly:grob-set-property! grob 'extra-offset '(-2 . 5)))))
1041 \override Tie #'after-line-breaking =
1049 Al aplicar este truco, la nueva función de callback
1050 @code{after-line-breaking} también debe llamar a la antigua,
1051 si existe este valor predeterminado. Por ejemplo, si se usa con
1052 @code{Hairpin}, se debe llamar también a
1053 @code{ly:spanner::kill-zero-spanned-time}.
1056 @item Algunos objetos no se pueden cambiar con @code{\override} por
1057 razones técnicas. Son ejemplos @code{NonMusicalPaperColumn} y
1058 @code{PaperColumn}. Se pueden cambiar con la función
1059 @code{\overrideProperty} que funciona de forma similar a @code{\once
1060 \override}, pero usa una sintaxis distinta.
1064 #"Score.NonMusicalPaperColumn" % Nombre del grob
1065 #'line-break-system-details % Nombre de la propiedad
1066 #'((next-padding . 20)) % Valor
1069 Observe, sin embargo, que @code{\override}, aplicado a
1070 @code{NonMusicalPaperColumn} y a @code{PaperColumn}, aún funciona
1071 como se espera dentro de los bloques @code{\context}.
1076 @node Interfaces de Scheme de LilyPond
1077 @chapter Interfaces de Scheme de LilyPond
1078 @translationof LilyPond Scheme interfaces
1080 Este capítulo cubre las diversas herramientas proporcionadas por
1081 LilyPond como ayuda a los programadores de Scheme a extraer e
1082 introducir información de los flujos musicales.
1084 HACER @c TODO -- figure out what goes in here and how to organize it