| [ << Scheme ] | [Top][Contents] | [ Spacing >> ] |
| [ < Generación de notas aleatorias ] | [ Up: Scheme ] | [ Símbolos de porcentaje sueltos > ] |
Generación de partituras completas y partes de libro en Scheme sin usar el analizador sintáctico
Internamente, una partitura de LilyPond no es más que una expresión de Scheme, generada por el analizador sintáctico de LilyPond. Usando Scheme, también podemos generar automáticamente una partitura sin ningún archivo de entrada. Si tenemos la expresión musical en Scheme, se puede generar la partitura simplemente llamando a
(scorify-music music)
sobre la música. Así se genera un objeto partitura, para el que podemos entonces fijar un bloque layout personalizado con
(let* ((layout (ly:output-def-clone $defaultlayout))) ; modificamos el layout aquí, y después lo asignamos: (ly:score-add-output-def! score layout) )
Finalmente, todo lo que tenemos que hacer es pasar esta partitura
a lilypond para que realice la composición tipográfica. Este
fragmento de código define las funciones (add-score score),
(add-text text) y (add-music music) para pasar una
partitura completa, elementos de marcado o algo de música a
LilyPond para su composición tipográfica.
Este fragmento de código también funciona para la tipografía de
partituras dentro de un bloque \book {...}, así como
partituras normales del nivel superior jerárquico. Para
conseguirlo, cada una de las partituras destinadas a su
tipografiado se añaden al final de una lista de partituras del
nivel superior jerárquico y se modifica el toplevel-book-handler
(que es una función de Scheme que se llama para procesar un libro
una vez que se ha cerrado el bloque \book{..}) para
insertar todas las partituras así coleccionadas al libro.
Nota: por razones técnicas, solo se muestra el primer
\book, debido a que las otras instrucciones \book
crean archivos de salida adicionales.
#(define-public (add-score score) (ly:parser-define! 'toplevel-scores (cons score (ly:parser-lookup 'toplevel-scores)))) #(define-public (add-text text) (add-score (list text))) #(define-public (add-music music) (collect-music-aux (lambda (score) (add-score score)) music)) #(define-public (toplevel-book-handler book) (map (lambda (score) (ly:book-add-score! book score)) (reverse! (ly:parser-lookup 'toplevel-scores))) (ly:parser-define! 'toplevel-scores (list)) (print-book-with-defaults book)) #(define-public (book-score-handler book score) (add-score score)) #(define-public (book-text-handler book text) (add-text text)) #(define-public (book-music-handler book music) (add-music music)) % Some example code to show how to use these functions. Each call to % `\oneNoteScore` constructs a global markup followed by a single % staff with a single quarter note. The pitch of this note is taken % from the variable `pitch`; the start value 0 corresponds to pitch C. % After emitting the score, variable `pitch` gets increased by 1. % % `\oneNoteScore` calls Scheme function `add-one-note-score` to do all % the work. #(define add-one-note-score #f) #(let ((pitch 0)) (set! add-one-note-score (lambda () (let* ((music (make-music 'EventChord 'elements (list (make-music 'NoteEvent 'duration (ly:make-duration 2 0 1/1) 'pitch (ly:make-pitch 0 pitch 0))))) (score (scorify-music music)) (layout (ly:output-def-clone $defaultlayout)) (note-name (case pitch ((0) "do") ((1) "ré") ((2) "mi") ((3) "fa") ((4) "sol") ((5) "la") ((6) "si") (else "huh"))) (title (markup #:large #:line ("Score with a" note-name)))) (ly:score-add-output-def! score layout) (add-text title) (add-score score)) (set! pitch (modulo (1+ pitch) 7))))) oneNoteScore = #(define-void-function () () (add-one-note-score)) \book { \oneNoteScore \paper { tagline = ##f } } \book { \oneNoteScore \oneNoteScore \paper { tagline = ##f } } % Top-level scores are also handled correctly. \oneNoteScore \oneNoteScore \paper { tagline = ##f }
| [ << Scheme ] | [Top][Contents] | [ Spacing >> ] |
| [ < Generación de notas aleatorias ] | [ Up: Scheme ] | [ Símbolos de porcentaje sueltos > ] |