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