1 @c -*- coding: utf-8; mode: texinfo; documentlanguage: es -*-
4 Translation of GIT committish: d4f58bb3ad4e7fe1967a6b48f25e3addffc8aa14
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 Interfaces para programadores
14 @chapter Interfaces para programadores
15 @translationof Interfaces for programmers
17 Se pueden realizar trucos avanzados mediante el uso de Scheme. Si no
18 está familiarizado con Scheme, le conviene leer nuestro tutorial de
19 Scheme, @rlearning{Tutorial de Scheme}.
22 * Funciones musicales::
23 * Interfaces para el programador::
24 * Interfaz de marcado para el programador::
25 * Contextos para programadores::
26 * Procedimientos de Scheme como propiedades::
27 * Usar código de Scheme en lugar de \tweak::
32 @node Funciones musicales
33 @section Funciones musicales
34 @translationof Music functions
36 Esta sección trata sobre cómo crear funciones musicales dentro de
40 * Panorámica de las funciones musicales::
41 * Funciones de sustitución sencillas::
42 * Funciones de sustitutión en parejas::
43 * Matemáticas dentro de las funciones::
45 * Funciones sin argumentos::
46 * Panorámica de las funciones musicales disponibles::
49 @node Panorámica de las funciones musicales
50 @subsection Panorámica de las funciones musicales
51 @translationof Overview of music functions
53 Es fácil hacer una función que sustituya a una variable en código de
54 LilyPond. La forma general de estas funciones es:
58 #(define-music-function (parser location @var{var1} @var{var2}...@var{vari}... )
59 (@var{var1-type?} @var{var2-type?}...@var{vari-type?}...)
68 @multitable @columnfractions .33 .66
69 @item @var{vari} @tab @var{i}-ésima variable
70 @item @var{vari-type?} @tab tipo de la @var{i}-ésima variable
71 @item @var{...música...} @tab entrada normal de LilyPond, usando las variables como @code{#$var1}, etc.
74 Los siguientes tipos de entrada se pueden usar como variables en una
75 función musical. Esta lista no es exhaustiva; consulte otros lugares
76 de la documentación específica de Scheme para ver otros tipos de
79 @multitable @columnfractions .33 .66
80 @headitem Tipo de entrada @tab notación de @var{vari-type?}
81 @item Entero @tab @code{integer?}
82 @item Flotante (número decimal) @tab @code{number?}
83 @item Cadena de texto @tab @code{string?}
84 @item Marcado @tab @code{markup?}
85 @item Expresión musical @tab @code{ly:music?}
86 @item Pareja de variables @tab @code{pair?}
89 Los argumentos @code{parser} y @code{location} son obligatorios, y se
90 usan en ciertas situaciones avanzadas. El argumento @code{parser} se
91 usa para tener acceso al valor de otra variable de LilyPond. El
92 argumento @code{location} se usa para establecer el @q{origen} de la
93 expresión musical que construye la función musical, de forma que en
94 caso de producirse un error de sintaxis LilyPond pueda informar al
95 usuario de un lugar adecuado donde buscar en el archivo de entrada.
98 @node Funciones de sustitución sencillas
99 @subsection Funciones de sustitución sencillas
100 @translationof Simple substitution functions
102 He aquí un ejemplo sencillo:
104 @lilypond[quote,verbatim,ragged-right]
105 padText = #(define-music-function (parser location padding) (number?)
107 \once \override TextScript #'padding = #$padding
115 c4^"piu mosso" fis a g
119 También se pueden sustituir las expresiones musicales:
121 @lilypond[quote,verbatim,ragged-right]
122 custosNote = #(define-music-function (parser location note)
125 \once \override Voice.NoteHead #'stencil =
126 #ly:text-interface::print
127 \once \override Voice.NoteHead #'text =
128 \markup \musicglyph #"custodes.mensural.u0"
129 \once \override Voice.Stem #'stencil = ##f
133 { c' d' e' f' \custosNote g' }
136 Se puede usar más de una variable:
138 @lilypond[quote,verbatim,ragged-right]
139 tempoPadded = #(define-music-function (parser location padding tempotext)
142 \once \override Score.MetronomeMark #'padding = $padding
143 \tempo \markup { \bold $tempotext }
147 \tempo \markup { "Low tempo" }
149 \tempoPadded #4.0 #"High tempo"
155 @node Funciones de sustitutión en parejas
156 @subsection Funciones de sustitutión en parejas
157 @translationof Paired substitution functions
159 Algunas instrucciones @code{\override} requieren un par de números
160 (llamados en Scheme una @code{célula cons}). Para pasar estos números
161 a una función, usamos una variable @code{pair?} o bien insertamos el
162 @code{cons} en la función musical.
167 #(define-music-function (parser location beg-end)
170 \once \override Beam #'positions = #$beg-end
174 \manualBeam #'(3 . 6) c8 d e f
182 @lilypond[quote,verbatim,ragged-right]
184 #(define-music-function (parser location beg end)
187 \once \override Beam #'positions = #(cons $beg $end)
191 \manualBeam #3 #6 c8 d e f
196 @node Matemáticas dentro de las funciones
197 @subsection Matemáticas dentro de las funciones
198 @translationof Mathematics in functions
200 Las funciones musicales pueden contar con programación de Scheme
201 además de la simple sustitución:
203 @lilypond[quote,verbatim,ragged-right]
204 AltOn = #(define-music-function (parser location mag) (number?)
205 #{ \override Stem #'length = #$(* 7.0 mag)
206 \override NoteHead #'font-size =
207 #$(inexact->exact (* (/ 6.0 (log 2.0)) (log mag))) #})
210 \revert Stem #'length
211 \revert NoteHead #'font-size
214 { c'2 \AltOn #0.5 c'4 c'
215 \AltOn #1.5 c' c' \AltOff c'2 }
219 Este ejemplo se puede reescribir de forma que pase expresiones
222 @lilypond[quote,verbatim,ragged-right]
223 withAlt = #(define-music-function (parser location mag music) (number? ly:music?)
224 #{ \override Stem #'length = #$(* 7.0 mag)
225 \override NoteHead #'font-size =
226 #$(inexact->exact (* (/ 6.0 (log 2.0)) (log mag)))
228 \revert Stem #'length
229 \revert NoteHead #'font-size #})
231 { c'2 \withAlt #0.5 {c'4 c'}
232 \withAlt #1.5 {c' c'} c'2 }
236 @node Funciones vacías
237 @subsection Funciones vacías
238 @translationof Void functions
240 Una función musical debe devolver una expresión musical, pero a veces
241 podemos necesitar una función en la que no hay música en juego (como
242 la desactivación de la funcionalidad Apuntar y Pulsar). Para hacerlo,
243 devolvemos una expresión musical @code{void} (vacía).
245 Este es el motivo por el que la forma que se devuelve es
246 @code{(make-music ...)}. Con el valor de la propiedad @code{'void}
247 establecido a @code{#t}, le decimos al analizador que descarte la
248 expresión musical devuelta. así, la parte importante de la función
249 musical vacía es el proceso realizado por la función, no la expresión
250 musical que se devuelve.
254 #(define-music-function (parser location) ()
255 (ly:set-option 'point-and-click #f)
256 (make-music 'SequentialMusic 'void #t))
258 \noPointAndClick % desactivar la funcionalidad Apuntar y Pulsar.
262 @node Funciones sin argumentos
263 @subsection Funciones sin argumentos
264 @translationof Functions without arguments
266 En casi todos los casos, una función sin argumentos se debe escribir
270 dolce = \markup@{ \italic \bold dolce @}
273 Sin embargo, en raras ocasiones puede ser de utilidad crear una
274 función musical sin argumentos:
278 #(define-music-function (parser location) ()
279 (if (eq? #t (ly:get-option 'display-bar-numbers))
280 #@{ \once \override Score.BarNumber #'break-visibility = ##f #@}
284 Para la impresión real de los números de compás donde se llama a esta
285 función, invoque a @command{lilypond} con
288 lilypond -d display-bar-numbers ARCHIVO.ly
292 @node Panorámica de las funciones musicales disponibles
293 @subsection Panorámica de las funciones musicales disponibles
294 @translationof Overview of available music functions
296 @c fixme ; this should be move somewhere else?
297 Las siguientes instrucciones son funciones musicales:
299 @include identifiers.tely
302 @node Interfaces para el programador
303 @section Interfaces para el programador
304 @translationof Programmer interfaces
306 Esta sección contiene información sobre cómo mezclar LilyPond y
310 * Variables de entrada y Scheme::
311 * Representación interna de la música::
314 @node Variables de entrada y Scheme
315 @subsection Variables de entrada y Scheme
316 @translationof Input variables and Scheme
318 El formato de entrada contempla la noción de variables: en el ejemplo
319 siguiente, se asigna una expresión musical a una variable con el
320 nombre @code{traLaLa}.
323 traLaLa = @{ c'4 d'4 @}
328 También existe una forma de ámbito léxico: en el ejemplo siguiente, el
329 bloque @code{\layout} también contiene una variable @code{traLaLa},
330 que es independiente de la @code{\traLaLa} exterior.
333 traLaLa = @{ c'4 d'4 @}
334 \layout @{ traLaLa = 1.0 @}
337 De hecho, cada archivo de entrada es un ámbito léxico, y todos los
338 bloques @code{\header}, @code{\midi} y @code{\layout} son ámbitos
339 anidados dentro de dicho ámbito de nivel superior.
341 Tanto el ámbito léxico como las variables están implementados en el
342 sistema de módulos GUILE. Se adjunta un módulo anónimo de Scheme a
343 cada ámbito. Una asignación de la forma
345 traLaLa = @{ c'4 d'4 @}
349 se convierte internamente a una definición de Scheme
351 (define traLaLa @var{Scheme value of `@code{... }'})
354 Esto supone que las variables de entrada y las variables de Scheme se
355 pueden entremezclar con libertad. En el ejemplo siguiente, se
356 almacena un fragmento musical en la variable @code{traLaLa}, y se
357 duplica utilizando Scheme. El resultado se importa en un bloque
358 @code{\score} por medio de una segunda variable @code{twice}:
361 traLaLa = { c'4 d'4 }
363 %% dummy action to deal with parser lookahead
364 #(display "this needs to be here, sorry!")
366 #(define newLa (map ly:music-deep-copy
367 (list traLaLa traLaLa)))
369 (make-sequential-music newLa))
374 @c Due to parser lookahead
376 En este ejemplo, la asignación se produce después de que el analizador
377 sintáctico ha verificado que no ocurre nada interesante después de
378 @code{traLaLa = @{ ... @}}. Sin el argumento mudo del ejemplo, la
379 definición @code{newLa} se ejecuta antes de que se defina
380 @code{traLaLa}, conduciendo a un error de sintaxis.
382 El ejemplo anterior muestra cómo @q{exportar} expresiones musicales
383 desde la entrada hasta el intérprete de Scheme. También es posible lo
384 contrario. Envolviendo un valor de Scheme en la función
385 @code{ly:export}, un valor de Scheme se interpreta como si hubiera
386 sido introducido en sintaxis de LilyPond. En vez de definir
387 @code{\twice}, el ejemplo anterior podría también haberse escrito como
391 @{ #(ly:export (make-sequential-music (list newLa))) @}
394 El código de Scheme se evalúa tan pronto como el analizador sintáctico
395 lo encuentra. Para definir código de Scheme en un macro (para
396 llamarlo con posterioridad), use @ref{Funciones vacías}, o bien
400 (ly:set-option 'point-and-click #f))
409 No es posible mezclar variables de Scheme y de LilyPond con la opción
413 @node Representación interna de la música
414 @subsection Representación interna de la música
415 @translationof Internal music representation
417 Cuando se analiza sintácticamente una expresión musical, se convierte
418 en un conjunto de objetos musicales de Scheme. La propiedad que
419 define a un objeto musical es que tiene una cierta duración. El
420 tiempo es un número racional que mide la longitud de un fragmento de
421 música en unidades del valor de una redonda.
423 Un objeto musical tiene tres clases de tipos:
426 nombre musical: cada expresión musical tiene un nombre. Por ejemplo,
427 una nota conduce a un evento @rinternals{NoteEvent}, y
428 @code{\simultaneous} conduce a @rinternals{SimultaneousMusic}. Hay
429 una lista de todas las expresiones que están disponibles en el Manual
430 de referencia de funcionamiento interno, bajo @rinternals{Music
434 @q{tipo} o interface: cada nombre de música tiene varios @q{tipos} o
435 interfaces, por ejemplo una nota es un @code{event}, pero también es
436 un @code{note-event}, un @code{rhythmic-event} y un
437 @code{melodic-event}. Todas las clases musicales se encuentran
438 relacionadas en la Referencia de funcionamiento interno bajo
439 @rinternals{Music classes}.
442 Objeto de C++: cada objeto musical está representado por un objeto de
443 la clase de C++ @code{Music}.
446 La información real de una expresión musical se almacena en forma de
447 propiedades. Por ejemplo, un evento @rinternals{NoteEvent} tiene
448 propiedades @code{pitch} y @code{duration} que almacenan la altura y
449 duración de la nota. Hay una lista completa de las propiedades que
450 están disponibles en la Referencia de funcionamiento interno, bajo
451 @rinternals{Music properties}.
453 Una expresión musical compuesta es un objeto musical que contiene
454 otros objetos musicales en sus propiedades. Se puede almacenar una
455 lista de objetos en la propiedad @code{elements} de un objeto musical,
456 o un solo objeto musical @q{hijo} en la propiedad @code{element}. Por
457 ejemplo, @rinternals{SequentialMusic} tiene sus hijos en
458 @code{elements}, y @rinternals{GraceMusic} tiene su elemento único en
459 @code{element}. El cuerpo de una repetición se almacena en la
460 propiedad @code{element} de @rinternals{RepeatedMusic}, y las
461 alternativas en @code{elements}.
465 @node Interfaz de marcado para el programador
466 @section Interfaz de marcado para el programador
467 @translationof Markup programmer interface
469 Los marcados están implementados como funciones de Scheme especiales
470 que producen un elemento Stencil (sello) dado un número de argumentos.
473 * Construcción del marcado en Scheme::
474 * Cómo funciona internamente el marcado::
475 * Definición de una instrucción de marcado nueva::
476 * Definición de nuevas instrucciones de lista de marcado::
479 @node Construcción del marcado en Scheme
480 @subsection Construcción del marcado en Scheme
481 @translationof Markup construction in Scheme
483 @cindex marcado, definir instrucciones de
485 El macro @code{markup} construye expresiones de marcado en Scheme,
486 proporcionando una sintaxis similar a la de LilyPond. Por ejemplo:
489 (markup #:column (#:line (#:bold #:italic "hola" #:raise 0.4 "mundo")
490 #:larger #:line ("fulano" "fulanito" "menganito")))
496 \markup \column @{ \line @{ \bold \italic "hola" \raise #0.4 "mundo" @}
497 \larger \line @{ fulano fulanito menganito @} @}
501 Este ejemplo muestra las principales reglas de traducción entre la
502 sintaxis del marcado normal de LilyPond y la sintaxis del marcado de
506 @multitable @columnfractions .3 .3
507 @item @b{LilyPond} @tab @b{Scheme}
508 @item @code{\markup marcado1} @tab @code{(markup marcado1)}
509 @item @code{\markup @{ marcado1 marcado2 ... @}} @tab
510 @code{(markup marcado1 marcado2 ... )}
511 @item @code{\instruccion} @tab @code{#:instruccion}
512 @item @code{\variable} @tab @code{variable}
513 @item @code{\center-column @{ ... @}} @tab @code{#:center-column ( ... )}
514 @item @code{cadena} @tab @code{"cadena"}
515 @item @code{#argumento-de-scheme} @tab @code{argumento-de-scheme}
519 Todo el lenguaje Scheme está accesible dentro del macro @code{markup}.
520 Por ejemplo, podemos usar llamadas a funciones dentro de @code{markup}
521 para así manipular cadenas de caracteres. Esto es útil si se están
522 definiendo instrucciones de marcado nuevas (véase @ref{Definición de una instrucción de marcado nueva}).
526 El argumento markup-list de instrucciones como @code{#:line},
527 @code{#:center} y @code{#:column} no pueden se una variable o el
528 resultado de la llamada a una función.
531 (markup #:line (funcion-que-devuelve-marcados))
535 no es válido. Hay que usar las funciones @code{make-line-markup},
536 @code{make-center-markup} o @code{make-column-markup} en su lugar:
539 (markup (make-line-markup (funcion-que-devuelve-marcados)))
543 @node Cómo funciona internamente el marcado
544 @subsection Cómo funciona internamente el marcado
545 @translationof How markups work internally
547 En un elemento de marcado como
550 \raise #0.5 "ejemplo de texto"
554 @code{\raise} se representa en realidad por medio de la función
555 @code{raise-markup}. La expresión de marcado se almacena como
558 (list raise-markup 0.5 (list simple-markup "ejemplo de texto"))
561 Cuando el marcado se convierte en objetos imprimibles (Stencils o
562 sellos), se llama la función @code{raise-markup} como
566 @var{\objeto de marcado}
567 @var{lista de listas asociativas de propiedades}
569 @var{el marcado "ejemplo de texto"})
572 Primero la función @code{raise-markup} crea el sello para la cadena
573 @code{ejemplo de texto}, y después eleva el sello Stencil en 0.5
574 espacios de pentagrama. Este es un ejemplo bastante simple; en el
575 resto de la sección podrán verse ejemplos más complejos, así como en
576 @file{scm/@/define@/-markup@/-commands@/.scm}.
579 @node Definición de una instrucción de marcado nueva
580 @subsection Definición de una instrucción de marcado nueva
581 @translationof New markup command definition
583 Las instrucciones de marcado nuevas se pueden definir con el macro de
584 Scheme @code{define-markup-command}.
587 (define-markup-command (@var{nombre-de-la-instruccion} @var{layout} @var{props} @var{arg1} @var{arg2} ...)
588 (@var{arg1-type?} @var{arg2-type?} ...)
596 @var{i}-ésimo argumento de la instrucción
598 predicado de tipo para el argumento @var{i}-ésimo
600 la definición de @q{presentación}
602 lista de listas asociativas, que contiene todas las propiedades
606 Como ejemplo sencillo, mostramos cómo añadir una instrucción
607 @code{\smallcaps}, que selecciona una tipografía de versalitas.
608 Normalmente podríamos seleccionar la tipografía de versalitas,
611 \markup @{ \override #'(font-shape . caps) Texto-en-versalitas @}
615 Esto selecciona la tipografía de versalitas mediante el
616 establecimiento de la propiedad @code{font-shape} a @code{#'caps} para
617 la interpretación de @code{Texto-en-versalitas}.
619 Para poner lo anterior disponible como la instrucción
620 @code{\smallcaps}, tenemos que definir una función utilizando
621 @code{define-markup-command}. La instrucción ha de tomar un argumento
622 del tipo @code{markup}. Por tanto, el inicio de la definición ha de
626 (define-markup-command (smallcaps layout props argument) (markup?)
631 Lo que aparece a continuación es el contenido de la instrucción:
632 debemos interpretar el @code{argument} como un marcado, es decir:
635 (interpret-markup layout @dots{} argument)
639 Esta interpretación tiene que añadir @code{'(font-shape . caps)} a las
640 propiedades activas, por lo que sustituimos lo siguiente por los
641 @dots{} en el ejemplo anterior:
644 (cons (list '(font-shape . caps) ) props)
648 La variable @code{props} es una lista de a-listas, y se lo anteponemos
649 haciendo la operación cons de una lista con el ajuste adicional.
651 Supongamos que estamos tipografiando un recitativo de una ópera y nos
652 gustaría definir una instrucción que presente los nombres de los
653 personajes de una forma personalizada. Queremos que los nombres se
654 impriman con versalitas y se desplacen un poco a la izquierda y hacia
655 arriba. Definimos una instrucción @code{\character} que toma en
656 cuenta la traslación necesaria y utiliza la instrucción
657 @code{\smallcaps} recién definida:
660 #(define-markup-command (character layout props nombre) (string?)
661 "Imprimir el nombre del personaje en versalitas, desplazado a la izquierda y hacia
662 arriba. Sintaxis: \\character #\"nombre\""
663 (interpret-markup layout props
664 (markup #:hspace 0 #:translate (cons -3 1) #:smallcaps nombre)))
667 Esta es una complicación que requiere una explicación: los textos por
668 encima y por debajo del pentagrama se mueven verticalmente de forma
669 que estén a una cierta distancia (la propiedad @code{padding}) del
670 pentagrama y de las notas. Para asegurar que este mecanismo no anula
671 el efecto de nuestro @code{#:translate}, añadimos una cadena vacía
672 (@code{#:hspace 0}) antes del texto trasladado. Ahora el
673 @code{#:hspace 0} se pone encima de las notas, y el @code{nombre} se
674 mueve en relación a dicha cadena vacía. El efecto neto es que el
675 texto se mueve hacia la izquierda y hacia arriba.
677 El resultado final es como sigue:
681 c''^\markup \character #"Cleopatra"
682 e'^\markup \character #"Giulio Cesare"
686 @lilypond[quote,ragged-right]
687 #(define-markup-command (smallcaps layout props str) (string?)
688 "Print the string argument in small caps. Syntax: \\smallcaps #\"string\""
689 (interpret-markup layout props
692 (if (= (string-length s) 0)
694 (markup #:large (string-upcase (substring s 0 1))
695 #:translate (cons -0.6 0)
696 #:tiny (string-upcase (substring s 1)))))
697 (string-split str #\Space)))))
699 #(define-markup-command (character layout props name) (string?)
700 "Print the character name in small caps, translated to the left and
701 top. Syntax: \\character #\"name\""
702 (interpret-markup layout props
703 (markup #:hspace 0 #:translate (cons -3 1) #:smallcaps name)))
706 c''^\markup \character #"Cleopatra" c'' c'' c''
707 e'^\markup \character #"Giulio Cesare" e' e' e'
711 Hemos usado la forma de fuente tipográfica @code{caps}, pero
712 supongamos que nuestra fuente no tiene la variante de versalitas. En
713 ese caso tenemos que hacer una falsa fuente de mayúsculas pequeñas
714 haciendo que la cadena en mayúsculas tenga la primera legra un poco
718 #(define-markup-command (smallcaps layout props str) (string?)
719 "Print the string argument in small caps."
720 (interpret-markup layout props
723 (if (= (string-length s) 0)
725 (markup #:large (string-upcase (substring s 0 1))
726 #:translate (cons -0.6 0)
727 #:tiny (string-upcase (substring s 1)))))
728 (string-split str #\Space)))))
731 La instrucción @code{smallcaps} primero divide su argumento de cadena
732 en unidades o palabras separadas por espacios (@code{(string-split str
733 #\Space)}); para cada unidad o palabra, se construye un marcado con la
734 primera letra agrandada y en mayúscula (@code{#:large (string-upcase
735 (substring s 0 1))}), y un segundo marcado construido con las letras
736 siguientes reducidas de tamaño y en mayúsculas (@code{#:tiny
737 (string-upcase (substring s 1))}). Como LilyPond introduce un espacio
738 entre los marcados de una misma línea, el segundo marcado se traslada
739 a la izquierda (@code{#:translate (cons -0.6 0) ...}). Después, los
740 marcados construidos para cada palabra se ponen en una línea mediante
741 @code{(make-line-markup ...)}. Finalmente, el marcado resultante se
742 pasa a la función @code{interpret-markup}, con los argumentos
743 @code{layout} y @code{props}.
745 Nota: ahora existe una instrucción interna @code{\smallCaps} que se
746 puede usar para poner texto en versalitas. Consulte @ref{Text markup commands}, para ver más detalles.
750 Actualmente las combinaciones de argumentos que hay disponibles
751 (después de los argumentos estándar @var{layout} y @var{props}) para
752 una instrucción de marcado definida con @code{define-markup-command}
753 se limitan a la siguiente lista:
756 @item (ningún argumento)
759 @itemx @var{markup markup}
761 @itemx @var{scm markup}
763 @itemx @var{scm scm markup}
764 @itemx @var{scm scm markup markup}
765 @itemx @var{scm markup markup}
766 @itemx @var{scm scm scm}
770 En la tabla de arriba, @var{scm} representa los tipos de datos nativos
771 de Scheme como @q{number} (número) o @q{string} (cadena).
773 Como ejemplo, no es posible usar una instrucción de marcado
774 @code{fulanito} con cuatro argumentos definida como
777 #(define-markup-command (fulanito layout props
779 (number? string? number? string?)
784 Si la aplicamos como, digamos,
787 \markup \fulanito #1 #"mengano" #2 #"zutano"
790 @cindex Scheme signature
791 @cindex signature, Scheme
793 @command{lilypond} protesta diciendo que no puede analizar
794 @code{fulanito} debido a su firma de Scheme desconocida.
797 @node Definición de nuevas instrucciones de lista de marcado
798 @subsection Definición de nuevas instrucciones de lista de marcado
799 @translationof New markup list command definition
801 Las instrucciones de listas de marcado se definen con el macro de
802 Scheme @code{define-markup-list-command}, que es similar al macro
803 @code{define-markup-command} descrito en @ref{Definición de una instrucción de marcado nueva}, excepto que donde éste devuelve un sello único, aquél
804 devuelve una lista de sellos.
806 En el siguiente ejemplo se define una instrucción de lista de marcado
807 @code{\paragraph}, que devuelve una lista de líneas justificadas,
808 estando la primera de ellas sangrada. La anchura del sangrado se toma
809 del argumento @code{props}.
812 #(define-markup-list-command (paragraph layout props args) (markup-list?)
813 (let ((indent (chain-assoc-get 'par-indent props 2)))
814 (interpret-markup-list layout props
815 (make-justified-lines-markup-list (cons (make-hspace-markup indent)
819 Aparte de los argumentos usuales @code{layout} y @code{props}, la
820 instrucción de lista de marcados @code{paragraph} toma un argumento de
821 lista de marcados, llamado @code{args}. El predicado para listas de
822 marcados es @code{markup-list?}.
824 En primer lugar, la función toma el ancho del sangrado, una propiedad
825 llamada aquí @code{par-indent}, de la lista de propiedades
826 @code{props}. Si no se encuentra la propiedad, el valor
827 predeterminado es @code{2}. Después, se hace una lista de líneas
828 justificadas usando la función
829 @code{make-justified-lines-markup-list}, que está relacionada con la
830 instrucción incorporada de lista de marcados @code{\justified-lines}.
831 Se añade un espacio horizontal al principio usando la función
832 @code{make-hspace-markup}. Finalmente, la lista de marcados se
833 interpreta usando la función @code{interpret-markup-list}.
835 Esta nueva instrucción de lista de marcados se puede usar como sigue:
840 El arte de la tipografía musical se llama \italic @{grabado (en plancha).@}
841 El término deriva del proceso tradicional de impresión de música.
842 hace sólo algunas décadas, las partituras se hacían cortando y estampando
843 la música en una plancha de zinc o lata en una imagen invertida.
845 \override-lines #'(par-indent . 4) \paragraph @{
846 La plancha se tenía que entintar, y las depresiones causadas por los cortes
847 y estampados retienen la tinta. Se formaba una imagen presionando el papel
848 contra la plancha. El estampado y cortado se hacía completamente
855 @node Contextos para programadores
856 @section Contextos para programadores
857 @translationof Contexts for programmers
860 * Evaluación de contextos::
861 * Ejecutar una función sobre todos los objetos de la presentación::
864 @node Evaluación de contextos
865 @subsection Evaluación de contextos
866 @translationof Context evaluation
868 @cindex código, llamadas durante la interpretación
869 @funindex \applyContext
871 Se pueden modificar los contextos durante la interpretación con código
872 de Scheme. La sintaxis para esto es
875 \applyContext @var{función}
878 @var{función} debe ser una función de Scheme que toma un único
879 argumento, que es el contexto al que aplicarla. El código siguiente
880 imprime el número del compás actual sobre la salida estándar durante
886 (format #t "\nSe nos ha llamado en el compás número ~a.\n"
887 (ly:context-property x 'currentBarNumber)))
891 @node Ejecutar una función sobre todos los objetos de la presentación
892 @subsection Ejecutar una función sobre todos los objetos de la presentación
893 @translationof Running a function on all layout objects
896 @cindex código, llamar sobre objetos de presentación
897 @funindex \applyOutput
900 La manera más versátil de realizar el ajuste fino de un objeto es
901 @code{\applyOutput}. Su sintaxis es
904 \applyOutput @var{contexto} @var{proc}
908 donde @var{proc} es una función de Scheme, que toma tres argumentos.
910 Al interpretarse, la función @var{proc} se llama para cada objeto de
911 presentación que se encuentra en el contexto @var{contexto}, con los
912 siguientes argumentos:
915 @item el propio objeto de presentación,
916 @item el contexto en que se creó el objeto de presentación, y
917 @item el contexto en que se procesa @code{\applyOutput}.
920 Además, la causa del objeto de presentación, es decir el objeto o
921 expresión musical que es responsable de haberlo creado, está en la
922 propiedad @code{cause} del objeto. Por ejemplo, para la cabeza de una
923 nota, éste es un evento @rinternals{NoteHead}, y para un objeto
924 @rinternals{Stem} (plica), éste es un objeto @rinternals{Stem}.
925 @c Impossible - changed to Stem --FV
927 He aquí una función que usar para @code{\applyOutput}; borra las
928 cabezas de las notas que están sobre la línea central:
930 @lilypond[quote,verbatim,ragged-right]
931 #(define (blanker grob grob-origin context)
932 (if (and (memq 'note-head-interface (ly:grob-interfaces grob))
933 (eq? (ly:grob-property grob 'staff-position) 0))
934 (set! (ly:grob-property grob 'transparent) #t)))
937 e4 g8 \applyOutput #'Voice #blanker b d2
942 @node Procedimientos de Scheme como propiedades
943 @section Procedimientos de Scheme como propiedades
944 @translationof Scheme procedures as properties
946 Las propiedades (como el grosor, la dirección, etc.) se pueden
947 establecer a valores fijos con \override, p. ej.
950 \override Stem #'thickness = #2.0
953 Las propiedades pueden fijarse también a un procedimiento de scheme,
955 @lilypond[fragment,verbatim,quote,relative=2]
956 \override Stem #'thickness = #(lambda (grob)
957 (if (= UP (ly:grob-property grob 'direction))
964 En este caso, el procedimiento se ejecuta tan pronto como el valor de
965 la propiedad se reclama durante el proceso de formateo.
967 Casi todo el motor de tipografiado está manejado por estos
968 @emph{callbacks}. Entre las propiedades que usan normalmente
969 @emph{callbacks} están
973 La rutina de impresión, que construye un dibujo para el símbolo
975 La rutina que establece la posición horizontal
977 La rutina que calcula la anchura de un objeto
980 El procedimiento siempre toma un argumento único, que es el grob (el
983 Si se deben llamar rutinas con varios argumentos, el grob actual se
984 puede insertar con una cerradura de grob. He aquí un ajuste
985 procedente de @code{AccidentalSuggestion},
989 ,(ly:make-simple-closure
991 ,(ly:make-simple-closure
992 (list ly:self-alignment-interface::centered-on-x-parent))
993 ,(ly:make-simple-closure
994 (list ly:self-alignment-interface::x-aligned-on-self)))))
998 En este ejemplo, tanto
999 @code{ly:self-alignment-interface::x-aligned-on-self} como
1000 @code{ly:self-alignment-interface::centered-on-x-parent} se llaman con
1001 el grob como argumento. El resultado se añade con la función
1002 @code{+}. Para asegurar que esta adición se ejecuta adecuadamente,
1003 todo ello se encierra dentro de @code{ly:make-simple-closure}.
1005 De hecho, usar un solo procedimiento como valor de una propiedad
1009 (ly:make-simple-closure (ly:make-simple-closure (list @var{proc})))
1013 El @code{ly:make-simple-closure} interior aporta el grob como
1014 argumento de @var{proc}, el exterior asegura que el resultado de la
1015 función es lo que se devuelve, en lugar del objeto
1016 @code{simple-closure}.
1019 @node Usar código de Scheme en lugar de \tweak
1020 @section Usar código de Scheme en lugar de @code{\tweak}
1021 @translationof Using Scheme code instead of \tweak
1023 La principal desventaja de @code{\tweak} es su inflexibilidad
1024 sintáctica. Por ejemplo, lo siguiente produce un error de sintaxis.
1027 F = \tweak #'font-size #-3 -\flageolet
1035 En otras palabras, @code{\tweak} no se comporta como una articulación
1036 en cuando a la sintaxis; concretamente, no se puede adjuntar con
1037 @code{^} y @code{_}.
1039 Usando Scheme, se puede dar un rodeo a este problema. La ruta hacia
1040 el resultado se da en @ref{Añadir articulación a las notas (ejemplo)},
1041 especialmente cómo usar @code{\displayMusic} como guía de ayuda.
1044 F = #(let ((m (make-music 'ArticulationEvent
1045 'articulation-type "flageolet")))
1046 (set! (ly:music-property m 'tweaks)
1047 (acons 'font-size -3
1048 (ly:music-property m 'tweaks)))
1057 Aquí, las propiedades @code{tweaks} del objeto flageolet @code{m}
1058 (creado con @code{make-music}) se extraen con
1059 @code{ly:music-property}, se antepone un nuevo par clave-valor para
1060 cambiar el tamaño de la tipografía a la lista de propiedades con la
1061 función de Scheme @code{acons}, y finalmente el resultado se escribe
1062 de nuevo con @code{set!}. El último elemento del bloque @code{let} es
1063 el valor de retorno, el propio @code{m}.
1065 @node Trucos difíciles
1066 @section Trucos difíciles
1067 @translationof Difficult tweaks
1069 Hay un cierto número de tipos de ajustes difíciles.
1074 Un tipo de ajuste difícil es la apariencia de los objetos de
1075 extensión, como las ligaduras de expresión y de unión. Inicialmente,
1076 sólo se crea uno de estos objetos, y pueden ajustarse con el mecanismo
1077 normal. Sin embargo, en ciertos casos los objetos extensores cruzan
1078 los saltos de línea. Si esto ocurre, estos objetos se clonan. Se
1079 crea un objeto distinto por cada sistema en que se encuentra. Éstos
1080 son clones del objeto original y heredan todas sus propiedades,
1081 incluidos los @code{\override}s.
1083 En otras palabras, un @code{\override} siempre afecta a todas las
1084 piezas de un objeto de extensión fragmentado. Para cambiar sólo una
1085 parte de un extensor en el salto de línea, es necesario inmiscuirse en
1086 el proceso de formateado. El @emph{callback}
1087 @code{after-line-breaking} contiene el procedimiento Scheme que se
1088 llama después de que se han determinado los saltos de línea, y los
1089 objetos de presentación han sido divididos sobre los distintos
1092 En el ejemplo siguiente, definimos un procedimiento
1093 @code{my-callback}. Este procedimiento
1097 determina si hemos sido divididos por los saltos de línea
1099 en caso afirmativo, reúne todos los objetos divididos
1101 comprueba si somos el último de los objetos divididos
1103 en caso afirmativo, establece @code{extra-offset}.
1106 Este procedimiento se instala en @rinternals{Tie} (ligadura de unión),
1107 de forma que la última parte de la ligadura dividida se traslada hacia
1110 @lilypond[quote,verbatim,ragged-right]
1111 #(define (my-callback grob)
1113 ; have we been split?
1114 (orig (ly:grob-original grob))
1116 ; if yes, get the split pieces (our siblings)
1117 (siblings (if (ly:grob? orig)
1118 (ly:spanner-broken-into orig) '() )))
1120 (if (and (>= (length siblings) 2)
1121 (eq? (car (last-pair siblings)) grob))
1122 (ly:grob-set-property! grob 'extra-offset '(-2 . 5)))))
1125 \override Tie #'after-line-breaking =
1132 Al aplicar este truco, la nueva función de callback
1133 @code{after-line-breaking} también debe llamar a la antigua
1134 @code{after-line-breaking}, si existe. Por ejemplo, si se usa con
1135 @code{Hairpin}, se debe llamar también a
1136 @code{ly:hairpin::after-line-breaking}.
1139 @item Algunos objetos no se pueden cambiar con @code{\override} por
1140 razones técnicas. Son ejemplos @code{NonMusicalPaperColumn} y
1141 @code{PaperColumn}. Se pueden cambiar con la función
1142 @code{\overrideProperty} que funciona de forma similar a @code{\once
1143 \override}, pero usa una sintaxis distinta.
1147 #"Score.NonMusicalPaperColumn" % Nombre del grob
1148 #'line-break-system-details % Nombre de la propiedad
1149 #'((next-padding . 20)) % Valor
1152 Observe, sin embargo, que @code{\override}, aplicado a
1153 @code{NonMusicalPaperColumn} y a @code{PaperColumn}, aún funciona
1154 como se espera dentro de los bloques @code{\context}.
1159 @node Interfaces de Scheme de LilyPond
1160 @chapter Interfaces de Scheme de LilyPond
1161 @translationof LilyPond Scheme interfaces