]> git.donarmstrong.com Git - lilypond.git/blob - Documentation/es/user/programming-interface.itely
Doc-es: Programming Interface, - l.922
[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: 4a527608c5ff2ce31e596495d00dce181dc1b9ea
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 funcion =
55 #(define-music-function (parser location @var{var1} @var{var2}... )
56                         (@var{var1-type?} @var{var2-type?}...)
57   #@{
58     @emph{...música...}
59   #@})
60 @end example
61
62 @noindent
63 donde
64
65 @multitable @columnfractions .33 .66
66 @item @var{argi}         @tab @var{i}-ésima variable
67 @item @var{argi-type?}   @tab tipo de variable
68 @item @var{...música...}  @tab entrada normal de LilyPond, usando las variables como @code{#$var1}.
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{argi-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
87 se usan en ciertas situaciones avanzadas.  El argumento
88 @code{parser} se usa para acceder al valor de otra variable de
89 LilyPond.  El argumento @code{location} se usa para establecer el
90 @q{origen} de la expresión musical que construye la función musical,
91 de forma que en caso de producirse un error de sintaxis LilyPond pueda
92 informar al usuario de un lugar adecuado donde buscar en el archivo de
93 entrada.
94
95
96 @node Simple substitution functions
97 @subsection Simple substitution functions
98
99 He aquí un ejemplo sencillo:
100
101 @lilypond[quote,verbatim,ragged-right]
102 padText = #(define-music-function (parser location padding) (number?)
103   #{
104     \once \override TextScript #'padding = #$padding
105   #})
106
107 \relative c''' {
108   c4^"piu mosso" b a b
109   \padText #1.8
110   c4^"piu mosso" d e f
111   \padText #2.6
112   c4^"piu mosso" fis a g
113 }
114 @end lilypond
115
116 También se pueden sustituir las expresiones musicales:
117
118 @lilypond[quote,verbatim,ragged-right]
119 custosNote = #(define-music-function (parser location note)
120                                      (ly:music?)
121   #{
122     \once \override Voice.NoteHead #'stencil =
123       #ly:text-interface::print
124     \once \override Voice.NoteHead #'text =
125       \markup \musicglyph #"custodes.mensural.u0"
126     \once \override Voice.Stem #'stencil = ##f
127     $note
128   #})
129
130 { c' d' e' f' \custosNote g' }
131 @end lilypond
132
133 Se pueden usar más de una variable:
134
135 @lilypond[quote,verbatim,ragged-right]
136 tempoMark = #(define-music-function (parser location padding marktext)
137                                     (number? string?)
138 #{
139   \once \override Score . RehearsalMark #'padding = $padding
140   \once \override Score . RehearsalMark #'extra-spacing-width = #'(+inf.0 . -inf.0)
141   \mark \markup { \bold $marktext }
142 #})
143
144 \relative c'' {
145 c2 e
146 \tempoMark #3.0 #"Allegro"
147 g c
148 }
149 @end lilypond
150
151
152 @node Paired substitution functions
153 @subsection Paired substitution functions
154
155 Algunas instrucciones @code{\override} requieren un par de números
156 (llamados en Scheme una @code{célula cons}).  Para pasar estos números
157 a una función, usamos una variable @code{pair?} o bien insertamos el
158 @code{cons} en la función musical.
159
160 @quotation
161 @example
162 manualBeam =
163 #(define-music-function (parser location beg-end)
164                         (pair?)
165 #@{
166   \once \override Beam #'positions = #$beg-end
167 #@})
168
169 \relative @{
170   \manualBeam #'(3 . 6) c8 d e f
171 @}
172 @end example
173 @end quotation
174
175 @noindent
176 o bien
177
178 @lilypond[quote,verbatim,ragged-right]
179 manualBeam =
180 #(define-music-function (parser location beg end)
181                         (number? number?)
182 #{
183   \once \override Beam #'positions = #(cons $beg $end)
184 #})
185
186 \relative {
187   \manualBeam #3 #6 c8 d e f
188 }
189 @end lilypond
190
191
192 @node Mathematics in functions
193 @subsection Mathematics in functions
194
195 Las funciones musicales pueden contar con programación de Scheme
196 además de la simple sustitución:
197
198 @lilypond[quote,verbatim,ragged-right]
199 AltOn = #(define-music-function (parser location mag) (number?)
200   #{ \override Stem #'length = #$(* 7.0 mag)
201      \override NoteHead #'font-size =
202        #$(inexact->exact (* (/ 6.0 (log 2.0)) (log mag))) #})
203
204 AltOff = {
205   \revert Stem #'length
206   \revert NoteHead #'font-size
207 }
208
209 { c'2 \AltOn #0.5 c'4 c'
210   \AltOn #1.5 c' c' \AltOff c'2 }
211 @end lilypond
212
213 @noindent
214 Este ejemplo se puede reescribir de forma que pase expresiones
215 musicales:
216
217 @lilypond[quote,verbatim,ragged-right]
218 withAlt = #(define-music-function (parser location mag music) (number? ly:music?)
219   #{ \override Stem #'length = #$(* 7.0 mag)
220      \override NoteHead #'font-size =
221        #$(inexact->exact (* (/ 6.0 (log 2.0)) (log mag)))
222      $music
223      \revert Stem #'length
224      \revert NoteHead #'font-size #})
225
226 { c'2 \withAlt #0.5 {c'4 c'}
227   \withAlt #1.5 {c' c'} c'2 }
228 @end lilypond
229
230
231 @node Void functions
232 @subsection Void functions
233
234 Una función musical debe devolver una expresión musical, per a veces
235 podemos necesitar una función en la que no hay música en juego (como
236 la desactivación de la funcionalidad Apuntar y Pulsar).  Para hacerlo,
237 devolvemos una expresión musical @code{void} (vacía).
238
239 Este es el motivo por el que la forma que se devuelve es
240 @code{(make-music ...)}.  Con el valor de la propiedad @code{'void}
241 establecido a @code{#t}, le decimos al analizador que descarte la
242 expresión musical devuelta.  así, la parte importante de la función
243 musical vacía es el proceso realizado por la función, no la expresión
244 musical que se devuelve.
245
246 @example
247 noPointAndClick =
248 #(define-music-function (parser location) ()
249    (ly:set-option 'point-and-click #f)
250    (make-music 'SequentialMusic 'void #t))
251 ...
252 \noPointAndClick   % desactivar la funcionalidad Apuntar y Pulsar.
253 @end example
254
255
256 @node Functions without arguments
257 @subsection Functions without arguments
258
259 En casi todos los casos, una función sin argumentos se debe escribir
260 con una variable:
261
262 @example
263 dolce = \markup@{ \italic \bold dolce @}
264 @end example
265
266 Sin embargo, en raras ocasiones puede ser de utilidad crear una
267 función musical sin argumentos:
268
269 @example
270 displayBarNum =
271 #(define-music-function (parser location) ()
272    (if (eq? #t (ly:get-option 'display-bar-numbers))
273        #@{ \once \override Score.BarNumber #'break-visibility = ##f #@}
274        #@{#@}))
275 @end example
276
277 Para la imresión real de los números de compás donde se llama a esta
278 función, invoque a @command{lilypond} con
279
280 @example
281 lilypond -d display-bar-numbers ARCHIVO.ly
282 @end example
283
284
285 @node Overview of available music functions
286 @subsection Overview of available music functions
287
288 @c fixme ; this should be move somewhere else?
289 Las siguientes instrucciones son funciones musicales:
290
291 @include identifiers.tely
292
293
294 @node Programmer interfaces
295 @section Programmer interfaces
296
297 Esta sección contiene información sobre cómo mezclar LilyPond y
298 Scheme.
299
300 @menu
301 * Input variables and Scheme::
302 * Internal music representation::
303 @end menu
304
305 @node Input variables and Scheme
306 @subsection Input variables and Scheme
307
308 El formato de entrada contempla la noción de variables: en el ejemplo
309 siguiente, se asigna una expresión musical a una variable con el
310 nombre @code{traLaLa}.
311
312 @example
313 traLaLa = @{ c'4 d'4 @}
314 @end example
315
316 @noindent
317
318 También existe una forma de ámbito léxico: en el ejemplo siguiente, el
319 bloque @code{\layout} también contiene una variable @code{traLaLa},
320 que es independiente de la @code{\traLaLa} exterior.
321
322 @example
323 traLaLa = @{ c'4 d'4 @}
324 \layout @{ traLaLa = 1.0 @}
325 @end example
326 @c
327 De hecho, cada archivo de entrada es un ámbito léxico, y todos los
328 bloques @code{\header}, @code{\midi} y @code{\layout} son ámbitos
329 anidados dentro de dicho ámbito de nivel superior.
330
331 Tanto el ámbito léxico como las variables están implementados en el
332 sistema de módulos GUILE.  Se adjunta un módulo anónimo de Scheme a
333 cada ámbito.  Una asignación de la forma
334 @example
335 traLaLa = @{ c'4 d'4 @}
336 @end example
337
338 @noindent
339 se convierte internamente a una definición de Scheme
340 @example
341 (define traLaLa @var{Scheme value of `@code{... }'})
342 @end example
343
344 Esto supone que las variables de entrada y las variables de Scheme se
345 pueden intermezclar con libertad.  En el ejemplo siguiente, se
346 almacena un fragmento musical en la variable @code{traLaLa}, y se
347 dupplica utilizando Scheme.  El resultado se importa en un bloque
348 @code{\score} por medio de una segunda variable @code{twice}:
349
350 @lilypond[verbatim]
351 traLaLa = { c'4 d'4 }
352
353 %% dummy action to deal with parser lookahead
354 #(display "this needs to be here, sorry!")
355
356 #(define newLa (map ly:music-deep-copy
357   (list traLaLa traLaLa)))
358 #(define twice
359   (make-sequential-music newLa))
360
361 { \twice }
362 @end lilypond
363
364 @c Due to parser lookahead
365
366 En este ejemplo, la asignación se produce después de que el analizador
367 sintáctico ha verificado que no ocurre nada interesante después de
368 @code{traLaLa = @{ ... @}}.  Sin el argumento mudo del ejemplo, la
369 definición @code{newLa} se ejecuta antes de que se defina
370 @code{traLaLa}, conduciendo a un error de sintaxis.
371
372 El ejemplo anterior muestra cómo @q{exportar} expresiones musicales
373 desde la entrada hasta el intérprete de Scheme.  También es posible lo
374 contrario.  Envolviendo un valor de Scheme en la función
375 @code{ly:export}, un valor de Scheme se interpreta como si hubiera
376 sido introducido en sintaxis de LilyPond.  En vez de definir
377 @code{\twice}, el ejemplo anterior podría también haberse escrito como
378 @example
379 @dots{}
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 @untranslated
931
932
933 @node New markup command definition
934 @subsection New markup command definition
935
936 @untranslated
937
938
939 @node New markup list command definition
940 @subsection New markup list command definition
941
942 @untranslated
943
944
945 @node Contexts for programmers
946 @section Contexts for programmers
947
948 @untranslated
949
950
951 @menu
952 * Context evaluation::
953 * Running a function on all layout objects::
954 @end menu
955
956 @node Context evaluation
957 @subsection Context evaluation
958
959 @untranslated
960
961
962 @node Running a function on all layout objects
963 @subsection Running a function on all layout objects
964
965 @untranslated
966
967
968 @node Scheme procedures as properties
969 @section Scheme procedures as properties
970
971 @untranslated
972
973
974
975 @node Using Scheme code instead of \tweak
976 @section Using Scheme code instead of @code{\tweak}
977
978 @untranslated
979
980
981 @node Difficult tweaks
982 @section Difficult tweaks
983
984 @untranslated