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