X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=Documentation%2Fes%2Fextending%2Fprogramming-interface.itely;h=a8e189f2788acfaaafe0900aac86dbbd171c4d79;hb=7bc4cec85321cfd9de1d91038504731bf8c9f264;hp=cdbb9365b8ae853df2a8b81a295a19e2bf658de5;hpb=a0e8cb13ef904814b9caf83778e2d2e313e82725;p=lilypond.git diff --git a/Documentation/es/extending/programming-interface.itely b/Documentation/es/extending/programming-interface.itely index cdbb9365b8..a8e189f278 100644 --- a/Documentation/es/extending/programming-interface.itely +++ b/Documentation/es/extending/programming-interface.itely @@ -1,13 +1,13 @@ @c -*- coding: utf-8; mode: texinfo; documentlanguage: es -*- @c This file is part of extending.tely @ignore - Translation of GIT committish: 26a079ca2393d053315ef8dbef626c897dc9645a + Translation of GIT committish: 84e6243cfa30f294727192befbba5e746fec6d5f When revising a translation, copy the HEAD committish of the version that you are working on. See TRANSLATION for details. @end ignore -@c \version "2.16.0" +@c \version "2.17.6" @node Interfaces para programadores @chapter Interfaces para programadores @@ -32,24 +32,64 @@ Scheme, @ref{Tutorial de Scheme}. @node Bloques de código de LilyPond @section Bloques de código de LilyPond -@translationof Lilypond code blocks +@translationof LilyPond code blocks + +@cindex Bloques de código de LilyPond +@cindex LilyPond, bloques de código de +@funindex #@{ @dots{} #@} +@funindex $ +@funindex # + +La creación de expresiones musicales en Scheme puede ser una tarea +tediosa porque a veces presentan muchos niveles de profundidad de +anidamiento y el código resultante es grande. Para algunas tareas +sencillas, esto puede evitarse utilizando bloques de código de +LilyPond, que permiten usar la sintaxis ordinaria de LilyPond +dentro de Scheme. Los bloques de código de LilyPond tienen el siguiente aspecto: @example #@{ @var{código de LilyPond} #@} @end example -Se pueden usar en cualquier lugar en el que se pueda escribir código -de Scheme: el lector de Scheme en efecto se modifica para que pueda -incorporar bloques de código de LilyPond y pueda ocuparse de las -expresiones de Scheme incrustadas que comienzan por @code{$} y@w{ }@code{#}. - -Extrae el bloque de código de LilyPond y genera una llamada al -@code{parser} o analizador sintáctico de LilyPond, que corre en tiempo -de ejecución para interpretar el bloque de código de LilyPond. -Cualquier expresión de Scheme que se halle incrustada se ejecuta en el -entorno léxico del bloque de código de LilyPond, de manera que tenemos -acceso a las variables locales y a los parámetros de función en el -punto en que se encuentra escrito el bloque de código de LilyPond. + +He aquí un ejemplo trivial: + +@lilypond[verbatim,quote] +ritpp = #(define-event-function (parser location) () + #{ ^"rit." \pp #} +) + +{ c'4 e'4\ritpp g'2 } +@end lilypond + +Los bloques de código de LilyPond se pueden usar en cualquier +lugar en el que se pueda escribir código de Scheme. El lector de +Scheme en efecto se modifica para que pueda incorporar bloques de +código de LilyPond y pueda ocuparse de las expresiones de Scheme +incrustadas que comienzan por @code{$} y@w{ }@code{#}. + +@cindex parser (function argument) +@cindex location + +El lector extrae el bloque de código de LilyPond y genera una +llamada en tiempo de ejecución al analizador sintáctico para que +interprete el código de LilyPond. Las expresiones de Scheme +incrustadas en el código de LilyPond se evalúan dentro del entorno +lóexico del bloque de código de LilyPond, de manera que puede +accederse a todas las variables locales y los parámetros de +función que están disponibles en el punto en que se escribe el +bloque de código de LilyPond. Las variables definidas en otros +módulos de Scheme, como los módulos que contienen bloques +@code{\header} y @code{\layout}, no están accesibles como +variables de Scheme, es decir, precedidas de@tie{}@code{#}, pero +se puede acceder a ellas como variables de LilyPond, es decir, +precedidas de@tie{}@code{\}. + +Si @code{location} (véase @ref{Funciones de Scheme}) se refiere a una +posición de entrada válida (como lo hace normalmente dentro de las +funciones musicales o de Scheme), toda la música generada dentro +del bloque de código tiene su @samp{origin} establecido a +@code{location}. Un bloque de código de LilyPond puede contener cualquier cosa que podríamos utilizar en la parte derecha de una asignación. Además, un @@ -101,28 +141,34 @@ donde de LilyPond (@code{#@{}@dots{}@code{#@}}) acceso al analizador sintáctico. +@item @code{location} +@tab tiene que ser literalmente @code{location} para ofrecer acceso al +objeto de situación de la entrada, que se usa para ofrecer +menssajes de error con nombres de archivo y números de línea. + @item @code{@var{argN}} @tab @var{n}-ésimo argumento @item @code{@var{typeN?}} @tab un @emph{predicado de tipo} de Scheme para el que @code{@var{argN}} -debe devolver @code{#t}. Algunos de estos predicados se reconocen de -forma especial por parte del analizador, véase más abajo. También -existe una forma especial @code{(@emph{predicate?} @emph{default})} -para especificar argumentos opcionales. Si el argumento actual no -está presente cuando se ll ama a la función, el valor predeterminado se -emplea en sustitución. Los valores predeterminados se evalúan en -tiempo de definición (¡incluyendo los bloques de código de LilyPond!), -de manera que se necesitamos un valor por omisión calculado en tiempo -de ejecución, debemos escribir en su lugar un valor especial que -podamos reconocer fácilmente. Si escribimos el predicado entre -paréntesis pero no lo seguimos por el valor predeterminado, se usa -@code{#f} como valor por omisión. Los valores por omisión no se -verifican con @emph{predicate?} en tiempo de definición ni en tiempo -de ejecución: es nuestra responsabilidad tratar con los valores que -especifiquemos. Los valores por omisión que son expresiones musicales -se copian mientras se establece @code{origin} al parámetro -@code{location}. +debe devolver @code{#t}. Algunos de estos predicados se reconocen +de forma especial por parte del analizador, véase más abajo. +También existe una forma especial @code{(@emph{predicate?} +@emph{default})} para especificar argumentos opcionales. Si el +argumento actual no está presente cuando se ll ama a la función, +el valor predeterminado se emplea en sustitución. Los valores +predeterminados se evalúan en tiempo de definición (¡incluyendo +los bloques de código de LilyPond!), de manera que se necesitamos +un valor por omisión calculado en tiempo de ejecución, debemos +escribir en su lugar un valor especial que podamos reconocer +fácilmente. Si escribimos el predicado entre paréntesis pero no +lo seguimos por el valor predeterminado, se usa @code{#f} como +valor por omisión. Los valores por omisión no se verifican con +@emph{predicate?} en tiempo de definición ni en tiempo de +ejecución: es nuestra responsabilidad tratar con los valores que +especifiquemos. Los valores por omisión que son expresiones +musicales se copian mientras se establece @code{origin} al +parámetro @code{location}. @item @code{@var{cuerpo}} @tab una secuencia de formas de Scheme que se evalúan ordenadamente; la @@ -263,7 +309,7 @@ noApuntarYPulsar = (parser location) () (ly:set-option 'point-and-click #f)) -... +@dots{} \noApuntarYPulsar % desactivar la función de apuntar y pulsar @end example @@ -407,7 +453,7 @@ barraManual = (parser location principio-final) (pair?) #@{ - \once \override Beam #'positions = #principio-final + \once \override Beam.positions = #principio-final #@}) \relative c' @{ @@ -425,7 +471,7 @@ manualBeam = (parser location beg end) (number? number?) #{ - \once \override Beam #'positions = #(cons beg end) + \once \override Beam.positions = #(cons beg end) #}) \relative c' { @@ -433,6 +479,61 @@ manualBeam = } @end lilypond +@funindex \temporary +@cindex sobreescrituras temporales +@cindex temporales, sobreescrituras +@cindex propiedades, recuperar valor anterior + +Las propiedades se mantienen conceptualmente utilizando una pila +por cada propiedad, por cada grob y por cada contexto. Las +funciones musicales pueden requerir la sobreescritura de una o +varias propiedades durante el tiempo de duración de la función, +restaurándolas a sus valores previos antes de salir. Sin embargo, +las sobreescrituras normales extraen y descartan la cima de la +pila de propiedades actual antes de introducir un valor en ella, +de manera que el valor anterior de la propiedad se pierde cuando +se sobreescribe. Si se quiere preservar el valor anterior, hay +que preceder la instrucción @code{\override} con la palabra clave +@code{\temporary}, así: + +@example +\temporary \override @dots{} +@end example + +El uso de @code{\temporary} hace que se borre la propiedad +(normalmente fijada a un cierto valor) @code{pop-first} de la +sobreescritura, de forma que el valor anterior no se extrae de la +pila de propiedades antes de poner en ella el valor nuevo. Cuando +una instrucción @code{\revert} posterior extrae el avlor +sobreescrito temporalmente, volverá a emerger el valor anterior. + +En otras palabras, una llamada a @code{\temporary \override} y a +continuación otra a @code{\revert} sobre la misma propiedad, tiene +un valor neto que es nulo. De forma similar, la combinación en +secuencia de @code{\temporary} y @code{\undo} sobre la misma +música que contiene las sobreescrituras, tiene un efecto neto +nulo. + +He aquí un ejemplo de una función musical que utiliza lo expuesto +anteriormente. El uso de @code{\temporary} asegura que los +valores de las propiedades @code{cross-staff} y @code{style} se +restauran a la salida a los valores que tenían cuando se llamó a +la función @code{crossStaff}. Sin @code{\temporary}, a la salida +se habrían fijado los valores predeterminados. + +@example +crossStaff = +#(define-music-function (parser location notes) (ly:music?) + (_i "Create cross-staff stems") + #@{ + \temporary \override Stem.cross-staff = #cross-staff-connect + \temporary \override Flag.style = #'no-flag + #notes + \revert Stem.cross-staff + \revert Flag.style +#@}) +@end example + @node Matemáticas dentro de las funciones @subsection Matemáticas dentro de las funciones @@ -447,14 +548,14 @@ AltOn = (parser location mag) (number?) #{ - \override Stem #'length = #(* 7.0 mag) - \override NoteHead #'font-size = + \override Stem.length = #(* 7.0 mag) + \override NoteHead.font-size = #(inexact->exact (* (/ 6.0 (log 2.0)) (log mag))) #}) AltOff = { - \revert Stem #'length - \revert NoteHead #'font-size + \revert Stem.length + \revert NoteHead.font-size } \relative c' { @@ -473,12 +574,12 @@ withAlt = (parser location mag music) (number? ly:music?) #{ - \override Stem #'length = #(* 7.0 mag) - \override NoteHead #'font-size = + \override Stem.length = #(* 7.0 mag) + \override NoteHead.font-size = #(inexact->exact (* (/ 6.0 (log 2.0)) (log mag))) #music - \revert Stem #'length - \revert NoteHead #'font-size + \revert Stem.length + \revert NoteHead.font-size #}) \relative c' { @@ -508,7 +609,7 @@ mostrarNumeroDeCompas = (parser location) () (if (eq? #t (ly:get-option 'display-bar-numbers)) - #@{ \once \override Score.BarNumber #'break-visibility = ##f #@} + #@{ \once \override Score.BarNumber.break-visibility = ##f #@} #@{#@})) @end example @@ -579,22 +680,49 @@ argumentos. @translationof Markup construction in Scheme @cindex marcado, definir instrucciones de +@funindex \displayScheme -El macro @code{markup} construye expresiones de marcado en Scheme, -proporcionando una sintaxis similar a la de LilyPond. Por ejemplo: +Las expresiones de marcado se representan internamente en Scheme +usando el macro @code{markup}: @example -(markup #:column (#:line (#:bold #:italic "hola" #:raise 0.4 "mundo") - #:larger #:line ("fulano" "fulanito" "menganito"))) +(markup @var{expr}) +@end example + +Para ver una expresión de marcado en su forma de Scheme, utilice +la instrucción @code{\displayScheme}: + +@example +\displayScheme +\markup @{ + \column @{ + \line @{ \bold \italic "hola" \raise #0.4 "mundo" @} + \larger \line @{ fulano fulanito menganito @} + @} +@} @end example @noindent -equivale a: +La compilación del código anterior envía a la consola lo +siguiente: + @example -#@{ \markup \column @{ \line @{ \bold \italic "hola" \raise #0.4 "mundo" @} - \larger \line @{ fulano fulanito menganito @} @} #@} +(markup + #:line + (#:column + (#:line + (#:bold (#:italic "hola") #:raise 0.4 "mundo") + #:larger + (#:line + (#:simple "fulano" #:simple "fulanito" #:simple "menganito"))))) @end example +Para evitar que el marcado se imprima en la página, use +@w{@samp{\void \displayScheme @var{marcado}}}. Asimismo, como +ocurre con la instrucción @code{\displayMusic}, la salida de +@code{\displayScheme} se puede guardar en un archivo externo. +Véase @ref{Presentación de las expresiones musicales}. + @noindent Este ejemplo muestra las principales reglas de traducción entre la sintaxis del marcado normal de LilyPond y la sintaxis del marcado de @@ -607,11 +735,12 @@ sólo con Scheme. @multitable @columnfractions .3 .3 @item @b{LilyPond} @tab @b{Scheme} @item @code{\markup marcado1} @tab @code{(markup marcado1)} -@item @code{\markup @{ marcado1 marcado2 ... @}} @tab - @code{(markup marcado1 marcado2 ... )} +@item @code{\markup @{ marcado1 marcado2 @dots{} @}} @tab + @code{(markup marcado1 marcado2 @dots{} )} @item @code{\instruccion} @tab @code{#:instruccion} @item @code{\variable} @tab @code{variable} -@item @code{\center-column @{ ... @}} @tab @code{#:center-column ( ... )} +@item @code{\center-column @{ @dots{} @}} @tab + @code{#:center-column ( @dots{} )} @item @code{cadena} @tab @code{"cadena"} @item @code{#argumento-de-scheme} @tab @code{argumento-de-scheme} @end multitable @@ -702,11 +831,11 @@ Se pueden definir instrucciones de marcado nuevas usando el macro de Scheme @code{define-markup-command}, en el nivel sintáctico superior. @lisp -(define-markup-command (@var{nombre-de-la-instruccion} @var{layout} @var{props} @var{arg1} @var{arg2} ...) - (@var{tipo-de-arg1?} @var{tipo-de-arg2?} ...) +(define-markup-command (@var{nombre-de-la-instruccion} @var{layout} @var{props} @var{arg1} @var{arg2} @dots{}) + (@var{tipo-de-arg1?} @var{tipo-de-arg2?} @dots{}) [ #:properties ((@var{propiedad1} @var{valor-predeterminado1}) - ...) ] - ..command body..) + @dots{}) ] + @dots{}command body@dots{}) @end lisp Los argumentos son @@ -945,7 +1074,7 @@ documentación): (number-pair?) #:category graphic #:properties ((thickness 1)) - "...documentación..." + "@dots{}documentación@dots{}" (let ((th (* (ly:output-def-lookup layout 'line-thickness) thickness)) (x (car dest)) @@ -963,7 +1092,7 @@ instrucciones de marcado definidas por el usuario. (define-markup-command (draw-double-line layout props dest) (number-pair?) #:properties ((thickness 1)) - "...documentación..." + "@dots{}documentación@dots{}" (let ((th (* (ly:output-def-lookup layout 'line-thickness) thickness)) (x (car dest)) @@ -980,8 +1109,8 @@ predeterminado de p.ej. 0.6: (number-pair?) #:properties ((thickness 1) (line-gap 0.6)) - "...documentación..." - ... + "@dots{}documentación@dots{}" + @dots{} @end lisp Finalmente, se añade el código para trazar las dos líneas. Se usan @@ -1132,14 +1261,14 @@ funciona insertando un evento dentro del contexto especificado (@rinternals{ApplyOutputEvent}). Su sintaxis es @example -\applyOutput @var{contexto} @var{proc} +\applyOutput @var{Contexto} @var{proc} @end example @noindent donde @code{@var{proc}} es una función de Scheme que toma tres argumentos. Al interpretarse, la función @code{@var{proc}} se llama para cada objeto de -presentación que se encuentra en el contexto @code{@var{contexto}} +presentación que se encuentra en el contexto @code{@var{Contexto}} en el tiempo actual, con los siguientes argumentos: @itemize @@ -1169,6 +1298,14 @@ cabezas de las notas que están sobre la línea central y junto a ella: } @end lilypond +Para que @var{función} se interprete en los niveles de @code{Score} o de @code{Staff} +utilice estas formas: + +@example +\applyOutput #'Score #@var{función} +\applyOutput #'Staff #@var{función} +@end example + @node Funciones de callback @section Funciones de callback @@ -1179,13 +1316,13 @@ Las propiedades (como @code{thickness} (grosor), @code{direction} p. ej.: @example -\override Stem #'thickness = #2.0 +\override Stem.thickness = #2.0 @end example Las propiedades pueden fijarse también a un procedimiento de Scheme, @lilypond[fragment,verbatim,quote,relative=2] -\override Stem #'thickness = #(lambda (grob) +\override Stem.thickness = #(lambda (grob) (if (= UP (ly:grob-property grob 'direction)) 2.0 7.0)) @@ -1264,7 +1401,7 @@ La principal desventaja de @code{\tweak} es su inflexibilidad sintáctica. Por ejemplo, lo siguiente produce un error de sintaxis. @example -F = \tweak #'font-size #-3 -\flageolet +F = \tweak font-size #-3 -\flageolet \relative c'' @{ c4^\F c4_\F @@ -1362,7 +1499,7 @@ arriba. (ly:grob-set-property! grob 'extra-offset '(-2 . 5))))) \relative c'' { - \override Tie #'after-line-breaking = + \override Tie.after-line-breaking = #my-callback c1 ~ \break c2 ~ c @@ -1385,9 +1522,10 @@ razones técnicas. Son ejemplos @code{NonMusicalPaperColumn} y @example \overrideProperty -#"Score.NonMusicalPaperColumn" % Nombre del grob -#'line-break-system-details % Nombre de la propiedad -#'((next-padding . 20)) % Valor +Score.NonMusicalPaperColumn % Nombre del grob + . line-break-system-details % Nombre de la propiedad + . next-padding % Nombre de la subpropiedad, opcional + #20 % Valor @end example Observe, sin embargo, que @code{\override}, aplicado a