]> git.donarmstrong.com Git - lilypond.git/blobdiff - Documentation/es/extending/programming-interface.itely
Imported Upstream version 2.16.0
[lilypond.git] / Documentation / es / extending / programming-interface.itely
index a1f552d15fd4d218884563c124e83c626ca1a17c..50512440e98d971d0c28f2c2e9c382ccbc1c962b 100644 (file)
@@ -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: 7ba0a22641cb0c7f5949d66a06d1e2e1fd0b3033
+    Translation of GIT committish: 3c169262c8f580c0f42c09f3a61b9ae9f0d6261c
 
     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.14.0"
+@c \version "2.16.0"
 
 @node Interfaces para programadores
 @chapter Interfaces para programadores
@@ -19,7 +19,10 @@ Scheme, @ref{Tutorial de Scheme}.
 
 
 @menu
+* Bloques de código de LilyPond::
+* Funciones de Scheme::
 * Funciones musicales::
+* Funciones de eventos::
 * Funciones de marcado::
 * Contextos para programadores::
 * Funciones de callback::
@@ -27,67 +30,300 @@ Scheme, @ref{Tutorial de Scheme}.
 * Trucos difíciles::
 @end menu
 
-@node Funciones musicales
-@section Funciones musicales
-@translationof Music functions
+@node Bloques de código de LilyPond
+@section Bloques de código de LilyPond
+@translationof Lilypond code blocks
 
-Las @emph{funciones musicales} son procedimientos de Scheme
-que pueden crear automáticamente expresiones musicales, y se
-pueden usar para simplificar enormemente el archivo de entrada.
+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.
+
+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
+bloque de LilyPond vacío corresponde a una expresión musical vacía, y
+un bloque de LilyPond que contiene varios eventos musicales se
+convierte en una expresión de música secuencial.
+
+@node Funciones de Scheme
+@section Funciones de Scheme
+@translationof Scheme functions
+@cindex Scheme, funciones de (sintaxis de LilyPond)
+
+Las @emph{funciones de Scheme} son procedimientos de Scheme que pueden
+crear expresiones de Scheme a partir de código de entrada escrito en
+la sintaxis de LilyPond.  Se pueden llamar desde prácticamente
+cualquier lugar en el que se permita el uso de @code{#} para la
+especificación de un valor en sintaxis de Scheme.  Mientras que Scheme
+tiene funciones propias, este capítulo se ocupa de las funciones
+@emph{sintácticas}, funciones que reciben argumentos especificados en
+la sintaxis de LilyPond.
 
 @menu
-* Sintaxis de las funciones musicales::
-* Funciones de sustitución sencillas::
-* Funciones de sustitución intermedias::
-* Matemáticas dentro de las funciones::
-* Funciones sin argumentos::
-* Funciones vacías::
+* Definición de funciones de Scheme::
+* Uso de las funciones de Scheme::
+* Funciones de Scheme vacías::
 @end menu
 
-@node Sintaxis de las funciones musicales
-@subsection Sintaxis de las funciones musicales
-@translationof Music function syntax
+@node Definición de funciones de Scheme
+@subsection Definición de funciones de Scheme
+@translationof Scheme function definitions
+@funindex define-scheme-function
 
-La forma general de una función musical es:
+La forma general de la definición de una función de Scheme es:
 
 @example
 funcion =
-#(define-music-function
+#(define-scheme-function
      (parser location @var{arg1} @var{arg2} @dots{})
-     (@var{type1?} @var{type2?} @dots{})
-   @var{música})
+     (@var{tipo1?} @var{tipo2?} @dots{})
+   @var{cuerpo})
 @end example
 
 @noindent
 donde
 
 @multitable @columnfractions .33 .66
+@item @code{parser}
+@tab tiene que ser literalmente @code{parser} para dar a los bloques de código
+de LilyPond (@code{#@{}@dots{}@code{#@}}) acceso al analizador
+sintáctico.
+
 @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}}
