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 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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
)
103 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
104 % Automatic staff and group generation
105 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
107 % Retrieve all music definitions for the given
108 #(define
(oly
:get
_music
_objects piece name instruments
)
109 (filter not-null?
(map
(lambda
(i
) (namedPieceInstrObject piece i
"Music")) instruments
))
112 #(define
(oly
:make
_staff
_internal piece name music
)
114 (tempo
(namedPieceInstrObject piece name
"Tempo"))
115 (lyrics
(namedPieceInstrObject piece name
"Lyrics"))
118 ;
(ly
:message
"Music in make_staff_internal (piece=~S, name=~S)" piece name
)
120 (if
(ly
:music? lyrics
)
121 (set
! musiccontent
(append musiccontent
(list dynamicUp
)))
122 (if
(not-null? lyrics
) (ly
:warning
(_ "Wrong type (no lyrics) for lyrics for instrument ~S in piece ~S") name piece
))
124 ; Append the settings
, key and clef
(if defined
)
127 (let
* ((object
(namedPieceInstrObject piece name type
)))
128 (if
(ly
:music? object
)
129 (set
! musiccontent
(append musiccontent
(list object
)))
130 (if
(not-null? object
) (ly
:warning
(_ "Wrong type (no ly:music) for ~S for instrument ~S in piece ~S") type name piece
))
134 '("Settings" "Key" "Clef")
137 (if
(ly
:music? music
)
139 (set
! musiccontent
(append musiccontent
(list music
)))
140 ;
(ly
:message
"Generating staff for ~a" name
)
143 (voicename
(oly
:generate
_object
_name piece name
"Voice" ))
144 (staffname
(oly
:generate
_staff
_name piece name
))
145 (voice
(context-spec-music
(make-simultaneous-music musiccontent
) 'Voice voicename
))
147 (staffcont
(list voice
))
148 (propops
(oly
:make
_staff
_properties piece name
))
150 ; I
f we have lyrics
, create
a lyrics context containing LyricCombineMusic
151 ; and add that
as second element to the staff
's elements list
...
152 (if
(ly
:music? lyrics
)
154 (lyricsname
(oly
:generate
_object
_name piece name
"Lyrics" ))
155 (lyricscont
(make-music
'LyricCombineMusic
'element lyrics
'associated-context voicename
))
157 (set
! staffcont
(append staffcont
158 (list
(context-spec-music lyricscont
'Lyrics lyricsname
))))
161 (set
! staff
(context-spec-music
(make-simultaneous-music staffcont
) 'Staff staffname
))
162 (if
(not-null? propops
)
163 (set
! (ly
:music-property staff
'property-operations
) propops
)
168 ; For empty music
, return empty
174 % TODO: Implement one-staff with multiple voices (\voiceOne and \voiceTwo),
175 % possibly with lyrics attached
176 #(define
(oly
:make
_multi
_voice
_staff parser piece instr voices
)
177 (ly
:message
"Generating a staff with multiple voices is not yet implemented, using 'SimultaneousMusic instead. Staff ID: ~a, voices: ~a" instr voices
)
178 (oly
:make
_parallel
_staves parser piece instr voices
)
181 #(define
(oly
:make
_staff parser piece instr
)
182 (let
* ( (music
(namedPieceInstrObject piece instr
"Music")) )
183 ;
(ly
:message
"make_staff: ~S ~S" piece instr
)
184 (if
(not-null? music
)
185 (oly
:make
_staff
_internal piece instr music
)
191 #(define
(oly
:make
_parallel
_staves parser piece instr instruments
)
193 (staves
(map
(lambda
(i
) (oly
:create
_staff
_or
_group parser piece i
)) instruments
))
194 (nonemptystaves
(filter not-null? staves
))
196 (if
(not-null? nonemptystaves
)
197 (make-simultaneous-music nonemptystaves
)
203 #(define
(oly
:make
_part
_combined
_staff parser piece instr instruments
)
204 (let
* ((music
(oly
:get
_music
_objects piece instr instruments
)))
205 ;
(ly
:message
"make_part_combined_staff: ~S ~S ~a" piece instr instruments
)
207 ((and
(pair? music
) (ly
:music?
(car music
)) (not-null?
(cdr music
)) (ly
:music?
(cadr music
)))
208 ;
(ly
:message
"Part-combine with two music expressions")
209 (oly
:make
_staff
_internal piece instr
(make-part-combine-music parser music
)))
211 ;
(ly
:message
"Part-combine without any music expressions")
213 ; exactly one is
a music expression
, simply use that by joining
215 ;
(ly
:message
"Part-combine with only one music expressions")
216 (oly
:make
_staff
_internal piece instr
(apply append music
)))
218 ;
(ly
:message
"make_part_combined_staff: ~S ~S ~a" piece instr instruments
)
224 #(define
(oly
:create
_staff
_or
_group parser piece instr
)
225 (let
* ( (staff
(namedPieceInstrObject piece instr
"Staff")) )
226 ;
(if
(not-null? staff
)
227 ;
(ly
:message
"Found staff variable for instrument ~a in piece ~a" instr piece
)
228 ;
(ly
:message
"Staff variable for instrument ~a in piece ~a NOT FOUND" instr piece
)
230 (if
(not-null? staff
)
231 ; Explicit staff variable
, use that
233 ; no staff defined
=> check hierarchy definition and match
a possible entry
234 ; against the four allowed forms
235 (match
(assoc-ref oly
:orchestral
_score
_structure instr
)
236 ; type
(ParallelMusic|SimultaneousMusic
("sub" "instruments"...))
238 ( ((or
'ParallelMusic
'SimultaneousMusic
) (? list? subinstr
))
239 (oly
:make
_parallel
_staves parser piece instr subinstr
) )
241 ; type
(StaffGroupType
("sub" "instruments"...)), generate staff group
242 ( ((? symbol? stafftype
) (? list? subinstr
))
243 (oly
:make
_staff
_group parser piece instr stafftype subinstr
) )
245 ; type
(#t
("sub" "instruments")) => part-combined staff
246 ( (#t
((? string? instone
) (? string? insttwo
)))
247 (oly
:make
_part
_combined
_staff parser piece instr
(list instone insttwo
)) )
249 ; type
(#f ("sub" "instruments")) => staff with multiple voices
250 ( (#f (? list? subinstr
))
251 (oly
:make
_multi
_voice
_staff parser piece instr subinstr
) )
253 ; not found in score history -
> simple staff
255 (oly
:make
_staff parser piece instr
) )
257 ; Any other type is invalid
, treat it like
a simple staff
!
259 (ly
:warning
(_ "Encountered illegal entry ~S in score structure for instrument ~a") invalidform instr
)
260 (ly
:warning
(_ "Trying to interpret ~S as a simple instrument") instr
)
261 (oly
:make
_staff parser piece instr
) )
267 % Given a property name and the extensions, either generate the pair to set
268 % the property or an empty list, if no pre-defined variable could be found
269 #(define
(oly
:generate
_property
_pair prop piece instr type
)
270 (let
* ((val
(namedPieceInstrObject piece instr type
)))
271 (if
(not-null? val
) (list
'assign prop val
) '() )
274 % Generate the properties for the staff for piece and instr. Typically, these
275 % are the instrument name and the short instrument name (if defined).
276 % return a (possibly empty) list of all assignments.
277 #(define
(oly
:make
_staff
_properties piece instr
)
280 (instrumentName
. "InstrumentName")
281 (shortInstrumentName
. "ShortInstrumentName")
282 (midiInstrument
. "MidiInstrument")
286 (oly
:generate
_property
_pair
(car pr
) piece instr
(cdr pr
))
289 (props
(filter not-null? assignments
))
296 #(define
(oly
:make
_staff
_group parser piece instr stafftype instruments
)
298 (staves
(oly
:make
_parallel
_staves parser piece instr instruments
))
300 (if
(not-null? staves
)
302 (staffname
(oly
:generate
_staff
_name piece instr
))
303 (group
(context-spec-music staves stafftype staffname
))
304 (propops
(oly
:make
_staff
_properties piece instr
))
306 (set
! (ly
:music-property group
'property-operations
) propops
)
309 ; Return empty list if no staves are generated
316 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
317 % Automatic score generation
318 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
320 % \setUserBook ##t/##f sets a flat to determine whether the calls to createScore
321 % are from within a book block or not
322 #(define oly
:score
_handler collect-scores-for-book
)
323 setUseBook
= #(define-music-function
(parser location usebook
) (boolean?
)
325 (set
! oly
:score
_handler book-score-handler
)
326 (set
! oly
:score
_handler toplevel-score-handler
)
328 (make-music
'Music
'void
#t
)
332 % Two functions to handle midi-blocks: Either don't set one, or set an empty
333 % one so that MIDI is generated
334 #(define
(oly
:set
_no
_midi
_block score
) '())
335 #(define
(oly
:set
_midi
_block score
)
336 (let
* ((midiblock
(if
(defined?
'$defaultmidi
)
337 (ly
:output-def-clone $defaultmidi
)
338 (ly
:make-output-def
))))
339 (ly
:output-def-set-variable
! midiblock
'is-midi
#t
)
340 (ly
:score-add-output-def
! score midiblock
)
344 % \setCreateMidi ##t/##f sets a flag to determine wheter MIDI output should
346 #(define oly
:apply
_score
_midi oly
:set
_no
_midi
_block
)
347 setCreateMIDI
= #(define-music-function
(parser location createmidi
) (boolean?
)
349 (set
! oly
:apply
_score
_midi oly
:set
_midi
_block
)
350 (set
! oly
:apply
_score
_midi oly
:set
_no
_midi
_block
)
352 (make-music
'Music
'void
#t
)
356 % Two functions to handle layout-blocks: Either don't set one, or set an empty
357 % one so that a PDF is generated
358 #(define
(oly
:set
_no
_layout
_block score
) '())
359 #(define
(oly
:set
_layout
_block score
)
360 (let
* ((layoutblock
(if
(defined?
'$defaultlayout
)
361 (ly
:output-def-clone $defaultlayout
)
362 (ly
:make-output-def
))))
363 (ly
:output-def-set-variable
! layoutblock
'is-layout
#t
)
364 (ly
:score-add-output-def
! score layoutblock
)
368 % \setCreatePDF ##t/##f sets a flag to determine wheter PDF output should
370 #(define oly
:apply
_score
_layout oly
:set
_no
_layout
_block
)
371 setCreatePDF
= #(define-music-function
(parser location createlayout
) (boolean?
)
373 (set
! oly
:apply
_score
_layout oly
:set
_layout
_block
)
374 (set
! oly
:apply
_score
_layout oly
:set
_no
_layout
_block
)
376 (make-music
'Music
'void
#t
)
380 % Set the piece title in a new header block.
381 #(define
(oly
:set
_piece
_header score piecename
)
382 (if
(not-null? piecename
)
383 (let
* ((header
(make-module
)))
384 (module-define
! header
'piece piecename
)
385 (ly
:score-set-header
! score header
)
392 % post-filter functions. By default, no filtering is done. However,
393 % for the *NoCues* function, the cue notes should be killed
394 identity
= #(define-music-function
(parser location music
) (ly
:music?
) music
)
395 cuefilter
= #(define-music-function
(parser location music
) (ly
:music?
)
396 ((ly
:music-function-extract removeWithTag
) parser location
'cued
((ly
:music-function-extract killCues
) parser location music
))
399 % The helper function to build a score.
400 #(define
(oly
:createScoreHelper parser location part instr func
)
402 (staves
(oly
:make
_parallel
_staves parser part
"topLevel" instr
))
403 (music
(if
(not-null? staves
)
404 ((ly
:music-function-extract func
) parser location staves
)
408 (piecename
(namedPieceInstrObject part
(car instr
) "PieceName"))
409 (piecenametacet
(namedPieceInstrObject part
(car instr
) "PieceNameTacet"))
413 ; No staves
, print tacet
415 (if
(not-null? piecenametacet
) (set
! piecename piecenametacet
))
416 (if
(not-null? piecename
)
417 (collect-scores-for-book parser
(list
(oly
:piece-title-markup piecename
)))
418 (ly
:warning
(_ "No music and no score title found for part ~a and instrument ~a") part instr
)
421 ; we have staves
, apply the piecename to the score and add layout
/midi blocks if needed
423 (set
! score
(scorify-music music parser
))
424 (oly
:set
_piece
_header score piecename
)
425 (oly
:apply
_score
_midi score
)
426 (oly
:apply
_score
_layout score
)
427 ; Schedule the score for typesetting
428 (collect-scores-for-book parser score
)
432 ; This is
a void function
, the score has been schedulled for typesetting already
433 (make-music
'Music
'void
#t
)
436 createScore
= #(define-music-function
(parser location piece instr
) (string? list?
)
437 (oly
:createScoreHelper parser location piece instr identity
)
439 createNoCuesScore
= #(define-music-function
(parser location piece instr
) (string? list?
)
440 (oly
:createScoreHelper parser location piece instr cuefilter
)
447 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
448 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
450 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
451 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
453 % set the cue instrument name
454 setCue
= #(define-music-function
(parser location instr
) (string?
)
455 #{ \set Voice
.instrumentCueName
= $instr
#} )
457 % generate a cue music section with instrument names
458 % Parameters: \namedCueDuring NameOfQuote CueDirection CueInstrument OriginalInstrument music
459 % -) NameOfQuote CueDirection music are the parameters for \cueDuring
460 % -) CueInstrument and OriginalInstrument are the displayed instrument names
462 % \namedCueDuring #"vIQuote" #UP #"V.I" #"Sop." { R1*3 }
463 % This adds the notes from vIQuote (defined via \addQuote) to three measures, prints "V.I" at
464 % the beginning of the cue notes and "Sop." at the end
465 namedCueDuring
= #(define-music-function
(parser location cuevoice direction instrcue instr cuemusic
) (string? number? string? string? ly
:music?
)
467 \cueDuring #$cuevoice
#$direction
{ \tag #'cued
\setCue #$instrcue $cuemusic
\tag #'cued
\setCue #$instr
}
468 % \tag #'uncued $cuemusic
471 namedTransposedCueDuring
= #(define-music-function
(parser location cuevoice direction instrcue instr trans cuemusic
) (string? number? string? string? ly
:music? ly
:music?
)
473 \transposedCueDuring #$cuevoice
#$direction $trans
{ \tag #'cued
\setCue #$instrcue $cuemusic
\tag #'cued
\setCue #$instr
}
474 % \tag #'uncued $cuemusic
478 % set the cue instrument name and clef
479 setClefCue
= #(define-music-function
(parser location instr clef
)
482 \once \override Staff
.Clef
#'font-size
= #-
3 $clef
483 \set Voice
.instrumentCueName
= $instr
486 % generate a cue music section with instrument names and clef changes
487 % Parameters: \cleffedCueDuring NameOfQuote CueDirection CueInstrument CueClef OriginalInstrument OriginalClef music
488 % -) NameOfQuote CueDirection music are the parameters for \cueDuring
489 % -) CueInstrument and OriginalInstrument are the displayed instrument names
490 % -) CueClef and OriginalClef are the clefs for the the cue notes and the clef of the containing voice
492 % \cleffedCueDuring #"vIQuote" #UP #"V.I" #"treble" #"Basso" #"bass" { R1*3 }
493 % This adds the notes from vIQuote (defined via \addQuote) to three measures, prints "V.I" at
494 % the beginning of the cue notes and "Basso" at the end. The clef is changed to treble at the
495 % beginning of the cue notes and reset to bass at the end
496 cleffedCueDuring
= #(define-music-function
(parser location cuevoice direction instrcue clefcue instr clefinstr cuemusic
)
497 (string? number? string? ly
:music? string? ly
:music? ly
:music?
)
499 \cueDuring #$cuevoice
#$direction
{ \tag #'cued
\setClefCue #$instrcue $clefcue $cuemusic
\tag #'cued
\setClefCue #$instr $clefinstr
}
500 % \tag #'uncued $cuemusic
507 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
508 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
510 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
511 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
513 tempoMark
= #(define-music-function
(parser location padding marktext
) (number? string?
)
515 \once \override Score
. RehearsalMark
#'padding
= $padding
516 \mark \markup { \bold \smaller $marktext
}
519 shiftDynamics
= #(define-music-function
(parser location xshift yshift
) (number? number?
)
521 \once \override DynamicTextSpanner
#'padding
= $yshift
522 \once\override DynamicText
#'extra-offset
= #(cons $xshift $yshift
)
525 ffz
= #(make-dynamic-script
"ffz")
526 pf
= #(make-dynamic-script
"pf")
527 sempp
= #(make-dynamic-script
(markup
#:line
( #:with-dimensions
'(0 . 0)
528 '(0 . 0) #:right-align
#:normal-text
#:italic
"sempre" #:dynamic
"pp")))
529 parenf
= #(make-dynamic-script
(markup
#:line
(#:normal-text
#:italic
#:fontsize
2 "(" #:dynamic
"f" #:normal-text
#:italic
#:fontsize
2 ")" )))
530 parenp
= #(make-dynamic-script
(markup
#:line
(#:normal-text
#:italic
#:fontsize
2 "(" #:dynamic
"p" #:normal-text
#:italic
#:fontsize
2 ")" )))
534 dim
= #(make-span-event
'DecrescendoEvent START
)
535 enddim
= #(make-span-event
'DecrescendoEvent STOP
)
536 decresc
= #(make-span-event
'DecrescendoEvent START
)
537 enddecresc
= #(make-span-event
'DecrescendoEvent STOP
)
538 cresc
= #(make-span-event
'CrescendoEvent START
)
539 endcresc
= #(make-span-event
'CrescendoEvent STOP
)
542 \set crescendoText
= \markup { \italic "cresc." }
543 \set crescendoSpanner
= #'dashed-line
546 \set decrescendoText
= \markup { \italic "decresc." }
547 \set decrescendoSpanner
= #'dashed-line
550 \set decrescendoText
= \markup { \italic "dim." }
551 \set decrescendoSpanner
= #'dashed-line
554 newOrOldClef
= #(define-music-function
(parser location new old
) (string? string?
)
555 (if
(ly
:get-option
'old-clefs
) #{ \clef $old
#} #{ \clef $new
#})
560 %%% Thanks to "Gilles THIBAULT" <gilles.thibault@free.fr>, there is a way
561 % to remove also the fermata from R1-\fermataMarkup: By filtering the music
562 % and removing the corresponding events.
563 % Documented as an LSR snippet: http://lsr.dsi.unimi.it/LSR/Item?id=372
564 #(define
(filterOneEventsMarkup event
)
565 ( let
( (eventname
(ly
:music-property event
'name
)) )
567 (or ;; add here event name you do NOT want
568 (eq? eventname
'MultiMeasureTextEvent
)
569 (eq? eventname
'AbsoluteDynamicEvent
)
570 (eq? eventname
'TextScriptEvent
)
571 (eq? eventname
'ArticulationEvent
)
572 (eq? eventname
'CrescendoEvent
)
573 (eq? eventname
'DecrescendoEvent
)
578 filterArticulations
= #(define-music-function
(parser location music
) (ly
:music?
)
579 (music-filter filterOneEventsMarkup music
)
592 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
593 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
594 %%%%% REST COMBINATION
595 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
596 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
600 %% REST COMBINING, TAKEN FROM http://lsr.dsi.unimi.it/LSR/Item?id=336
603 %% \new Staff \with {
604 %% \override RestCollision #'positioning-done = #merge-rests-on-positioning
605 %% } << \somevoice \\ \othervoice >>
610 %% \override RestCollision #'positioning-done = #merge-rests-on-positioning
615 %% - only handles two voices
616 %% - does not handle multi-measure/whole-measure rests
618 #(define
(rest-score r
)
620 (yoff
(ly
:grob-property-data r
'Y-offset
))
621 (sp
(ly
:grob-property-data r
'staff-position
)))
623 (set
! score
(+ score
2))
624 (if
(eq? yoff
'calculation-in-progress
)
625 (set
! score
(- score
3))))
628 (set
! score
(+ score
2))
629 (set
! score
(- score
(abs
(-
1 sp
)))))
632 #(define
(merge-rests-on-positioning grob
)
633 (let
* ((can-merge
#f)
634 (elts
(ly
:grob-object grob
'elements
))
635 (num-elts
(and
(ly
:grob-array? elts
)
636 (ly
:grob-array-length elts
)))
637 (two-voice?
(= num-elts
2)))
639 (let
* ((v
1-grob
(ly
:grob-array-ref elts
0))
640 (v
2-grob
(ly
:grob-array-ref elts
1))
641 (v
1-rest
(ly
:grob-object v
1-grob
'rest
))
642 (v
2-rest
(ly
:grob-object v
2-grob
'rest
)))
646 (let
* ((v
1-duration-log
(ly
:grob-property v
1-rest
'duration-log
))
647 (v
2-duration-log
(ly
:grob-property v
2-rest
'duration-log
))
648 (v
1-dot
(ly
:grob-object v
1-rest
'dot
))
649 (v
2-dot
(ly
:grob-object v
2-rest
'dot
))
650 (v
1-dot-count
(and
(ly
:grob? v
1-dot
)
651 (ly
:grob-property v
1-dot
'dot-count -
1)))
652 (v
2-dot-count
(and
(ly
:grob? v
2-dot
)
653 (ly
:grob-property v
2-dot
'dot-count -
1))))
656 (number? v
1-duration-log
)
657 (number? v
2-duration-log
)
658 (= v
1-duration-log v
2-duration-log
)
659 (eq? v
1-dot-count v
2-dot-count
)))
661 ;; keep the rest that looks best
:
662 (let
* ((keep-v
1?
(>= (rest-score v
1-rest
)
663 (rest-score v
2-rest
)))
664 (rest-to-keep
(if keep-v
1? v
1-rest v
2-rest
))
665 (dot-to-kill
(if keep-v
1? v
2-dot v
1-dot
)))
666 ;; uncomment if you
're curious of which rest was chosen
:
667 ;;
(ly
:grob-set-property
! v
1-rest
'color green
)
668 ;;
(ly
:grob-set-property
! v
2-rest
'color blue
)
669 (ly
:grob-suicide
! (if keep-v
1? v
2-rest v
1-rest
))
670 (if
(ly
:grob? dot-to-kill
)
671 (ly
:grob-suicide
! dot-to-kill
))
672 (ly
:grob-set-property
! rest-to-keep
'direction
0)
673 (ly
:rest
::y-offset-callback rest-to-keep
)))))))
676 (ly
:rest-collision
::calc-positioning-done grob
))))
685 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
686 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
687 %%%%% TITLE PAGE / HEADER
688 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
689 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
693 scoreTitleMarkup
= \markup \piece-title
\fromproperty #'header
:piece
694 bookTitleMarkup
= \markup {
695 \override #'(baseline-skip
. 3.5)
697 \override #'(baseline-skip
. 3.5)
701 \bigger \fromproperty #'header
:title
704 \large \smaller \bold
705 \bigger \fromproperty #'header
:subtitle
709 \fromproperty #'header
:subsubtitle
712 { \large \bold \fromproperty #'header
:instrument
}
715 \fromproperty #'header
:poet
716 \fromproperty #'header
:composer
719 \fromproperty #'header
:meter
720 \fromproperty #'header
:arranger
732 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
733 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
734 %%%%% SCORE (HEADER / LAYOUT) SETTINGS
735 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
736 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
742 % after-title-space = 0.5\cm
744 ragged-last-bottom
= ##f
749 % If only one non-empty staff in a system exists, still print the backet
750 \override SystemStartBracket
#'collapse-height
= #1
754 % If only one non-empty staff in a system exists, still print the backet
755 \override SystemStartBracket
#'collapse-height
= #1
759 % Force multi-measure rests to be written as one span
760 \override MultiMeasureRest
#'expand-limit
= #3
763 hairpinToBarline
= ##f
764 \override BarNumber
#'break-visibility
= #end-of-line-invisible
765 \override CombineTextScript
#'avoid-slur
= #'outside
766 barNumberVisibility
= #(every-nth-bar-number-visible
5)
767 \override DynamicTextSpanner
#'dash-period
= #-
1.0
768 \override InstrumentSwitch
#'font-size
= #-
1
771 \override RestCollision
#'positioning-done
= #merge-rests-on-positioning
772 % Auto-Accidentals: Use modern-cautionary style...
774 autoAccidentals
= #'(Staff
(same-octave
. 0))
775 autoCautionaries
= #'(Staff
(any-octave
. 0) (same-octave
. 1))
776 printKeyCancellation
= ##t
779 \RemoveEmptyStaffContext
783 \override VerticalAxisGroup
#'minimum-Y-extent
= #'(0.5 . 0.5)
787 \consists "Instrument_name_engraver"