1 @c -*- coding: utf-8; mode: texinfo; documentlanguage: es -*-
2 @c This file is part of lilypond.tely
4 Translation of GIT committish: 4a527608c5ff2ce31e596495d00dce181dc1b9ea
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 for programmers
13 @chapter Interfaces for programmers
15 Se pueden realizar trucos avanzados mediante el uso de Scheme. Si no
16 está familizarizado con Scheme, le conviene leer nuestro tutorial de
17 Scheme, @rlearning{Scheme tutorial}.
21 * Programmer interfaces::
22 * Building complicated functions::
23 * Markup programmer interface::
24 * Contexts for programmers::
25 * Scheme procedures as properties::
26 * Using Scheme code instead of \tweak::
32 @section Music functions
34 Esta sección trata sobre cómo crear funciones musicales dentro de
38 * Overview of music functions::
39 * Simple substitution functions::
40 * Paired substitution functions::
41 * Mathematics in functions::
43 * Functions without arguments::
44 * Overview of available music functions::
47 @node Overview of music functions
48 @subsection Overview of music functions
50 Es fácil hacer una función que sustituya a una variable en código de
51 LilyPond. La forma general de estas funciones es:
55 #(define-music-function (parser location @var{var1} @var{var2}... )
56 (@var{var1-type?} @var{var2-type?}...)
65 @multitable @columnfractions .33 .66
66 @item @var{argi} @tab @var{i}-ésima variable
67 @item @var{argi-type?} @tab tipo de variable
68 @item @var{...música...} @tab entrada normal de LilyPond, usando las variables como @code{#$var1}.
71 Los siguientes tipos de entrada se pueden usar como variables en una
72 función musical. Esta lista no es exhaustiva; consulte otros lugares
73 de la documentación específica de Scheme para ver otros tipos de
76 @multitable @columnfractions .33 .66
77 @headitem Tipo de entrada @tab notación de @var{argi-type?}
78 @item Entero @tab @code{integer?}
79 @item Flotante (número decimal) @tab @code{number?}
80 @item Cadena de texto @tab @code{string?}
81 @item Marcado @tab @code{markup?}
82 @item Expresión musical @tab @code{ly:music?}
83 @item Pareja de variables @tab @code{pair?}
86 Los argumentos @code{parser} y @code{location} son obligatorios, y
87 se usan en ciertas situaciones avanzadas. El argumento
88 @code{parser} se usa para acceder al valor de otra variable de
89 LilyPond. El argumento @code{location} se usa para establecer el
90 @q{origen} de la expresión musical que construye la función musical,
91 de forma que en caso de producirse un error de sintaxis LilyPond pueda
92 informar al usuario de un lugar adecuado donde buscar en el archivo de
96 @node Simple substitution functions
97 @subsection Simple substitution functions
99 He aquí un ejemplo sencillo:
101 @lilypond[quote,verbatim,ragged-right]
102 padText = #(define-music-function (parser location padding) (number?)
104 \once \override TextScript #'padding = #$padding
112 c4^"piu mosso" fis a g
116 También se pueden sustituir las expresiones musicales:
118 @lilypond[quote,verbatim,ragged-right]
119 custosNote = #(define-music-function (parser location note)
122 \once \override Voice.NoteHead #'stencil =
123 #ly:text-interface::print
124 \once \override Voice.NoteHead #'text =
125 \markup \musicglyph #"custodes.mensural.u0"
126 \once \override Voice.Stem #'stencil = ##f
130 { c' d' e' f' \custosNote g' }
133 Se pueden usar más de una variable:
135 @lilypond[quote,verbatim,ragged-right]
136 tempoMark = #(define-music-function (parser location padding marktext)
139 \once \override Score . RehearsalMark #'padding = $padding
140 \once \override Score . RehearsalMark #'extra-spacing-width = #'(+inf.0 . -inf.0)
141 \mark \markup { \bold $marktext }
146 \tempoMark #3.0 #"Allegro"
152 @node Paired substitution functions
153 @subsection Paired substitution functions
155 Algunas instrucciones @code{\override} requieren un par de números
156 (llamados en Scheme una @code{célula cons}). Para pasar estos números
157 a una función, usamos una variable @code{pair?} o bien insertamos el
158 @code{cons} en la función musical.
163 #(define-music-function (parser location beg-end)
166 \once \override Beam #'positions = #$beg-end
170 \manualBeam #'(3 . 6) c8 d e f
178 @lilypond[quote,verbatim,ragged-right]
180 #(define-music-function (parser location beg end)
183 \once \override Beam #'positions = #(cons $beg $end)
187 \manualBeam #3 #6 c8 d e f
192 @node Mathematics in functions
193 @subsection Mathematics in functions
195 Las funciones musicales pueden contar con programación de Scheme
196 además de la simple sustitución:
198 @lilypond[quote,verbatim,ragged-right]
199 AltOn = #(define-music-function (parser location mag) (number?)
200 #{ \override Stem #'length = #$(* 7.0 mag)
201 \override NoteHead #'font-size =
202 #$(inexact->exact (* (/ 6.0 (log 2.0)) (log mag))) #})
205 \revert Stem #'length
206 \revert NoteHead #'font-size
209 { c'2 \AltOn #0.5 c'4 c'
210 \AltOn #1.5 c' c' \AltOff c'2 }
214 Este ejemplo se puede reescribir de forma que pase expresiones
217 @lilypond[quote,verbatim,ragged-right]
218 withAlt = #(define-music-function (parser location mag music) (number? ly:music?)
219 #{ \override Stem #'length = #$(* 7.0 mag)
220 \override NoteHead #'font-size =
221 #$(inexact->exact (* (/ 6.0 (log 2.0)) (log mag)))
223 \revert Stem #'length
224 \revert NoteHead #'font-size #})
226 { c'2 \withAlt #0.5 {c'4 c'}
227 \withAlt #1.5 {c' c'} c'2 }
232 @subsection Void functions
234 Una función musical debe devolver una expresión musical, per a veces
235 podemos necesitar una función en la que no hay música en juego (como
236 la desactivación de la funcionalidad Apuntar y Pulsar). Para hacerlo,
237 devolvemos una expresión musical @code{void} (vacía).
239 Este es el motivo por el que la forma que se devuelve es
240 @code{(make-music ...)}. Con el valor de la propiedad @code{'void}
241 establecido a @code{#t}, le decimos al analizador que descarte la
242 expresión musical devuelta. así, la parte importante de la función
243 musical vacía es el proceso realizado por la función, no la expresión
244 musical que se devuelve.
248 #(define-music-function (parser location) ()
249 (ly:set-option 'point-and-click #f)
250 (make-music 'SequentialMusic 'void #t))
252 \noPointAndClick % desactivar la funcionalidad Apuntar y Pulsar.
256 @node Functions without arguments
257 @subsection Functions without arguments
259 En casi todos los casos, una función sin argumentos se debe escribir
263 dolce = \markup@{ \italic \bold dolce @}
266 Sin embargo, en raras ocasiones puede ser de utilidad crear una
267 función musical sin argumentos:
271 #(define-music-function (parser location) ()
272 (if (eq? #t (ly:get-option 'display-bar-numbers))
273 #@{ \once \override Score.BarNumber #'break-visibility = ##f #@}
277 Para la imresión real de los números de compás donde se llama a esta
278 función, invoque a @command{lilypond} con
281 lilypond -d display-bar-numbers ARCHIVO.ly
285 @node Overview of available music functions
286 @subsection Overview of available music functions
288 @c fixme ; this should be move somewhere else?
289 Las siguientes instrucciones son funciones musicales:
291 @include identifiers.tely
294 @node Programmer interfaces
295 @section Programmer interfaces
297 Esta sección contiene información sobre cómo mezclar LilyPond y
301 * Input variables and Scheme::
302 * Internal music representation::
305 @node Input variables and Scheme
306 @subsection Input variables and Scheme
308 El formato de entrada contempla la noción de variables: en el ejemplo
309 siguiente, se asigna una expresión musical a una variable con el
310 nombre @code{traLaLa}.
313 traLaLa = @{ c'4 d'4 @}
318 También existe una forma de ámbito léxico: en el ejemplo siguiente, el
319 bloque @code{\layout} también contiene una variable @code{traLaLa},
320 que es independiente de la @code{\traLaLa} exterior.
323 traLaLa = @{ c'4 d'4 @}
324 \layout @{ traLaLa = 1.0 @}
327 De hecho, cada archivo de entrada es un ámbito léxico, y todos los
328 bloques @code{\header}, @code{\midi} y @code{\layout} son ámbitos
329 anidados dentro de dicho ámbito de nivel superior.
331 Tanto el ámbito léxico como las variables están implementados en el
332 sistema de módulos GUILE. Se adjunta un módulo anónimo de Scheme a
333 cada ámbito. Una asignación de la forma
335 traLaLa = @{ c'4 d'4 @}
339 se convierte internamente a una definición de Scheme
341 (define traLaLa @var{Scheme value of `@code{... }'})
344 Esto supone que las variables de entrada y las variables de Scheme se
345 pueden intermezclar con libertad. En el ejemplo siguiente, se
346 almacena un fragmento musical en la variable @code{traLaLa}, y se
347 dupplica utilizando Scheme. El resultado se importa en un bloque
348 @code{\score} por medio de una segunda variable @code{twice}:
351 traLaLa = { c'4 d'4 }
353 %% dummy action to deal with parser lookahead
354 #(display "this needs to be here, sorry!")
356 #(define newLa (map ly:music-deep-copy
357 (list traLaLa traLaLa)))
359 (make-sequential-music newLa))
364 @c Due to parser lookahead
366 En este ejemplo, la asignación se produce después de que el analizador
367 sintáctico ha verificado que no ocurre nada interesante después de
368 @code{traLaLa = @{ ... @}}. Sin el argumento mudo del ejemplo, la
369 definición @code{newLa} se ejecuta antes de que se defina
370 @code{traLaLa}, conduciendo a un error de sintaxis.
372 El ejemplo anterior muestra cómo @q{exportar} expresiones musicales
373 desde la entrada hasta el intérprete de Scheme. También es posible lo
374 contrario. Envolviendo un valor de Scheme en la función
375 @code{ly:export}, un valor de Scheme se interpreta como si hubiera
376 sido introducido en sintaxis de LilyPond. En vez de definir
377 @code{\twice}, el ejemplo anterior podría también haberse escrito como
380 @{ #(ly:export (make-sequential-music (list newLa))) @}
383 El sódigo de Scheme se evalúa tan pronto como el analizador sintáctico
384 lo encuentra. Para definir código de Scheme en un macro (para
385 llamarlo con posterioridad), use @ref{Void functions}, o bien
389 (ly:set-option 'point-and-click #f))
398 No es posible mezclar variables de Scheme y de LilyPond con la opción
402 @node Internal music representation
403 @subsection Internal music representation
405 Cuando se analiza sintácticamente una expresión musical, se convierte
406 en un conjunto de objetos musicales de Scheme. La propiedad que
407 define a un objeto musical es que tiene una cierta duración. El
408 tiempo es un número racional que mide la longitud de un fragmento de
409 música en unidades del valor de una redonda.
411 Un objeto musical tiene tres clases de tipos:
414 nombre musical: cada expresión musical tiene un nombre. Por ejemplo,
415 una nota conduce a un evento @rinternals{NoteEvent}, y
416 @code{\simultaneous} conduce a @rinternals{SimultaneousMusic}. Hay
417 una lista de todas las expresiones que están disponibles en el Manual
418 de referencia de funcionamiento interno, bajo @rinternals{Music
422 @q{typo} o intterface: cada nombre de música tiene varios @q{tipos} o
423 interfaces, por ejemplo una nota es un @code{event}, pero también es
424 un @code{note-event}, un @code{rhythmic-event} y un
425 @code{melodic-event}. Todas las clases musicales se encuentran
426 relacionadas en la Referencia de funcionamiento interno bajo
427 @rinternals{Music classes}.
430 Objeto de C++: cada objeto musical está representado por un objeto de
431 la clase de C++ @code{Music}.
434 La información real de una expresión musical se almacena en forma de
435 propiedades. Por ejemplo, un evento @rinternals{NoteEvent} tiene
436 propiedades @code{pitch} y @code{duration} que almacenan la altura y
437 duración de la nota. Hay una lista completa de las propiedades que
438 están disponibles en la Referencia de funcionamiento interno, bajo
439 @rinternals{Music properties}.
441 Una expresión musical compuesta es un objeto musical que contiene
442 otros objetos musicales en sus propiedades. Se puede almacernar una
443 lista de objetos en la propiedad @code{elements} de un objeto musical,
444 o un solo objeto musical @q{hijo} en la propiedad @code{element}. Por
445 ejemplo, @rinternals{SequentialMusic} tiene sus hijos en
446 @code{elements}, y @rinternals{GraceMusic} tiene su elemento único en
447 @code{element}. El cuerpo de una repetición se almacena en la
448 propiedad @code{element} de @rinternals{RepeatedMusic}, y las
449 alternativas en @code{elements}.
452 @node Building complicated functions
453 @section Building complicated functions
455 Esta sección explica cómo reunir la información necesaria para crear
456 funciones musicales complejas.
460 * Displaying music expressions::
462 * Doubling a note with slurs (example)::
463 * Adding articulation to notes (example)::
466 @node Displaying music expressions
467 @subsection Displaying music expressions
469 @cindex interno, almacenamiento
470 @funindex \displayMusic
472 Si se está escribiendo una función musical puede ser muy instructivo
473 examinar cómo se almacena internamente una expresión musical. Esto se
474 puede hacer con la función musical @code{\displayMusic}:
478 \displayMusic @{ c'4\f @}
483 imprime lo siguiente:
495 (ly:make-duration 2 0 1 1)
497 (ly:make-pitch 0 0 0))
499 'AbsoluteDynamicEvent
504 De forma predeterminada, LilyPond imprime estos mensajes en la consola
505 junto al resto de los mensajes. Para discernir entre estos mensajes y
506 guardar el resultado de @code{\display@{MATERIAL@}}, redirija la
507 salida hacia un archivo.
510 lilypond archivo.ly >resultado.txt
513 Con la aplicación de un poco de formato, la inforamción anterior es
517 (make-music 'SequentialMusic
518 'elements (list (make-music 'EventChord
519 'elements (list (make-music 'NoteEvent
520 'duration (ly:make-duration 2 0 1 1)
521 'pitch (ly:make-pitch 0 0 0))
522 (make-music 'AbsoluteDynamicEvent
526 Una secuencia musical @code{@{ ... @}} tiene el nombre
527 @code{SequentialMusic}, y sus expresiones internas se almacenan como
528 una lista en su propiedad @code{'elements}. Una nota se representa
529 como una expresión @code{EventChord} que contiene un objeto
530 @code{NoteEvent} (que almacena las propiedades de duración y altura) y
531 cualquier otra información adicional (en este caso, un evento
532 @code{AbsoluteDynamicEvent} con una porpiedad de texto @code{"f"}.
535 @node Music properties
536 @subsection Music properties
538 El objeto @code{NoteEvent} es el primer objeto de la propiedad
539 @code{'elements} de @code{someNote}.
543 \displayMusic \unaNota
551 (ly:make-duration 2 0 1 1)
553 (ly:make-pitch 0 0 0))))
556 La función @code{display-scheme-music} es la función utilizada por
557 @code{\displayMusic} para imprimir la representación de Scheme de una
561 #(display-scheme-music (first (ly:music-property unaNota 'elements)))
566 (ly:make-duration 2 0 1 1)
568 (ly:make-pitch 0 0 0))
571 Después se accede a la altura de la nota a través de la propiedad
572 @code{'pitch} del objeto @code{NoteEvent}:
575 #(display-scheme-music
576 (ly:music-property (first (ly:music-property unaNota 'elements))
579 (ly:make-pitch 0 0 0)
582 La altura de la nota se puede cambiar estableciendo el valor de esta
585 @funindex \displayLilyMusic
588 #(set! (ly:music-property (first (ly:music-property unaNota 'elements))
590 (ly:make-pitch 0 1 0)) ;; fijar la altura a d'.
591 \displayLilyMusic \unaNota
597 @node Doubling a note with slurs (example)
598 @subsection Doubling a note with slurs (example)
600 Supongamos que queremos crear una función que traduce una entrada como
601 @code{a} a algo como @code{a( a)}. Empezamos examinando la
602 representación interna de la música con la que queremos terminar.
605 \displayMusic@{ a'( a') @}
616 (ly:make-duration 2 0 1 1)
618 (ly:make-pitch 0 5 0))
629 (ly:make-duration 2 0 1 1)
631 (ly:make-pitch 0 5 0))
638 Las malas noticias son que las espresiones @code{SlurEvent} se deben
639 añadir @q{dentro} de la nota (o más concretamente, dentro de la
640 expresión @code{EventChord}).
642 Ahora observamos la entrada:
654 (ly:make-duration 2 0 1 1)
656 (ly:make-pitch 0 5 0))))))
659 Así pues, en nuestra función, tenemos que clonar esta expresión (de
660 forma que tengamos dos notas para construir la secuencia), añadir
661 @code{SlurEvents} a la propiedad @code{'elements} de cada una de
662 ellas, y por último hacer una secuencia @code{SequentialMusic} con los
663 dos @code{EventChords}.
666 doubleSlur = #(define-music-function (parser location note) (ly:music?)
667 "Return: @{ note ( note ) @}.
668 `note' is supposed to be an EventChord."
669 (let ((note2 (ly:music-deep-copy note)))
670 (set! (ly:music-property note 'elements)
671 (cons (make-music 'SlurEvent 'span-direction -1)
672 (ly:music-property note 'elements)))
673 (set! (ly:music-property note2 'elements)
674 (cons (make-music 'SlurEvent 'span-direction 1)
675 (ly:music-property note2 'elements)))
676 (make-music 'SequentialMusic 'elements (list note note2))))
680 @node Adding articulation to notes (example)
681 @subsection Adding articulation to notes (example)
683 La manera fácil de añadir articulación a las notas es fundir dos
684 expresiones musicales en un contexto único, como está explicado en
685 @ref{Creating contexts}. Sin embargo, suponga que queremos escribir
686 una función musical que haga esto.
688 Una @code{$variable} dentro de la notación @code{#@{...#@}} es como
689 usar una @code{\variable} normal en la notación clásica de LilyPond.
697 no funciona en LilyPond. Podemos evitar este problema adjuntando la
698 articulación a una nota de mentira,
701 @{ << \musica s1*0-.-> @}
705 pero a los efectos de este ejemplo, aprenderemos ahora cómo hacerlo en
706 Scheme. Comenzamos examinando nuestra entrada y la salida deseada:
718 (ly:make-duration 2 0 1 1)
720 (ly:make-pitch -1 0 0))))
731 (ly:make-duration 2 0 1 1)
733 (ly:make-pitch -1 0 0))
740 Vemos que una nota (@code{c4}) se representa como una expresión
741 @code{EventChord}, con una expresión @code{NoteEvent} en su lista de
742 elementos. Para añadir una articulación marcato, se debe añadir una
743 expresión @code{ArticulationEvent} a la propiedad elementos de la
744 expresión @code{EventChord}.
746 Para construir esta función, empezamos con
749 (define (add-marcato event-chord)
750 "Añadir una ArticulationEvent de marcato a los elementos de `event-chord',
751 que se ssupone que es una expresión EventChord."
752 (let ((result-event-chord (ly:music-deep-copy event-chord)))
753 (set! (ly:music-property result-event-chord 'elements)
754 (cons (make-music 'ArticulationEvent
755 'articulation-type "marcato")
756 (ly:music-property result-event-chord 'elements)))
760 La primera línea es la forma de definir una función en Scheme: el
761 nombre de la función es @code{add-marcato}, y tiene una variable
762 llamada @code{event-chord}. En Scheme, el tipo de variable suele
763 quedar claro a partir de su nombre (¡esto también es una buena
764 práctica en otros lenguajes de programación!).
767 "Añadir una ArticulationEvent de marcato..."
771 es una descripción de lo que hace la función. No es estrictamente
772 necesario, pero como los nombres de variable claros, es una buena
776 (let ((result-event-chord (ly:music-deep-copy event-chord)))
779 @code{let} se usa para declarar variables locales. Aquí usamos una
780 variable local, llamada @code{result-event-chord}, a la que le damos
781 el valor @code{(ly:music-deep-copy event-chord)}.
782 @code{ly:music-deep-copy} es una función específica de LilyPond, como
783 todas las funciones que comienzan por @code{ly:}. Se usa para hacer
784 una copia de una expresión musical. Aquí, copiamos @code{event-chord}
785 (el parámetro de la función). Recuerde que el propósito es añadir un
786 marcato a una expresión @code{EventChord}. Es mejor no modificar el
787 @code{EventChord} que se dio como argumento, porque podría utilizarse
790 Ahora tenemos un @code{result-event-chord}, que es una expresión
791 @code{NoteEventChord} y es una copia de @code{event-chord}. Añadimos
792 el marcato a su propiedad lista de elementos.
795 (set! place new-value)
798 Aquí, lo que queremos establecer (el @q{place}) es la propiedad
799 @q{elements} de la expresión @code{result-event-chord}.
802 (ly:music-property result-event-chord 'elements)
805 @code{ly:music-property} es la función que se usa para acceder a las
806 propiedades musicales (los @code{'elements}, @code{'duration},
807 @code{'pitch}, etc., que vemos en la salida de @code{\displayMusic}
808 más arriba). El nuevo valor es la anterior propiedad elements, con un
809 elemento adicional: la expresión @code{ArticulationEvent}, que
810 copiamos a partir de la salida de @code{\displayMusic},
813 (cons (make-music 'ArticulationEvent
814 'articulation-type "marcato")
815 (ly:music-property result-event-chord 'elements))
818 @code{cons} se usa para añadir un elemento a una lsita sin modificar
819 la lista original. Esto es lo que queremos: la misma lista que antes,
820 más la nueva expresión @code{ArticulationEvent}. El orden dentro de
821 la propiedad elements no es importante aquí.
823 Finalmente, una vez añadida la articulación marcato a su propiedad
824 @code{elements}, podemos devolver @code{result-event-chord}, de aquí
825 la última línea de la función.
827 Ahora transformamos la función @code{add-marcato} en una función
831 addMarcato = #(define-music-function (parser location event-chord)
833 "Add a marcato ArticulationEvent to the elements of `event-chord',
834 which is supposed to be an EventChord expression."
835 (let ((result-event-chord (ly:music-deep-copy event-chord)))
836 (set! (ly:music-property result-event-chord 'elements)
837 (cons (make-music 'ArticulationEvent
838 'articulation-type "marcato")
839 (ly:music-property result-event-chord 'elements)))
843 Podemos verificar que esta función musical funciona correctamente,
846 \displayMusic \addMarcato c4
850 @node Markup programmer interface
851 @section Markup programmer interface
853 Los marcados están implementados como funciones de Scheme especiales
854 que producen un elemento Stencil (sello) dado un número de argumentos.
857 * Markup construction in Scheme::
858 * How markups work internally::
859 * New markup command definition::
860 * New markup list command definition::
863 @node Markup construction in Scheme
864 @subsection Markup construction in Scheme
866 @cindex marcado, definir instrucciones de
868 El macro @code{markup} construye expresiones de marcado en Scheme,
869 proporcionando una sintaxis similar a la de LilyPond. Por ejemplo:
872 (markup #:column (#:line (#:bold #:italic "hola" #:raise 0.4 "mundo")
873 #:larger #:line ("fulano" "fulanito" "menganito")))
879 \markup \column @{ \line @{ \bold \italic "hola" \raise #0.4 "mundo" @}
880 \larger \line @{ fulano fulanito menganito @} @}
884 Este ejemplo muestra las principales reglas de traducción entre la
885 sitaxis del marcado normal de LilyPond y la sintaxis del marcado de
889 @multitable @columnfractions .3 .3
890 @item @b{LilyPond} @tab @b{Scheme}
891 @item @code{\markup marcado1} @tab @code{(markup marcado1)}
892 @item @code{\markup @{ marcado1 marcado2 ... @}} @tab
893 @code{(markup marcado1 marcado2 ... )}
894 @item @code{\instruccion} @tab @code{#:instruccion}
895 @item @code{\variable} @tab @code{variable}
896 @item @code{\center-column @{ ... @}} @tab @code{#:center-column ( ... )}
897 @item @code{cadena} @tab @code{"cadena"}
898 @item @code{#argumento-de-scheme} @tab @code{argumento-de-scheme}
902 Todo el lenguaje Scheme está accesible dentro del macro @code{markup}.
903 Por ejemplo, podemos usar llamadas a funciones dentro de @code{markup}
904 para así manipular cadenas de caracteres. Esto es útil si se están
905 definiendo instrucciones de marcado nuevas (véase @ref{New markup
906 command definition}).
910 El argumento markup-list de instrucciones como @code{#:line},
911 @code{#:center} y @code{#:column} no pueden se una variable o el
912 resultado de la llamada a una función.
915 (markup #:line (funcion-que-devuelve-marcados))
919 no es válido. Hay que usar las funciones @code{make-line-markup},
920 @code{make-center-markup} o @code{make-column-markup} en su lugar:
923 (markup (make-line-markup (funcion-que-devuelve-marcados)))
927 @node How markups work internally
928 @subsection How markups work internally
930 En un elemento de marcado como
933 \raise #0.5 "ejemplo de texto"
937 @code{\raise} se representa en realidad por medio de la función
938 @code{raise-markup}. La expresión de marcado se almacena como
941 (list raise-markup 0.5 (list simple-markup "ejemplo de texto"))
944 Cuando el marcado se convierte en objetos imprimibles (Stencils o
945 sellos), se llama la función @code{raise-markup} como
949 @var{\objeto de marcado}
950 @var{lista de listas asociativas de propiedades}
952 @var{el marcado "ejemplo de texto"})
955 Primero la función @code{raise-markup} crea el sello para la cadena
956 @code{ejemplo de texto}, y después eleva el sello Stencil en 0.5
957 espacios de pentagrama. Este es un ejemplo bastante simple; en el
958 resto de la sección podrán verse ejemplos más complejos, así como en
959 @file{scm/@/define@/-markup@/-commands@/.scm}.
962 @node New markup command definition
963 @subsection New markup command definition
965 Las instrucciones de marcado nuevas se pueden definir con el macro de
966 Scheme @code{define-markup-command}.
969 (define-markup-command (@var{nombre-de-la-instruccion} @var{layout} @var{props} @var{arg1} @var{arg2} ...)
970 (@var{arg1-type?} @var{arg2-type?} ...)
978 @var{i}-ésimo argumento de la instrucción
980 predicado de tipo para el argumento @var{i}-ésimo
982 la definición de @q{presentación}
984 lista de listas asociativas, que contiene todas las propiedades
988 Como ejemplo sencillo, mostramos cómo añadir una instrucción
989 @code{\smallcaps}, que selecciona una tipografía de versalitas.
990 Normalmente podríamos seleccionar la tipografía de versalitas,
993 \markup @{ \override #'(font-shape . caps) Texto-en-versalitas @}
997 Esto selecciona la tipografía de versalitas mediante el
998 establecimiento de la propiedad @code{font-shape} a @code{#'caps} para
999 la interpretación de @code{Texto-en-versalitas}.
1001 Para poner lo anterior disponible como la instrucción
1002 @code{\smallcaps}, tenemos que definir una función utilizando
1003 @code{define-markup-command}. La instrucción ha de tomar un argumento
1004 del tipo @code{markup}. Por tanto, el inicio de la definición ha de
1008 (define-markup-command (smallcaps layout props argument) (markup?)
1013 Lo que aparece a continuación es el contenido de la instrucción:
1014 debemos interpretar el @code{argument} como un marcado, es decir:
1017 (interpret-markup layout @dots{} argument)
1021 Esta interpretación tiene que añadir @code{'(font-shape . caps)} a las
1022 propiedades activas, por lo que sustituimos lo siguiente por los
1023 @dots{} en el ejemplo anterior:
1026 (cons (list '(font-shape . caps) ) props)
1030 La variable @code{props} es una lista de a-listas, y se lo anteponemos
1031 haciendo la operación cons de una lista con el ajuste adicional.
1033 Supongamos que estamos tipografiando un recitativo de una ópera y nos
1034 gustaría definir una instrucción que presente los nombres de los
1035 personajes de una forma personalizada. Queremos que los nombres se
1036 impriman con versalitas y se desplacen un poco a la izquierda y hacia
1037 arriba. Definimos una instrucción @code{\character} que toma en
1038 cuenta la traslación necesaria y utiliza la instrucción
1039 @code{\smallcaps} recién definida:
1042 #(define-markup-command (character layout props nombre) (string?)
1043 "Imprimir el nombre del personaje en versalitas, desplazado a la izquierda y hacia
1044 arriba. Sintaxis: \\character #\"nombre\""
1045 (interpret-markup layout props
1046 (markup #:hspace 0 #:translate (cons -3 1) #:smallcaps nombre)))
1049 Esta es una complicación que requiere una explicación: los textos por
1050 encima y por debajo del pentagrama se mueven verticalmente de forma
1051 que estén a una cierta distancia (la propiedad @code{padding}) del
1052 pentagrama y de las notas. Para asegurar que este mecanismo no anula
1053 el efecto de nuestro @code{#:translate}, añadimos una cadena vacía
1054 (@code{#:hspace 0}) antes del texto trasladado. Ahora el
1055 @code{#:hspace 0} se pone encima de las notas, y el @code{nombre} se
1056 mueve en relación a dicha cadena vacía. El efecto neto es que el
1057 texto se mueve hacia la izquierda y hacia arriba.
1059 El resultado final es como sigue:
1063 c''^\markup \character #"Cleopatra"
1064 e'^\markup \character #"Giulio Cesare"
1068 @lilypond[quote,ragged-right]
1069 #(define-markup-command (smallcaps layout props str) (string?)
1070 "Print the string argument in small caps. Syntax: \\smallcaps #\"string\""
1071 (interpret-markup layout props
1074 (if (= (string-length s) 0)
1076 (markup #:large (string-upcase (substring s 0 1))
1077 #:translate (cons -0.6 0)
1078 #:tiny (string-upcase (substring s 1)))))
1079 (string-split str #\Space)))))
1081 #(define-markup-command (character layout props name) (string?)
1082 "Print the character name in small caps, translated to the left and
1083 top. Syntax: \\character #\"name\""
1084 (interpret-markup layout props
1085 (markup #:hspace 0 #:translate (cons -3 1) #:smallcaps name)))
1088 c''^\markup \character #"Cleopatra" c'' c'' c''
1089 e'^\markup \character #"Giulio Cesare" e' e' e'
1093 Hemos usado la forma de fuente tipográfica @code{caps}, pero
1094 supongamos que nuestra fuente no tiene la variante de versalitas. En
1095 ese caso tenemos que hacer una falsa fuente de mayúsculas pequeñas
1096 haciendo que la cadena en mayúsculas tenga la primera legra un poco
1100 #(define-markup-command (smallcaps layout props str) (string?)
1101 "Print the string argument in small caps."
1102 (interpret-markup layout props
1105 (if (= (string-length s) 0)
1107 (markup #:large (string-upcase (substring s 0 1))
1108 #:translate (cons -0.6 0)
1109 #:tiny (string-upcase (substring s 1)))))
1110 (string-split str #\Space)))))
1113 La instrucción @code{smallcaps} primero divide su argumento de cadena
1114 en unidades o palabras separadas por espacios (@code{(string-split str
1115 #\Space)}); para cada unidad o palabra, se construye un marcado con la
1116 primera letra agrandada y en mayúscula (@code{#:large (string-upcase
1117 (substring s 0 1))}), y un segundo marcado construido con las letras
1118 siguientes reducidas de tamaño y en mayúsculas (@code{#:tiny
1119 (string-upcase (substring s 1))}). Como LilyPond introduce un espacio
1120 entre los marcados de una misma línea, el segundo marcado se traslada
1121 a la izquierda (@code{#:translate (cons -0.6 0) ...}). Después, los
1122 marcados construidos para cada palabra se ponen en una línea mediante
1123 @code{(make-line-markup ...)}. Finalmente, el marcado resultante se
1124 pasa a la función @code{interpret-markup}, con los argumentos
1125 @code{layout} y @code{props}.
1127 Nota: ahora existe una instrucción interna @code{\smallCaps} que se
1128 puede usar para poner texto en versalitas. Consulte @ref{Text markup
1129 commands}, para ver más detalles.
1133 Actualmente las combinaciones de argumentos que hay disponibles
1134 (después de los argumentos estándar @var{layout} y @var{props}) para
1135 una instrucción de marcado definida con @code{define-markup-command}
1136 se limitan a la siguiente lista:
1139 @item (ningún argumento)
1142 @itemx @var{markup markup}
1144 @itemx @var{scm markup}
1145 @itemx @var{scm scm}
1146 @itemx @var{scm scm markup}
1147 @itemx @var{scm scm markup markup}
1148 @itemx @var{scm markup markup}
1149 @itemx @var{scm scm scm}
1153 En la tabla de arriba, @var{scm} representa los tipos de datos nativos
1154 de Scheme como @q{number} (número) o @q{string} (cadena).
1156 Como ejemplo, no es posible usar una instrucción de marcado
1157 @code{fulanito} con cuatro argumentos definida como
1160 #(define-markup-command (fulanito layout props
1161 num1 str1 num2 str2)
1162 (number? string? number? string?)
1167 Si la aplicamos como, digamos,
1170 \markup \fulanito #1 #"mengano" #2 #"zutano"
1173 @cindex Scheme signature
1174 @cindex signature, Scheme
1176 @command{lilypond} protesta diciendo que no puede analizar
1177 @code{fulanito} debido a su firma de Scheme desconocida.
1180 @node New markup list command definition
1181 @subsection New markup list command definition
1183 Las instrucciones de listas de marcado se definen con el macro de
1184 Scheme @code{define-markup-list-command}, que es similar al macro
1185 @code{define-markup-command} descrito en @ref{New markup command
1186 definition}, excepto que donde éste devuelve un sello único, aquél
1187 devuelve una lista de sellos.
1189 En el siguiente ejemplo se define una instrucción de lista de marcado
1190 @code{\paragraph}, que devuelve una lista de líneas justificadas,
1191 estando la primera de ellas sangrada. La anchura del sangrado se toma
1192 del argumento @code{props}.
1195 #(define-markup-list-command (paragraph layout props args) (markup-list?)
1196 (let ((indent (chain-assoc-get 'par-indent props 2)))
1197 (interpret-markup-list layout props
1198 (make-justified-lines-markup-list (cons (make-hspace-markup indent)
1202 Aparte de los argumentos usuales @code{layout} y @code{props}, la
1203 instrucción de lista de marcados @code{paragraph} toma un argumento de
1204 lista de marcados, llamado @code{args}. El predicado para listas de
1205 marcados es @code{markup-list?}.
1207 Em primer lugar, la función toma el ancho del sangrado, una propiedad
1208 llamada aquí @code{par-indent}, de la lista de propiedades
1209 @code{props}. Si no se encuentra la propiedad, el valor
1210 predeterminado es @code{2}. Después, se hace una lista de líneas
1211 justificadas usando la función
1212 @code{make-justified-lines-markup-list}, que está relacionada con la
1213 instrucción incorporada de lista de marcados @code{\justified-lines}.
1214 Se añade un espacio horizontal al principio usando la función
1215 @code{make-hspace-markup}. Finalmente, la lista de marcados se
1216 interpreta usando la función @code{interpret-markup-list}.
1218 Esta nueva instrucción de lista de marcados se puede usar como sigue:
1223 El arte de la tipografía musical se llama \italic @{grabado (en plancha).@}
1224 El término deriva del proceso tradicional de impresión de música.
1225 hace sólo algunas décadas, las partituras se hacían cortando y estampando
1226 la música en una plancha de zinc o lata en una imagen invertida.
1228 \override-lines #'(par-indent . 4) \paragraph @{
1229 La plancha se tenía que entintar, y las depresiones causadas por los cortes
1230 y estampados retienen la tinta. Se formaba una imagen presionando el papel
1231 contra la plancha. El estampado y cortado se hacía completamente
1238 @node Contexts for programmers
1239 @section Contexts for programmers
1242 * Context evaluation::
1243 * Running a function on all layout objects::
1246 @node Context evaluation
1247 @subsection Context evaluation
1249 @cindex código, llamadas durante la interpretación
1250 @funindex \applyContext
1252 Se pueden modificar los contextos durante la interpretación con código
1253 de Scheme. La sintaxis para esto es
1256 \applyContext @var{función}
1259 @var{función} debe ser una función de Scheme que toma un único
1260 argumento, que es el contexto al que aplicarla. El código siguiente
1261 imprime el número del compás actual sobre la salida estándar durante
1267 (format #t "\nSe nos ha llamado en el compás número ~a.\n"
1268 (ly:context-property x 'currentBarNumber)))
1272 @node Running a function on all layout objects
1273 @subsection Running a function on all layout objects
1278 @node Scheme procedures as properties
1279 @section Scheme procedures as properties
1285 @node Using Scheme code instead of \tweak
1286 @section Using Scheme code instead of @code{\tweak}
1291 @node Difficult tweaks
1292 @section Difficult tweaks