]> git.donarmstrong.com Git - lilypond.git/blob - Documentation/es/notation/programming-interface.itely
Merge branch 'lilypond/translation' of ssh://git.sv.gnu.org/srv/git/lilypond into...
[lilypond.git] / Documentation / es / notation / programming-interface.itely
1 @c -*- coding: utf-8; mode: texinfo; documentlanguage: es -*-
2
3 @ignore
4     Translation of GIT committish: d4f58bb3ad4e7fe1967a6b48f25e3addffc8aa14
5
6     When revising a translation, copy the HEAD committish of the
7     version that you are working on.  See TRANSLATION for details.
8 @end ignore
9
10 @c \version "2.12.0"
11
12 @node Interfaces para programadores
13 @chapter Interfaces para programadores
14 @translationof Interfaces for programmers
15
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, @rlearning{Tutorial de Scheme}.
19
20 @menu
21 * Funciones musicales::
22 * Interfaces para el programador::
23 * Construcción de funciones complejas::
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::
28 * Trucos difíciles::
29 @end menu
30
31
32 @node Funciones musicales
33 @section Funciones musicales
34 @translationof Music functions
35
36 Esta sección trata sobre cómo crear funciones musicales dentro de
37 LilyPond.
38
39 @menu
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::
44 * Funciones vacías::
45 * Funciones sin argumentos::
46 * Pranorámica de las funciones musicales disponibles::
47 @end menu
48
49 @node Panorámica de las funciones musicales
50 @subsection Panorámica de las funciones musicales
51 @translationof Overview of music functions
52
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:
55
56 @example
57 function =
58 #(define-music-function (parser location @var{var1} @var{var2}...@var{vari}... )
59                         (@var{var1-type?} @var{var2-type?}...@var{vari-type?}...)
60   #@{
61     @emph{...música...}
62   #@})
63 @end example
64
65 @noindent
66 donde
67
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.
72 @end multitable
73
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
77 variables.
78
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?}
87 @end multitable
88
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.
96
97
98 @node Funciones de sustitución sencillas
99 @subsection Funciones de sustitución sencillas
100 @translationof Simple substitution functions
101
102 He aquí un ejemplo sencillo:
103
104 @lilypond[quote,verbatim,ragged-right]
105 padText = #(define-music-function (parser location padding) (number?)
106   #{
107     \once \override TextScript #'padding = #$padding
108   #})
109
110 \relative c''' {
111   c4^"piu mosso" b a b
112   \padText #1.8
113   c4^"piu mosso" d e f
114   \padText #2.6
115   c4^"piu mosso" fis a g
116 }
117 @end lilypond
118
119 También se pueden sustituir las expresiones musicales:
120
121 @lilypond[quote,verbatim,ragged-right]
122 custosNote = #(define-music-function (parser location note)
123                                      (ly:music?)
124   #{
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
130     $note
131   #})
132
133 { c' d' e' f' \custosNote g' }
134 @end lilypond
135
136 Se puede usar más de una variable:
137
138 @lilypond[quote,verbatim,ragged-right]
139 tempoPadded = #(define-music-function (parser location padding tempotext)
140   (number? string?)
141 #{
142   \once \override Score.MetronomeMark #'padding = $padding
143   \tempo \markup { \bold $tempotext }
144 #})
145
146 \relative c'' {
147   \tempo \markup { "Low tempo" }
148   c4 d e f g1
149   \tempoPadded #4.0 #"High tempo"
150   g4 f e d c1
151 }
152 @end lilypond
153
154
155 @node Funciones de sustitutión en parejas
156 @subsection Funciones de sustitutión en parejas
157 @translationof Paired substitution functions
158
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.
163
164 @quotation
165 @example
166 manualBeam =
167 #(define-music-function (parser location beg-end)
168                         (pair?)
169 #@{
170   \once \override Beam #'positions = #$beg-end
171 #@})
172
173 \relative @{
174   \manualBeam #'(3 . 6) c8 d e f
175 @}
176 @end example
177 @end quotation
178
179 @noindent
180 o bien
181
182 @lilypond[quote,verbatim,ragged-right]
183 manualBeam =
184 #(define-music-function (parser location beg end)
185                         (number? number?)
186 #{
187   \once \override Beam #'positions = #(cons $beg $end)
188 #})
189
190 \relative {
191   \manualBeam #3 #6 c8 d e f
192 }
193 @end lilypond
194
195
196 @node Matemáticas dentro de las funciones
197 @subsection Matemáticas dentro de las funciones
198 @translationof Mathematics in functions
199
200 Las funciones musicales pueden contar con programación de Scheme
201 además de la simple sustitución:
202
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))) #})
208
209 AltOff = {
210   \revert Stem #'length
211   \revert NoteHead #'font-size
212 }
213
214 { c'2 \AltOn #0.5 c'4 c'
215   \AltOn #1.5 c' c' \AltOff c'2 }
216 @end lilypond
217
218 @noindent
219 Este ejemplo se puede reescribir de forma que pase expresiones
220 musicales:
221
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)))
227      $music
228      \revert Stem #'length
229      \revert NoteHead #'font-size #})
230
231 { c'2 \withAlt #0.5 {c'4 c'}
232   \withAlt #1.5 {c' c'} c'2 }
233 @end lilypond
234
235
236 @node Funciones vacías
237 @subsection Funciones vacías
238 @translationof Void functions
239
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).
244
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.
251
252 @example
253 noPointAndClick =
254 #(define-music-function (parser location) ()
255    (ly:set-option 'point-and-click #f)
256    (make-music 'SequentialMusic 'void #t))
257 ...
258 \noPointAndClick   % desactivar la funcionalidad Apuntar y Pulsar.
259 @end example
260
261
262 @node Funciones sin argumentos
263 @subsection Funciones sin argumentos
264 @translationof Functions without arguments
265
266 En casi todos los casos, una función sin argumentos se debe escribir
267 con una variable:
268
269 @example
270 dolce = \markup@{ \italic \bold dolce @}
271 @end example
272
273 Sin embargo, en raras ocasiones puede ser de utilidad crear una
274 función musical sin argumentos:
275
276 @example
277 displayBarNum =
278 #(define-music-function (parser location) ()
279    (if (eq? #t (ly:get-option 'display-bar-numbers))
280        #@{ \once \override Score.BarNumber #'break-visibility = ##f #@}
281        #@{#@}))
282 @end example
283
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
286
287 @example
288 lilypond -d display-bar-numbers ARCHIVO.ly
289 @end example
290
291
292 @node Pranorámica de las funciones musicales disponibles
293 @subsection Pranorámica de las funciones musicales disponibles
294 @translationof Overview of available music functions
295
296 @c fixme ; this should be move somewhere else?
297 Las siguientes instrucciones son funciones musicales:
298
299 @include identifiers.tely
300
301
302 @node Interfaces para el programador
303 @section Interfaces para el programador
304 @translationof Programmer interfaces
305
306 Esta sección contiene información sobre cómo mezclar LilyPond y
307 Scheme.
308
309 @menu
310 * Variables de entrada y Scheme::
311 * Representación interna de la música::
312 @end menu
313
314 @node Variables de entrada y Scheme
315 @subsection Variables de entrada y Scheme
316 @translationof Input variables and Scheme
317
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}.
321
322 @example
323 traLaLa = @{ c'4 d'4 @}
324 @end example
325
326 @noindent
327
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.
331
332 @example
333 traLaLa = @{ c'4 d'4 @}
334 \layout @{ traLaLa = 1.0 @}
335 @end example
336 @c
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.
340
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
344 @example
345 traLaLa = @{ c'4 d'4 @}
346 @end example
347
348 @noindent
349 se convierte internamente a una definición de Scheme
350 @example
351 (define traLaLa @var{Scheme value of `@code{... }'})
352 @end example
353
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}:
359
360 @lilypond[verbatim]
361 traLaLa = { c'4 d'4 }
362
363 %% dummy action to deal with parser lookahead
364 #(display "this needs to be here, sorry!")
365
366 #(define newLa (map ly:music-deep-copy
367   (list traLaLa traLaLa)))
368 #(define twice
369   (make-sequential-music newLa))
370
371 { \twice }
372 @end lilypond
373
374 @c Due to parser lookahead
375
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.
381
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
388
389 @example
390 ...
391 @{ #(ly:export (make-sequential-music (list newLa))) @}
392 @end example
393
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
397
398 @example
399 #(define (nopc)
400   (ly:set-option 'point-and-click #f))
401
402 ...
403 #(nopc)
404 @{ c'4 @}
405 @end example
406
407 @knownissues
408
409 No es posible mezclar variables de Scheme y de LilyPond con la opción
410 @code{--safe}.
411
412
413 @node Representación interna de la música
414 @subsection Representación interna de la música
415 @translationof Internal music representation
416
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.
422
423 Un objeto musical tiene tres clases de tipos:
424 @itemize
425 @item
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
431 expressions}.
432
433 @item
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}.
440
441 @item
442 Objeto de C++: cada objeto musical está representado por un objeto de
443 la clase de C++ @code{Music}.
444 @end itemize
445
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}.
452
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}.
462
463
464 @node Construcción de funciones complejas
465 @section Construcción de funciones complejas
466 @translationof Building complicated functions
467
468 Esta sección explica cómo reunir la información necesaria para crear
469 funciones musicales complejas.
470
471
472 @menu
473 * Presentación de expresiones musicales::
474 * Propiedades de la música::
475 * Doblar una nota con ligaduras (ejemplo)::
476 * Añadir articulación a las notas (ejemplo)::
477 @end menu
478
479 @node Presentación de expresiones musicales
480 @subsection Presentación de expresiones musicales
481 @translationof Displaying music expressions
482
483 @cindex interno, almacenamiento
484 @cindex mostrar expresiones musicales
485 @cindex interna, representación, mostrar
486
487 @funindex \displayMusic
488
489 Si se está escribiendo una función musical puede ser muy instructivo
490 examinar cómo se almacena internamente una expresión musical.  Esto se
491 puede hacer con la función musical @code{\displayMusic}:
492
493 @example
494 @{
495   \displayMusic @{ c'4\f @}
496 @}
497 @end example
498
499 @noindent
500 imprime lo siguiente:
501
502 @example
503 (make-music
504   'SequentialMusic
505   'elements
506   (list (make-music
507           'EventChord
508           'elements
509           (list (make-music
510                   'NoteEvent
511                   'duration
512                   (ly:make-duration 2 0 1 1)
513                   'pitch
514                   (ly:make-pitch 0 0 0))
515                 (make-music
516                   'AbsoluteDynamicEvent
517                   'text
518                   "f")))))
519 @end example
520
521 De forma predeterminada, LilyPond imprime estos mensajes en la consola
522 junto al resto de los mensajes.  Para discernir entre estos mensajes y
523 guardar el resultado de @code{\display@{MATERIAL@}}, redirija la
524 salida hacia un archivo.
525
526 @example
527 lilypond archivo.ly >resultado.txt
528 @end example
529
530 Con la aplicación de un poco de formato, la información anterior es
531 fácil de leer:
532
533 @example
534 (make-music 'SequentialMusic
535   'elements (list (make-music 'EventChord
536                     'elements (list (make-music 'NoteEvent
537                                       'duration (ly:make-duration 2 0 1 1)
538                                       'pitch (ly:make-pitch 0 0 0))
539                                     (make-music 'AbsoluteDynamicEvent
540                                       'text "f")))))
541 @end example
542
543 Una secuencia musical @code{@{ ... @}} tiene el nombre
544 @code{SequentialMusic}, y sus expresiones internas se almacenan como
545 una lista en su propiedad @code{'elements}.  Una nota se representa
546 como una expresión @code{EventChord} que contiene un objeto
547 @code{NoteEvent} (que almacena las propiedades de duración y altura) y
548 cualquier otra información adicional (en este caso, un evento
549 @code{AbsoluteDynamicEvent} con una propiedad de texto @code{"f"}.
550
551
552 @node Propiedades de la música
553 @subsection Propiedades de la música
554 @translationof Music properties
555
556 El objeto @code{NoteEvent} es el primer objeto de la propiedad
557 @code{'elements} de @code{someNote}.
558
559 @example
560 unaNota = c'
561 \displayMusic \unaNota
562 ===>
563 (make-music
564   'EventChord
565   'elements
566   (list (make-music
567           'NoteEvent
568           'duration
569           (ly:make-duration 2 0 1 1)
570           'pitch
571           (ly:make-pitch 0 0 0))))
572 @end example
573
574 La función @code{display-scheme-music} es la función utilizada por
575 @code{\displayMusic} para imprimir la representación de Scheme de una
576 expresión musical.
577
578 @example
579 #(display-scheme-music (first (ly:music-property unaNota 'elements)))
580 ===>
581 (make-music
582   'NoteEvent
583   'duration
584   (ly:make-duration 2 0 1 1)
585   'pitch
586   (ly:make-pitch 0 0 0))
587 @end example
588
589 Después se accede a la altura de la nota a través de la propiedad
590 @code{'pitch} del objeto @code{NoteEvent}:
591
592 @example
593 #(display-scheme-music
594    (ly:music-property (first (ly:music-property unaNota 'elements))
595                       'pitch))
596 ===>
597 (ly:make-pitch 0 0 0)
598 @end example
599
600 La altura de la nota se puede cambiar estableciendo el valor de esta
601 propiedad 'pitch:
602
603 @funindex \displayLilyMusic
604
605 @example
606 #(set! (ly:music-property (first (ly:music-property unaNota 'elements))
607                           'pitch)
608        (ly:make-pitch 0 1 0)) ;; fijar la altura a d'.
609 \displayLilyMusic \unaNota
610 ===>
611 d'
612 @end example
613
614
615 @node Doblar una nota con ligaduras (ejemplo)
616 @subsection Doblar una nota con ligaduras (ejemplo)
617 @translationof Doubling a note with slurs (example)
618
619 Supongamos que queremos crear una función que traduce una entrada como
620 @code{a} a algo como @code{a( a)}.  Empezamos examinando la
621 representación interna de la música con la que queremos terminar.
622
623 @example
624 \displayMusic@{ a'( a') @}
625 ===>
626 (make-music
627   'SequentialMusic
628   'elements
629   (list (make-music
630           'EventChord
631           'elements
632           (list (make-music
633                   'NoteEvent
634                   'duration
635                   (ly:make-duration 2 0 1 1)
636                   'pitch
637                   (ly:make-pitch 0 5 0))
638                 (make-music
639                   'SlurEvent
640                   'span-direction
641                   -1)))
642         (make-music
643           'EventChord
644           'elements
645           (list (make-music
646                   'NoteEvent
647                   'duration
648                   (ly:make-duration 2 0 1 1)
649                   'pitch
650                   (ly:make-pitch 0 5 0))
651                 (make-music
652                   'SlurEvent
653                   'span-direction
654                   1)))))
655 @end example
656
657 Las malas noticias son que las expresiones @code{SlurEvent} se deben
658 añadir @q{dentro} de la nota (o más concretamente, dentro de la
659 expresión @code{EventChord}).
660
661 Ahora observamos la entrada:
662
663 @example
664 (make-music
665   'SequentialMusic
666   'elements
667   (list (make-music
668           'EventChord
669           'elements
670           (list (make-music
671                   'NoteEvent
672                   'duration
673                   (ly:make-duration 2 0 1 1)
674                   'pitch
675                   (ly:make-pitch 0 5 0))))))
676 @end example
677
678 Así pues, en nuestra función, tenemos que clonar esta expresión (de
679 forma que tengamos dos notas para construir la secuencia), añadir
680 @code{SlurEvents} a la propiedad @code{'elements} de cada una de
681 ellas, y por último hacer una secuencia @code{SequentialMusic} con los
682 dos @code{EventChords}.
683
684 @example
685 doubleSlur = #(define-music-function (parser location note) (ly:music?)
686          "Return: @{ note ( note ) @}.
687          `note' is supposed to be an EventChord."
688          (let ((note2 (ly:music-deep-copy note)))
689            (set! (ly:music-property note 'elements)
690                  (cons (make-music 'SlurEvent 'span-direction -1)
691                        (ly:music-property note 'elements)))
692            (set! (ly:music-property note2 'elements)
693                  (cons (make-music 'SlurEvent 'span-direction 1)
694                        (ly:music-property note2 'elements)))
695            (make-music 'SequentialMusic 'elements (list note note2))))
696 @end example
697
698
699 @node Añadir articulación a las notas (ejemplo)
700 @subsection Añadir articulación a las notas (ejemplo)
701 @translationof Adding articulation to notes (example)
702
703 La manera fácil de añadir articulación a las notas es fundir dos
704 expresiones musicales en un contexto único, como está explicado en
705 @ref{Crear contextos}.  Sin embargo, suponga que queremos escribir
706 una función musical que haga esto.
707
708 Una @code{$variable} dentro de la notación @code{#@{...#@}} es como
709 usar una @code{\variable} normal en la notación clásica de LilyPond.
710 Sabemos que
711
712 @example
713 @{ \musica -. -> @}
714 @end example
715
716 @noindent
717 no funciona en LilyPond.  Podemos evitar este problema adjuntando la
718 articulación a una nota de mentira,
719
720 @example
721 @{ << \musica s1*0-.-> @}
722 @end example
723
724 @noindent
725 pero a los efectos de este ejemplo, aprenderemos ahora cómo hacerlo en
726 Scheme.  Comenzamos examinando nuestra entrada y la salida deseada:
727
728 @example
729 %  entrada
730 \displayMusic c4
731 ===>
732 (make-music
733   'EventChord
734   'elements
735   (list (make-music
736           'NoteEvent
737           'duration
738           (ly:make-duration 2 0 1 1)
739           'pitch
740           (ly:make-pitch -1 0 0))))
741 =====
742 %  salida deseada
743 \displayMusic c4->
744 ===>
745 (make-music
746   'EventChord
747   'elements
748   (list (make-music
749           'NoteEvent
750           'duration
751           (ly:make-duration 2 0 1 1)
752           'pitch
753           (ly:make-pitch -1 0 0))
754         (make-music
755           'ArticulationEvent
756           'articulation-type
757           "marcato")))
758 @end example
759
760 Vemos que una nota (@code{c4}) se representa como una expresión
761 @code{EventChord}, con una expresión @code{NoteEvent} en su lista de
762 elementos.  Para añadir una articulación marcato, se debe añadir una
763 expresión @code{ArticulationEvent} a la propiedad elementos de la
764 expresión @code{EventChord}.
765
766 Para construir esta función, empezamos con
767
768 @example
769 (define (add-marcato event-chord)
770   "Añadir una ArticulationEvent de marcato a los elementos de `event-chord',
771   que se supone que es una expresión EventChord."
772   (let ((result-event-chord (ly:music-deep-copy event-chord)))
773     (set! (ly:music-property result-event-chord 'elements)
774           (cons (make-music 'ArticulationEvent
775                   'articulation-type "marcato")
776                 (ly:music-property result-event-chord 'elements)))
777     result-event-chord))
778 @end example
779
780 La primera línea es la forma de definir una función en Scheme: el
781 nombre de la función es @code{add-marcato}, y tiene una variable
782 llamada @code{event-chord}.  En Scheme, el tipo de variable suele
783 quedar claro a partir de su nombre (¡esto también es una buena
784 práctica en otros lenguajes de programación!).
785
786 @example
787 "Añadir una ArticulationEvent de marcato..."
788 @end example
789
790 @noindent
791 es una descripción de lo que hace la función.  No es estrictamente
792 necesario, pero como los nombres de variable claros, es una buena
793 práctica.
794
795 @example
796 (let ((result-event-chord (ly:music-deep-copy event-chord)))
797 @end example
798
799 @code{let} se usa para declarar variables locales.  Aquí usamos una
800 variable local, llamada @code{result-event-chord}, a la que le damos
801 el valor @code{(ly:music-deep-copy event-chord)}.
802 @code{ly:music-deep-copy} es una función específica de LilyPond, como
803 todas las funciones que comienzan por @code{ly:}.  Se usa para hacer
804 una copia de una expresión musical.  Aquí, copiamos @code{event-chord}
805 (el parámetro de la función).  Recuerde que el propósito es añadir un
806 marcato a una expresión @code{EventChord}.  Es mejor no modificar el
807 @code{EventChord} que se dio como argumento, porque podría utilizarse
808 en algún otro lugar.
809
810 Ahora tenemos un @code{result-event-chord}, que es una expresión
811 @code{NoteEventChord} y es una copia de @code{event-chord}.  Añadimos
812 el marcato a su propiedad lista de elementos.
813
814 @example
815 (set! lugar valor-nuevo)
816 @end example
817
818 Aquí, lo que queremos establecer (el @q{lugar}) es la propiedad
819 @q{elements} de la expresión @code{result-event-chord}.
820
821 @example
822 (ly:music-property result-event-chord 'elements)
823 @end example
824
825 @code{ly:music-property} es la función que se usa para acceder a las
826 propiedades musicales (los @code{'elements}, @code{'duration},
827 @code{'pitch}, etc., que vemos en la salida de @code{\displayMusic}
828 más arriba).  El nuevo valor es la anterior propiedad elements, con un
829 elemento adicional: la expresión @code{ArticulationEvent}, que
830 copiamos a partir de la salida de @code{\displayMusic},
831
832 @example
833 (cons (make-music 'ArticulationEvent
834         'articulation-type "marcato")
835       (ly:music-property result-event-chord 'elements))
836 @end example
837
838 @code{cons} se usa para añadir un elemento a una lista sin modificar
839 la lista original.  Esto es lo que queremos: la misma lista que antes,
840 más la nueva expresión @code{ArticulationEvent}.  El orden dentro de
841 la propiedad elements no es importante aquí.
842
843 Finalmente, una vez añadida la articulación marcato a su propiedad
844 @code{elements}, podemos devolver @code{result-event-chord}, de aquí
845 la última línea de la función.
846
847 Ahora transformamos la función @code{add-marcato} en una función
848 musical,
849
850 @example
851 addMarcato = #(define-music-function (parser location event-chord)
852                                      (ly:music?)
853     "Añadir un ArticulationEvent de marcato a los elementos de `event-chord',
854     que se supone que es una expresión EventChord."
855     (let ((result-event-chord (ly:music-deep-copy event-chord)))
856       (set! (ly:music-property result-event-chord 'elements)
857             (cons (make-music 'ArticulationEvent
858                     'articulation-type "marcato")
859                   (ly:music-property result-event-chord 'elements)))
860       result-event-chord))
861 @end example
862
863 Podemos verificar que esta función musical funciona correctamente,
864
865 @example
866 \displayMusic \addMarcato c4
867 @end example
868
869
870 @node Interfaz de marcado para el programador
871 @section Interfaz de marcado para el programador
872 @translationof Markup programmer interface
873
874 Los marcados están implementados como funciones de Scheme especiales
875 que producen un elemento Stencil (sello) dado un número de argumentos.
876
877 @menu
878 * Construcción del marcado en Scheme::
879 * Cómo funciona internamente el marcado::
880 * Definición de una instrucción de marcado nueva::
881 * Definición de nuevas instrucciones de lista de marcado::
882 @end menu
883
884 @node Construcción del marcado en Scheme
885 @subsection Construcción del marcado en Scheme
886 @translationof Markup construction in Scheme
887
888 @cindex marcado, definir instrucciones de
889
890 El macro @code{markup} construye expresiones de marcado en Scheme,
891 proporcionando una sintaxis similar a la de LilyPond.  Por ejemplo:
892
893 @example
894 (markup #:column (#:line (#:bold #:italic "hola" #:raise 0.4 "mundo")
895                   #:larger #:line ("fulano" "fulanito" "menganito")))
896 @end example
897
898 @noindent
899 equivale a:
900 @example
901 \markup \column @{ \line @{ \bold \italic "hola" \raise #0.4 "mundo" @}
902                   \larger \line @{ fulano fulanito menganito @} @}
903 @end example
904
905 @noindent
906 Este ejemplo muestra las principales reglas de traducción entre la
907 sintaxis del marcado normal de LilyPond y la sintaxis del marcado de
908 Scheme.
909
910 @quotation
911 @multitable @columnfractions .3 .3
912 @item @b{LilyPond} @tab @b{Scheme}
913 @item @code{\markup marcado1} @tab @code{(markup marcado1)}
914 @item @code{\markup @{ marcado1 marcado2 ... @}} @tab
915         @code{(markup marcado1 marcado2 ... )}
916 @item @code{\instruccion} @tab @code{#:instruccion}
917 @item @code{\variable} @tab @code{variable}
918 @item @code{\center-column @{ ... @}} @tab @code{#:center-column ( ... )}
919 @item @code{cadena} @tab @code{"cadena"}
920 @item @code{#argumento-de-scheme} @tab @code{argumento-de-scheme}
921 @end multitable
922 @end quotation
923
924 Todo el lenguaje Scheme está accesible dentro del macro @code{markup}.
925 Por ejemplo, podemos usar llamadas a funciones dentro de @code{markup}
926 para así manipular cadenas de caracteres.  Esto es útil si se están
927 definiendo instrucciones de marcado nuevas (véase @ref{Definición de una instrucción de marcado nueva}).
928
929 @knownissues
930
931 El argumento markup-list de instrucciones como @code{#:line},
932 @code{#:center} y @code{#:column} no pueden se una variable o el
933 resultado de la llamada a una función.
934
935 @lisp
936 (markup #:line (funcion-que-devuelve-marcados))
937 @end lisp
938
939 @noindent
940 no es válido.  Hay que usar las funciones @code{make-line-markup},
941 @code{make-center-markup} o @code{make-column-markup} en su lugar:
942
943 @lisp
944 (markup (make-line-markup (funcion-que-devuelve-marcados)))
945 @end lisp
946
947
948 @node Cómo funciona internamente el marcado
949 @subsection Cómo funciona internamente el marcado
950 @translationof How markups work internally
951
952 En un elemento de marcado como
953
954 @example
955 \raise #0.5 "ejemplo de texto"
956 @end example
957
958 @noindent
959 @code{\raise} se representa en realidad por medio de la función
960 @code{raise-markup}.  La expresión de marcado se almacena como
961
962 @example
963 (list raise-markup 0.5 (list simple-markup "ejemplo de texto"))
964 @end example
965
966 Cuando el marcado se convierte en objetos imprimibles (Stencils o
967 sellos), se llama la función @code{raise-markup} como
968
969 @example
970 (apply raise-markup
971        @var{\objeto de marcado}
972        @var{lista de listas asociativas de propiedades}
973        0.5
974        @var{el marcado "ejemplo de texto"})
975 @end example
976
977 Primero la función @code{raise-markup} crea el sello para la cadena
978 @code{ejemplo de texto}, y después eleva el sello Stencil en 0.5
979 espacios de pentagrama.  Este es un ejemplo bastante simple; en el
980 resto de la sección podrán verse ejemplos más complejos, así como en
981 @file{scm/@/define@/-markup@/-commands@/.scm}.
982
983
984 @node Definición de una instrucción de marcado nueva
985 @subsection Definición de una instrucción de marcado nueva
986 @translationof New markup command definition
987
988 Las instrucciones de marcado nuevas se pueden definir con el macro de
989 Scheme @code{define-markup-command}.
990
991 @lisp
992 (define-markup-command (@var{nombre-de-la-instruccion} @var{layout} @var{props} @var{arg1} @var{arg2} ...)
993             (@var{arg1-type?} @var{arg2-type?} ...)
994   ..command body..)
995 @end lisp
996
997 Los argumentos son
998
999 @table @var
1000 @item argi
1001 @var{i}-ésimo argumento de la instrucción
1002 @item argi-type?
1003 predicado de tipo para el argumento @var{i}-ésimo
1004 @item layout
1005 la definición de @q{presentación}
1006 @item props
1007 lista de listas asociativas, que contiene todas las propiedades
1008 activas.
1009 @end table
1010
1011 Como ejemplo sencillo, mostramos cómo añadir una instrucción
1012 @code{\smallcaps}, que selecciona una tipografía de versalitas.
1013 Normalmente podríamos seleccionar la tipografía de versalitas,
1014
1015 @example
1016 \markup @{ \override #'(font-shape . caps) Texto-en-versalitas @}
1017 @end example
1018
1019 @noindent
1020 Esto selecciona la tipografía de versalitas mediante el
1021 establecimiento de la propiedad @code{font-shape} a @code{#'caps} para
1022 la interpretación de @code{Texto-en-versalitas}.
1023
1024 Para poner lo anterior disponible como la instrucción
1025 @code{\smallcaps}, tenemos que definir una función utilizando
1026 @code{define-markup-command}.  La instrucción ha de tomar un argumento
1027 del tipo @code{markup}.  Por tanto, el inicio de la definición ha de
1028 ser
1029
1030 @example
1031 (define-markup-command (smallcaps layout props argument) (markup?)
1032 @end example
1033
1034 @noindent
1035
1036 Lo que aparece a continuación es el contenido de la instrucción:
1037 debemos interpretar el @code{argument} como un marcado, es decir:
1038
1039 @example
1040 (interpret-markup layout @dots{} argument)
1041 @end example
1042
1043 @noindent
1044 Esta interpretación tiene que añadir @code{'(font-shape . caps)} a las
1045 propiedades activas, por lo que sustituimos lo siguiente por los
1046 @dots{} en el ejemplo anterior:
1047
1048 @example
1049 (cons (list '(font-shape . caps) ) props)
1050 @end example
1051
1052 @noindent
1053 La variable @code{props} es una lista de a-listas, y se lo anteponemos
1054 haciendo la operación cons de una lista con el ajuste adicional.
1055
1056 Supongamos que estamos tipografiando un recitativo de una ópera y nos
1057 gustaría definir una instrucción que presente los nombres de los
1058 personajes de una forma personalizada.  Queremos que los nombres se
1059 impriman con versalitas y se desplacen un poco a la izquierda y hacia
1060 arriba.  Definimos una instrucción @code{\character} que toma en
1061 cuenta la traslación necesaria y utiliza la instrucción
1062 @code{\smallcaps} recién definida:
1063
1064 @example
1065 #(define-markup-command (character layout props nombre) (string?)
1066   "Imprimir el nombre del personaje en versalitas, desplazado a la izquierda y hacia
1067   arriba.  Sintaxis: \\character #\"nombre\""
1068   (interpret-markup layout props
1069    (markup #:hspace 0 #:translate (cons -3 1) #:smallcaps nombre)))
1070 @end example
1071
1072 Esta es una complicación que requiere una explicación: los textos por
1073 encima y por debajo del pentagrama se mueven verticalmente de forma
1074 que estén a una cierta distancia (la propiedad @code{padding}) del
1075 pentagrama y de las notas.  Para asegurar que este mecanismo no anula
1076 el efecto de nuestro @code{#:translate}, añadimos una cadena vacía
1077 (@code{#:hspace 0}) antes del texto trasladado.  Ahora el
1078 @code{#:hspace 0} se pone encima de las notas, y el @code{nombre} se
1079 mueve en relación a dicha cadena vacía.  El efecto neto es que el
1080 texto se mueve hacia la izquierda y hacia arriba.
1081
1082 El resultado final es como sigue:
1083
1084 @example
1085 @{
1086   c''^\markup \character #"Cleopatra"
1087   e'^\markup \character #"Giulio Cesare"
1088 @}
1089 @end example
1090
1091 @lilypond[quote,ragged-right]
1092 #(define-markup-command (smallcaps layout props str) (string?)
1093   "Print the string argument in small caps.  Syntax: \\smallcaps #\"string\""
1094   (interpret-markup layout props
1095    (make-line-markup
1096     (map (lambda (s)
1097           (if (= (string-length s) 0)
1098               s
1099               (markup #:large (string-upcase (substring s 0 1))
1100                       #:translate (cons -0.6 0)
1101                       #:tiny (string-upcase (substring s 1)))))
1102          (string-split str #\Space)))))
1103
1104 #(define-markup-command (character layout props name) (string?)
1105   "Print the character name in small caps, translated to the left and
1106   top.  Syntax: \\character #\"name\""
1107   (interpret-markup layout props
1108    (markup #:hspace 0 #:translate (cons -3 1) #:smallcaps name)))
1109
1110 {
1111   c''^\markup \character #"Cleopatra" c'' c'' c''
1112   e'^\markup \character #"Giulio Cesare" e' e' e'
1113 }
1114 @end lilypond
1115
1116 Hemos usado la forma de fuente tipográfica @code{caps}, pero
1117 supongamos que nuestra fuente no tiene la variante de versalitas.  En
1118 ese caso tenemos que hacer una falsa fuente de mayúsculas pequeñas
1119 haciendo que la cadena en mayúsculas tenga la primera legra un poco
1120 mayor:
1121
1122 @example
1123 #(define-markup-command (smallcaps layout props str) (string?)
1124   "Print the string argument in small caps."
1125   (interpret-markup layout props
1126    (make-line-markup
1127     (map (lambda (s)
1128           (if (= (string-length s) 0)
1129               s
1130               (markup #:large (string-upcase (substring s 0 1))
1131                       #:translate (cons -0.6 0)
1132                       #:tiny (string-upcase (substring s 1)))))
1133          (string-split str #\Space)))))
1134 @end example
1135
1136 La instrucción @code{smallcaps} primero divide su argumento de cadena
1137 en unidades o palabras separadas por espacios (@code{(string-split str
1138 #\Space)}); para cada unidad o palabra, se construye un marcado con la
1139 primera letra agrandada y en mayúscula (@code{#:large (string-upcase
1140 (substring s 0 1))}), y un segundo marcado construido con las letras
1141 siguientes reducidas de tamaño y en mayúsculas (@code{#:tiny
1142 (string-upcase (substring s 1))}).  Como LilyPond introduce un espacio
1143 entre los marcados de una misma línea, el segundo marcado se traslada
1144 a la izquierda (@code{#:translate (cons -0.6 0) ...}).  Después, los
1145 marcados construidos para cada palabra se ponen en una línea mediante
1146 @code{(make-line-markup ...)}.  Finalmente, el marcado resultante se
1147 pasa a la función @code{interpret-markup}, con los argumentos
1148 @code{layout} y @code{props}.
1149
1150 Nota: ahora existe una instrucción interna @code{\smallCaps} que se
1151 puede usar para poner texto en versalitas.  Consulte @ref{Text markup commands}, para ver más detalles.
1152
1153 @knownissues
1154
1155 Actualmente las combinaciones de argumentos que hay disponibles
1156 (después de los argumentos estándar @var{layout} y @var{props}) para
1157 una instrucción de marcado definida con @code{define-markup-command}
1158 se limitan a la siguiente lista:
1159
1160 @table @asis
1161 @item (ningún argumento)
1162 @itemx @var{list}
1163 @itemx @var{markup}
1164 @itemx @var{markup markup}
1165 @itemx @var{scm}
1166 @itemx @var{scm markup}
1167 @itemx @var{scm scm}
1168 @itemx @var{scm scm markup}
1169 @itemx @var{scm scm markup markup}
1170 @itemx @var{scm markup markup}
1171 @itemx @var{scm scm scm}
1172 @end table
1173
1174 @noindent
1175 En la tabla de arriba, @var{scm} representa los tipos de datos nativos
1176 de Scheme como @q{number} (número) o @q{string} (cadena).
1177
1178 Como ejemplo, no es posible usar una instrucción de marcado
1179 @code{fulanito} con cuatro argumentos definida como
1180
1181 @example
1182 #(define-markup-command (fulanito layout props
1183                          num1    str1    num2    str2)
1184                         (number? string? number? string?)
1185   ...)
1186 @end example
1187
1188 @noindent
1189 Si la aplicamos como, digamos,
1190
1191 @example
1192 \markup \fulanito #1 #"mengano" #2 #"zutano"
1193 @end example
1194
1195 @cindex Scheme signature
1196 @cindex signature, Scheme
1197 @noindent
1198 @command{lilypond} protesta diciendo que no puede analizar
1199 @code{fulanito} debido a su firma de Scheme desconocida.
1200
1201
1202 @node Definición de nuevas instrucciones de lista de marcado
1203 @subsection Definición de nuevas instrucciones de lista de marcado
1204 @translationof New markup list command definition
1205
1206 Las instrucciones de listas de marcado se definen con el macro de
1207 Scheme @code{define-markup-list-command}, que es similar al macro
1208 @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
1209 devuelve una lista de sellos.
1210
1211 En el siguiente ejemplo se define una instrucción de lista de marcado
1212 @code{\paragraph}, que devuelve una lista de líneas justificadas,
1213 estando la primera de ellas sangrada.  La anchura del sangrado se toma
1214 del argumento @code{props}.
1215
1216 @example
1217 #(define-markup-list-command (paragraph layout props args) (markup-list?)
1218    (let ((indent (chain-assoc-get 'par-indent props 2)))
1219      (interpret-markup-list layout props
1220        (make-justified-lines-markup-list (cons (make-hspace-markup indent)
1221                                                args)))))
1222 @end example
1223
1224 Aparte de los argumentos usuales @code{layout} y @code{props}, la
1225 instrucción de lista de marcados @code{paragraph} toma un argumento de
1226 lista de marcados, llamado @code{args}.  El predicado para listas de
1227 marcados es @code{markup-list?}.
1228
1229 En primer lugar, la función toma el ancho del sangrado, una propiedad
1230 llamada aquí @code{par-indent}, de la lista de propiedades
1231 @code{props}.  Si no se encuentra la propiedad, el valor
1232 predeterminado es @code{2}.  Después, se hace una lista de líneas
1233 justificadas usando la función
1234 @code{make-justified-lines-markup-list}, que está relacionada con la
1235 instrucción incorporada de lista de marcados @code{\justified-lines}.
1236 Se añade un espacio horizontal al principio usando la función
1237 @code{make-hspace-markup}.  Finalmente, la lista de marcados se
1238 interpreta usando la función @code{interpret-markup-list}.
1239
1240 Esta nueva instrucción de lista de marcados se puede usar como sigue:
1241
1242 @example
1243 \markuplines @{
1244   \paragraph @{
1245     El arte de la tipografía musical se llama  \italic @{grabado (en plancha).@}
1246     El término deriva del proceso tradicional de impresión de música.
1247     hace sólo algunas décadas, las partituras se hacían cortando y estampando
1248     la música en una plancha de zinc o lata en una imagen invertida.
1249   @}
1250   \override-lines #'(par-indent . 4) \paragraph @{
1251     La plancha se tenía que entintar, y las depresiones causadas por los cortes
1252     y estampados retienen la tinta.  Se formaba una imagen presionando el papel
1253     contra la plancha.  El estampado y cortado se hacía completamente
1254     a mano.
1255   @}
1256 @}
1257 @end example
1258
1259
1260 @node Contextos para programadores
1261 @section Contextos para programadores
1262 @translationof Contexts for programmers
1263
1264 @menu
1265 * Evaluación de contextos::
1266 * Ejecutar una función sobre todos los objetos de la presentación::
1267 @end menu
1268
1269 @node Evaluación de contextos
1270 @subsection Evaluación de contextos
1271 @translationof Context evaluation
1272
1273 @cindex código, llamadas durante la interpretación
1274 @funindex \applyContext
1275
1276 Se pueden modificar los contextos durante la interpretación con código
1277 de Scheme.  La sintaxis para esto es
1278
1279 @example
1280 \applyContext @var{función}
1281 @end example
1282
1283 @var{función} debe ser una función de Scheme que toma un único
1284 argumento, que es el contexto al que aplicarla.  El código siguiente
1285 imprime el número del compás actual sobre la salida estándar durante
1286 la compilación:
1287
1288 @example
1289 \applyContext
1290   #(lambda (x)
1291     (format #t "\nSe nos ha llamado en el compás número ~a.\n"
1292      (ly:context-property x 'currentBarNumber)))
1293 @end example
1294
1295
1296 @node Ejecutar una función sobre todos los objetos de la presentación
1297 @subsection Ejecutar una función sobre todos los objetos de la presentación
1298 @translationof Running a function on all layout objects
1299
1300
1301 @cindex código, llamar sobre objetos de presentación
1302 @funindex \applyOutput
1303
1304
1305 La manera más versátil de realizar el ajuste fino de un objeto es
1306 @code{\applyOutput}.  Su sintaxis es
1307
1308 @example
1309 \applyOutput @var{contexto} @var{proc}
1310 @end example
1311
1312 @noindent
1313 donde @var{proc} es una función de Scheme, que toma tres argumentos.
1314
1315 Al interpretarse, la función @var{proc} se llama para cada objeto de
1316 presentación que se encuentra en el contexto @var{contexto}, con los
1317 siguientes argumentos:
1318
1319 @itemize
1320 @item el propio objeto de presentación,
1321 @item el contexto en que se creó el objeto de presentación, y
1322 @item el contexto en que se procesa @code{\applyOutput}.
1323 @end itemize
1324
1325 Además, la causa del objeto de presentación, es decir el objeto o
1326 expresión musical que es responsable de haberlo creado, está en la
1327 propiedad @code{cause} del objeto.  Por ejemplo, para la cabeza de una
1328 nota, éste es un evento @rinternals{NoteHead}, y para un objeto
1329 @rinternals{Stem} (plica), éste es un objeto @rinternals{Stem}.
1330 @c Impossible - changed to Stem --FV
1331
1332 He aquí una función que usar para @code{\applyOutput}; borra las
1333 cabezas de las notas que están sobre la línea central:
1334
1335 @lilypond[quote,verbatim,ragged-right]
1336 #(define (blanker grob grob-origin context)
1337    (if (and (memq 'note-head-interface (ly:grob-interfaces grob))
1338             (eq? (ly:grob-property grob 'staff-position) 0))
1339        (set! (ly:grob-property grob 'transparent) #t)))
1340
1341 \relative {
1342   e4 g8 \applyOutput #'Voice #blanker b d2
1343 }
1344 @end lilypond
1345
1346
1347 @node Procedimientos de Scheme como propiedades
1348 @section Procedimientos de Scheme como propiedades
1349 @translationof Scheme procedures as properties
1350
1351 Las propiedades (como el grosor, la dirección, etc.) se pueden
1352 establecer a valores fijos con \override, p. ej.
1353
1354 @example
1355 \override Stem #'thickness = #2.0
1356 @end example
1357
1358 Las propiedades pueden fijarse también a un procedimiento de scheme,
1359
1360 @lilypond[fragment,verbatim,quote,relative=2]
1361 \override Stem #'thickness = #(lambda (grob)
1362     (if (= UP (ly:grob-property grob 'direction))
1363         2.0
1364         7.0))
1365 c b a g b a g b
1366 @end lilypond
1367
1368 @noindent
1369 En este caso, el procedimiento se ejecuta tan pronto como el valor de
1370 la propiedad se reclama durante el proceso de formateo.
1371
1372 Casi todo el motor de tipografiado está manejado por estos
1373 @emph{callbacks}.  Entre las propiedades que usan normalmente
1374 @emph{callbacks} están
1375
1376 @table @code
1377 @item stencil
1378   La rutina de impresión, que construye un dibujo para el símbolo
1379 @item X-offset
1380   La rutina que establece la posición horizontal
1381 @item X-extent
1382   La rutina que calcula la anchura de un objeto
1383 @end table
1384
1385 El procedimiento siempre toma un argumento único, que es el grob (el
1386 objeto gráfico).
1387
1388 Si se deben llamar rutinas con varios argumentos, el grob actual se
1389 puede insertar con una cerradura de grob.  He aquí un ajuste
1390 procedente de @code{AccidentalSuggestion},
1391
1392 @example
1393 (X-offset .
1394   ,(ly:make-simple-closure
1395     `(,+
1396         ,(ly:make-simple-closure
1397            (list ly:self-alignment-interface::centered-on-x-parent))
1398       ,(ly:make-simple-closure
1399            (list ly:self-alignment-interface::x-aligned-on-self)))))
1400 @end example
1401
1402 @noindent
1403 En este ejemplo, tanto
1404 @code{ly:self-alignment-interface::x-aligned-on-self} como
1405 @code{ly:self-alignment-interface::centered-on-x-parent} se llaman con
1406 el grob como argumento.  El resultado se añade con la función
1407 @code{+}.  Para asegurar que esta adición se ejecuta adecuadamente,
1408 todo ello se encierra dentro de @code{ly:make-simple-closure}.
1409
1410 De hecho, usar un solo procedimiento como valor de una propiedad
1411 equivale a
1412
1413 @example
1414 (ly:make-simple-closure (ly:make-simple-closure (list @var{proc})))
1415 @end example
1416
1417 @noindent
1418 El @code{ly:make-simple-closure} interior aporta el grob como
1419 argumento de @var{proc}, el exterior asegura que el resultado de la
1420 función es lo que se devuelve, en lugar del objeto
1421 @code{simple-closure}.
1422
1423
1424 @node Usar código de Scheme en lugar de \tweak
1425 @section Usar código de Scheme en lugar de @code{\tweak}
1426 @translationof Using Scheme code instead of \tweak
1427
1428 La principal desventaja de @code{\tweak} es su inflexibilidad
1429 sintáctica.  Por ejemplo, lo siguiente produce un error de sintaxis.
1430
1431 @example
1432 F = \tweak #'font-size #-3 -\flageolet
1433
1434 \relative c'' @{
1435   c4^\F c4_\F
1436 @}
1437 @end example
1438
1439 @noindent
1440 En otras palabras, @code{\tweak} no se comporta como una articulación
1441 en cuando a la sintaxis; concretamente, no se puede adjuntar con
1442 @code{^} y @code{_}.
1443
1444 Usando Scheme, se puede dar un rodeo a este problema.  La ruta hacia
1445 el resultado se da en @ref{Añadir articulación a las notas (ejemplo)},
1446 especialmente cómo usar @code{\displayMusic} como guía de ayuda.
1447
1448 @example
1449 F = #(let ((m (make-music 'ArticulationEvent
1450                           'articulation-type "flageolet")))
1451        (set! (ly:music-property m 'tweaks)
1452              (acons 'font-size -3
1453                     (ly:music-property m 'tweaks)))
1454        m)
1455
1456 \relative c'' @{
1457   c4^\F c4_\F
1458 @}
1459 @end example
1460
1461 @noindent
1462 Aquí, las propiedades @code{tweaks} del objeto flageolet @code{m}
1463 (creado con @code{make-music}) se extraen con
1464 @code{ly:music-property}, se antepone un nuevo par clave-valor para
1465 cambiar el tamaño de la tipografía a la lista de propiedades con la
1466 función de Scheme @code{acons}, y finalmente el resultado se escribe
1467 de nuevo con @code{set!}.  El último elemento del bloque @code{let} es
1468 el valor de retorno, el propio @code{m}.
1469
1470 @node Trucos difíciles
1471 @section Trucos difíciles
1472 @translationof Difficult tweaks
1473
1474 Hay un cierto número de tipos de ajustes difíciles.
1475
1476 @itemize
1477
1478 @item
1479 Un tipo de ajuste difícil es la apariencia de los objetos de
1480 extensión, como las ligaduras de expresión y de unión.  Inicialmente,
1481 sólo se crea uno de estos objetos, y pueden ajustarse con el mecanismo
1482 normal.  Sin embargo, en ciertos casos los objetos extensores cruzan
1483 los saltos de línea.  Si esto ocurre, estos objetos se clonan.  Se
1484 crea un objeto distinto por cada sistema en que se encuentra.  Éstos
1485 son clones del objeto original y heredan todas sus propiedades,
1486 incluidos los @code{\override}s.
1487
1488 En otras palabras, un @code{\override} siempre afecta a todas las
1489 piezas de un objeto de extensión fragmentado.  Para cambiar sólo una
1490 parte de un extensor en el salto de línea, es necesario inmiscuirse en
1491 el proceso de formateado.  El @emph{callback}
1492 @code{after-line-breaking} contiene el procedimiento Scheme que se
1493 llama después de que se han determinado los saltos de línea, y los
1494 objetos de presentación han sido divididos sobre los distintos
1495 sistemas.
1496
1497 En el ejemplo siguiente, definimos un procedimiento
1498 @code{my-callback}.  Este procedimiento
1499
1500 @itemize
1501 @item
1502 determina si hemos sido divididos por los saltos de línea
1503 @item
1504 en caso afirmativo, reúne todos los objetos divididos
1505 @item
1506 comprueba si somos el último de los objetos divididos
1507 @item
1508 en caso afirmativo, establece @code{extra-offset}.
1509 @end itemize
1510
1511 Este procedimiento se instala en @rinternals{Tie} (ligadura de unión),
1512 de forma que la última parte de la ligadura dividida se traslada hacia
1513 arriba.
1514
1515 @lilypond[quote,verbatim,ragged-right]
1516 #(define (my-callback grob)
1517   (let* (
1518          ; have we been split?
1519          (orig (ly:grob-original grob))
1520
1521          ; if yes, get the split pieces (our siblings)
1522          (siblings (if (ly:grob? orig)
1523                      (ly:spanner-broken-into orig) '() )))
1524
1525    (if (and (>= (length siblings) 2)
1526              (eq? (car (last-pair siblings)) grob))
1527      (ly:grob-set-property! grob 'extra-offset '(-2 . 5)))))
1528
1529 \relative c'' {
1530   \override Tie #'after-line-breaking =
1531   #my-callback
1532   c1 ~ \break c2 ~ c
1533 }
1534 @end lilypond
1535
1536 @noindent
1537 Al aplicar este truco, la nueva función de callback
1538 @code{after-line-breaking} también debe llamar a la antigua
1539 @code{after-line-breaking}, si existe.  Por ejemplo, si se usa con
1540 @code{Hairpin}, se debe llamar también a
1541 @code{ly:hairpin::after-line-breaking}.
1542
1543
1544 @item Algunos objetos no se pueden cambiar con @code{\override} por
1545 razones técnicas.  Son ejemplos @code{NonMusicalPaperColumn} y
1546 @code{PaperColumn}.  Se pueden cambiar con la función
1547 @code{\overrideProperty} que funciona de forma similar a @code{\once
1548 \override}, pero usa una sintaxis distinta.
1549
1550 @example
1551 \overrideProperty
1552 #"Score.NonMusicalPaperColumn"  % Nombre del grob
1553 #'line-break-system-details     % Nombre de la propiedad
1554 #'((next-padding . 20))         % Valor
1555 @end example
1556
1557 Observe, sin embargo, que @code{\override}, aplicado a
1558 @code{NonMusicalPaperColumn} y a @code{PaperColumn}, aún funciona
1559 como se espera dentro de los bloques @code{\context}.
1560
1561 @end itemize