3 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6 % Desciption: Lilypond package to make writing large orchestral scores easier.
7 % Documentation: http://wiki.kainhofer.com/lilypond/orchestrallily
8 % Version: 0.01, 2008-03-02
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
12 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14 #(use-modules
(ice-
9 match
))
17 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
18 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
19 %%%%% SCORE STRUCTURE AND AUTOMATIC GENERATION
20 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
21 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
26 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
28 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
30 % Helper function to filter all non-null entries
31 #(define
(not-null? x
) (not
(null? x
)))
33 % Helper function to extract a given variable, built from [Piece][Instrument]Identifier
34 #(define
(namedPieceInstrObject piece instr name
)
36 (fullname
(string-
>symbol
(string-append piece instr name
)))
37 (instrname
(string-
>symbol
(string-append instr name
)))
38 (piecename
(string-
>symbol
(string-append piece name
)))
41 ((defined? fullname
) (primitive-eval fullname
))
42 ((defined? instrname
) (primitive-eval instrname
))
43 ((defined? piecename
) (primitive-eval piecename
))
49 %% Print text as a justified paragraph, taken from the lilypond Notation Reference
50 #(define-markup-list-command
(paragraph layout props args
) (markup-list?
)
51 (let
((indent
(chain-assoc-get
'par-indent props
2)))
52 (interpret-markup-list layout props
53 (make-justified-lines-markup-list
(cons
(make-hspace-markup indent
)
56 conditionalBreak
= #(define-music-function
(parser location
) ()
57 #{ \tag #'instrumental-score
\pageBreak #}
60 #(define
(oly
:piece-title-markup title
) (markup
#:column
(#:line
(#:fontsize
#'3 #:bold title
))) )
62 #(define-markup-command
(piece-title layout props title
) (markup?
)
64 (interpret-markup layout props
(oly
:piece-title-markup title
))
67 #(define
(oly
:generate
_object
_name piece instr obj
)
68 (if
(and
(string? piece
) (string? instr
) (string? obj
))
69 (string-append piece instr obj
)
73 #(define
(oly
:generate
_staff
_name piece instr
) (oly
:generate
_object
_name piece instr
"St"))
75 #(define
(set-context-property context property value
)
76 (set
! (ly
:music-property context property
) value
)
80 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
82 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
84 #(define oly
:orchestral
_score
_structure
'())
86 #(define
(oly
:set
_score
_structure struct
)
88 (set
! oly
:orchestral
_score
_structure struct
)
89 (ly
:warning
(_ "oly:set_score_structure needs an association list as argument!"))
93 orchestralScoreStructure
= #(define-music-function
(parser location structure
) (list?
)
94 (oly
:set
_score
_structure structure
)
95 (make-music
'Music
'void
#t
)
99 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
100 % Automatic staff and group generation
101 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
103 % Retrieve all music definitions for the given
104 #(define
(oly
:get
_music
_objects piece name instruments
)
105 (filter not-null?
(map
(lambda
(i
) (namedPieceInstrObject piece i
"Music")) instruments
))
108 #(define
(oly
:make
_staff
_internal piece name music
)
110 (tempo
(namedPieceInstrObject piece name
"Tempo"))
111 (lyrics
(namedPieceInstrObject piece name
"Lyrics"))
114 ;
(ly
:message
"Music in make_staff_internal (piece=~S, name=~S)" piece name
)
116 (if
(ly
:music? lyrics
)
117 (set
! musiccontent
(append musiccontent
(list dynamicUp
)))
118 (if
(not-null? lyrics
) (ly
:warning
(_ "Wrong type (no lyrics) for lyrics for instrument ~S in piece ~S") name piece
))
120 ; Append the settings
, key and clef
(if defined
)
123 (let
* ((object
(namedPieceInstrObject piece name type
)))
124 (if
(ly
:music? object
)
125 (set
! musiccontent
(append musiccontent
(list object
)))
126 (if
(not-null? object
) (ly
:warning
(_ "Wrong type (no ly:music) for ~S for instrument ~S in piece ~S") type name piece
))
130 '("Settings" "Key" "Clef")
133 (if
(ly
:music? music
)
135 (set
! musiccontent
(append musiccontent
(list music
)))
136 ;
(ly
:message
"Generating staff for ~a" name
)
139 (voicename
(oly
:generate
_object
_name piece name
"Voice" ))
140 (staffname
(oly
:generate
_staff
_name piece name
))
141 (voice
(context-spec-music
(make-simultaneous-music musiccontent
) 'Voice voicename
))
143 (staffcont
(list voice
))
144 (propops
(oly
:make
_staff
_properties piece name
))
146 ; I
f we have lyrics
, create
a lyrics context containing LyricCombineMusic
147 ; and add that
as second element to the staff
's elements list
...
148 (if
(ly
:music? lyrics
)
150 (lyricsname
(oly
:generate
_object
_name piece name
"Lyrics" ))
151 (lyricscont
(make-music
'LyricCombineMusic
'element lyrics
'associated-context voicename
))
153 (set
! staffcont
(append staffcont
154 (list
(context-spec-music lyricscont
'Lyrics lyricsname
))))
157 (set
! staff
(context-spec-music
(make-simultaneous-music staffcont
) 'Staff staffname
))
158 (if
(not-null? propops
)
159 (set
! (ly
:music-property staff
'property-operations
) propops
)
164 ; For empty music
, return empty
170 % TODO: Implement one-staff with multiple voices (\voiceOne and \voiceTwo),
171 % possibly with lyrics attached
172 #(define
(oly
:make
_multi
_voice
_staff parser piece instr voices
)
173 (ly
:message
"Generating a staff with multiple voices is not yet implemented, using 'SimultaneousMusic instead. Staff ID: ~a, voices: ~a" instr voices
)
174 (oly
:make
_parallel
_staves parser piece instr voices
)
177 #(define
(oly
:make
_staff parser piece instr
)
178 (let
* ( (music
(namedPieceInstrObject piece instr
"Music")) )
179 ;
(ly
:message
"make_staff: ~S ~S" piece instr
)
180 (if
(not-null? music
)
181 (oly
:make
_staff
_internal piece instr music
)
187 #(define
(oly
:make
_parallel
_staves parser piece instr instruments
)
189 (staves
(map
(lambda
(i
) (oly
:create
_staff
_or
_group parser piece i
)) instruments
))
190 (nonemptystaves
(filter not-null? staves
))
192 (if
(not-null? nonemptystaves
)
193 (make-simultaneous-music nonemptystaves
)
199 #(define
(oly
:make
_part
_combined
_staff parser piece instr instruments
)
200 (let
* ((music
(oly
:get
_music
_objects piece instr instruments
)))
201 ;
(ly
:message
"make_part_combined_staff: ~S ~S ~a" piece instr instruments
)
203 ((and
(pair? music
) (ly
:music?
(car music
)) (not-null?
(cdr music
)) (ly
:music?
(cadr music
)))
204 ;
(ly
:message
"Part-combine with two music expressions")
205 (oly
:make
_staff
_internal piece instr
(make-part-combine-music parser music
)))
207 ;
(ly
:message
"Part-combine without any music expressions")
209 ; exactly one is
a music expression
, simply use that by joining
211 ;
(ly
:message
"Part-combine with only one music expressions")
212 (oly
:make
_staff
_internal piece instr
(apply append music
)))
214 ;
(ly
:message
"make_part_combined_staff: ~S ~S ~a" piece instr instruments
)
220 #(define
(oly
:create
_staff
_or
_group parser piece instr
)
221 (let
* ( (staff
(namedPieceInstrObject piece instr
"Staff")) )
222 ;
(if
(not-null? staff
)
223 ;
(ly
:message
"Found staff variable for instrument ~a in piece ~a" instr piece
)
224 ;
(ly
:message
"Staff variable for instrument ~a in piece ~a NOT FOUND" instr piece
)
226 (if
(not-null? staff
)
227 ; Explicit staff variable
, use that
229 ; no staff defined
=> check hierarchy definition and match
a possible entry
230 ; against the four allowed forms
231 (match
(assoc-ref oly
:orchestral
_score
_structure instr
)
232 ; type
(ParallelMusic|SimultaneousMusic
("sub" "instruments"...))
234 ( ((or
'ParallelMusic
'SimultaneousMusic
) (? list? subinstr
))
235 (oly
:make
_parallel
_staves parser piece instr subinstr
) )
237 ; type
(StaffGroupType
("sub" "instruments"...)), generate staff group
238 ( ((? symbol? stafftype
) (? list? subinstr
))
239 (oly
:make
_staff
_group parser piece instr stafftype subinstr
) )
241 ; type
(#t
("sub" "instruments")) => part-combined staff
242 ( (#t
((? string? instone
) (? string? insttwo
)))
243 (oly
:make
_part
_combined
_staff parser piece instr
(list instone insttwo
)) )
245 ; type
(#f ("sub" "instruments")) => staff with multiple voices
246 ( (#f (? list? subinstr
))
247 (oly
:make
_multi
_voice
_staff parser piece instr subinstr
) )
249 ; not found in score history -
> simple staff
251 (oly
:make
_staff parser piece instr
) )
253 ; Any other type is invalid
, treat it like
a simple staff
!
255 (ly
:warning
(_ "Encountered illegal entry ~S in score structure for instrument ~a") invalidform instr
)
256 (ly
:warning
(_ "Trying to interpret ~S as a simple instrument") instr
)
257 (oly
:make
_staff parser piece instr
) )
263 % Generate the properties for the staff for piece and instr. Typically, these
264 % are the instrument name and the short instrument name (if defined).
265 % return a (possibly empty) list of all assignments.
266 #(define
(oly
:make
_staff
_properties piece instr
)
268 (instrName
(namedPieceInstrObject piece instr
"InstrumentName"))
269 (shortInstrName
(namedPieceInstrObject piece instr
"ShortInstrumentName"))
272 (if
(not-null? instrName
)
273 (set
! props
(append props
(list
(list
'assign
'instrumentName instrName
)))))
274 (if
(not-null? shortInstrName
)
275 (set
! props
(append props
(list
(list
'assign
'shortInstrumentName shortInstrName
)))))
279 #(define
(oly
:settings
_pair setting value
)
280 (if
(not-null? value
)
285 #(define
(oly
:make
_staff
_group parser piece instr stafftype instruments
)
287 (staves
(oly
:make
_parallel
_staves parser piece instr instruments
))
289 (if
(not-null? staves
)
291 (staffname
(oly
:generate
_staff
_name piece instr
))
292 (group
(context-spec-music staves stafftype staffname
))
293 (propops
(oly
:make
_staff
_properties piece instr
))
295 (set
! (ly
:music-property group
'property-operations
) propops
)
298 ; Return empty list if no staves are generated
305 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
306 % Automatic score generation
307 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
309 #(define oly
:score
_handler collect-scores-for-book
)
310 useBook
= #(define-music-function
(parser location usebook
) (boolean?
)
312 (set
! oly
:score
_handler book-score-handler
)
313 (set
! oly
:score
_handler toplevel-score-handler
)
315 (make-music
'Music
'void
#t
)
319 % post-filter functions. By default, no filtering is done. However,
320 % for the *NoCues* function, the cue notes should be killed
321 identity
= #(define-music-function
(parser location music
) (ly
:music?
) music
)
322 cuefilter
= #(define-music-function
(parser location music
) (ly
:music?
)
323 ((ly
:music-function-extract removeWithTag
) parser location
'cued
((ly
:music-function-extract killCues
) parser location music
))
326 % The helper function to build a score.
327 #(define
(createScoreHelper parser location part instr func
)
329 (staves
(oly
:make
_parallel
_staves parser part
"topLevel" instr
))
330 (music
(if
(not-null? staves
)
331 ((ly
:music-function-extract func
) parser location staves
)
335 (piecename
(namedPieceInstrObject part
(car instr
) "PieceName"))
336 (piecenametacet
(namedPieceInstrObject part
(car instr
) "PieceNameTacet"))
339 ; Set the piecename in the header and apply it to the score
340 ;
(display-lily-music music parser
)
341 ;
(display-scheme-music music
)
343 ; No staves
, print tacet
345 (if
(not-null? piecenametacet
) (set
! piecename piecenametacet
))
346 (if
(not-null? piecename
)
347 (collect-scores-for-book parser
(list
(oly
:piece-title-markup piecename
)))
348 (ly
:warning
(_ "No music and no score title found for part ~a and instrument ~a") part instr
)
351 ; we have staves
, apply the piecename to the score
353 (set
! header
(make-module
))
354 (if
(not-null? piecename
)
355 (module-define
! header
'piece piecename
) )
356 (set
! score
(scorify-music music parser
))
357 (ly
:score-set-header
! score header
)
358 ; Schedule the score for typesetting
359 (collect-scores-for-book parser score
)
363 ; This is
a void function
, the score has been schedulled for typesetting already
364 (make-music
'Music
'void
#t
)
366 createScore
= #(define-music-function
(parser location piece instr
) (string? list?
)
367 (createScoreHelper parser location piece instr identity
)
369 createNoCuesScore
= #(define-music-function
(parser location piece instr
) (string? list?
)
370 (createScoreHelper parser location piece instr cuefilter
)
377 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
378 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
380 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
381 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
383 % set the cue instrument name
384 setCue
= #(define-music-function
(parser location instr
) (string?
)
385 #{ \set Voice
.instrumentCueName
= $instr
#} )
387 % generate a cue music section with instrument names
388 % Parameters: \namedCueDuring NameOfQuote CueDirection CueInstrument OriginalInstrument music
389 % -) NameOfQuote CueDirection music are the parameters for \cueDuring
390 % -) CueInstrument and OriginalInstrument are the displayed instrument names
392 % \namedCueDuring #"vIQuote" #UP #"V.I" #"Sop." { R1*3 }
393 % This adds the notes from vIQuote (defined via \addQuote) to three measures, prints "V.I" at
394 % the beginning of the cue notes and "Sop." at the end
395 namedCueDuring
= #(define-music-function
(parser location cuevoice direction instrcue instr cuemusic
) (string? number? string? string? ly
:music?
)
397 \cueDuring #$cuevoice
#$direction
{ \tag #'cued
\setCue #$instrcue $cuemusic
\tag #'cued
\setCue #$instr
}
398 % \tag #'uncued $cuemusic
401 namedTransposedCueDuring
= #(define-music-function
(parser location cuevoice direction instrcue instr trans cuemusic
) (string? number? string? string? ly
:music? ly
:music?
)
403 \transposedCueDuring #$cuevoice
#$direction $trans
{ \tag #'cued
\setCue #$instrcue $cuemusic
\tag #'cued
\setCue #$instr
}
404 % \tag #'uncued $cuemusic
408 % set the cue instrument name and clef
409 setClefCue
= #(define-music-function
(parser location instr clef
)
412 \once \override Staff
.Clef
#'font-size
= #-
3 $clef
413 \set Voice
.instrumentCueName
= $instr
416 % generate a cue music section with instrument names and clef changes
417 % Parameters: \cleffedCueDuring NameOfQuote CueDirection CueInstrument CueClef OriginalInstrument OriginalClef music
418 % -) NameOfQuote CueDirection music are the parameters for \cueDuring
419 % -) CueInstrument and OriginalInstrument are the displayed instrument names
420 % -) CueClef and OriginalClef are the clefs for the the cue notes and the clef of the containing voice
422 % \cleffedCueDuring #"vIQuote" #UP #"V.I" #"treble" #"Basso" #"bass" { R1*3 }
423 % This adds the notes from vIQuote (defined via \addQuote) to three measures, prints "V.I" at
424 % the beginning of the cue notes and "Basso" at the end. The clef is changed to treble at the
425 % beginning of the cue notes and reset to bass at the end
426 cleffedCueDuring
= #(define-music-function
(parser location cuevoice direction instrcue clefcue instr clefinstr cuemusic
)
427 (string? number? string? ly
:music? string? ly
:music? ly
:music?
)
429 \cueDuring #$cuevoice
#$direction
{ \tag #'cued
\setClefCue #$instrcue $clefcue $cuemusic
\tag #'cued
\setClefCue #$instr $clefinstr
}
430 % \tag #'uncued $cuemusic
437 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
438 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
440 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
441 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
443 tempoMark
= #(define-music-function
(parser location padding marktext
) (number? string?
)
445 \once \override Score
. RehearsalMark
#'padding
= $padding
446 \mark \markup { \bold \smaller $marktext
}
449 shiftDynamics
= #(define-music-function
(parser location xshift yshift
) (number? number?
)
451 \once \override DynamicTextSpanner
#'padding
= $yshift
452 \once\override DynamicText
#'extra-offset
= #(cons $xshift $yshift
)
455 ffz
= #(make-dynamic-script
"ffz")
456 pf
= #(make-dynamic-script
"pf")
457 sempp
= #(make-dynamic-script
(markup
#:line
( #:with-dimensions
'(0 . 0)
458 '(0 . 0) #:right-align
#:normal-text
#:italic
"sempre" #:dynamic
"pp")))
459 parenf
= #(make-dynamic-script
(markup
#:line
(#:normal-text
#:italic
#:fontsize
2 "(" #:dynamic
"f" #:normal-text
#:italic
#:fontsize
2 ")" )))
460 parenp
= #(make-dynamic-script
(markup
#:line
(#:normal-text
#:italic
#:fontsize
2 "(" #:dynamic
"p" #:normal-text
#:italic
#:fontsize
2 ")" )))
464 dim
= #(make-span-event
'DecrescendoEvent START
)
465 enddim
= #(make-span-event
'DecrescendoEvent STOP
)
466 decresc
= #(make-span-event
'DecrescendoEvent START
)
467 enddecresc
= #(make-span-event
'DecrescendoEvent STOP
)
468 cresc
= #(make-span-event
'CrescendoEvent START
)
469 endcresc
= #(make-span-event
'CrescendoEvent STOP
)
472 \set crescendoText
= \markup { \italic "cresc." }
473 \set crescendoSpanner
= #'dashed-line
476 \set decrescendoText
= \markup { \italic "decresc." }
477 \set decrescendoSpanner
= #'dashed-line
480 \set decrescendoText
= \markup { \italic "dim." }
481 \set decrescendoSpanner
= #'dashed-line
484 newOrOldClef
= #(define-music-function
(parser location new old
) (string? string?
)
485 (if
(ly
:get-option
'old-clefs
) #{ \clef $old
#} #{ \clef $new
#})
490 %%% Thanks to "Gilles THIBAULT" <gilles.thibault@free.fr>, there is a way
491 % to remove also the fermata from R1-\fermataMarkup: By filtering the music
492 % and removing the corresponding events.
493 % Documented as an LSR snippet: http://lsr.dsi.unimi.it/LSR/Item?id=372
494 #(define
(filterOneEventsMarkup event
)
495 ( let
( (eventname
(ly
:music-property event
'name
)) )
497 (or ;; add here event name you do NOT want
498 (eq? eventname
'MultiMeasureTextEvent
)
499 (eq? eventname
'AbsoluteDynamicEvent
)
500 (eq? eventname
'TextScriptEvent
)
501 (eq? eventname
'ArticulationEvent
)
502 (eq? eventname
'CrescendoEvent
)
503 (eq? eventname
'DecrescendoEvent
)
508 filterArticulations
= #(define-music-function
(parser location music
) (ly
:music?
)
509 (music-filter filterOneEventsMarkup music
)
522 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
523 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
524 %%%%% REST COMBINATION
525 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
526 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
530 %% REST COMBINING, TAKEN FROM http://lsr.dsi.unimi.it/LSR/Item?id=336
533 %% \new Staff \with {
534 %% \override RestCollision #'positioning-done = #merge-rests-on-positioning
535 %% } << \somevoice \\ \othervoice >>
540 %% \override RestCollision #'positioning-done = #merge-rests-on-positioning
545 %% - only handles two voices
546 %% - does not handle multi-measure/whole-measure rests
548 #(define
(rest-score r
)
550 (yoff
(ly
:grob-property-data r
'Y-offset
))
551 (sp
(ly
:grob-property-data r
'staff-position
)))
553 (set
! score
(+ score
2))
554 (if
(eq? yoff
'calculation-in-progress
)
555 (set
! score
(- score
3))))
558 (set
! score
(+ score
2))
559 (set
! score
(- score
(abs
(-
1 sp
)))))
562 #(define
(merge-rests-on-positioning grob
)
563 (let
* ((can-merge
#f)
564 (elts
(ly
:grob-object grob
'elements
))
565 (num-elts
(and
(ly
:grob-array? elts
)
566 (ly
:grob-array-length elts
)))
567 (two-voice?
(= num-elts
2)))
569 (let
* ((v
1-grob
(ly
:grob-array-ref elts
0))
570 (v
2-grob
(ly
:grob-array-ref elts
1))
571 (v
1-rest
(ly
:grob-object v
1-grob
'rest
))
572 (v
2-rest
(ly
:grob-object v
2-grob
'rest
)))
576 (let
* ((v
1-duration-log
(ly
:grob-property v
1-rest
'duration-log
))
577 (v
2-duration-log
(ly
:grob-property v
2-rest
'duration-log
))
578 (v
1-dot
(ly
:grob-object v
1-rest
'dot
))
579 (v
2-dot
(ly
:grob-object v
2-rest
'dot
))
580 (v
1-dot-count
(and
(ly
:grob? v
1-dot
)
581 (ly
:grob-property v
1-dot
'dot-count -
1)))
582 (v
2-dot-count
(and
(ly
:grob? v
2-dot
)
583 (ly
:grob-property v
2-dot
'dot-count -
1))))
586 (number? v
1-duration-log
)
587 (number? v
2-duration-log
)
588 (= v
1-duration-log v
2-duration-log
)
589 (eq? v
1-dot-count v
2-dot-count
)))
591 ;; keep the rest that looks best
:
592 (let
* ((keep-v
1?
(>= (rest-score v
1-rest
)
593 (rest-score v
2-rest
)))
594 (rest-to-keep
(if keep-v
1? v
1-rest v
2-rest
))
595 (dot-to-kill
(if keep-v
1? v
2-dot v
1-dot
)))
596 ;; uncomment if you
're curious of which rest was chosen
:
597 ;;
(ly
:grob-set-property
! v
1-rest
'color green
)
598 ;;
(ly
:grob-set-property
! v
2-rest
'color blue
)
599 (ly
:grob-suicide
! (if keep-v
1? v
2-rest v
1-rest
))
600 (if
(ly
:grob? dot-to-kill
)
601 (ly
:grob-suicide
! dot-to-kill
))
602 (ly
:grob-set-property
! rest-to-keep
'direction
0)
603 (ly
:rest
::y-offset-callback rest-to-keep
)))))))
606 (ly
:rest-collision
::calc-positioning-done grob
))))
615 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
616 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
617 %%%%% TITLE PAGE / HEADER
618 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
619 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
623 scoreTitleMarkup
= \markup \piece-title
\fromproperty #'header
:piece
624 bookTitleMarkup
= \markup {
625 \override #'(baseline-skip
. 3.5)
627 \override #'(baseline-skip
. 3.5)
631 \bigger \fromproperty #'header
:title
634 \large \smaller \bold
635 \bigger \fromproperty #'header
:subtitle
639 \fromproperty #'header
:subsubtitle
642 { \large \bold \fromproperty #'header
:instrument
}
645 \fromproperty #'header
:poet
646 \fromproperty #'header
:composer
649 \fromproperty #'header
:meter
650 \fromproperty #'header
:arranger
662 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
663 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
664 %%%%% SCORE (HEADER / LAYOUT) SETTINGS
665 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
666 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
672 % after-title-space = 0.5\cm
674 ragged-last-bottom
= ##f
679 % If only one non-empty staff in a system exists, still print the backet
680 \override SystemStartBracket
#'collapse-height
= #1
684 % If only one non-empty staff in a system exists, still print the backet
685 \override SystemStartBracket
#'collapse-height
= #1
689 % Force multi-measure rests to be written as one span
690 \override MultiMeasureRest
#'expand-limit
= #3
693 hairpinToBarline
= ##f
694 \override BarNumber
#'break-visibility
= #end-of-line-invisible
695 \override CombineTextScript
#'avoid-slur
= #'outside
696 barNumberVisibility
= #(every-nth-bar-number-visible
5)
697 \override DynamicTextSpanner
#'dash-period
= #-
1.0
698 \override InstrumentSwitch
#'font-size
= #-
1
701 \override RestCollision
#'positioning-done
= #merge-rests-on-positioning
702 % Auto-Accidentals: Use modern-cautionary style...
704 autoAccidentals
= #'(Staff
(same-octave
. 0))
705 autoCautionaries
= #'(Staff
(any-octave
. 0) (same-octave
. 1))
706 printKeyCancellation
= ##t
709 \RemoveEmptyStaffContext
713 \override VerticalAxisGroup
#'minimum-Y-extent
= #'(0.5 . 0.5)
717 \consists "Instrument_name_engraver"