-deve devolver @code{#t}.
-
-@item @code{@var{música}}
-@tab una expresión musical, opcionalmente escrita en Scheme, con
-el código de LilyPond que pudiera tener, encerrado entre llaves
-con almohadilla
-(@tie{}@w{@code{#@{@dots{}#@}}}@tie{}).  Dentro de los bloques
-de código de LilyPond, use @code{$} para referenciar a los argumentos
-de la función (p. ej. @samp{$arg1})
-o para iniciar una expresión en línea de Scheme
-que contenga argumentos de función
-(p.ej., @w{@samp{$(cons arg1 arg2)}}).
-
+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
+última forma de la secuencia se usa como el valor de retorno de la
+función de Scheme. Puede contener bloques de código de LilyPond
+encerrados entre llaves con almohadillas
+(@tie{}@w{@code{#@{@dots{}#@}}}@tie{}), como se describe en
+@ref{Bloques de código de LilyPond}.  Dentro de los bloques de código
+de LilyPond, use el símbolo @code{#} para hacer referencia a
+argumentos de función (p.ej. @samp{#arg1}) o para iniciar una
+expresión en línea de Scheme que contenga argumentos de función
+(p.ej. @w{@samp{#(cons arg1 arg2)}}).  Donde las expresiones de Scheme
+normales que usan @code{#} no funcionan, podríamos necesitar volver a
+expresiones de Scheme inmediatas que usan @code{$}, como por ejemplo
+@samp{$music}.
+
+Si nuestra función devuelve una expresión musical, recibe un valor
+@code{origin} útil.
 @end multitable
 
 @noindent
+Ciertos predicados de tipo se manejan de forma especial por parte del
+analizador sintáctico ya que de otro modo éste no es capaz de
+reconocer los argumentos eficientemente.  Actualmente son
+@code{ly:pitch?} y @code{ly:duration?}.
+
+La idoneidad de lpos argumentos para el resto de los predicados viene
+determinada mediante llamadas reales al predicado después de que
+LilyPond ya las ha convertido en una expresión de Scheme.  Como
+consecuencia, el argumento se puede especificar en la sintaxis de
+Scheme si se desea (precedido de @code{#} o como resultado de haber
+llamado a una función de Scheme), pero LilyPond también convierte
+algunas construcciones de LilyPond en Scheme antes de hacer
+efectivamente la comprobación del predicado sobre ellas.  Actualmente
+se encuentran entre ellas la música, los post-eventos, las cadenas
+simples (entrecomilladas o no), los números, los elementos de marcado
+y de listas de marcado, score (partitura), book (libro), bookpart
+(parte de libro), las definiciones de contexto y los bloques de
+definición de salida.
+
+Para ciertos tipos de expresión (como la mayor parte de la música que
+no está encerrada entre llaves) LilyPond necesita más allá de la
+expresión misma para poder determinar su final.  Si tal expresión se
+considerase un argumento opcional mediante la evaluación de su
+predicado, LilyPond no podría recuperarse después de decidir que la
+expresión no se corresponde con el parámetro.  Así, ciertas formas de
+música necesitan ir encerradas entre llaves para que LilyPond pueda
+aceptarlas.  Existen también otras ambigüedades que LilyPond resuelve
+mediante la comprobación con funciones de predicado: ¿es @samp{-3} un
+post-evento de digitación o un nnúmero negativo?  ¿Es @code{"a" 4} en
+el modo de letra una cadena seguida por un número, o un evento de
+letra con la duración @code{4}?  LilyPond lo decide preguntándole a
+los predicados.  Ello significa que un debemos evitar los
+predicados permisivos como @code{scheme?} si tenemos en mente
+un uso particular en vez de una función de uso general.
+
 Para ver una lista de los predicados de tipo disponibles, consulte
 @ruser{Predicados de tipo predefinidos}.
-También se permiten predicados de tipo definidos por el usuario.
+
+@seealso
+
+Referencia de la notación:
+@ruser{Predicados de tipo predefinidos}.
+
+Archivos instalados:
+@file{lily/music-scheme.cc},
+@file{scm/c++.scm},
+@file{scm/lily.scm}.
+
+
+@node Uso de las funciones de Scheme
+@subsection Uso de las funciones de Scheme
+@translationof Scheme function usage
+
+Las funciones de Scheme se pueden llamar casi desde cualquier lugar en
+que puede escribirse una expresión de Scheme que comience con la
+almohadilla@tie{}@code{#}.  Llamamos a una función de Scheme
+escribiendo su nombre precedido de la barra invertida@tie{}@code{\}, y
+seguido por sus argumentos.  Una vez que un argumento opcional no
+corresponde a ningún argumento, LilyPond se salta este argumento y
+todos los que le siguen, sustituyéndolos por su valor por omisión
+especificado, y @q{recupera} el argumento que no correspondía al lugar
+del siguiente argumento obligatorio.  Dado que el argumento recuperado
+necesita ir a algún lugar, los argumentos opcionales no se consideran
+realmente opcionales a no ser que vayan seguidos de un argumento
+obligatorio.
+
+Existe una excepción: si escribimos @code{\default} en el lugar de un
+argumento opcional, este argumento y todos los argumentos opcionales
+que le siguen se saltan y se sustituyen por sus valores
+predeterminados.  Esto funciona incluso si no sigue ningún argumento
+obligatorio porque @code{\default} no necesita recuperarse.  Las
+instrucciones @code{mark} y @code{key} hacen uso de este truco para
+ofrecer su comportamiento predeterminado cuando van seguidas solamente
+por @code{\default}.
+
+Aparte de los lugares en que se requiere un valor de Scheme hay
+ciertos sitios en que se aceptan expresiones de almohadilla @code{#} y
+se evalúan por sus efectos secundarios, pero por lo demás se ignoran.
+Son, mayormente, los lugares en que también sería aceptable colocar
+una asignación.
+
+Dado que no es buena idea devolver valores que puedan malinterpretarse
+en algún contexto, debería usar funciones de Scheme normales solo para
+los casos en que siempre se devuelve un valor útil, y usar funciones
+de Scheme vacías (@pxref{Funciones de Scheme vacías}) en caso
+contrario.
+
+
+@node Funciones de Scheme vacías
+@subsection Funciones de Scheme vacías
+@translationof Void scheme functions
+@funindex define-void-function
+@funindex \void
+
+En ocasiones, un procedimiento se ejecuta con el objeto de llevar a
+cabo alguna acción más que para devolver un valor.  Algunos lenguajes
+de programación (como C y Scheme) usan las funciones para los dos
+conceptos y se limitan a descartar el valor devuelto (usualmente
+haciendo que cualquier expresión pueda actuar como instrucción,
+ignorando el resultado devuelto).  Esto puede parecer inteligente pero
+es propenso a errores: casi todos los compiladores de C de hoy en día
+emiten advertencias cuando se descarta una expresión no vacía.  Para
+muchas funciones que ejecutan una acción, los estándares de Scheme
+declaran que el valor de retorno sea no especificado.  Guile, el
+intérprete de Scheme de LilyPond, tiene un valor único
+@code{*unspecified*} que en tales casos devuelve de forma usual (como
+cuando se usa directamente @code{set!} sobre una variable), pero
+desgraciadamente no de forma consistente.
+
+Definir una función de LilyPond con @code{define-void-function}
+asegura que se devuelve este valor especial, el único valor que
+satisface el predicado @code{void?}.
+
+@example
+noApuntarYPulsar =
+#(define-void-function
+     (parser location)
+     ()
+   (ly:set-option 'point-and-click #f))
+...
+\noApuntarYPulsar   % desactivar la función de apuntar y pulsar
+@end example
+
+Si queremos evaluar una expresión sólo por su efecto colateral y no
+queremos que se interprete ningún valor que pueda devolver, podemos
+hacerlo anteponiendo el prefijo @code{\void}:
+
+@example
+\void #(hashq-set! some-table some-key some-value)
+@end example
+
+De esta forma podemos asegurar que LilyPond no asignará ningún
+significado al valor devuelto, independientemente de dónde lo
+encuentre.  También funciona para funciones musicales como
+@code{\displayMusic}.
+
+@node Funciones musicales
+@section Funciones musicales
+@translationof Music functions
+
+@cindex funciones musicales
+
+Las @emph{funciones musicales} son procedimientos de Scheme que pueden
+crear automáticamente expresiones musicales, y se pueden usar para
+simplificar enormemente el archivo de entrada.
+
+@menu
+* Definiciones de funciones musicales::
+* Uso de las funciones musicales::
+* Funciones de sustitución sencillas::
+* Funciones de sustitución intermedias::
+* Matemáticas dentro de las funciones::
+* Funciones sin argumentos::
+* Funciones musicales vacías::
+@end menu
 
 
+@node Definiciones de funciones musicales
+@subsection Definiciones de funciones musicales
+@translationof Music function definitions
+@cindex definición de funciones musicales
+@funindex define-music-function
+
+La forma general para definir funciones musicales es:
+
+@example
+funcion =
+#(define-music-function
+     (parser location @var{arg1} @var{arg2} @dots{})
+     (@var{tipo1?} @var{tipo2?} @dots{})
+   @var{cuerpo})
+@end example
+
+@noindent
+de forma bastante análoga a @ref{Definición de funciones de Scheme}.
+Lo más probable es que el @var{cuerpo} sea un
+@ref{Bloques de código de LilyPond,bloque de código de LilyPond}.
+
+Para ver una lista de los predicados de tipo disponibles, consulte
+@ruser{Predicados de tipo predefinidos}.
 
 @seealso
 
@@ -100,6 +336,46 @@ Archivos de inicio:
 @file{scm/lily.scm}.
 
 
+@node Uso de las funciones musicales
+@subsection Uso de las funciones musicales
+@translationof Music function usage
+
+Las funciones musicales se pueden actualmente utilizar en varios
+lugares.  Dependiendo de dónde se usan, son de aplicación ciertas
+restricciones para que sea posible su análisis sintáctico de forma
+no ambigua.  El resultado que devuelve una función musical debe ser
+compatible con el contexto desde el que se la llama.
+
+@itemize
+@item
+En el nivel superior dentro de una expresión musical.  Aquí
+no se aplica ninguna restricción.
+
+@item
+Como un post-evento, que comienza explícitamente con un indicador de
+dirección (a elegir entre @code{-}, @code{^} @w{y @code{_}}).
+Observe que se puede aceptar la devolución de un
+post-evento por parte de las funciones musicales que se llaman como
+música normal, lo que lleva a un resultado aproximadamente equivalente
+a
+@example
+s 1*0-\fun
+@end example
+
+En este caso, no podemos usar una expresión musical @emph{abierta}
+como último argumento, que terminaría en una expresión musical
+capaz de aceptar post-eventos adicionales.
+
+@item
+Como componente de un acorde.  La expresión devuelta debe ser
+del tipo @code{rhythmic-event}, probablemente un @code{NoteEvent}.
+@end itemize
+
+@noindent
+Las reglas especiales para los argumentos del final hacen posible
+escribir funciones polimórficas como @code{\tweak} que se pueden
+aplicar a construcciones distintas.
+
 @node Funciones de sustitución sencillas
 @subsection Funciones de sustitución sencillas
 @translationof Simple substitution functions
@@ -131,7 +407,7 @@ barraManual =
      (parser location principio-final)
      (pair?)
    #@{
-     \once \override Beam #'positions = $principio-final
+     \once \override Beam #'positions = #principio-final
    #@})
 
 \relative c' @{
@@ -149,7 +425,7 @@ manualBeam =
      (parser location beg end)
      (number? number?)
    #{
-     \once \override Beam #'positions = $(cons beg end)
+     \once \override Beam #'positions = #(cons beg end)
    #})
 
 \relative c' {
@@ -171,9 +447,9 @@ AltOn =
      (parser location mag)
      (number?)
    #{
-     \override Stem #'length = $(* 7.0 mag)
+     \override Stem #'length = #(* 7.0 mag)
      \override NoteHead #'font-size =
-       $(inexact->exact (* (/ 6.0 (log 2.0)) (log mag)))
+       #(inexact->exact (* (/ 6.0 (log 2.0)) (log mag)))
    #})
 
 AltOff = {
@@ -197,10 +473,10 @@ withAlt =
      (parser location mag music)
      (number? ly:music?)
    #{
-     \override Stem #'length = $(* 7.0 mag)
+     \override Stem #'length = #(* 7.0 mag)
      \override NoteHead #'font-size =
-       $(inexact->exact (* (/ 6.0 (log 2.0)) (log mag)))
-     $music
+       #(inexact->exact (* (/ 6.0 (log 2.0)) (log mag)))
+     #music
      \revert Stem #'length
      \revert NoteHead #'font-size
    #})
@@ -244,30 +520,42 @@ lilypond -d display-bar-numbers ARCHIVO.ly
 @end example
 
 
-@node Funciones vacías
-@subsection Funciones vacías
-@translationof Void functions
+@node Funciones musicales vacías
+@subsection Funciones musicales vacías
+@translationof Void music functions
 
-Una función musical debe devolver una expresión musical, pero 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).
+Una función musical debe devolver una expresión musical.  Si quiere
+ejecutar una función exclusivamente por sus efectos secundarios,
+debería usar @code{define-void-function}.  Pero
+puede haber casos en los que a veces queremos producir una expresión
+musical, y a veces no (como en el ejemplo anterior).  Devolver una
+expresión musical @code{void} (vacía) por medio de @code{#@{ #@}} lo
+hace posible.
 
-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
-noApuntarYPulsar =
-#(define-music-function (parser location) ()
-   (ly:set-option 'point-and-click #f)
-   (make-music 'SequentialMusic 'void #t))
-...
-\noApuntarYPulsar   % desactivar la funcionalidad Apuntar y Pulsar.
-@end example
+@node Funciones de eventos
+@section Funciones de eventos
+@translationof Event functions
+@funindex define-event-function
+@cindex event functions
+
+Para usar una función musical en el lugar de un evento, tenemos que
+escribir un indicador de dirección antes de ella.  Pero a veces, ello
+hace que se pierda la correspondencia con la sintaxis de las
+construcciones que queremos sustituir.  Por ejemplo, si queremos
+escribir instrucciones de matiz dinámico, éstos se adjuntan
+habitualmente sin indicador de dirección, como @code{c'\pp}.  He aquí
+una forma de escribir indicaciones dinámicas arbitrarias:
+
+@lilypond[quote,verbatim,ragged-right]
+dyn=#(define-event-function (parser location arg) (markup?)
+         (make-dynamic-script arg))
+\relative c' { c\dyn pfsss }
+@end lilypond
+
+Podríamos hacer lo mismo usando una función musical, pero entonces
+tendríamos que escribir siempre un indicador de dirección antes de
+llamarla, como @code{@w{c-\dyn pfsss}}.
 
 
 @node Funciones de marcado
@@ -303,14 +591,17 @@ proporcionando una sintaxis similar a la de LilyPond.  Por ejemplo:
 @noindent
 equivale a:
 @example
-\markup \column @{ \line @{ \bold \italic "hola" \raise #0.4 "mundo" @}
-                  \larger \line @{ fulano fulanito menganito @} @}
+#@{ \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
 sintaxis del marcado normal de LilyPond y la sintaxis del marcado de
-Scheme.
+Scheme.  La utilización de @code{#@{ @dots{} #@}} para escribir en la
+sintaxis de LilyPond será con frecuencia lo más conveniente, pero
+explicamos cómo usar la macro @code{markup} para obtener una solución
+sólo con Scheme.
 
 @quotation
 @multitable @columnfractions .3 .3
@@ -329,7 +620,8 @@ Scheme.
 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{Definición de una instrucción de marcado nueva}).
+definiendo instrucciones de marcado nuevas (véase
+@ref{Definición de una instrucción de marcado nueva}).
 
 
 @knownissues
@@ -457,7 +749,7 @@ aplicado a todos los elementos de la lista de marcados original.
 Dado que la replicación de los argumentos precedentes para aplicar una
 función de marcado a una lista de marcados es poco costosa
 principalmente por los argumentos de Scheme, se evitan las caídas de
-reindimiento simplemente mediante la utilización de argumentos de
+rendimiento simplemente mediante la utilización de argumentos de
 Scheme para los argumentos antecedentes de las funciones de marcado
 que toman un marcado como su último argumento.
 
@@ -506,8 +798,8 @@ El ejemplo siguiente define una instrucción de marcado para trazar un
 rectángulo doble alrededor de un fragmento de texto.
 
 En primer lugar, necesitamos construir un resultado aproximado
-utilizando marcados.  Una consulta a @ruser{Text markup commands} nos
-muestra que es útil la instrucción @code{\box}:
+utilizando marcados.  Una consulta a @ruser{Instrucciones de marcado
+de texto} nos muestra que es útil la instrucción @code{\box}:
 
 @lilypond[quote,verbatim,ragged-right]
 \markup \box \box HELLO
@@ -527,7 +819,8 @@ Después, el relleno o separación entre los dos rectángulos nos parece
 muy pequeño, así que lo vamos a sobreescribir también:
 
 @lilypond[quote,verbatim,ragged-right]
-\markup \override #'(box-padding . 0.4) \box \override #'(box-padding . 0.6) \box A
+\markup \override #'(box-padding . 0.4) \box
+     \override #'(box-padding . 0.6) \box A
 @end lilypond
 
 Repetir esta extensa instrucción de marcado una y otra vez sería un
@@ -536,6 +829,16 @@ marcado.  Así pues, escribimos una instrucción de marcado
 @code{double-box}, que toma un argumento (el texto).  Dibuja los dos
 rectángulos y añade una separación.
 
+@lisp
+#(define-markup-command (double-box layout props text) (markup?)
+  "Trazar un rectángulo doble rodeando el texto."
+  (interpret-markup layout props
+    #@{\markup \override #'(box-padding . 0.4) \box
+            \override #'(box-padding . 0.6) \box @{ #text @}#@}))
+@end lisp
+
+or, equivalently
+
 @lisp
 #(define-markup-command (double-box layout props text) (markup?)
   "Trazar un rectángulo doble rodeando el texto."
@@ -548,10 +851,11 @@ rectángulos y añade una separación.
 @code{markup?} es el tipo: lo identifica como un elemento de marcado.
 La función @code{interpret-markup} se usa en casi todas las
 instrucciones de marcado: construye un sello, usando @code{layout},
-@code{props}, y un elemento de marcado.  Aquí, la marca se construye
-usando el macro de Scheme @code{markup}, véase @ref{Construcción de
-elementos de marcado en Scheme}.  La transformación de una expresión
-@code{\markup} en una expresión de marcado de Scheme es directa.
+@code{props}, y un elemento de marcado.  En el segundo caso, la marca
+se construye usando el macro de Scheme @code{markup}, véase
+@ref{Construcción de elementos de marcado en Scheme}.  La
+transformación de una expresión @code{\markup} en una expresión de
+marcado de Scheme es directa.
 
 La instrucción nueva se puede usar como sigue:
 
@@ -568,6 +872,19 @@ nueva propiedad, @code{inter-box-padding}, para el relleno entre los
 rectángulos.  El @code{box-padding} se usará para el relleno interno.
 Ahora el código nuevo es como se ve a continuación:
 
+@lisp
+#(define-markup-command (double-box layout props text) (markup?)
+  #:properties ((inter-box-padding 0.4)
+                (box-padding 0.6))
+  "Trazar un rectángulo doble rodeando el texto."
+  (interpret-markup layout props
+    #@{\markup \override #`(box-padding . ,inter-box-padding) \box
+               \override #`(box-padding . ,box-padding) \box
+               @{ #text @} #@}))
+@end lisp
+
+De nuevo, la versión equivalente que utiliza la macro de marcado sería:
+
 @lisp
 #(define-markup-command (double-box layout props text) (markup?)
   #:properties ((inter-box-padding 0.4)
@@ -598,8 +915,9 @@ y el relleno de los rectángulos se puede personalizar:
                 (box-padding 0.6))
   "Draw a double box around text."
   (interpret-markup layout props
-    (markup #:override `(box-padding . ,inter-box-padding) #:box
-            #:override `(box-padding . ,box-padding) #:box text)))
+    #{\markup \override #`(box-padding . ,inter-box-padding) \box
+              \override #`(box-padding . ,box-padding) \box
+              { #text } #}))
 
 \markup \double-box A
 \markup \override #'(inter-box-padding . 0.8) \double-box A
@@ -711,6 +1029,15 @@ En el siguiente ejemplo se define una instrucción de lista de marcado
 estando la primera de ellas sangrada.  La anchura del sangrado se toma
 del argumento @code{props}.
 
+@example
+#(define-markup-list-command (paragraph layout props args) (markup-list?)
+   #:properties ((par-indent 2))
+   (interpret-markup-list layout props
+     #@{\markuplist \justified-lines @{ \hspace #par-indent #args @} #@}))
+@end example
+
+
+La versión que usa solamente Scheme es más compleja:
 @example
 #(define-markup-list-command (paragraph layout props args) (markup-list?)
    #:properties ((par-indent 2))
@@ -728,17 +1055,17 @@ En primer lugar, la función toma el ancho del sangrado, una propiedad
 llamada aquí @code{par-indent}, de la lista de propiedades
 @code{props}.  Si no se encuentra la propiedad, el valor
 predeterminado es @code{2}.  Después, se hace una lista de líneas
-justificadas usando la función
-@code{make-justified-lines-markup-list}, que está relacionada con la
-instrucción incorporada de lista de marcados @code{\justified-lines}.
-Se añade un espacio horizontal al principio usando la función
-@code{make-hspace-markup}.  Finalmente, la lista de marcados se
+justificadas usando la instrucción incorporada de lista de marcados
+@code{\justified-lines}, que está relacionada con la función
+@code{make-justified-lines-markup-list}.  Se añade un espacio
+horizontal al principio usando @code{\hspace} (o la función
+@code{make-hspace-markup}).  Finalmente, la lista de marcados se
 interpreta usando la función @code{interpret-markup-list}.
 
 Esta nueva instrucción de lista de marcados se puede usar como sigue:
 
 @example
-\markuplines @{
+\markuplist @{
   \paragraph @{
     El arte de la tipografía musical se llama  \italic @{grabado (en plancha).@}
     El término deriva del proceso tradicional de impresión de música.
@@ -855,7 +1182,7 @@ p. ej.:
 \override Stem #'thickness = #2.0
 @end example
 
-Las propiedades pueden fijarse también a un procedimiento de scheme,
+Las propiedades pueden fijarse también a un procedimiento de Scheme,
 
 @lilypond[fragment,verbatim,quote,relative=2]
 \override Stem #'thickness = #(lambda (grob)
@@ -945,10 +1272,6 @@ F = \tweak #'font-size #-3 -\flageolet
 @end example
 
 @noindent
-En otras palabras, @code{\tweak} no se comporta como una articulación
-en cuando a la sintaxis; concretamente, no se puede adjuntar con
-@code{^} y @code{_}.
-
 Usando Scheme, se puede dar un rodeo a este problema.  La ruta hacia
 el resultado se da en @ref{Añadir articulaciones a las notas
 (ejemplo)}, especialmente cómo usar @code{\displayMusic} como guía de