]> git.donarmstrong.com Git - lilypond.git/blob - Documentation/es/user/programming-interface.itely
Merge branch 'master' into lilypond/translation
[lilypond.git] / Documentation / es / user / programming-interface.itely
1 @c -*- coding: utf-8; mode: texinfo; documentlanguage: es -*-
2 @c This file is part of lilypond.tely
3 @ignore
4     Translation of GIT committish: 88f1608ae6fd17b05344bafb2f0721aafdac657b
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.11.61"
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á familizarizado 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 pueden usar más de una variable:
133
134 @lilypond[quote,verbatim,ragged-right]
135 tempoMark = #(define-music-function (parser location padding marktext)
136                                     (number? string?)
137 #{
138   \once \override Score . RehearsalMark #'padding = $padding
139   \once \override Score . RehearsalMark #'extra-spacing-width = #'(+inf.0 . -inf.0)
140   \mark \markup { \bold $marktext }
141 #})
142
143 \relative c'' {
144 c2 e
145 \tempoMark #3.0 #"Allegro"
146 g c
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, per 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 imresió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 intermezclar con libertad.  En el ejemplo siguiente, se
345 almacena un fragmento musical en la variable @code{traLaLa}, y se
346 dupplica 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 sódigo de Scheme se evalúa tan pronto como el analizador sintáctico
384 lo encuentra.  Para definir código de Scheme en un macro (para
385 llamarlo con posterioridad), use @ref{Void functions}, o bien
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{typo} o intterface: cada nombre de música tiene varios @q{tipos} o
423 interfaces, por ejemplo una nota es un @code{event}, pero también es
424 un @code{note-event}, un @code{rhythmic-event} y un
425 @code{melodic-event}.  Todas las clases musicales se encuentran
426 relacionadas en la Referencia de funcionamiento interno bajo
427 @rinternals{Music classes}.
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 almacernar una
443 lista de objetos en la propiedad @code{elements} de un objeto musical,
444 o un solo objeto musical @q{hijo} en la propiedad @code{element}.  Por
445 ejemplo, @rinternals{SequentialMusic} tiene sus hijos en
446 @code{elements}, y @rinternals{GraceMusic} tiene su elemento único en
447 @code{element}.  El cuerpo de una repetición se almacena en la
448 propiedad @code{element} de @rinternals{RepeatedMusic}, y las
449 alternativas en @code{elements}.
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 @funindex \displayMusic
471
472 Si se está escribiendo una función musical puede ser muy instructivo
473 examinar cómo se almacena internamente una expresión musical.  Esto se
474 puede hacer con la función musical @code{\displayMusic}:
475
476 @example
477 @{
478   \displayMusic @{ c'4\f @}
479 @}
480 @end example
481
482 @noindent
483 imprime lo siguiente:
484
485 @example
486 (make-music
487   'SequentialMusic
488   'elements
489   (list (make-music
490           'EventChord
491           'elements
492           (list (make-music
493                   'NoteEvent
494                   'duration
495                   (ly:make-duration 2 0 1 1)
496                   'pitch
497                   (ly:make-pitch 0 0 0))
498                 (make-music
499                   'AbsoluteDynamicEvent
500                   'text
501                   "f")))))
502 @end example
503
504 De forma predeterminada, LilyPond imprime estos mensajes en la consola
505 junto al resto de los mensajes.  Para discernir entre estos mensajes y
506 guardar el resultado de @code{\display@{MATERIAL@}}, redirija la
507 salida hacia un archivo.
508
509 @example
510 lilypond archivo.ly >resultado.txt
511 @end example
512
513 Con la aplicación de un poco de formato, la inforamción anterior es
514 fácil de leer:
515
516 @example
517 (make-music 'SequentialMusic
518   'elements (list (make-music 'EventChord
519                     'elements (list (make-music 'NoteEvent
520                                       'duration (ly:make-duration 2 0 1 1)
521                                       'pitch (ly:make-pitch 0 0 0))
522                                     (make-music 'AbsoluteDynamicEvent
523                                       'text "f")))))
524 @end example
525
526 Una secuencia musical @code{@{ ... @}} tiene el nombre
527 @code{SequentialMusic}, y sus expresiones internas se almacenan como
528 una lista en su propiedad @code{'elements}.  Una nota se representa
529 como una expresión @code{EventChord} que contiene un objeto
530 @code{NoteEvent} (que almacena las propiedades de duración y altura) y
531 cualquier otra información adicional (en este caso, un evento
532 @code{AbsoluteDynamicEvent} con una porpiedad de texto @code{"f"}.
533
534
535 @node Music properties
536 @subsection Music properties
537
538 El objeto @code{NoteEvent} es el primer objeto de la propiedad
539 @code{'elements} de @code{someNote}.
540
541 @example
542 unaNota = c'
543 \displayMusic \unaNota
544 ===>
545 (make-music
546   'EventChord
547   'elements
548   (list (make-music
549           'NoteEvent
550           'duration
551           (ly:make-duration 2 0 1 1)
552           'pitch
553           (ly:make-pitch 0 0 0))))
554 @end example
555
556 La función @code{display-scheme-music} es la función utilizada por
557 @code{\displayMusic} para imprimir la representación de Scheme de una
558 expresión musical.
559
560 @example
561 #(display-scheme-music (first (ly:music-property unaNota 'elements)))
562 ===>
563 (make-music
564   'NoteEvent
565   'duration
566   (ly:make-duration 2 0 1 1)
567   'pitch
568   (ly:make-pitch 0 0 0))
569 @end example
570
571 Después se accede a la altura de la nota a través de la propiedad
572 @code{'pitch} del objeto @code{NoteEvent}:
573
574 @example
575 #(display-scheme-music
576    (ly:music-property (first (ly:music-property unaNota 'elements))
577                       'pitch))
578 ===>
579 (ly:make-pitch 0 0 0)
580 @end example
581
582 La altura de la nota se puede cambiar estableciendo el valor de esta
583 propiedad 'pitch:
584
585 @funindex \displayLilyMusic
586
587 @example
588 #(set! (ly:music-property (first (ly:music-property unaNota 'elements))
589                           'pitch)
590        (ly:make-pitch 0 1 0)) ;; fijar la altura a d'.
591 \displayLilyMusic \unaNota
592 ===>
593 d'
594 @end example
595
596
597 @node Doubling a note with slurs (example)
598 @subsection Doubling a note with slurs (example)
599
600 Supongamos que queremos crear una función que traduce una entrada como
601 @code{a} a algo como @code{a( a)}.  Empezamos examinando la
602 representación interna de la música con la que queremos terminar.
603
604 @example
605 \displayMusic@{ a'( a') @}
606 ===>
607 (make-music
608   'SequentialMusic
609   'elements
610   (list (make-music
611           'EventChord
612           'elements
613           (list (make-music
614                   'NoteEvent
615                   'duration
616                   (ly:make-duration 2 0 1 1)
617                   'pitch
618                   (ly:make-pitch 0 5 0))
619                 (make-music
620                   'SlurEvent
621                   'span-direction
622                   -1)))
623         (make-music
624           'EventChord
625           'elements
626           (list (make-music
627                   'NoteEvent
628                   'duration
629                   (ly:make-duration 2 0 1 1)
630                   'pitch
631                   (ly:make-pitch 0 5 0))
632                 (make-music
633                   'SlurEvent
634                   'span-direction
635                   1)))))
636 @end example
637
638 Las malas noticias son que las espresiones @code{SlurEvent} se deben
639 añadir @q{dentro} de la nota (o más concretamente, dentro de la
640 expresión @code{EventChord}).
641
642 Ahora observamos la entrada:
643
644 @example
645 (make-music
646   'SequentialMusic
647   'elements
648   (list (make-music
649           'EventChord
650           'elements
651           (list (make-music
652                   'NoteEvent
653                   'duration
654                   (ly:make-duration 2 0 1 1)
655                   'pitch
656                   (ly:make-pitch 0 5 0))))))
657 @end example
658
659 Así pues, en nuestra función, tenemos que clonar esta expresión (de
660 forma que tengamos dos notas para construir la secuencia), añadir
661 @code{SlurEvents} a la propiedad @code{'elements} de cada una de
662 ellas, y por último hacer una secuencia @code{SequentialMusic} con los
663 dos @code{EventChords}.
664
665 @example
666 doubleSlur = #(define-music-function (parser location note) (ly:music?)
667          "Return: @{ note ( note ) @}.
668          `note' is supposed to be an EventChord."
669          (let ((note2 (ly:music-deep-copy note)))
670            (set! (ly:music-property note 'elements)
671                  (cons (make-music 'SlurEvent 'span-direction -1)
672                        (ly:music-property note 'elements)))
673            (set! (ly:music-property note2 'elements)
674                  (cons (make-music 'SlurEvent 'span-direction 1)
675                        (ly:music-property note2 'elements)))
676            (make-music 'SequentialMusic 'elements (list note note2))))
677 @end example
678
679
680 @node Adding articulation to notes (example)
681 @subsection Adding articulation to notes (example)
682
683 La manera fácil de añadir articulación a las notas es fundir dos
684 expresiones musicales en un contexto único, como está explicado en
685 @ref{Creating contexts}.  Sin embargo, suponga que queremos escribir
686 una función musical que haga esto.
687
688 Una @code{$variable} dentro de la notación @code{#@{...#@}} es como
689 usar una @code{\variable} normal en la notación clásica de LilyPond.
690 Sabemos que
691
692 @example
693 @{ \musica -. -> @}
694 @end example
695
696 @noindent
697 no funciona en LilyPond.  Podemos evitar este problema adjuntando la
698 articulación a una nota de mentira,
699
700 @example
701 @{ << \musica s1*0-.-> @}
702 @end example
703
704 @noindent
705 pero a los efectos de este ejemplo, aprenderemos ahora cómo hacerlo en
706 Scheme.  Comenzamos examinando nuestra entrada y la salida deseada:
707
708 @example
709 %  entrada
710 \displayMusic c4
711 ===>
712 (make-music
713   'EventChord
714   'elements
715   (list (make-music
716           'NoteEvent
717           'duration
718           (ly:make-duration 2 0 1 1)
719           'pitch
720           (ly:make-pitch -1 0 0))))
721 =====
722 %  salida deseada
723 \displayMusic c4->
724 ===>
725 (make-music
726   'EventChord
727   'elements
728   (list (make-music
729           'NoteEvent
730           'duration
731           (ly:make-duration 2 0 1 1)
732           'pitch
733           (ly:make-pitch -1 0 0))
734         (make-music
735           'ArticulationEvent
736           'articulation-type
737           "marcato")))
738 @end example
739
740 Vemos que una nota (@code{c4}) se representa como una expresión
741 @code{EventChord}, con una expresión @code{NoteEvent} en su lista de
742 elementos.  Para añadir una articulación marcato, se debe añadir una
743 expresión @code{ArticulationEvent} a la propiedad elementos de la
744 expresión @code{EventChord}.
745
746 Para construir esta función, empezamos con
747
748 @example
749 (define (add-marcato event-chord)
750   "Añadir una ArticulationEvent de marcato a los elementos de `event-chord',
751   que se ssupone que es una expresión EventChord."
752   (let ((result-event-chord (ly:music-deep-copy event-chord)))
753     (set! (ly:music-property result-event-chord 'elements)
754           (cons (make-music 'ArticulationEvent
755                   'articulation-type "marcato")
756                 (ly:music-property result-event-chord 'elements)))
757     result-event-chord))
758 @end example
759
760 La primera línea es la forma de definir una función en Scheme: el
761 nombre de la función es @code{add-marcato}, y tiene una variable
762 llamada @code{event-chord}.  En Scheme, el tipo de variable suele
763 quedar claro a partir de su nombre (¡esto también es una buena
764 práctica en otros lenguajes de programación!).
765
766 @example
767 "Añadir una ArticulationEvent de marcato..."
768 @end example
769
770 @noindent
771 es una descripción de lo que hace la función.  No es estrictamente
772 necesario, pero como los nombres de variable claros, es una buena
773 práctica.
774
775 @example
776 (let ((result-event-chord (ly:music-deep-copy event-chord)))
777 @end example
778
779 @code{let} se usa para declarar variables locales.  Aquí usamos una
780 variable local, llamada @code{result-event-chord}, a la que le damos
781 el valor @code{(ly:music-deep-copy event-chord)}.
782 @code{ly:music-deep-copy} es una función específica de LilyPond, como
783 todas las funciones que comienzan por @code{ly:}.  Se usa para hacer
784 una copia de una expresión musical.  Aquí, copiamos @code{event-chord}
785 (el parámetro de la función).  Recuerde que el propósito es añadir un
786 marcato a una expresión @code{EventChord}.  Es mejor no modificar el
787 @code{EventChord} que se dio como argumento, porque podría utilizarse
788 en algún otro lugar.
789
790 Ahora tenemos un @code{result-event-chord}, que es una expresión
791 @code{NoteEventChord} y es una copia de @code{event-chord}.  Añadimos
792 el marcato a su propiedad lista de elementos.
793
794 @example
795 (set! place new-value)
796 @end example
797
798 Aquí, lo que queremos establecer (el @q{place}) es la propiedad
799 @q{elements} de la expresión @code{result-event-chord}.
800
801 @example
802 (ly:music-property result-event-chord 'elements)
803 @end example
804
805 @code{ly:music-property} es la función que se usa para acceder a las
806 propiedades musicales (los @code{'elements}, @code{'duration},
807 @code{'pitch}, etc., que vemos en la salida de @code{\displayMusic}
808 más arriba).  El nuevo valor es la anterior propiedad elements, con un
809 elemento adicional: la expresión @code{ArticulationEvent}, que
810 copiamos a partir de la salida de @code{\displayMusic},
811
812 @example
813 (cons (make-music 'ArticulationEvent
814         'articulation-type "marcato")
815       (ly:music-property result-event-chord 'elements))
816 @end example
817
818 @code{cons} se usa para añadir un elemento a una lsita sin modificar
819 la lista original.  Esto es lo que queremos: la misma lista que antes,
820 más la nueva expresión @code{ArticulationEvent}.  El orden dentro de
821 la propiedad elements no es importante aquí.
822
823 Finalmente, una vez añadida la articulación marcato a su propiedad
824 @code{elements}, podemos devolver @code{result-event-chord}, de aquí
825 la última línea de la función.
826
827 Ahora transformamos la función @code{add-marcato} en una función
828 musical,
829
830 @example
831 addMarcato = #(define-music-function (parser location event-chord)
832                                      (ly:music?)
833     "Add a marcato ArticulationEvent to the elements of `event-chord',
834     which is supposed to be an EventChord expression."
835     (let ((result-event-chord (ly:music-deep-copy event-chord)))
836       (set! (ly:music-property result-event-chord 'elements)
837             (cons (make-music 'ArticulationEvent
838                     'articulation-type "marcato")
839                   (ly:music-property result-event-chord 'elements)))
840       result-event-chord))
841 @end example
842
843 Podemos verificar que esta función musical funciona correctamente,
844
845 @example
846 \displayMusic \addMarcato c4
847 @end example
848
849
850 @node Markup programmer interface
851 @section Markup programmer interface
852
853 Los marcados están implementados como funciones de Scheme especiales
854 que producen un elemento Stencil (sello) dado un número de argumentos.
855
856 @menu
857 * Markup construction in Scheme::
858 * How markups work internally::
859 * New markup command definition::
860 * New markup list command definition::
861 @end menu
862
863 @node Markup construction in Scheme
864 @subsection Markup construction in Scheme
865
866 @cindex marcado, definir instrucciones de
867
868 El macro @code{markup} construye expresiones de marcado en Scheme,
869 proporcionando una sintaxis similar a la de LilyPond.  Por ejemplo:
870
871 @example
872 (markup #:column (#:line (#:bold #:italic "hola" #:raise 0.4 "mundo")
873                   #:larger #:line ("fulano" "fulanito" "menganito")))
874 @end example
875
876 @noindent
877 equivale a:
878 @example
879 \markup \column @{ \line @{ \bold \italic "hola" \raise #0.4 "mundo" @}
880                   \larger \line @{ fulano fulanito menganito @} @}
881 @end example
882
883 @noindent
884 Este ejemplo muestra las principales reglas de traducción entre la
885 sitaxis del marcado normal de LilyPond y la sintaxis del marcado de
886 Scheme.
887
888 @quotation
889 @multitable @columnfractions .3 .3
890 @item @b{LilyPond} @tab @b{Scheme}
891 @item @code{\markup marcado1} @tab @code{(markup marcado1)}
892 @item @code{\markup @{ marcado1 marcado2 ... @}} @tab
893         @code{(markup marcado1 marcado2 ... )}
894 @item @code{\instruccion} @tab @code{#:instruccion}
895 @item @code{\variable} @tab @code{variable}
896 @item @code{\center-column @{ ... @}} @tab @code{#:center-column ( ... )}
897 @item @code{cadena} @tab @code{"cadena"}
898 @item @code{#argumento-de-scheme} @tab @code{argumento-de-scheme}
899 @end multitable
900 @end quotation
901
902 Todo el lenguaje Scheme está accesible dentro del macro @code{markup}.
903 Por ejemplo, podemos usar llamadas a funciones dentro de @code{markup}
904 para así manipular cadenas de caracteres.  Esto es útil si se están
905 definiendo instrucciones de marcado nuevas (véase @ref{New markup
906 command definition}).
907
908 @knownissues
909
910 El argumento markup-list de instrucciones como @code{#:line},
911 @code{#:center} y @code{#:column} no pueden se una variable o el
912 resultado de la llamada a una función.
913
914 @lisp
915 (markup #:line (funcion-que-devuelve-marcados))
916 @end lisp
917
918 @noindent
919 no es válido.  Hay que usar las funciones @code{make-line-markup},
920 @code{make-center-markup} o @code{make-column-markup} en su lugar:
921
922 @lisp
923 (markup (make-line-markup (funcion-que-devuelve-marcados)))
924 @end lisp
925
926
927 @node How markups work internally
928 @subsection How markups work internally
929
930 En un elemento de marcado como
931
932 @example
933 \raise #0.5 "ejemplo de texto"
934 @end example
935
936 @noindent
937 @code{\raise} se representa en realidad por medio de la función
938 @code{raise-markup}.  La expresión de marcado se almacena como
939
940 @example
941 (list raise-markup 0.5 (list simple-markup "ejemplo de texto"))
942 @end example
943
944 Cuando el marcado se convierte en objetos imprimibles (Stencils o
945 sellos), se llama la función @code{raise-markup} como
946
947 @example
948 (apply raise-markup
949        @var{\objeto de marcado}
950        @var{lista de listas asociativas de propiedades}
951        0.5
952        @var{el marcado "ejemplo de texto"})
953 @end example
954
955 Primero la función @code{raise-markup} crea el sello para la cadena
956 @code{ejemplo de texto}, y después eleva el sello Stencil en 0.5
957 espacios de pentagrama.  Este es un ejemplo bastante simple; en el
958 resto de la sección podrán verse ejemplos más complejos, así como en
959 @file{scm/@/define@/-markup@/-commands@/.scm}.
960
961
962 @node New markup command definition
963 @subsection New markup command definition
964
965 Las instrucciones de marcado nuevas se pueden definir con el macro de
966 Scheme @code{define-markup-command}.
967
968 @lisp
969 (define-markup-command (@var{nombre-de-la-instruccion} @var{layout} @var{props} @var{arg1} @var{arg2} ...)
970             (@var{arg1-type?} @var{arg2-type?} ...)
971   ..command body..)
972 @end lisp
973
974 Los argumentos son
975
976 @table @var
977 @item argi
978 @var{i}-ésimo argumento de la instrucción
979 @item argi-type?
980 predicado de tipo para el argumento @var{i}-ésimo
981 @item layout
982 la definición de @q{presentación}
983 @item props
984 lista de listas asociativas, que contiene todas las propiedades
985 activas.
986 @end table
987
988 Como ejemplo sencillo, mostramos cómo añadir una instrucción
989 @code{\smallcaps}, que selecciona una tipografía de versalitas.
990 Normalmente podríamos seleccionar la tipografía de versalitas,
991
992 @example
993 \markup @{ \override #'(font-shape . caps) Texto-en-versalitas @}
994 @end example
995
996 @noindent
997 Esto selecciona la tipografía de versalitas mediante el
998 establecimiento de la propiedad @code{font-shape} a @code{#'caps} para
999 la interpretación de @code{Texto-en-versalitas}.
1000
1001 Para poner lo anterior disponible como la instrucción
1002 @code{\smallcaps}, tenemos que definir una función utilizando
1003 @code{define-markup-command}.  La instrucción ha de tomar un argumento
1004 del tipo @code{markup}.  Por tanto, el inicio de la definición ha de
1005 ser
1006
1007 @example
1008 (define-markup-command (smallcaps layout props argument) (markup?)
1009 @end example
1010
1011 @noindent
1012
1013 Lo que aparece a continuación es el contenido de la instrucción:
1014 debemos interpretar el @code{argument} como un marcado, es decir:
1015
1016 @example
1017 (interpret-markup layout @dots{} argument)
1018 @end example
1019
1020 @noindent
1021 Esta interpretación tiene que añadir @code{'(font-shape . caps)} a las
1022 propiedades activas, por lo que sustituimos lo siguiente por los
1023 @dots{} en el ejemplo anterior:
1024
1025 @example
1026 (cons (list '(font-shape . caps) ) props)
1027 @end example
1028
1029 @noindent
1030 La variable @code{props} es una lista de a-listas, y se lo anteponemos
1031 haciendo la operación cons de una lista con el ajuste adicional.
1032
1033 Supongamos que estamos tipografiando un recitativo de una ópera y nos
1034 gustaría definir una instrucción que presente los nombres de los
1035 personajes de una forma personalizada.  Queremos que los nombres se
1036 impriman con versalitas y se desplacen un poco a la izquierda y hacia
1037 arriba.  Definimos una instrucción @code{\character} que toma en
1038 cuenta la traslación necesaria y utiliza la instrucción
1039 @code{\smallcaps} recién definida:
1040
1041 @example
1042 #(define-markup-command (character layout props nombre) (string?)
1043   "Imprimir el nombre del personaje en versalitas, desplazado a la izquierda y hacia
1044   arriba.  Sintaxis: \\character #\"nombre\""
1045   (interpret-markup layout props
1046    (markup #:hspace 0 #:translate (cons -3 1) #:smallcaps nombre)))
1047 @end example
1048
1049 Esta es una complicación que requiere una explicación: los textos por
1050 encima y por debajo del pentagrama se mueven verticalmente de forma
1051 que estén a una cierta distancia (la propiedad @code{padding}) del
1052 pentagrama y de las notas.  Para asegurar que este mecanismo no anula
1053 el efecto de nuestro @code{#:translate}, añadimos una cadena vacía
1054 (@code{#:hspace 0}) antes del texto trasladado.  Ahora el
1055 @code{#:hspace 0} se pone encima de las notas, y el @code{nombre} se
1056 mueve en relación a dicha cadena vacía.  El efecto neto es que el
1057 texto se mueve hacia la izquierda y hacia arriba.
1058
1059 El resultado final es como sigue:
1060
1061 @example
1062 @{
1063   c''^\markup \character #"Cleopatra"
1064   e'^\markup \character #"Giulio Cesare"
1065 @}
1066 @end example
1067
1068 @lilypond[quote,ragged-right]
1069 #(define-markup-command (smallcaps layout props str) (string?)
1070   "Print the string argument in small caps.  Syntax: \\smallcaps #\"string\""
1071   (interpret-markup layout props
1072    (make-line-markup
1073     (map (lambda (s)
1074           (if (= (string-length s) 0)
1075               s
1076               (markup #:large (string-upcase (substring s 0 1))
1077                       #:translate (cons -0.6 0)
1078                       #:tiny (string-upcase (substring s 1)))))
1079          (string-split str #\Space)))))
1080
1081 #(define-markup-command (character layout props name) (string?)
1082   "Print the character name in small caps, translated to the left and
1083   top.  Syntax: \\character #\"name\""
1084   (interpret-markup layout props
1085    (markup #:hspace 0 #:translate (cons -3 1) #:smallcaps name)))
1086
1087 {
1088   c''^\markup \character #"Cleopatra" c'' c'' c''
1089   e'^\markup \character #"Giulio Cesare" e' e' e'
1090 }
1091 @end lilypond
1092
1093 Hemos usado la forma de fuente tipográfica @code{caps}, pero
1094 supongamos que nuestra fuente no tiene la variante de versalitas.  En
1095 ese caso tenemos que hacer una falsa fuente de mayúsculas pequeñas
1096 haciendo que la cadena en mayúsculas tenga la primera legra un poco
1097 mayor:
1098
1099 @example
1100 #(define-markup-command (smallcaps layout props str) (string?)
1101   "Print the string argument in small caps."
1102   (interpret-markup layout props
1103    (make-line-markup
1104     (map (lambda (s)
1105           (if (= (string-length s) 0)
1106               s
1107               (markup #:large (string-upcase (substring s 0 1))
1108                       #:translate (cons -0.6 0)
1109                       #:tiny (string-upcase (substring s 1)))))
1110          (string-split str #\Space)))))
1111 @end example
1112
1113 La instrucción @code{smallcaps} primero divide su argumento de cadena
1114 en unidades o palabras separadas por espacios (@code{(string-split str
1115 #\Space)}); para cada unidad o palabra, se construye un marcado con la
1116 primera letra agrandada y en mayúscula (@code{#:large (string-upcase
1117 (substring s 0 1))}), y un segundo marcado construido con las letras
1118 siguientes reducidas de tamaño y en mayúsculas (@code{#:tiny
1119 (string-upcase (substring s 1))}).  Como LilyPond introduce un espacio
1120 entre los marcados de una misma línea, el segundo marcado se traslada
1121 a la izquierda (@code{#:translate (cons -0.6 0) ...}).  Después, los
1122 marcados construidos para cada palabra se ponen en una línea mediante
1123 @code{(make-line-markup ...)}.  Finalmente, el marcado resultante se
1124 pasa a la función @code{interpret-markup}, con los argumentos
1125 @code{layout} y @code{props}.
1126
1127 Nota: ahora existe una instrucción interna @code{\smallCaps} que se
1128 puede usar para poner texto en versalitas.  Consulte @ref{Text markup
1129 commands}, para ver más detalles.
1130
1131 @knownissues
1132
1133 Actualmente las combinaciones de argumentos que hay disponibles
1134 (después de los argumentos estándar @var{layout} y @var{props}) para
1135 una instrucción de marcado definida con @code{define-markup-command}
1136 se limitan a la siguiente lista:
1137
1138 @table @asis
1139 @item (ningún argumento)
1140 @itemx @var{list}
1141 @itemx @var{markup}
1142 @itemx @var{markup markup}
1143 @itemx @var{scm}
1144 @itemx @var{scm markup}
1145 @itemx @var{scm scm}
1146 @itemx @var{scm scm markup}
1147 @itemx @var{scm scm markup markup}
1148 @itemx @var{scm markup markup}
1149 @itemx @var{scm scm scm}
1150 @end table
1151
1152 @noindent
1153 En la tabla de arriba, @var{scm} representa los tipos de datos nativos
1154 de Scheme como @q{number} (número) o @q{string} (cadena).
1155
1156 Como ejemplo, no es posible usar una instrucción de marcado
1157 @code{fulanito} con cuatro argumentos definida como
1158
1159 @example
1160 #(define-markup-command (fulanito layout props
1161                          num1    str1    num2    str2)
1162                         (number? string? number? string?)
1163   ...)
1164 @end example
1165
1166 @noindent
1167 Si la aplicamos como, digamos,
1168
1169 @example
1170 \markup \fulanito #1 #"mengano" #2 #"zutano"
1171 @end example
1172
1173 @cindex Scheme signature
1174 @cindex signature, Scheme
1175 @noindent
1176 @command{lilypond} protesta diciendo que no puede analizar
1177 @code{fulanito} debido a su firma de Scheme desconocida.
1178
1179
1180 @node New markup list command definition
1181 @subsection New markup list command definition
1182
1183 Las instrucciones de listas de marcado se definen con el macro de
1184 Scheme @code{define-markup-list-command}, que es similar al macro
1185 @code{define-markup-command} descrito en @ref{New markup command
1186 definition}, excepto que donde éste devuelve un sello único, aquél
1187 devuelve una lista de sellos.
1188
1189 En el siguiente ejemplo se define una instrucción de lista de marcado
1190 @code{\paragraph}, que devuelve una lista de líneas justificadas,
1191 estando la primera de ellas sangrada.  La anchura del sangrado se toma
1192 del argumento @code{props}.
1193
1194 @example
1195 #(define-markup-list-command (paragraph layout props args) (markup-list?)
1196    (let ((indent (chain-assoc-get 'par-indent props 2)))
1197      (interpret-markup-list layout props
1198        (make-justified-lines-markup-list (cons (make-hspace-markup indent)
1199                                                args)))))
1200 @end example
1201
1202 Aparte de los argumentos usuales @code{layout} y @code{props}, la
1203 instrucción de lista de marcados @code{paragraph} toma un argumento de
1204 lista de marcados, llamado @code{args}.  El predicado para listas de
1205 marcados es @code{markup-list?}.
1206
1207 Em primer lugar, la función toma el ancho del sangrado, una propiedad
1208 llamada aquí @code{par-indent}, de la lista de propiedades
1209 @code{props}.  Si no se encuentra la propiedad, el valor
1210 predeterminado es @code{2}.  Después, se hace una lista de líneas
1211 justificadas usando la función
1212 @code{make-justified-lines-markup-list}, que está relacionada con la
1213 instrucción incorporada de lista de marcados @code{\justified-lines}.
1214 Se añade un espacio horizontal al principio usando la función
1215 @code{make-hspace-markup}.  Finalmente, la lista de marcados se
1216 interpreta usando la función @code{interpret-markup-list}.
1217
1218 Esta nueva instrucción de lista de marcados se puede usar como sigue:
1219
1220 @example
1221 \markuplines @{
1222   \paragraph @{
1223     El arte de la tipografía musical se llama  \italic @{grabado (en plancha).@}
1224     El término deriva del proceso tradicional de impresión de música.
1225     hace sólo algunas décadas, las partituras se hacían cortando y estampando
1226     la música en una plancha de zinc o lata en una imagen invertida.
1227   @}
1228   \override-lines #'(par-indent . 4) \paragraph @{
1229     La plancha se tenía que entintar, y las depresiones causadas por los cortes
1230     y estampados retienen la tinta.  Se formaba una imagen presionando el papel
1231     contra la plancha.  El estampado y cortado se hacía completamente
1232     a mano.
1233   @}
1234 @}
1235 @end example
1236
1237
1238 @node Contexts for programmers
1239 @section Contexts for programmers
1240
1241 @menu
1242 * Context evaluation::
1243 * Running a function on all layout objects::
1244 @end menu
1245
1246 @node Context evaluation
1247 @subsection Context evaluation
1248
1249 @cindex código, llamadas durante la interpretación
1250 @funindex \applyContext
1251
1252 Se pueden modificar los contextos durante la interpretación con código
1253 de Scheme.  La sintaxis para esto es
1254
1255 @example
1256 \applyContext @var{función}
1257 @end example
1258
1259 @var{función} debe ser una función de Scheme que toma un único
1260 argumento, que es el contexto al que aplicarla.  El código siguiente
1261 imprime el número del compás actual sobre la salida estándar durante
1262 la compilación:
1263
1264 @example
1265 \applyContext
1266   #(lambda (x)
1267     (format #t "\nSe nos ha llamado en el compás número ~a.\n"
1268      (ly:context-property x 'currentBarNumber)))
1269 @end example
1270
1271
1272 @node Running a function on all layout objects
1273 @subsection Running a function on all layout objects
1274
1275
1276 @cindex código, llamar sobre objetos de presentación
1277 @funindex \applyOutput
1278
1279
1280 La manera más versátil de realizar el ajuste fino de un objeto es
1281 @code{\applyOutput}.  Su sintaxis es
1282
1283 @example
1284 \applyOutput @var{contexto} @var{proc}
1285 @end example
1286
1287 @noindent
1288 donde @var{proc} es una función de Scheme, que toma tres argumentos.
1289
1290 Al interpretarse, la función @var{proc} se llama para cada objeto de
1291 presentación que se encuentra en el contexto @var{contexto}, con los
1292 siguientes argumentos:
1293
1294 @itemize
1295 @item el propio objeto de presentación,
1296 @item el contexto en que se creó el objeto de presentación, y
1297 @item el contexto en que se procesa @code{\applyOutput}.
1298 @end itemize
1299
1300 Además, la causa del objeto de presentación, es decir el objeto o
1301 expresión musical que es responsable de haberlo creado, está en la
1302 propiedad @code{cause} del objeto.  Por ejemplo, para la cabeza de una
1303 nota, éste es un evento @rinternals{NoteHead}, y para un objeto
1304 @rinternals{Stem} (plica), éste es un objeto @rinternals{Stem}.
1305 @c Impossible - changed to Stem --FV
1306
1307 He aquí una función que usar para @code{\applyOutput}; borra las
1308 cabezas de las notas que están sobre la línea central:
1309
1310 @example
1311 (define (blanker grob grob-origin context)
1312  (if (and (memq (ly:grob-property grob 'interfaces)
1313                 note-head-interface)
1314           (eq? (ly:grob-property grob 'staff-position) 0))
1315      (set! (ly:grob-property grob 'transparent) #t)))
1316 @end example
1317
1318
1319 @node Scheme procedures as properties
1320 @section Scheme procedures as properties
1321
1322 Las propiedades (como el grosor, la dirección, etc.) se pueden
1323 establecer a valores fijos con \override, p. ej.
1324
1325 @example
1326 \override Stem #'thickness = #2.0
1327 @end example
1328
1329 Las propiedades pueden fijarse también a un procedimiento de scheme,
1330
1331 @lilypond[fragment,verbatim,quote,relative=2]
1332 \override Stem #'thickness = #(lambda (grob)
1333     (if (= UP (ly:grob-property grob 'direction))
1334         2.0
1335         7.0))
1336 c b a g b a g b
1337 @end lilypond
1338
1339 @noindent
1340 En este caso, el procedimiento se ejecuta tan pronto como el valor de
1341 la propiedad se reclama durante el proceso de formateo.
1342
1343 Casi todo el motor de tipografiado está manejado por estos
1344 @emph{callbacks}.  Entre las propiedades que usan normalmente
1345 @emph{callbacks} están
1346
1347 @table @code
1348 @item stencil
1349   La rutina de impresión, que construye un dibujo para el símbolo
1350 @item X-offset
1351   La rutina que establece la posición horizontal
1352 @item X-extent
1353   La rutina que calcula la anchura de un objeto
1354 @end table
1355
1356 El procedimiento siempre toma un argumento único, que es el grob (el
1357 objeto gráfico).
1358
1359 Si se deben llamar rutinas con varios argumentos, el grob actual se
1360 puede insertar con una cerradura de grob.  He aquí un ajuste
1361 procedente de @code{AccidentalSuggestion},
1362
1363 @example
1364 (X-offset .
1365   ,(ly:make-simple-closure
1366     `(,+
1367         ,(ly:make-simple-closure
1368            (list ly:self-alignment-interface::centered-on-x-parent))
1369       ,(ly:make-simple-closure
1370            (list ly:self-alignment-interface::x-aligned-on-self)))))
1371 @end example
1372
1373 @noindent
1374 En este ejemplo, tanto
1375 @code{ly:self-alignment-interface::x-aligned-on-self} como
1376 @code{ly:self-alignment-interface::centered-on-x-parent} se llaman con
1377 el grob como argumento.  El resultado se añade con la función
1378 @code{+}.  Para asegurar que esta adición se ejecuta adecuadamente,
1379 todo ello se encierra dentro de @code{ly:make-simple-closure}.
1380
1381 De hecho, usar un solo procedimiento como valor de una propiedad
1382 equivale a
1383
1384 @example
1385 (ly:make-simple-closure (ly:make-simple-closure (list @var{proc})))
1386 @end example
1387
1388 @noindent
1389 El @code{ly:make-simple-closure} interior aporta el grob como
1390 argumento de @var{proc}, el exterior asegura que el resultado de la
1391 función es lo que se devuelve, en lugar del objeto
1392 @code{simple-closure}.
1393
1394
1395 @node Using Scheme code instead of \tweak
1396 @section Using Scheme code instead of @code{\tweak}
1397
1398 La principal desventaja de @code{\tweak} es su inflexibilidad
1399 sintáctica.  Por ejemplo, lo siguiente produce un error de sintaxis.
1400
1401 @example
1402 F = \tweak #'font-size #-3 -\flageolet
1403
1404 \relative c'' @{
1405   c4^\F c4_\F
1406 @}
1407 @end example
1408
1409 @noindent
1410 En otras palabras, @code{\tweak} no se comporta como una articulación
1411 en cuando a la sintaxis; concretamente, no se puede adjuntar con
1412 @code{^} y @code{_}.
1413
1414 Usando Scheme, se puede dar un rodeo a este problema.  La ruta hacia
1415 el resultado se da en @ref{Adding articulation to notes (example)},
1416 especialmente cómo usar @code{\displayMusic} como guía de ayuda.
1417
1418 @example
1419 F = #(let ((m (make-music 'ArticulationEvent
1420                           'articulation-type "flageolet")))
1421        (set! (ly:music-property m 'tweaks)
1422              (acons 'font-size -3
1423                     (ly:music-property m 'tweaks)))
1424        m)
1425
1426 \relative c'' @{
1427   c4^\F c4_\F
1428 @}
1429 @end example
1430
1431 @noindent
1432 Aquí, las propiedades @code{tweaks} del objeto flageolet @code{m}
1433 (creado con @code{make-music}) se extraen con
1434 @code{ly:music-property}, se antepone un nuevo par clave-valor para
1435 cambiar el tamaño de la tipografía a la lista de propiedades con la
1436 función de Scheme @code{acons}, y finalmente el resultado se escribe
1437 de nuevo con @code{set!}.  El último elemento del bloque @code{let} es
1438 el valor de retorno, el propio @code{m}.
1439
1440 @node Difficult tweaks
1441 @section Difficult tweaks
1442
1443 Hay un cierto número de tipos de ajustes difíciles.
1444
1445 @itemize
1446
1447 @item
1448 Un tipo de ajuste difícil es la apariencia de los objetos de
1449 extensión, como las ligaduras de expresión y de unión.  Inicialmente,
1450 sólo se crea uno de estos objetos, y pueden ajustarse con el mecanismo
1451 normal.  Sin embargo, en ciertos casos los objetos extensores cruzan
1452 los saltos de línea.  Si esto ocurre, estos objetos se clonan.  Se
1453 crea un objeto distinto por cada sistema en que se encuentra.  Éstos
1454 son clones del objeto original y heredan todas sus propiedades,
1455 incluidos los @code{\override}s.
1456
1457 En otras palabras, un @code{\override} siempre afecta a todas las
1458 piezas de un objeto de extensión fragmentado.  Para cambiar sólo una
1459 parte de un extensor en el salto de línea, es necesario inmiscuirse en
1460 el proceso de formateado.  El @emph{callback}
1461 @code{after-line-breaking} contiene el procedimiento Scheme que se
1462 llama después de que se han determinado los saltos de línea, y los
1463 objetos de presentación han sido divididos sobre los distintos
1464 sistemas.
1465
1466 En el ejemplo siguiente, definimos un procedimiento
1467 @code{my-callback}.  Este procedimiento
1468
1469 @itemize
1470 @item
1471 determina si hemos sido divididos por los saltos de línea
1472 @item
1473 en caso afirmativo, reúne todos los objetos divididos
1474 @item
1475 comprueba si somos el último de los objetos divididos
1476 @item
1477 en caso afirmativo, establece @code{extra-offset}.
1478 @end itemize
1479
1480 Este procedimiento se instala en @rinternals{Tie} (ligadura de unión),
1481 de forma que la última parte de la ligadura dividida se traslada hacia
1482 arriba.
1483
1484 @lilypond[quote,verbatim,ragged-right]
1485 #(define (my-callback grob)
1486   (let* (
1487          ; have we been split?
1488          (orig (ly:grob-original grob))
1489
1490          ; if yes, get the split pieces (our siblings)
1491          (siblings (if (ly:grob? orig)
1492                      (ly:spanner-broken-into orig) '() )))
1493
1494    (if (and (>= (length siblings) 2)
1495              (eq? (car (last-pair siblings)) grob))
1496      (ly:grob-set-property! grob 'extra-offset '(-2 . 5)))))
1497
1498 \relative c'' {
1499   \override Tie #'after-line-breaking =
1500   #my-callback
1501   c1 ~ \break c2 ~ c
1502 }
1503 @end lilypond
1504
1505 @noindent
1506 Al aplicar este truco, la nueva función de callback
1507 @code{after-line-breaking} también debe llamar a la antigua
1508 @code{after-line-breaking}, si existe.  Por ejemplo, si se usa con
1509 @code{Hairpin}, se debe llamar también a
1510 @code{ly:hairpin::after-line-breaking}.
1511
1512
1513 @item Algunos objetos no se pueden cambiar con @code{\override} por
1514 razones técnicas.  Son ejemplos @code{NonMusicalPaperColumn} y
1515 @code{PaperColumn}.  Se pueden cambiar con la función
1516 @code{\overrideProperty} que funciona de forma similar a @code{\once
1517 \override}, pero usa una sintaxis distinta.
1518
1519 @example
1520 \overrideProperty
1521 #"Score.NonMusicalPaperColumn"  % Nombre del grob
1522 #'line-break-system-details     % Nombre de la propiedad
1523 #'((next-padding . 20))         % Valor
1524 @end example
1525
1526 Observe, sin embargo, que @code{\override}, aplicado a
1527 @code{NoteMusicalPaperColumn} y a @code{PaperColumn}, aún funciona
1528 como se espera dentro de los bloques @code{\context}.
1529
1530 @end itemize