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