3 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6 % Desciption: Lilypond package to make writing large orchestral scores easier.
7 % Documentation: http://wiki.kainhofer.com/lilypond/orchestrallily
8 % Version: 0.02, 2008-03-06
9 % Author: Reinhold Kainhofer, reinhold@kainhofer.com
10 % Copyright: (C) 2008 by Reinhold Kainhofer
11 % License: GPL v3.0, http://www.gnu.org/licenses/gpl.html
14 % 0.01 (2008-03-02): Initial Version
15 % 0.02 (2008-03-06): Added basic MIDI support (*MidiInstrument and \setCreateMIDI)
16 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
18 #(use-modules
(ice-
9 match
))
21 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
22 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
23 %%%%% SCORE STRUCTURE AND AUTOMATIC GENERATION
24 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
25 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
30 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
32 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34 % Helper function to filter all non-null entries
35 #(define
(not-null? x
) (not
(null? x
)))
37 % Helper function to extract a given variable, built from [Piece][Instrument]Identifier
38 #(define
(namedPieceInstrObject piece instr name
)
40 (fullname
(string-
>symbol
(string-append piece instr name
)))
41 (instrname
(string-
>symbol
(string-append instr name
)))
42 (piecename
(string-
>symbol
(string-append piece name
)))
45 ((defined? fullname
) (primitive-eval fullname
))
46 ((defined? instrname
) (primitive-eval instrname
))
47 ((defined? piecename
) (primitive-eval piecename
))
53 %% Print text as a justified paragraph, taken from the lilypond Notation Reference
54 #(define-markup-list-command
(paragraph layout props args
) (markup-list?
)
55 (let
((indent
(chain-assoc-get
'par-indent props
2)))
56 (interpret-markup-list layout props
57 (make-justified-lines-markup-list
(cons
(make-hspace-markup indent
)
60 conditionalBreak
= #(define-music-function
(parser location
) ()
61 #{ \tag #'instrumental-score
\pageBreak #}
64 #(define
(oly
:piece-title-markup title
) (markup
#:column
(#:line
(#:fontsize
#'3 #:bold title
))) )
66 #(define-markup-command
(piece-title layout props title
) (markup?
)
68 (interpret-markup layout props
(oly
:piece-title-markup title
))
71 #(define
(oly
:generate
_object
_name piece instr obj
)
72 (if
(and
(string? piece
) (string? instr
) (string? obj
))
73 (string-append piece instr obj
)
77 #(define
(oly
:generate
_staff
_name piece instr
) (oly
:generate
_object
_name piece instr
"St"))
79 #(define
(set-context-property context property value
)
80 (set
! (ly
:music-property context property
) value
)
84 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
85 % Score structure and voice types
86 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
88 #(define oly
:orchestral
_score
_structure
'())
90 #(define
(oly
:set
_score
_structure struct
)
92 (set
! oly
:orchestral
_score
_structure struct
)
93 (ly
:warning
(_ "oly:set_score_structure needs an association list as argument!"))
97 orchestralScoreStructure
= #(define-music-function
(parser location structure
) (list?
)
98 (oly
:set
_score
_structure structure
)
99 (make-music
'Music
'void
#t
)
102 #(define oly
:voice
_types
'())
104 #(define
(oly
:set
_voice
_types types
)
106 (set
! oly
:voice
_types types
)
107 (ly
:warning
(_ "oly:set_voice_types needs an association list as argument!"))
111 orchestralVoiceTypes
= #(define-music-function
(parser location types
) (list?
)
112 (oly
:set
_voice
_types types
)
113 (make-music
'Music
'void
#t
)
117 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
118 % Automatic staff and group generation
119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
121 % Retrieve all music definitions for the given
122 #(define
(oly
:get
_music
_object piece instrument
)
123 (namedPieceInstrObject piece instrument
"Music")
125 #(define
(oly
:get
_music
_objects piece instruments
)
126 (filter not-null?
(map
(lambda
(i
) (oly
:get
_music
_object piece i
)) instruments
))
129 % Given a property name and the extensions, either generate the pair to set
130 % the property or an empty list, if no pre-defined variable could be found
131 #(define
(oly
:generate
_property
_pair prop piece instr type
)
132 (let
* ((val
(namedPieceInstrObject piece instr type
)))
133 (if
(not-null? val
) (list
'assign prop val
) '() )
137 #(define
(oly
:staff
_type type
)
139 ((string? type
) (string-
>symbol type
))
140 ((symbol? type
) type
)
146 #(define
(oly
:voice
_handler
_internal parser piece name type music
)
148 (tempo
(namedPieceInstrObject piece name
"Tempo"))
149 (lyrics
(namedPieceInstrObject piece name
"Lyrics"))
153 (if
(ly
:music? lyrics
)
154 (set
! musiccontent
(append musiccontent
(list dynamicUp
)))
155 (if
(not-null? lyrics
) (ly
:warning
(_ "Wrong type (no lyrics) for lyrics for instrument ~S in piece ~S") name piece
))
157 ; Append the settings
, key and clef
(if defined
)
160 (let
* ((object
(namedPieceInstrObject piece name type
)))
161 (if
(ly
:music? object
)
162 (set
! musiccontent
(append musiccontent
(list object
)))
163 (if
(not-null? object
) (ly
:warning
(_ "Wrong type (no ly:music) for ~S for instrument ~S in piece ~S") type name piece
))
167 '("Settings" "Key" "Clef" "TimeSignature")
170 (if
(ly
:music? music
)
172 (set
! musiccontent
(append musiccontent
(list music
)))
173 ;
(ly
:message
"Generating staff for ~a" name
)
176 (voicename
(oly
:generate
_object
_name piece name
"Voice" ))
177 (voicetype
(oly
:staff
_type type
))
178 (voice
(context-spec-music
(make-simultaneous-music musiccontent
) voicetype voicename
))
179 (staffcont
(list voice
))
181 ; I
f we have lyrics
, create
a lyrics context containing LyricCombineMusic
182 ; and add that
as second element to the staff
's elements list
...
183 (if
(ly
:music? lyrics
)
185 (lyricsname
(oly
:generate
_object
_name piece name
"Lyrics" ))
186 (lyricscont
(make-music
'LyricCombineMusic
'element lyrics
'associated-context voicename
))
188 (set
! staffcont
(append staffcont
189 (list
(context-spec-music lyricscont
'Lyrics lyricsname
))))
195 ; For empty music
, return empty
201 #(define
(oly
:voice
_handler parser piece name type
)
202 (let
* ((music
(oly
:get
_music
_object piece name
))
204 (oly
:voice
_handler
_internal parser piece name type music
)
209 #(define
(oly
:staff
_handler
_internal parser piece name type voices
)
210 (if
(not-null? voices
)
212 (staffname
(oly
:generate
_staff
_name piece name
))
213 (stafftype
(oly
:staff
_type type
))
214 (staff
(make-simultaneous-music voices
))
215 (propops
(oly
:staff
_handler
_properties piece name
))
218 ((SimultaneousMusic ParallelMusic
) #f)
219 (else
(set
! staff
(context-spec-music staff stafftype staffname
)))
221 (if
(not-null? propops
)
222 (set
! (ly
:music-property staff
'property-operations
) propops
)
226 ; For empty music
, return empty
231 #(define
(oly
:staff
_handler parser piece name type children
)
232 (let
* ((c (if
(not-null? children
) children
(list name
)))
233 (voices
(apply append
(map
(lambda
(v
) (oly
:create
_voice parser piece v
)) c)) )
235 (if
(not-null? voices
)
236 (oly
:staff
_handler
_internal parser piece name type voices
)
242 #(define
(oly
:parallel
_voices
_staff
_handler parser piece name type children
)
244 (voices
(map
(lambda
(i
) (oly
:create
_voice parser piece i
)) children
))
245 ; get the lsit of non-empty voices and flatten it
!
246 (nonemptyvoices
(apply append
(filter not-null? voices
)))
248 (if
(not-null? nonemptyvoices
)
249 (oly
:staff
_handler
_internal parser piece name
"Staff" nonemptyvoices
)
255 #(define
(oly
:part
_combined
_staff
_handler parser piece name type children
)
256 (let
* ((music
(oly
:get
_music
_objects piece children
)))
258 ((and
(pair? music
) (ly
:music?
(car music
)) (not-null?
(cdr music
)) (ly
:music?
(cadr music
)))
259 ;
(ly
:message
"Part-combine with two music expressions")
260 (oly
:staff
_handler
_internal parser piece name
"Staff" (list
(make-part-combine-music parser music
))))
262 (ly
:warning
"Part-combine without any music expressions")
264 ; exactly one is
a music expression
, simply use that by joining
266 (ly
:message
"Part-combine with only one music expressions")
267 (oly
:staff
_handler
_internal parser piece name
"Staff" (list
(apply append music
))))
269 ;
(ly
:message
"make_part_combined_staff: ~S ~S ~a" piece instr instruments
)
275 % Generate the properties for the staff for piece and instr. Typically, these
276 % are the instrument name and the short instrument name (if defined).
277 % return a (possibly empty) list of all assignments.
278 #(define
(oly
:staff
_handler
_properties piece instr
)
281 (instrumentName
. "InstrumentName")
282 (shortInstrumentName
. "ShortInstrumentName")
283 (midiInstrument
. "MidiInstrument")
287 (oly
:generate
_property
_pair
(car pr
) piece instr
(cdr pr
))
290 (props
(filter not-null? assignments
))
296 #(define
(oly
:staff
_group
_handler parser piece name type children
)
298 (staves
(map
(lambda
(i
) (oly
:create
_staff
_or
_group parser piece i
)) children
))
299 (nonemptystaves
(filter not-null? staves
))
301 (if
(not-null? nonemptystaves
)
303 (musicexpr
(if
(= 1 (length nonemptystaves
)) (car nonemptystaves
) (make-simultaneous-music staves
)))
304 (groupname
(oly
:generate
_staff
_name piece name
))
305 (grouptype
(oly
:staff
_type type
))
307 (propops
(oly
:staff
_handler
_properties piece name
))
310 ((SimultaneousMusic ParallelMusic
) #f)
311 (else
(set
! group
(context-spec-music group grouptype groupname
)))
313 (set
! (ly
:music-property group
'property-operations
) propops
)
316 ; Return empty list if no staves are generated
322 #(define oly
:staff
_handlers
325 '("GrandStaff" . oly
:staff
_group
_handler
)
326 '("PianoStaff" . oly
:staff
_group
_handler
)
327 '("ChoirStaff" . oly
:staff
_group
_handler
)
328 '("StaffGroup" . oly
:staff
_group
_handler
)
329 '("ParallelMusic" . oly
:staff
_group
_handler
)
330 '("SimultaneousMusic" . oly
:staff
_group
_handler
)
332 '("Staff" . oly
:staff
_handler
)
333 '("DrumStaff" . oly
:staff
_handler
)
334 '("PartCombinedStaff" . oly
:part
_combined
_staff
_handler
)
335 '("ParallelVoicesStaff" . oly
:parallel
_voices
_staff
_handler
)
339 #(define oly
:voice
_handlers
342 '("Voice" . oly
:voice
_handler
)
343 '("FiguredBass" . oly
:voice
_handler
)
344 '("Lyrics" . oly
:lyrics
_handler
)
345 '("DrumVoice" . oly
:voice
_handler
)
346 '("Dynamics" . oly
:dynamics
_handler
)
350 #(define
(oly
:create
_voice parser piece name
)
351 (let
* ( (voice
(namedPieceInstrObject piece name
"Voice"))
352 (type
(assoc-ref oly
:voice
_types name
)) )
353 (if
(not-null? voice
)
354 ; Explicit voice variable
, use that
358 ; No entry in structure found
=> simple voice
359 (oly
:voice
_handler parser piece name
"Voice")
360 ; Entry found in structure
=> use the handler for the given type
362 (voicetype
(car type
))
363 (handler
(assoc-ref oly
:voice
_handlers voicetype
))
366 ((primitive-eval handler
) parser piece name voicetype
)
368 (ly
:warning
"No handler found for voice type ~a, using default voice handler" voicetype
)
369 (oly
:voice
_handler parser piece name voicetype
)
378 #(define
(oly
:create
_staff
_or
_group parser piece name
)
379 (let
* ( (staff
(namedPieceInstrObject piece name
"Staff"))
380 (type
_from
_structure
(assoc-ref oly
:orchestral
_score
_structure name
)) )
381 ;
(if
(not-null? staff
)
382 ;
(ly
:message
"Found staff variable for instrument ~a in piece ~a" instr piece
)
383 ;
(ly
:message
"Staff variable for instrument ~a in piece ~a NOT FOUND" instr piece
)
385 (if
(not-null? staff
)
386 ; Explicit staff variable
, use that
389 (if
(not
(list? type
_from
_structure
))
390 ; No entry in structure found
=> simple staff
391 (oly
:staff
_handler parser piece name
"Staff" '())
393 ; Entry found in structure
=> use the handler for the given type
394 (let
* ((type
(car type
_from
_structure
))
395 (handler
(assoc-ref oly
:staff
_handlers type
))
396 (children
(cadr type
_from
_structure
))
399 ((primitive-eval handler
) parser piece name type children
)
401 (ly
:warning
"No handler found for staff type ~a, using default staff handler" type
)
402 (oly
:staff
_handler parser piece name type children
)
411 #(define
(oly
:register
_staff
_type
_handler type func
)
412 ;
(ly
:message
"Registering staff handler ~a for type ~a" func type
)
413 (set
! oly
:staff
_handlers
(assoc-set
! oly
:staff
_handlers type func
))
416 #(define
(oly
:register
_voice
_type
_handler type func
)
417 ;
(ly
:message
"Registering voice type handler ~a for type ~a" func type
)
418 (set
! oly
:voice
_handlers
(assoc-set
! oly
:voice
_handlers type func
))
421 % handlers for deprecated API
422 #(oly
:register
_staff
_type
_handler
'StaffGroup
'oly
:staff
_group
_handler
)
423 #(oly
:register
_staff
_type
_handler
'ParallelMusic
'oly
:staff
_group
_handler
)
426 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
427 % Automatic score generation
428 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
430 % \setUserBook ##t/##f sets a flat to determine whether the calls to createScore
431 % are from within a book block or not
432 #(define oly
:score
_handler collect-scores-for-book
)
433 setUseBook
= #(define-music-function
(parser location usebook
) (boolean?
)
435 (set
! oly
:score
_handler book-score-handler
)
436 (set
! oly
:score
_handler toplevel-score-handler
)
438 (make-music
'Music
'void
#t
)
442 % Two functions to handle midi-blocks: Either don't set one, or set an empty
443 % one so that MIDI is generated
444 #(define
(oly
:set
_no
_midi
_block score
) '())
445 #(define
(oly
:set
_midi
_block score
)
446 (let
* ((midiblock
(if
(defined?
'$defaultmidi
)
447 (ly
:output-def-clone $defaultmidi
)
448 (ly
:make-output-def
))))
449 (ly
:output-def-set-variable
! midiblock
'is-midi
#t
)
450 (ly
:score-add-output-def
! score midiblock
)
454 % \setCreateMidi ##t/##f sets a flag to determine wheter MIDI output should
456 #(define oly
:apply
_score
_midi oly
:set
_no
_midi
_block
)
457 setCreateMIDI
= #(define-music-function
(parser location createmidi
) (boolean?
)
459 (set
! oly
:apply
_score
_midi oly
:set
_midi
_block
)
460 (set
! oly
:apply
_score
_midi oly
:set
_no
_midi
_block
)
462 (make-music
'Music
'void
#t
)
466 % Two functions to handle layout-blocks: Either don't set one, or set an empty
467 % one so that a PDF is generated
468 #(define
(oly
:set
_no
_layout
_block score
) '())
469 #(define
(oly
:set
_layout
_block score
)
470 (let
* ((layoutblock
(if
(defined?
'$defaultlayout
)
471 (ly
:output-def-clone $defaultlayout
)
472 (ly
:make-output-def
))))
473 (ly
:output-def-set-variable
! layoutblock
'is-layout
#t
)
474 (ly
:score-add-output-def
! score layoutblock
)
478 % \setCreatePDF ##t/##f sets a flag to determine wheter PDF output should
480 #(define oly
:apply
_score
_layout oly
:set
_no
_layout
_block
)
481 setCreatePDF
= #(define-music-function
(parser location createlayout
) (boolean?
)
483 (set
! oly
:apply
_score
_layout oly
:set
_layout
_block
)
484 (set
! oly
:apply
_score
_layout oly
:set
_no
_layout
_block
)
486 (make-music
'Music
'void
#t
)
490 % Set the piece title in a new header block.
491 #(define
(oly
:set
_piece
_header score piecename
)
492 (if
(not-null? piecename
)
493 (let
* ((header
(make-module
)))
494 (module-define
! header
'piece piecename
)
495 (ly
:score-set-header
! score header
)
502 % post-filter functions. By default, no filtering is done. However,
503 % for the *NoCues* function, the cue notes should be killed
504 identity
= #(define-music-function
(parser location music
) (ly
:music?
) music
)
505 cuefilter
= #(define-music-function
(parser location music
) (ly
:music?
)
506 ((ly
:music-function-extract removeWithTag
) parser location
'cued
((ly
:music-function-extract killCues
) parser location music
))
509 % The helper function to build a score.
510 #(define
(oly
:createScoreHelper parser location piece children func
)
512 (staves
(oly
:staff
_group
_handler parser piece
"" "SimultaneousMusic" children
))
513 (music
(if
(not-null? staves
)
514 ((ly
:music-function-extract func
) parser location staves
)
518 (piecename
(namedPieceInstrObject piece
(car children
) "PieceName"))
519 (piecenametacet
(namedPieceInstrObject piece
(car children
) "PieceNameTacet"))
523 ; No staves
, print tacet
525 (if
(not-null? piecenametacet
) (set
! piecename piecenametacet
))
526 (if
(not-null? piecename
)
527 (collect-scores-for-book parser
(list
(oly
:piece-title-markup piecename
)))
528 (ly
:warning
(_ "No music and no score title found for part ~a and instrument ~a") piece children
)
531 ; we have staves
, apply the piecename to the score and add layout
/midi blocks if needed
533 (set
! score
(scorify-music music parser
))
534 (oly
:set
_piece
_header score piecename
)
535 (oly
:apply
_score
_midi score
)
536 (oly
:apply
_score
_layout score
)
537 ; Schedule the score for typesetting
538 (collect-scores-for-book parser score
)
542 ; This is
a void function
, the score has been schedulled for typesetting already
543 (make-music
'Music
'void
#t
)
546 createScore
= #(define-music-function
(parser location piece children
) (string? list?
)
547 (oly
:createScoreHelper parser location piece children identity
)
549 createNoCuesScore
= #(define-music-function
(parser location piece children
) (string? list?
)
550 (oly
:createScoreHelper parser location piece children cuefilter
)
557 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
558 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
560 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
561 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
563 % set the cue instrument name
564 setCue
= #(define-music-function
(parser location instr
) (string?
)
565 #{ \set Voice
.instrumentCueName
= $instr
#} )
567 % generate a cue music section with instrument names
568 % Parameters: \namedCueDuring NameOfQuote CueDirection CueInstrument OriginalInstrument music
569 % -) NameOfQuote CueDirection music are the parameters for \cueDuring
570 % -) CueInstrument and OriginalInstrument are the displayed instrument names
572 % \namedCueDuring #"vIQuote" #UP #"V.I" #"Sop." { R1*3 }
573 % This adds the notes from vIQuote (defined via \addQuote) to three measures, prints "V.I" at
574 % the beginning of the cue notes and "Sop." at the end
575 namedCueDuring
= #(define-music-function
(parser location cuevoice direction instrcue instr cuemusic
) (string? number? string? string? ly
:music?
)
577 \cueDuring #$cuevoice
#$direction
{ \tag #'cued
\setCue #$instrcue $cuemusic
\tag #'cued
\setCue #$instr
}
578 % \tag #'uncued $cuemusic
581 namedTransposedCueDuring
= #(define-music-function
(parser location cuevoice direction instrcue instr trans cuemusic
) (string? number? string? string? ly
:music? ly
:music?
)
583 \transposedCueDuring #$cuevoice
#$direction $trans
{ \tag #'cued
\setCue #$instrcue $cuemusic
\tag #'cued
\setCue #$instr
}
584 % \tag #'uncued $cuemusic
588 % set the cue instrument name and clef
589 setClefCue
= #(define-music-function
(parser location instr clef
)
592 \once \override Staff
.Clef
#'font-size
= #-
3 $clef
593 \set Voice
.instrumentCueName
= $instr
596 % generate a cue music section with instrument names and clef changes
597 % Parameters: \cleffedCueDuring NameOfQuote CueDirection CueInstrument CueClef OriginalInstrument OriginalClef music
598 % -) NameOfQuote CueDirection music are the parameters for \cueDuring
599 % -) CueInstrument and OriginalInstrument are the displayed instrument names
600 % -) CueClef and OriginalClef are the clefs for the the cue notes and the clef of the containing voice
602 % \cleffedCueDuring #"vIQuote" #UP #"V.I" #"treble" #"Basso" #"bass" { R1*3 }
603 % This adds the notes from vIQuote (defined via \addQuote) to three measures, prints "V.I" at
604 % the beginning of the cue notes and "Basso" at the end. The clef is changed to treble at the
605 % beginning of the cue notes and reset to bass at the end
606 cleffedCueDuring
= #(define-music-function
(parser location cuevoice direction instrcue clefcue instr clefinstr cuemusic
)
607 (string? number? string? ly
:music? string? ly
:music? ly
:music?
)
609 \cueDuring #$cuevoice
#$direction
{ \tag #'cued
\setClefCue #$instrcue $clefcue $cuemusic
\tag #'cued
\setClefCue #$instr $clefinstr
}
610 % \tag #'uncued $cuemusic
617 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
618 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
620 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
621 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
623 tempoMark
= #(define-music-function
(parser location padding marktext
) (number? string?
)
625 \once \override Score
. RehearsalMark
#'padding
= $padding
626 \mark \markup { \bold \smaller $marktext
}
629 shiftDynamics
= #(define-music-function
(parser location xshift yshift
) (number? number?
)
631 \once \override DynamicTextSpanner
#'padding
= $yshift
632 \once\override DynamicText
#'extra-offset
= #(cons $xshift $yshift
)
635 ffz
= #(make-dynamic-script
"ffz")
636 pf
= #(make-dynamic-script
"pf")
637 sempp
= #(make-dynamic-script
(markup
#:line
( #:with-dimensions
'(0 . 0)
638 '(0 . 0) #:right-align
#:normal-text
#:italic
"sempre" #:dynamic
"pp")))
639 parenf
= #(make-dynamic-script
(markup
#:line
(#:normal-text
#:italic
#:fontsize
2 "(" #:dynamic
"f" #:normal-text
#:italic
#:fontsize
2 ")" )))
640 parenp
= #(make-dynamic-script
(markup
#:line
(#:normal-text
#:italic
#:fontsize
2 "(" #:dynamic
"p" #:normal-text
#:italic
#:fontsize
2 ")" )))
644 dim
= #(make-span-event
'DecrescendoEvent START
)
645 enddim
= #(make-span-event
'DecrescendoEvent STOP
)
646 decresc
= #(make-span-event
'DecrescendoEvent START
)
647 enddecresc
= #(make-span-event
'DecrescendoEvent STOP
)
648 cresc
= #(make-span-event
'CrescendoEvent START
)
649 endcresc
= #(make-span-event
'CrescendoEvent STOP
)
652 \set crescendoText
= \markup { \italic "cresc." }
653 \set crescendoSpanner
= #'dashed-line
656 \set decrescendoText
= \markup { \italic "decresc." }
657 \set decrescendoSpanner
= #'dashed-line
660 \set decrescendoText
= \markup { \italic "dim." }
661 \set decrescendoSpanner
= #'dashed-line
664 newOrOldClef
= #(define-music-function
(parser location new old
) (string? string?
)
665 (if
(ly
:get-option
'old-clefs
) #{ \clef $old
#} #{ \clef $new
#})
670 %%% Thanks to "Gilles THIBAULT" <gilles.thibault@free.fr>, there is a way
671 % to remove also the fermata from R1-\fermataMarkup: By filtering the music
672 % and removing the corresponding events.
673 % Documented as an LSR snippet: http://lsr.dsi.unimi.it/LSR/Item?id=372
674 #(define
(filterOneEventsMarkup event
)
675 ( let
( (eventname
(ly
:music-property event
'name
)) )
677 (or ;; add here event name you do NOT want
678 (eq? eventname
'MultiMeasureTextEvent
)
679 (eq? eventname
'AbsoluteDynamicEvent
)
680 (eq? eventname
'TextScriptEvent
)
681 (eq? eventname
'ArticulationEvent
)
682 (eq? eventname
'CrescendoEvent
)
683 (eq? eventname
'DecrescendoEvent
)
688 filterArticulations
= #(define-music-function
(parser location music
) (ly
:music?
)
689 (music-filter filterOneEventsMarkup music
)
702 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
703 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
704 %%%%% REST COMBINATION
705 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
706 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
710 %% REST COMBINING, TAKEN FROM http://lsr.dsi.unimi.it/LSR/Item?id=336
713 %% \new Staff \with {
714 %% \override RestCollision #'positioning-done = #merge-rests-on-positioning
715 %% } << \somevoice \\ \othervoice >>
720 %% \override RestCollision #'positioning-done = #merge-rests-on-positioning
725 %% - only handles two voices
726 %% - does not handle multi-measure/whole-measure rests
728 #(define
(rest-score r
)
730 (yoff
(ly
:grob-property-data r
'Y-offset
))
731 (sp
(ly
:grob-property-data r
'staff-position
)))
733 (set
! score
(+ score
2))
734 (if
(eq? yoff
'calculation-in-progress
)
735 (set
! score
(- score
3))))
738 (set
! score
(+ score
2))
739 (set
! score
(- score
(abs
(-
1 sp
)))))
742 #(define
(merge-rests-on-positioning grob
)
743 (let
* ((can-merge
#f)
744 (elts
(ly
:grob-object grob
'elements
))
745 (num-elts
(and
(ly
:grob-array? elts
)
746 (ly
:grob-array-length elts
)))
747 (two-voice?
(= num-elts
2)))
749 (let
* ((v
1-grob
(ly
:grob-array-ref elts
0))
750 (v
2-grob
(ly
:grob-array-ref elts
1))
751 (v
1-rest
(ly
:grob-object v
1-grob
'rest
))
752 (v
2-rest
(ly
:grob-object v
2-grob
'rest
)))
756 (let
* ((v
1-duration-log
(ly
:grob-property v
1-rest
'duration-log
))
757 (v
2-duration-log
(ly
:grob-property v
2-rest
'duration-log
))
758 (v
1-dot
(ly
:grob-object v
1-rest
'dot
))
759 (v
2-dot
(ly
:grob-object v
2-rest
'dot
))
760 (v
1-dot-count
(and
(ly
:grob? v
1-dot
)
761 (ly
:grob-property v
1-dot
'dot-count -
1)))
762 (v
2-dot-count
(and
(ly
:grob? v
2-dot
)
763 (ly
:grob-property v
2-dot
'dot-count -
1))))
766 (number? v
1-duration-log
)
767 (number? v
2-duration-log
)
768 (= v
1-duration-log v
2-duration-log
)
769 (eq? v
1-dot-count v
2-dot-count
)))
771 ;; keep the rest that looks best
:
772 (let
* ((keep-v
1?
(>= (rest-score v
1-rest
)
773 (rest-score v
2-rest
)))
774 (rest-to-keep
(if keep-v
1? v
1-rest v
2-rest
))
775 (dot-to-kill
(if keep-v
1? v
2-dot v
1-dot
)))
776 ;; uncomment if you
're curious of which rest was chosen
:
777 ;;
(ly
:grob-set-property
! v
1-rest
'color green
)
778 ;;
(ly
:grob-set-property
! v
2-rest
'color blue
)
779 (ly
:grob-suicide
! (if keep-v
1? v
2-rest v
1-rest
))
780 (if
(ly
:grob? dot-to-kill
)
781 (ly
:grob-suicide
! dot-to-kill
))
782 (ly
:grob-set-property
! rest-to-keep
'direction
0)
783 (ly
:rest
::y-offset-callback rest-to-keep
)))))))
786 (ly
:rest-collision
::calc-positioning-done grob
))))
795 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
796 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
797 %%%%% TITLE PAGE / HEADER
798 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
799 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
803 scoreTitleMarkup
= \markup \piece-title
\fromproperty #'header
:piece
804 bookTitleMarkup
= \markup {
805 \override #'(baseline-skip
. 3.5)
807 \override #'(baseline-skip
. 3.5)
811 \bigger \fromproperty #'header
:title
814 \large \smaller \bold
815 \bigger \fromproperty #'header
:subtitle
819 \fromproperty #'header
:subsubtitle
822 { \large \bold \fromproperty #'header
:instrument
}
825 \fromproperty #'header
:poet
826 \fromproperty #'header
:composer
829 \fromproperty #'header
:meter
830 \fromproperty #'header
:arranger
842 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
843 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
844 %%%%% SCORE (HEADER / LAYOUT) SETTINGS
845 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
846 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
852 % after-title-space = 0.5\cm
854 ragged-last-bottom
= ##f
859 % If only one non-empty staff in a system exists, still print the backet
860 \override SystemStartBracket
#'collapse-height
= #1
861 \consists "Instrument_name_engraver"
866 % If only one non-empty staff in a system exists, still print the backet
867 \override SystemStartBracket
#'collapse-height
= #1
868 \consists "Instrument_name_engraver"
872 \override SystemStartBracket
#'collapse-height
= #1
873 \consists "Instrument_name_engraver"
877 % Force multi-measure rests to be written as one span
878 \override MultiMeasureRest
#'expand-limit
= #3
881 hairpinToBarline
= ##f
882 \override BarNumber
#'break-visibility
= #end-of-line-invisible
883 barNumberVisibility
= #(every-nth-bar-number-visible
5)
884 \override CombineTextScript
#'avoid-slur
= #'outside
885 \override DynamicTextSpanner
#'dash-period
= #-
1.0
886 \override InstrumentSwitch
#'font-size
= #-
1
889 \override RestCollision
#'positioning-done
= #merge-rests-on-positioning
890 % Auto-Accidentals: Use modern-cautionary style...
892 autoAccidentals
= #'(Staff
(same-octave
. 0))
893 autoCautionaries
= #'(Staff
(any-octave
. 0) (same-octave
. 1))
894 printKeyCancellation
= ##t
897 \RemoveEmptyStaffContext
901 \override VerticalAxisGroup
#'minimum-Y-extent
= #'(0.5 . 0.5)