]> git.donarmstrong.com Git - lilypond.git/blob - Documentation/snippets/generating-whole-scores-also-book-parts-in-scheme-without-using-the-parser.ly
Local updates to LSR July 2012
[lilypond.git] / Documentation / snippets / generating-whole-scores-also-book-parts-in-scheme-without-using-the-parser.ly
1 %% DO NOT EDIT this file manually; it is automatically
2 %% generated from LSR http://lsr.dsi.unimi.it
3 %% Make any changes in LSR itself, or in Documentation/snippets/new/ ,
4 %% and then run scripts/auxiliar/makelsr.py
5 %%
6 %% This file is in the public domain.
7 \version "2.14.2"
8
9 \header {
10   lsrtags = "automatic-notation, scheme-language, really-cool"
11
12 %% Translation of GIT committish: 57f9346bb030f49336a858fcbf1519366fe56454
13   texidocfr = "
14 Une partition LilyPond, de manière interne, n'est rien d'autre qu'une
15 expression Scheme générée par l'analyseur syntaxique de lilypond.  Il
16 est donc possible, à l'aide de Scheme, de générer automatiquement une
17 partition sans fichier source.  Une expression musicale en Scheme sera
18 transformée en partition par un appel à
19 @code{(scorify-music music parser)}.  Ceci aura pour effet de générer
20 un objet @code{score} auquel sera appliqué un bloc @code{layout}
21 comportant la fonction
22
23 @example
24 (let* ((layout (ly:output-def-clone $defaultlayout)))
25    ; modification de la mise en forme, puis assignation :
26    (ly:score-add-output-def! score layout)
27   )
28 @end example
29
30 Il suffit alors de transmettre ce @code{score} à lilypond pour qu'il le
31 grave.  Les trois fonctions -- @code{(add-score parser score)},
32 @code{(add-text parser text)} et @code{(add-music parser music)} --
33 définies dans le code ci-dessous permettent de transmettre à lilypond,
34 aux fins de les graver, une partition complète, un @emph{markup} ou
35 simplement de la musique.
36
37 Cet exemple permet aussi de graver les pièces contenues dans un bloc
38 @code{\\book@{@dots{}@}} ainsi que des partitions de niveau supérieur.
39 Chaque partition destinée à être gravée est alors ajoutée à la liste des
40 partitions de niveau supérieur ; le @code{toplevel-book-handler} --
41 fonction Scheme appelée pour traiter un @emph{book} dès que le bloc
42 @code{\\book@{@dots{}@}} est clôturé -- s'adapte pour prendre en charge
43 tous les @code{score} jusque là collectés dans l'ouvrage.
44
45 "
46   doctitlefr = "Génération en Scheme de partitions complètes (y compris des parties d'ouvrage) sans utiliser l'analyseur"
47
48   texidoc = "
49 A lilypond score internally is just a Scheme expression, generated by
50 the lilypond parser. Using scheme, one can also automatically generate
51 a score without an input file. If you have the music expression in
52 scheme, a score can be generated by simply calling (scorify-music music
53 parser) on your music. This will generate a score object, for which you
54 can then set a custom layout block with (let* ((layout
55 (ly:output-def-clone $defaultlayout)))
56    ; modify the layout here, then assign it:
57    (ly:score-add-output-def! score layout)
58   )
59
60
61 Finally, all you have to do it to pass this score to lilypond for
62 typesetting. This snippet defines functions @code{(add-score parser
63 score)}, @code{(add-text parser text)} and @code{(add-music parser
64 music)} to pass a complete score, some markup or some music to lilypond
65 for typesetting.
66
67 This snippet also works for typesetting scores inside a @code{\\book
68 @{...@}} block, as well as top-level scores. To achieve this, each
69 score schedulled for typesetting is appended to the list of toplevel
70 scores and the toplevel-book-handler (which is a scheme function called
71 to process a book once a @code{\\book@{..@}} block is closed) is
72 modified to inser all collected scores so far to the book.
73
74 "
75   doctitle = "Generating whole scores (also book parts) in scheme without using the parser"
76 } % begin verbatim
77
78 #(define-public (add-score parser score)
79    (ly:parser-define! parser 'toplevel-scores
80                       (cons score (ly:parser-lookup parser 'toplevel-scores))))
81
82 #(define-public (add-text parser text)
83   (add-score parser (list text)))
84
85 #(define-public (add-music parser music)
86   (collect-music-aux (lambda (score)
87                        (add-score parser score))
88                      parser
89                      music))
90
91 #(define-public (toplevel-book-handler parser book)
92    (map (lambda (score)
93           (ly:book-add-score! book score))
94         (reverse! (ly:parser-lookup parser 'toplevel-scores)))
95    (ly:parser-define! parser 'toplevel-scores (list))
96    (print-book-with-defaults parser book))
97
98 #(define-public (book-score-handler book score)
99    (add-score parser score))
100
101 #(define-public (book-text-handler book text)
102    (add-text parser text))
103
104 #(define-public (book-music-handler parser book music)
105    (add-music parser music))
106
107 %%%
108
109
110 %% Just some example score to show how to use these functions:
111 #(define add-one-note-score #f)
112 #(let ((pitch 0))
113   (set! add-one-note-score
114         (lambda (parser)
115           (let* ((music (make-music 'EventChord
116                           'elements (list (make-music 'NoteEvent
117                                             'duration (ly:make-duration 2 0 1 1)
118                                             'pitch (ly:make-pitch 0 pitch 0)))))
119                  (score (scorify-music music parser))
120                  (layout (ly:output-def-clone $defaultlayout))
121                  (note-name (case pitch
122                               ((0) "do")
123                               ((1) "ré")
124                               ((2) "mi")
125                               ((3) "fa")
126                               ((4) "sol")
127                               ((5) "la")
128                               ((6) "si")
129                               (else "huh")))
130                  (title (markup #:large #:line ("Score with a" note-name))))
131             (ly:score-add-output-def! score layout)
132             (add-text parser title)
133             (add-score parser score))
134             (set! pitch (modulo (1+ pitch) 7)))))
135
136 oneNoteScore =
137 #(define-music-function (parser location) ()
138    (add-one-note-score parser)
139    (make-music 'Music 'void #t))
140
141 %%%
142
143 \book {
144   \oneNoteScore
145 }
146
147
148 \book {
149   \oneNoteScore
150   \oneNoteScore
151 }
152
153 % Top-level scores are also handled correctly
154 \oneNoteScore
155 \oneNoteScore