@c -*- coding: utf-8; mode: texinfo; documentlanguage: es -*- @c This file is part of lilypond.tely @ignore Translation of GIT committish: 4a527608c5ff2ce31e596495d00dce181dc1b9ea 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.11.61" @node Interfaces for programmers @chapter Interfaces for programmers Se pueden realizar trucos avanzados mediante el uso de Scheme. Si no está familizarizado con Scheme, le conviene leer nuestro tutorial de Scheme, @rlearning{Scheme tutorial}. @menu * Music functions:: * Programmer interfaces:: * Building complicated functions:: * Markup programmer interface:: * Contexts for programmers:: * Scheme procedures as properties:: * Using Scheme code instead of \tweak:: * Difficult tweaks:: @end menu @node Music functions @section Music functions Esta sección trata sobre cómo crear funciones musicales dentro de LilyPond. @menu * Overview of music functions:: * Simple substitution functions:: * Paired substitution functions:: * Mathematics in functions:: * Void functions:: * Functions without arguments:: * Overview of available music functions:: @end menu @node Overview of music functions @subsection Overview of music functions Es fácil hacer una función que sustituya a una variable en código de LilyPond. La forma general de estas funciones es: @example funcion = #(define-music-function (parser location @var{var1} @var{var2}... ) (@var{var1-type?} @var{var2-type?}...) #@{ @emph{...música...} #@}) @end example @noindent donde @multitable @columnfractions .33 .66 @item @var{argi} @tab @var{i}-ésima variable @item @var{argi-type?} @tab tipo de variable @item @var{...música...} @tab entrada normal de LilyPond, usando las variables como @code{#$var1}. @end multitable Los siguientes tipos de entrada se pueden usar como variables en una función musical. Esta lista no es exhaustiva; consulte otros lugares de la documentación específica de Scheme para ver otros tipos de variables. @multitable @columnfractions .33 .66 @headitem Tipo de entrada @tab notación de @var{argi-type?} @item Entero @tab @code{integer?} @item Flotante (número decimal) @tab @code{number?} @item Cadena de texto @tab @code{string?} @item Marcado @tab @code{markup?} @item Expresión musical @tab @code{ly:music?} @item Pareja de variables @tab @code{pair?} @end multitable Los argumentos @code{parser} y @code{location} son obligatorios, y se usan en ciertas situaciones avanzadas. El argumento @code{parser} se usa para acceder al valor de otra variable de LilyPond. El argumento @code{location} se usa para establecer el @q{origen} de la expresión musical que construye la función musical, de forma que en caso de producirse un error de sintaxis LilyPond pueda informar al usuario de un lugar adecuado donde buscar en el archivo de entrada. @node Simple substitution functions @subsection Simple substitution functions He aquí un ejemplo sencillo: @lilypond[quote,verbatim,ragged-right] padText = #(define-music-function (parser location padding) (number?) #{ \once \override TextScript #'padding = #$padding #}) \relative c''' { c4^"piu mosso" b a b \padText #1.8 c4^"piu mosso" d e f \padText #2.6 c4^"piu mosso" fis a g } @end lilypond También se pueden sustituir las expresiones musicales: @lilypond[quote,verbatim,ragged-right] custosNote = #(define-music-function (parser location note) (ly:music?) #{ \once \override Voice.NoteHead #'stencil = #ly:text-interface::print \once \override Voice.NoteHead #'text = \markup \musicglyph #"custodes.mensural.u0" \once \override Voice.Stem #'stencil = ##f $note #}) { c' d' e' f' \custosNote g' } @end lilypond Se pueden usar más de una variable: @lilypond[quote,verbatim,ragged-right] tempoMark = #(define-music-function (parser location padding marktext) (number? string?) #{ \once \override Score . RehearsalMark #'padding = $padding \once \override Score . RehearsalMark #'extra-spacing-width = #'(+inf.0 . -inf.0) \mark \markup { \bold $marktext } #}) \relative c'' { c2 e \tempoMark #3.0 #"Allegro" g c } @end lilypond @node Paired substitution functions @subsection Paired substitution functions Algunas instrucciones @code{\override} requieren un par de números (llamados en Scheme una @code{célula cons}). Para pasar estos números a una función, usamos una variable @code{pair?} o bien insertamos el @code{cons} en la función musical. @quotation @example manualBeam = #(define-music-function (parser location beg-end) (pair?) #@{ \once \override Beam #'positions = #$beg-end #@}) \relative @{ \manualBeam #'(3 . 6) c8 d e f @} @end example @end quotation @noindent o bien @lilypond[quote,verbatim,ragged-right] manualBeam = #(define-music-function (parser location beg end) (number? number?) #{ \once \override Beam #'positions = #(cons $beg $end) #}) \relative { \manualBeam #3 #6 c8 d e f } @end lilypond @node Mathematics in functions @subsection Mathematics in functions Las funciones musicales pueden contar con programación de Scheme además de la simple sustitución: @lilypond[quote,verbatim,ragged-right] AltOn = #(define-music-function (parser location mag) (number?) #{ \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 } { c'2 \AltOn #0.5 c'4 c' \AltOn #1.5 c' c' \AltOff c'2 } @end lilypond @noindent Este ejemplo se puede reescribir de forma que pase expresiones musicales: @lilypond[quote,verbatim,ragged-right] withAlt = #(define-music-function (parser location mag music) (number? ly:music?) #{ \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 #}) { c'2 \withAlt #0.5 {c'4 c'} \withAlt #1.5 {c' c'} c'2 } @end lilypond @node Void functions @subsection Void functions Una función musical debe devolver una expresión musical, per a veces podemos necesitar una función en la que no hay música en juego (como la desactivación de la funcionalidad Apuntar y Pulsar). Para hacerlo, devolvemos una expresión musical @code{void} (vacía). Este es el motivo por el que la forma que se devuelve es @code{(make-music ...)}. Con el valor de la propiedad @code{'void} establecido a @code{#t}, le decimos al analizador que descarte la expresión musical devuelta. así, la parte importante de la función musical vacía es el proceso realizado por la función, no la expresión musical que se devuelve. @example noPointAndClick = #(define-music-function (parser location) () (ly:set-option 'point-and-click #f) (make-music 'SequentialMusic 'void #t)) ... \noPointAndClick % desactivar la funcionalidad Apuntar y Pulsar. @end example @node Functions without arguments @subsection Functions without arguments En casi todos los casos, una función sin argumentos se debe escribir con una variable: @example dolce = \markup@{ \italic \bold dolce @} @end example Sin embargo, en raras ocasiones puede ser de utilidad crear una función musical sin argumentos: @example displayBarNum = #(define-music-function (parser location) () (if (eq? #t (ly:get-option 'display-bar-numbers)) #@{ \once \override Score.BarNumber #'break-visibility = ##f #@} #@{#@})) @end example Para la imresión real de los números de compás donde se llama a esta función, invoque a @command{lilypond} con @example lilypond -d display-bar-numbers ARCHIVO.ly @end example @node Overview of available music functions @subsection Overview of available music functions @c fixme ; this should be move somewhere else? Las siguientes instrucciones son funciones musicales: @include identifiers.tely @node Programmer interfaces @section Programmer interfaces Esta sección contiene información sobre cómo mezclar LilyPond y Scheme. @menu * Input variables and Scheme:: * Internal music representation:: @end menu @node Input variables and Scheme @subsection Input variables and Scheme El formato de entrada contempla la noción de variables: en el ejemplo siguiente, se asigna una expresión musical a una variable con el nombre @code{traLaLa}. @example traLaLa = @{ c'4 d'4 @} @end example @noindent También existe una forma de ámbito léxico: en el ejemplo siguiente, el bloque @code{\layout} también contiene una variable @code{traLaLa}, que es independiente de la @code{\traLaLa} exterior. @example traLaLa = @{ c'4 d'4 @} \layout @{ traLaLa = 1.0 @} @end example @c De hecho, cada archivo de entrada es un ámbito léxico, y todos los bloques @code{\header}, @code{\midi} y @code{\layout} son ámbitos anidados dentro de dicho ámbito de nivel superior. Tanto el ámbito léxico como las variables están implementados en el sistema de módulos GUILE. Se adjunta un módulo anónimo de Scheme a cada ámbito. Una asignación de la forma @example traLaLa = @{ c'4 d'4 @} @end example @noindent se convierte internamente a una definición de Scheme @example (define traLaLa @var{Scheme value of `@code{... }'}) @end example Esto supone que las variables de entrada y las variables de Scheme se pueden intermezclar con libertad. En el ejemplo siguiente, se almacena un fragmento musical en la variable @code{traLaLa}, y se dupplica utilizando Scheme. El resultado se importa en un bloque @code{\score} por medio de una segunda variable @code{twice}: @lilypond[verbatim] traLaLa = { c'4 d'4 } %% dummy action to deal with parser lookahead #(display "this needs to be here, sorry!") #(define newLa (map ly:music-deep-copy (list traLaLa traLaLa))) #(define twice (make-sequential-music newLa)) { \twice } @end lilypond @c Due to parser lookahead En este ejemplo, la asignación se produce después de que el analizador sintáctico ha verificado que no ocurre nada interesante después de @code{traLaLa = @{ ... @}}. Sin el argumento mudo del ejemplo, la definición @code{newLa} se ejecuta antes de que se defina @code{traLaLa}, conduciendo a un error de sintaxis. El ejemplo anterior muestra cómo @q{exportar} expresiones musicales desde la entrada hasta el intérprete de Scheme. También es posible lo contrario. Envolviendo un valor de Scheme en la función @code{ly:export}, un valor de Scheme se interpreta como si hubiera sido introducido en sintaxis de LilyPond. En vez de definir @code{\twice}, el ejemplo anterior podría también haberse escrito como @example @dots{} @{ #(ly:export (make-sequential-music (list newLa))) @} @end example El sódigo de Scheme se evalúa tan pronto como el analizador sintáctico lo encuentra. Para definir código de Scheme en un macro (para llamarlo con posterioridad), use @ref{Void functions}, o bien @example #(define (nopc) (ly:set-option 'point-and-click #f)) ... #(nopc) @{ c'4 @} @end example @knownissues No es posible mezclar variables de Scheme y de LilyPond con la opción @code{--safe}. @node Internal music representation @subsection Internal music representation Cuando se analiza sintácticamente una expresión musical, se convierte en un conjunto de objetos musicales de Scheme. La propiedad que define a un objeto musical es que tiene una cierta duración. El tiempo es un número racional que mide la longitud de un fragmento de música en unidades del valor de una redonda. Un objeto musical tiene tres clases de tipos: @itemize @item nombre musical: cada expresión musical tiene un nombre. Por ejemplo, una nota conduce a un evento @rinternals{NoteEvent}, y @code{\simultaneous} conduce a @rinternals{SimultaneousMusic}. Hay una lista de todas las expresiones que están disponibles en el Manual de referencia de funcionamiento interno, bajo @rinternals{Music expressions}. @item @q{typo} o intterface: cada nombre de música tiene varios @q{tipos} o interfaces, por ejemplo una nota es un @code{event}, pero también es un @code{note-event}, un @code{rhythmic-event} y un @code{melodic-event}. Todas las clases musicales se encuentran relacionadas en la Referencia de funcionamiento interno bajo @rinternals{Music classes}. @item Objeto de C++: cada objeto musical está representado por un objeto de la clase de C++ @code{Music}. @end itemize La información real de una expresión musical se almacena en forma de propiedades. Por ejemplo, un evento @rinternals{NoteEvent} tiene propiedades @code{pitch} y @code{duration} que almacenan la altura y duración de la nota. Hay una lista completa de las propiedades que están disponibles en la Referencia de funcionamiento interno, bajo @rinternals{Music properties}. Una expresión musical compuesta es un objeto musical que contiene otros objetos musicales en sus propiedades. Se puede almacernar una lista de objetos en la propiedad @code{elements} de un objeto musical, o un solo objeto musical @q{hijo} en la propiedad @code{element}. Por ejemplo, @rinternals{SequentialMusic} tiene sus hijos en @code{elements}, y @rinternals{GraceMusic} tiene su elemento único en @code{element}. El cuerpo de una repetición se almacena en la propiedad @code{element} de @rinternals{RepeatedMusic}, y las alternativas en @code{elements}. @node Building complicated functions @section Building complicated functions Esta sección explica cómo reunir la información necesaria para crear funciones musicales complejas. @menu * Displaying music expressions:: * Music properties:: * Doubling a note with slurs (example):: * Adding articulation to notes (example):: @end menu @node Displaying music expressions @subsection Displaying music expressions @cindex interno, almacenamiento @funindex \displayMusic Si se está escribiendo una función musical puede ser muy instructivo examinar cómo se almacena internamente una expresión musical. Esto se puede hacer con la función musical @code{\displayMusic}: @example @{ \displayMusic @{ c'4\f @} @} @end example @noindent imprime lo siguiente: @example (make-music 'SequentialMusic 'elements (list (make-music 'EventChord 'elements (list (make-music 'NoteEvent 'duration (ly:make-duration 2 0 1 1) 'pitch (ly:make-pitch 0 0 0)) (make-music 'AbsoluteDynamicEvent 'text "f"))))) @end example De forma predeterminada, LilyPond imprime estos mensajes en la consola junto al resto de los mensajes. Para discernir entre estos mensajes y guardar el resultado de @code{\display@{MATERIAL@}}, redirija la salida hacia un archivo. @example lilypond archivo.ly >resultado.txt @end example Con la aplicación de un poco de formato, la inforamción anterior es fácil de leer: @example (make-music 'SequentialMusic 'elements (list (make-music 'EventChord 'elements (list (make-music 'NoteEvent 'duration (ly:make-duration 2 0 1 1) 'pitch (ly:make-pitch 0 0 0)) (make-music 'AbsoluteDynamicEvent 'text "f"))))) @end example Una secuencia musical @code{@{ ... @}} tiene el nombre @code{SequentialMusic}, y sus expresiones internas se almacenan como una lista en su propiedad @code{'elements}. Una nota se representa como una expresión @code{EventChord} que contiene un objeto @code{NoteEvent} (que almacena las propiedades de duración y altura) y cualquier otra información adicional (en este caso, un evento @code{AbsoluteDynamicEvent} con una porpiedad de texto @code{"f"}. @node Music properties @subsection Music properties El objeto @code{NoteEvent} es el primer objeto de la propiedad @code{'elements} de @code{someNote}. @example unaNota = c' \displayMusic \unaNota ===> (make-music 'EventChord 'elements (list (make-music 'NoteEvent 'duration (ly:make-duration 2 0 1 1) 'pitch (ly:make-pitch 0 0 0)))) @end example La función @code{display-scheme-music} es la función utilizada por @code{\displayMusic} para imprimir la representación de Scheme de una expresión musical. @example #(display-scheme-music (first (ly:music-property unaNota 'elements))) ===> (make-music 'NoteEvent 'duration (ly:make-duration 2 0 1 1) 'pitch (ly:make-pitch 0 0 0)) @end example Después se accede a la altura de la nota a través de la propiedad @code{'pitch} del objeto @code{NoteEvent}: @example #(display-scheme-music (ly:music-property (first (ly:music-property unaNota 'elements)) 'pitch)) ===> (ly:make-pitch 0 0 0) @end example La altura de la nota se puede cambiar estableciendo el valor de esta propiedad 'pitch: @funindex \displayLilyMusic @example #(set! (ly:music-property (first (ly:music-property unaNota 'elements)) 'pitch) (ly:make-pitch 0 1 0)) ;; fijar la altura a d'. \displayLilyMusic \unaNota ===> d' @end example @node Doubling a note with slurs (example) @subsection Doubling a note with slurs (example) Supongamos que queremos crear una función que traduce una entrada como @code{a} a algo como @code{a( a)}. Empezamos examinando la representación interna de la música con la que queremos terminar. @example \displayMusic@{ a'( a') @} ===> (make-music 'SequentialMusic 'elements (list (make-music 'EventChord 'elements (list (make-music 'NoteEvent 'duration (ly:make-duration 2 0 1 1) 'pitch (ly:make-pitch 0 5 0)) (make-music 'SlurEvent 'span-direction -1))) (make-music 'EventChord 'elements (list (make-music 'NoteEvent 'duration (ly:make-duration 2 0 1 1) 'pitch (ly:make-pitch 0 5 0)) (make-music 'SlurEvent 'span-direction 1))))) @end example Las malas noticias son que las espresiones @code{SlurEvent} se deben añadir @q{dentro} de la nota (o más concretamente, dentro de la expresión @code{EventChord}). Ahora observamos la entrada: @example (make-music 'SequentialMusic 'elements (list (make-music 'EventChord 'elements (list (make-music 'NoteEvent 'duration (ly:make-duration 2 0 1 1) 'pitch (ly:make-pitch 0 5 0)))))) @end example Así pues, en nuestra función, tenemos que clonar esta expresión (de forma que tengamos dos notas para construir la secuencia), añadir @code{SlurEvents} a la propiedad @code{'elements} de cada una de ellas, y por último hacer una secuencia @code{SequentialMusic} con los dos @code{EventChords}. @example doubleSlur = #(define-music-function (parser location note) (ly:music?) "Return: @{ note ( note ) @}. `note' is supposed to be an EventChord." (let ((note2 (ly:music-deep-copy note))) (set! (ly:music-property note 'elements) (cons (make-music 'SlurEvent 'span-direction -1) (ly:music-property note 'elements))) (set! (ly:music-property note2 'elements) (cons (make-music 'SlurEvent 'span-direction 1) (ly:music-property note2 'elements))) (make-music 'SequentialMusic 'elements (list note note2)))) @end example @node Adding articulation to notes (example) @subsection Adding articulation to notes (example) La manera fácil de añadir articulación a las notas es fundir dos expresiones musicales en un contexto único, como está explicado en @ref{Creating contexts}. Sin embargo, suponga que queremos escribir una función musical que haga esto. Una @code{$variable} dentro de la notación @code{#@{...#@}} es como usar una @code{\variable} normal en la notación clásica de LilyPond. Sabemos que @example @{ \musica -. -> @} @end example @noindent no funciona en LilyPond. Podemos evitar este problema adjuntando la articulación a una nota de mentira, @example @{ << \musica s1*0-.-> @} @end example @noindent pero a los efectos de este ejemplo, aprenderemos ahora cómo hacerlo en Scheme. Comenzamos examinando nuestra entrada y la salida deseada: @example % entrada \displayMusic c4 ===> (make-music 'EventChord 'elements (list (make-music 'NoteEvent 'duration (ly:make-duration 2 0 1 1) 'pitch (ly:make-pitch -1 0 0)))) ===== % salida deseada \displayMusic c4-> ===> (make-music 'EventChord 'elements (list (make-music 'NoteEvent 'duration (ly:make-duration 2 0 1 1) 'pitch (ly:make-pitch -1 0 0)) (make-music 'ArticulationEvent 'articulation-type "marcato"))) @end example Vemos que una nota (@code{c4}) se representa como una expresión @code{EventChord}, con una expresión @code{NoteEvent} en su lista de elementos. Para añadir una articulación marcato, se debe añadir una expresión @code{ArticulationEvent} a la propiedad elementos de la expresión @code{EventChord}. Para construir esta función, empezamos con @example (define (add-marcato event-chord) "Añadir una ArticulationEvent de marcato a los elementos de `event-chord', que se ssupone que es una expresión EventChord." (let ((result-event-chord (ly:music-deep-copy event-chord))) (set! (ly:music-property result-event-chord 'elements) (cons (make-music 'ArticulationEvent 'articulation-type "marcato") (ly:music-property result-event-chord 'elements))) result-event-chord)) @end example La primera línea es la forma de definir una función en Scheme: el nombre de la función es @code{add-marcato}, y tiene una variable llamada @code{event-chord}. En Scheme, el tipo de variable suele quedar claro a partir de su nombre (¡esto también es una buena práctica en otros lenguajes de programación!). @example "Añadir una ArticulationEvent de marcato..." @end example @noindent es una descripción de lo que hace la función. No es estrictamente necesario, pero como los nombres de variable claros, es una buena práctica. @example (let ((result-event-chord (ly:music-deep-copy event-chord))) @end example @code{let} se usa para declarar variables locales. Aquí usamos una variable local, llamada @code{result-event-chord}, a la que le damos el valor @code{(ly:music-deep-copy event-chord)}. @code{ly:music-deep-copy} es una función específica de LilyPond, como todas las funciones que comienzan por @code{ly:}. Se usa para hacer una copia de una expresión musical. Aquí, copiamos @code{event-chord} (el parámetro de la función). Recuerde que el propósito es añadir un marcato a una expresión @code{EventChord}. Es mejor no modificar el @code{EventChord} que se dio como argumento, porque podría utilizarse en algún otro lugar. Ahora tenemos un @code{result-event-chord}, que es una expresión @code{NoteEventChord} y es una copia de @code{event-chord}. Añadimos el marcato a su propiedad lista de elementos. @example (set! place new-value) @end example Aquí, lo que queremos establecer (el @q{place}) es la propiedad @q{elements} de la expresión @code{result-event-chord}. @example (ly:music-property result-event-chord 'elements) @end example @code{ly:music-property} es la función que se usa para acceder a las propiedades musicales (los @code{'elements}, @code{'duration}, @code{'pitch}, etc., que vemos en la salida de @code{\displayMusic} más arriba). El nuevo valor es la anterior propiedad elements, con un elemento adicional: la expresión @code{ArticulationEvent}, que copiamos a partir de la salida de @code{\displayMusic}, @example (cons (make-music 'ArticulationEvent 'articulation-type "marcato") (ly:music-property result-event-chord 'elements)) @end example @code{cons} se usa para añadir un elemento a una lsita sin modificar la lista original. Esto es lo que queremos: la misma lista que antes, más la nueva expresión @code{ArticulationEvent}. El orden dentro de la propiedad elements no es importante aquí. Finalmente, una vez añadida la articulación marcato a su propiedad @code{elements}, podemos devolver @code{result-event-chord}, de aquí la última línea de la función. Ahora transformamos la función @code{add-marcato} en una función musical, @example addMarcato = #(define-music-function (parser location event-chord) (ly:music?) "Add a marcato ArticulationEvent to the elements of `event-chord', which is supposed to be an EventChord expression." (let ((result-event-chord (ly:music-deep-copy event-chord))) (set! (ly:music-property result-event-chord 'elements) (cons (make-music 'ArticulationEvent 'articulation-type "marcato") (ly:music-property result-event-chord 'elements))) result-event-chord)) @end example Podemos verificar que esta función musical funciona correctamente, @example \displayMusic \addMarcato c4 @end example @node Markup programmer interface @section Markup programmer interface Los marcados están implementados como funciones de Scheme especiales que producen un elemento Stencil (sello) dado un número de argumentos. @menu * Markup construction in Scheme:: * How markups work internally:: * New markup command definition:: * New markup list command definition:: @end menu @node Markup construction in Scheme @subsection Markup construction in Scheme @cindex marcado, definir instrucciones de El macro @code{markup} construye expresiones de marcado en Scheme, proporcionando una sintaxis similar a la de LilyPond. Por ejemplo: @example (markup #:column (#:line (#:bold #:italic "hola" #:raise 0.4 "mundo") #:larger #:line ("fulano" "fulanito" "menganito"))) @end example @noindent equivale a: @example \markup \column @{ \line @{ \bold \italic "hola" \raise #0.4 "mundo" @} \larger \line @{ fulano fulanito menganito @} @} @end example @noindent Este ejemplo muestra las principales reglas de traducción entre la sitaxis del marcado normal de LilyPond y la sintaxis del marcado de Scheme. @quotation @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{\instruccion} @tab @code{#:instruccion} @item @code{\variable} @tab @code{variable} @item @code{\center-column @{ ... @}} @tab @code{#:center-column ( ... )} @item @code{cadena} @tab @code{"cadena"} @item @code{#argumento-de-scheme} @tab @code{argumento-de-scheme} @end multitable @end quotation Todo el lenguaje Scheme está accesible dentro del macro @code{markup}. Por ejemplo, podemos usar llamadas a funciones dentro de @code{markup} para así manipular cadenas de caracteres. Esto es útil si se están definiendo instrucciones de marcado nuevas (véase @ref{New markup command definition}). @knownissues El argumento markup-list de instrucciones como @code{#:line}, @code{#:center} y @code{#:column} no pueden se una variable o el resultado de la llamada a una función. @lisp (markup #:line (funcion-que-devuelve-marcados)) @end lisp @noindent no es válido. Hay que usar las funciones @code{make-line-markup}, @code{make-center-markup} o @code{make-column-markup} en su lugar: @lisp (markup (make-line-markup (funcion-que-devuelve-marcados))) @end lisp @node How markups work internally @subsection How markups work internally @untranslated @node New markup command definition @subsection New markup command definition @untranslated @node New markup list command definition @subsection New markup list command definition @untranslated @node Contexts for programmers @section Contexts for programmers @untranslated @menu * Context evaluation:: * Running a function on all layout objects:: @end menu @node Context evaluation @subsection Context evaluation @untranslated @node Running a function on all layout objects @subsection Running a function on all layout objects @untranslated @node Scheme procedures as properties @section Scheme procedures as properties @untranslated @node Using Scheme code instead of \tweak @section Using Scheme code instead of @code{\tweak} @untranslated @node Difficult tweaks @section Difficult tweaks @untranslated