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 % 0.03 (2008-07-xx): General staff/voice types, title pages, etc.
17 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
19 #(use-modules
(ice-
9 match
))
22 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
23 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
24 %%%%% SCORE STRUCTURE AND AUTOMATIC GENERATION
25 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
26 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
31 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35 % Helper function to filter all non-null entries
36 #(define
(not-null? x
) (not
(null? x
)))
38 % Helper function to extract a given variable, built from [Piece][Instrument]Identifier
39 #(define
(namedPieceInstrObject piece instr name
)
41 (fullname
(string-
>symbol
(string-append piece instr name
)))
42 (instrname
(string-
>symbol
(string-append instr name
)))
43 (piecename
(string-
>symbol
(string-append piece name
)))
46 ((defined? fullname
) (primitive-eval fullname
))
47 ((defined? instrname
) (primitive-eval instrname
))
48 ((defined? piecename
) (primitive-eval piecename
))
54 %% Print text as a justified paragraph, taken from the lilypond Notation Reference
55 #(define-markup-list-command
(paragraph layout props args
) (markup-list?
)
56 (let
((indent
(chain-assoc-get
'par-indent props
2)))
57 (interpret-markup-list layout props
58 (make-justified-lines-markup-list
(cons
(make-hspace-markup indent
)
61 conditionalBreak
= #(define-music-function
(parser location
) ()
62 #{ \tag #'instrumental-score
\pageBreak #}
65 #(define
(oly
:piece-title-markup title
) (markup
#:column
(#:line
(#:fontsize
#'3 #:bold title
))) )
67 #(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
)
145 #(define
(oly
:extractPitch music
)
147 (elems
(if
(ly
:music? music
) (ly
:music-property music
'elements
)))
148 (note
(if
(pair? elems
) (car elems
)))
149 (pitch
(if
(ly
:music? note
) (ly
:music-property note
'pitch
)))
151 (if
(and
(not-null? music
) (not
(ly
:pitch? pitch
)))
152 (ly
:warning
"Unable to interpret as a pitch!")
158 #(define
(oly
:extractTranspositionPitch piece name
)
160 (trpFromPitch
(oly
:extractPitch
(namedPieceInstrObject piece name
"TransposeFrom")))
161 (trpToPitch
(oly
:extractPitch
(namedPieceInstrObject piece name
"TransposeTo")))
163 (if
(ly
:pitch? trpFromPitch
)
164 (if
(ly
:pitch? trpToPitch
)
166 (ly
:pitch-diff trpFromPitch trpToPitch
)
167 (ly
:pitch-diff trpFromPitch
(ly
:make-pitch
0 0 0))
169 (if
(ly
:pitch? trpToPitch
)
170 (ly
:pitch-diff
(ly
:make-pitch
0 0 0) trpToPitch
)
177 #(define
(oly
:musiccontent
_for
_voice parser piece name music additional
)
178 (let
* ((musiccontent additional
))
180 ; Append the settings
, key and clef
(if defined
)
183 (let
* ((object
(namedPieceInstrObject piece name type
)))
184 (if
(ly
:music? object
)
185 (set
! musiccontent
(append musiccontent
(list
(ly
:music-deep-copy object
))))
186 (if
(not-null? object
) (ly
:warning
(_ "Wrong type (no ly:music) for ~S for instrument ~S in piece ~S") type name piece
))
190 ; TODO
: Does the
"Tempo" work here???
191 '("Settings" "Key" "Clef" "TimeSignature" ;
"Tempo"
195 (if
(ly
:music? music
)
197 (set
! musiccontent
(make-simultaneous-music
(append musiccontent
(list music
))))
198 ;
(ly
:message
"Generating staff for ~a" name
)
199 (let
* ((trpPitch
(oly
:extractTranspositionPitch piece name
)))
200 (if
(ly
:pitch? trpPitch
)
201 (set
! musiccontent
(ly
:music-transpose musiccontent trpPitch
))
206 ; For empty music
, return empty
211 #(define
(oly
:voice
_handler
_internal parser piece name type music
)
213 (lyrics
(namedPieceInstrObject piece name
"Lyrics"))
217 (if
(ly
:music? lyrics
)
218 (set
! additional
(list dynamicUp
))
219 (if
(not-null? lyrics
) (ly
:warning
(_ "Wrong type (no lyrics) for lyrics for instrument ~S in piece ~S") name piece
))
222 (if
(ly
:music? music
)
223 (let
* ((musiccontent
(oly
:musiccontent
_for
_voice parser piece name music additional
))
224 (voicename
(oly
:generate
_object
_name piece name
"Voice" ))
225 (voicetype
(oly
:staff
_type type
))
226 (voice
(context-spec-music musiccontent voicetype voicename
))
227 (staffcont
(list voice
))
229 ; I
f we have lyrics
, create
a lyrics context containing LyricCombineMusic
230 ; and add that
as second element to the staff
's elements list
...
231 (if
(ly
:music? lyrics
)
233 (lyricsname
(oly
:generate
_object
_name piece name
"Lyrics" ))
234 (lyricscont
(make-music
'LyricCombineMusic
'element lyrics
'associated-context voicename
))
236 (set
! staffcont
(append staffcont
237 (list
(context-spec-music lyricscont
'Lyrics lyricsname
))))
242 ; For empty music
, return empty
248 #(define
(oly
:voice
_handler parser piece name type
)
249 (let
* ((music
(oly
:get
_music
_object piece name
))
251 (oly
:voice
_handler
_internal parser piece name type music
)
256 #(define
(oly
:staff
_handler
_internal parser piece name type voices
)
257 (if
(not-null? voices
)
259 (staffname
(oly
:generate
_staff
_name piece name
))
260 (stafftype
(oly
:staff
_type type
))
261 (staff
(make-simultaneous-music voices
))
262 (propops
(oly
:staff
_handler
_properties piece name
))
265 ((SimultaneousMusic ParallelMusic
) #f)
266 (else
(set
! staff
(context-spec-music staff stafftype staffname
)))
268 (if
(not-null? propops
)
269 (set
! (ly
:music-property staff
'property-operations
) propops
)
273 ; For empty music
, return empty
278 #(define
(oly
:staff
_handler parser piece name type children
)
279 (let
* ((c (if
(not-null? children
) children
(list name
)))
280 (voices
(apply append
(map
(lambda
(v
) (oly
:create
_voice parser piece v
)) c)) )
282 (if
(not-null? voices
)
283 (oly
:staff
_handler
_internal parser piece name type voices
)
289 #(define
(oly
:parallel
_voices
_staff
_handler parser piece name type children
)
291 (voices
(map
(lambda
(i
) (oly
:create
_voice parser piece i
)) children
))
292 ; get the list of non-empty voices and flatten it
!
293 (nonemptyvoices
(apply append
(filter not-null? voices
)))
295 (if
(not-null? nonemptyvoices
)
296 (oly
:staff
_handler
_internal parser piece name
"Staff" nonemptyvoices
)
302 #(define
(oly
:part
_combined
_staff
_handler parser piece name type children
)
303 (let
* ((rawmusic
(map
(lambda
(c) (oly
:musiccontent
_for
_voice parser piece name
(oly
:get
_music
_object piece
c) '())) children
))
304 (music
(filter not-null? rawmusic
)))
306 ((and
(pair? music
) (ly
:music?
(car music
)) (not-null?
(cdr music
)) (ly
:music?
(cadr music
)))
307 ;
(ly
:message
"Part-combine with two music expressions")
308 (oly
:staff
_handler
_internal parser piece name
"Staff" (list
(make-part-combine-music parser music
))))
310 (ly
:warning
"Part-combine without any music expressions")
312 ; exactly one is
a music expression
, simply use that by joining
314 (ly
:message
"Part-combine with only one music expressions")
315 (oly
:staff
_handler
_internal parser piece name
"Staff" (list
(apply append music
))))
317 ;
(ly
:message
"make_part_combined_staff: ~S ~S ~a" piece instr instruments
)
323 % Generate the properties for the staff for piece and instr. Typically, these
324 % are the instrument name and the short instrument name (if defined).
325 % return a (possibly empty) list of all assignments.
326 #(define
(oly
:staff
_handler
_properties piece instr
)
329 (instrumentName
. "InstrumentName")
330 (shortInstrumentName
. "ShortInstrumentName")
331 (midiInstrument
. "MidiInstrument")
335 (oly
:generate
_property
_pair
(car pr
) piece instr
(cdr pr
))
338 (props
(filter not-null? assignments
))
344 % Figured bass is a special case, as it can be voice- or staff-type. When
345 % given as a staff type, simply call the voice handler, instead
347 #(define
(oly
:figured
_bass
_staff
_handler parser piece name type children
)
348 (let
* ((c (if
(not-null? children
) children
(list name
)))
349 (voice
(oly
:voice
_handler parser piece
(car
c) type
)))
350 (if
(pair? voice
) (car voice
) ())
355 #(define
(oly
:staff
_group
_handler parser piece name type children
)
357 (staves
(map
(lambda
(i
) (oly
:create
_staff
_or
_group parser piece i
)) children
))
358 (nonemptystaves
(filter not-null? staves
))
360 (if
(not-null? nonemptystaves
)
362 (musicexpr
(if
(= 1 (length nonemptystaves
))
364 (make-simultaneous-music nonemptystaves
)))
365 (groupname
(oly
:generate
_staff
_name piece name
))
366 (grouptype
(oly
:staff
_type type
))
368 (propops
(oly
:staff
_handler
_properties piece name
))
371 ((SimultaneousMusic ParallelMusic
) #f)
372 (else
(set
! group
(context-spec-music group grouptype groupname
)))
374 (set
! (ly
:music-property group
'property-operations
) propops
)
377 ; Return empty list if no staves are generated
383 #(define
(oly
:create
_voice parser piece name
)
384 (let
* ( (voice
(namedPieceInstrObject piece name
"Voice"))
385 (type
(assoc-ref oly
:voice
_types name
)) )
386 (if
(not-null? voice
)
387 ; Explicit voice variable
, use that
391 ; No entry in structure found
=> simple voice
392 (oly
:voice
_handler parser piece name
"Voice")
393 ; Entry found in structure
=> use the handler for the given type
395 (voicetype
(car type
))
396 (handler
(assoc-ref oly
:voice
_handlers voicetype
))
399 ((primitive-eval handler
) parser piece name voicetype
)
401 (ly
:warning
"No handler found for voice type ~a, using default voice handler" voicetype
)
402 (oly
:voice
_handler parser piece name voicetype
)
411 #(define
(oly
:create
_staff
_or
_group parser piece name
)
412 (let
* ( (staff
(namedPieceInstrObject piece name
"Staff"))
413 (type
_from
_structure
(assoc-ref oly
:orchestral
_score
_structure name
)) )
414 ;
(if
(not-null? staff
)
415 ;
(ly
:message
"Found staff variable for instrument ~a in piece ~a" instr piece
)
416 ;
(ly
:message
"Staff variable for instrument ~a in piece ~a NOT FOUND" instr piece
)
418 (if
(not-null? staff
)
419 ; Explicit staff variable
, use that
422 (if
(not
(list? type
_from
_structure
))
423 ; No entry in structure found
=> simple staff
424 (oly
:staff
_handler parser piece name
"Staff" '())
426 ; Entry found in structure
=> use the handler for the given type
427 (let
* ((type
(car type
_from
_structure
))
428 (handler
(assoc-ref oly
:staff
_handlers type
))
429 (children
(cadr type
_from
_structure
))
432 ((primitive-eval handler
) parser piece name type children
)
434 (ly
:warning
"No handler found for staff type ~a, using default staff handler" type
)
435 (oly
:staff
_handler parser piece name type children
)
444 #(define oly
:staff
_handlers
447 '("GrandStaff" . oly
:staff
_group
_handler
)
448 '("PianoStaff" . oly
:staff
_group
_handler
)
449 '("ChoirStaff" . oly
:staff
_group
_handler
)
450 '("StaffGroup" . oly
:staff
_group
_handler
)
451 '("InnerChoirStaff" . oly
:staff
_group
_handler
)
452 '("InnerStaffGroup" . oly
:staff
_group
_handler
)
453 '("ParallelMusic" . oly
:staff
_group
_handler
)
454 '("SimultaneousMusic" . oly
:staff
_group
_handler
)
456 '("Staff" . oly
:staff
_handler
)
457 '("DrumStaff" . oly
:staff
_handler
)
458 '("RhythmicStaff" . oly
:staff
_handler
)
459 '("TabStaff" . oly
:staff
_handler
)
460 '("GregorianTranscriptionStaff" . oly
:staff
_handler
)
461 '("MensuralStaff" . oly
:staff
_handler
)
462 '("VaticanaStaff" . oly
:staff
_handler
)
463 ; staves with multiple voices
464 '("PartCombinedStaff" . oly
:part
_combined
_staff
_handler
)
465 '("ParallelVoicesStaff" . oly
:parallel
_voices
_staff
_handler
)
466 ; special cases
: Figured bass can be staff or voice type
!
467 '("FiguredBass" . oly
:figured
_bass
_staff
_handler
)
471 #(define oly
:voice
_handlers
474 '("Voice" . oly
:voice
_handler
)
475 '("CueVoice" . oly
:voice
_handler
)
476 '("DrumVoice" . oly
:voice
_handler
)
477 '("FiguredBass" . oly
:voice
_handler
)
478 '("GregorianTranscriptionVoice" . oly
:voice
_handler
)
479 '("NoteNames" . oly
:voice
_handler
)
480 '("TabVoice" . oly
:voice
_handler
)
481 '("VaticanaVoice" . oly
:voice
_handler
)
482 ;
'("Dynamics" . oly
:dynamics
_handler
)
487 #(define
(oly
:register
_staff
_type
_handler type func
)
488 ;
(ly
:message
"Registering staff handler ~a for type ~a" func type
)
489 (set
! oly
:staff
_handlers
(assoc-set
! oly
:staff
_handlers type func
))
492 #(define
(oly
:register
_voice
_type
_handler type func
)
493 ;
(ly
:message
"Registering voice type handler ~a for type ~a" func type
)
494 (set
! oly
:voice
_handlers
(assoc-set
! oly
:voice
_handlers type func
))
497 % handlers for deprecated API
498 #(oly
:register
_staff
_type
_handler
'StaffGroup
'oly
:staff
_group
_handler
)
499 #(oly
:register
_staff
_type
_handler
'GrandStaff
'oly
:staff
_group
_handler
)
500 #(oly
:register
_staff
_type
_handler
'PianoStaff
'oly
:staff
_group
_handler
)
501 #(oly
:register
_staff
_type
_handler
'ChoirStaff
'oly
:staff
_group
_handler
)
502 #(oly
:register
_staff
_type
_handler
'Staff
'oly
:staff
_handler
)
503 #(oly
:register
_staff
_type
_handler
'ParallelMusic
'oly
:staff
_group
_handler
)
504 #(oly
:register
_staff
_type
_handler
'SimultaneousMusic
'oly
:staff
_group
_handler
)
505 #(oly
:register
_staff
_type
_handler
#t
'oly
:part
_combined
_staff
_handler
)
506 #(oly
:register
_staff
_type
_handler
#f 'oly
:parallel
_voices
_staff
_handler
)
510 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
511 % Automatic score generation
512 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
514 % \setUseBook ##t/##f sets a flag to determine whether the calls to createScore
515 % are from within a book block or not
516 % #(define oly:score_handler collect-scores-for-book)
517 #(define oly
:score
_handler toplevel-score-handler
)
518 #(define oly
:music
_handler toplevel-music-handler
)
519 #(define oly
:text
_handler toplevel-text-handler
)
521 setUseBook
= #(define-music-function
(parser location usebook
) (boolean?
)
524 (set
! oly
:score
_handler book-score-handler
)
525 (set
! oly
:music
_handler book-music-handler
)
526 (set
! oly
:text
_handler book-text-handler
)
529 (set
! oly
:score
_handler toplevel-score-handler
)
530 (set
! oly
:music
_handler toplevel-music-handler
)
531 (set
! oly
:text
_handler toplevel-text-handler
)
534 (make-music
'Music
'void
#t
)
538 % Two functions to handle midi-blocks: Either don't set one, or set an empty
539 % one so that MIDI is generated
540 #(define
(oly
:set
_no
_midi
_block score
) '())
541 #(define
(oly
:set
_midi
_block score
)
542 (let
* ((midiblock
(if
(defined?
'$defaultmidi
)
543 (ly
:output-def-clone $defaultmidi
)
544 (ly
:make-output-def
))))
545 (ly
:output-def-set-variable
! midiblock
'is-midi
#t
)
546 (ly
:score-add-output-def
! score midiblock
)
550 % \setCreateMidi ##t/##f sets a flag to determine wheter MIDI output should
552 #(define oly
:apply
_score
_midi oly
:set
_no
_midi
_block
)
553 setCreateMIDI
= #(define-music-function
(parser location createmidi
) (boolean?
)
555 (set
! oly
:apply
_score
_midi oly
:set
_midi
_block
)
556 (set
! oly
:apply
_score
_midi oly
:set
_no
_midi
_block
)
558 (make-music
'Music
'void
#t
)
562 % Two functions to handle layout-blocks: Either don't set one, or set an empty
563 % one so that a PDF is generated
564 #(define
(oly
:set
_no
_layout
_block score
) '())
565 #(define
(oly
:set
_layout
_block score
)
566 (let
* ((layoutblock
(if
(defined?
'$defaultlayout
)
567 (ly
:output-def-clone $defaultlayout
)
568 (ly
:make-output-def
))))
569 (ly
:output-def-set-variable
! layoutblock
'is-layout
#t
)
570 (ly
:score-add-output-def
! score layoutblock
)
574 % \setCreatePDF ##t/##f sets a flag to determine wheter PDF output should
576 #(define oly
:apply
_score
_layout oly
:set
_no
_layout
_block
)
577 setCreatePDF
= #(define-music-function
(parser location createlayout
) (boolean?
)
579 (set
! oly
:apply
_score
_layout oly
:set
_layout
_block
)
580 (set
! oly
:apply
_score
_layout oly
:set
_no
_layout
_block
)
582 (make-music
'Music
'void
#t
)
586 % Set the piece title in a new header block.
587 #(define
(oly
:set
_piece
_header score piecename
)
588 (if
(not-null? piecename
)
589 (let
* ((header
(make-module
)))
590 (module-define
! header
'piece piecename
)
591 (ly
:score-set-header
! score header
)
597 % post-filter functions. By default, no filtering is done. However,
598 % for the *NoCues* function, the cue notes should be killed
599 identity
= #(define-music-function
(parser location music
) (ly
:music?
) music
)
600 cuefilter
= #(define-music-function
(parser location music
) (ly
:music?
)
601 ((ly
:music-function-extract removeWithTag
) parser location
'cued
((ly
:music-function-extract killCues
) parser location music
))
605 #(define
(oly
:create-toc-file layout pages
)
606 (let
* ((label-table
(ly
:output-def-lookup layout
'label-page-table
))
607 (format-line
(lambda
(toc-item
)
608 (let
* ((label
(car toc-item
))
609 (text
(caddr toc-item
))
610 (label-page
(and
(list? label-table
)
611 (assoc label label-table
)))
612 (page
(and label-page
(cdr label-page
))))
613 (format
#f "~a, section, 1, {~a}, ~a" page text label
))))
614 (formatted-toc-items
(map format-line
(toc-items
)))
615 (whole-string
(string-join formatted-toc-items
",\n"))
616 (output-name
(ly
:parser-output-name parser
))
617 (outfilename
(format
"~a.toc" output-name
))
618 (outfile
(open-output-file outfilename
)))
619 (if
(output-port? outfile
)
620 (display whole-string outfile
)
621 (ly
:warning
(_ "Unable to open output file ~a for the TOC information") outfilename
))
622 (close-output-port outfile
)))
625 #(define-public
(oly
:add-toc-item parser markup-symbol text
)
626 (oly
:music
_handler parser
(add-toc-item
! markup-symbol text
)))
629 #(define
(oly
:add-score parser score piecename
)
630 (if
(not-null? piecename
)
631 (oly
:add-toc-item parser
'tocItemMarkup piecename
))
632 (oly
:score
_handler parser score
)
634 % The helper function to build a score.
635 #(define
(oly
:createScoreHelper parser location piece children func
)
637 (staves
(oly
:staff
_group
_handler parser piece
"" "SimultaneousMusic" children
))
638 (music
(if
(not-null? staves
)
639 ((ly
:music-function-extract func
) parser location staves
)
643 (piecename
(namedPieceInstrObject piece
(car children
) "PieceName"))
644 (piecenametacet
(namedPieceInstrObject piece
(car children
) "PieceNameTacet"))
648 ; No staves
, print tacet
650 (if
(not-null? piecenametacet
) (set
! piecename piecenametacet
))
651 (if
(not-null? piecename
)
652 (oly
:add-score parser
(list
(oly
:piece-title-markup piecename
)) piecename
)
653 (ly
:warning
(_ "No music and no score title found for part ~a and instrument ~a") piece children
)
656 ; we have staves
, apply the piecename to the score and add layout
/midi blocks if needed
658 (set
! score
(scorify-music music parser
))
659 (oly
:set
_piece
_header score piecename
)
660 (oly
:apply
_score
_midi score
)
661 (oly
:apply
_score
_layout score
)
662 ; Schedule the score for typesetting
663 (oly
:add-score parser score piecename
)
667 ; This is
a void function
, the score has been schedulled for typesetting already
668 (make-music
'Music
'void
#t
)
671 createScore
= #(define-music-function
(parser location piece children
) (string? list?
)
672 (oly
:createScoreHelper parser location piece children identity
)
674 createNoCuesScore
= #(define-music-function
(parser location piece children
) (string? list?
)
675 (oly
:createScoreHelper parser location piece children cuefilter
)
678 createHeadline
= #(define-music-function
(parser location headline
) (string?
)
679 (oly
:add-toc-item parser
'tocItemMarkup headline
)
680 (oly
:score
_handler parser
(list
(oly
:piece-title-markup headline
)))
681 (make-music
'Music
'void
#t
)
686 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
687 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
689 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
690 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
692 newInstrument
= #(define-music-function
(parser location instr
) (string?
)
694 \set Voice
.instrumentCueName
= #$
(string-join
(list
"+" instr
))
697 cueText
= #(define-music-function
(parser location instr
) (string?
)
699 \set Voice
.instrumentCueName
= $instr
703 % generate a cue music section with instrument names
704 % Parameters: \namedCueDuring NameOfQuote CueDirection CueInstrument OriginalInstrument music
705 % -) NameOfQuote CueDirection music are the parameters for \cueDuring
706 % -) CueInstrument and OriginalInstrument are the displayed instrument names
708 % \namedCueDuring #"vIQuote" #UP #"V.I" #"Sop." { R1*3 }
709 % This adds the notes from vIQuote (defined via \addQuote) to three measures, prints "V.I" at
710 % the beginning of the cue notes and "Sop." at the end
711 namedCueDuring
= #(define-music-function
(parser location cuevoice direction instrcue instr cuemusic
) (string? number? string? string? ly
:music?
)
713 \cueDuring #$cuevoice
#$direction
{ \tag #'cued
\cueText #$instrcue $cuemusic
\tag #'cued
\cueText #$instr
}
714 % \tag #'uncued $cuemusic
717 namedTransposedCueDuring
= #(define-music-function
(parser location cuevoice direction instrcue instr trans cuemusic
) (string? number? string? string? ly
:music? ly
:music?
)
719 \transposedCueDuring #$cuevoice
#$direction $trans
{ \tag #'cued
\cueText #$instrcue $cuemusic
\tag #'cued
\cueText #$instr
}
720 % \tag #'uncued $cuemusic
724 % set the cue instrument name and clef
725 setClefCue
= #(define-music-function
(parser location instr clef
)
728 \once \override Staff
.Clef
#'font-size
= #-
3 $clef
729 \set Voice
.instrumentCueName
= $instr
732 % generate a cue music section with instrument names and clef changes
733 % Parameters: \cleffedCueDuring NameOfQuote CueDirection CueInstrument CueClef OriginalInstrument OriginalClef music
734 % -) NameOfQuote CueDirection music are the parameters for \cueDuring
735 % -) CueInstrument and OriginalInstrument are the displayed instrument names
736 % -) CueClef and OriginalClef are the clefs for the the cue notes and the clef of the containing voice
738 % \cleffedCueDuring #"vIQuote" #UP #"V.I" #"treble" #"Basso" #"bass" { R1*3 }
739 % This adds the notes from vIQuote (defined via \addQuote) to three measures, prints "V.I" at
740 % the beginning of the cue notes and "Basso" at the end. The clef is changed to treble at the
741 % beginning of the cue notes and reset to bass at the end
742 cleffedCueDuring
= #(define-music-function
(parser location cuevoice direction instrcue clefcue instr clefinstr cuemusic
)
743 (string? number? string? ly
:music? string? ly
:music? ly
:music?
)
745 \cueDuring #$cuevoice
#$direction
{ \tag #'cued
\setClefCue #$instrcue $clefcue $cuemusic
\tag #'cued
\setClefCue #$instr $clefinstr
}
746 % \tag #'uncued $cuemusic
753 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
754 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
756 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
757 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
760 dynamicsX
= #(define-music-function
(parser location offset
) (number?
)
762 \once \override DynamicText
#'X-offset
= $offset
763 \once \override DynamicLineSpanner
#'Y-offset
= #0
766 % Move the dynamic sign inside the staff to a fixed staff-relative position
767 % posY (where 0 means vertically starts at the middle staff line)
768 dynamicsAllInside
= #(define-music-function
(parser location offsetX posY
)
771 % Invalid y-extent -> hidden from skyline calculation and collisions
772 \once \override DynamicLineSpanner
#'Y-extent
= #(cons +
0 -
0.01)
773 % move by X offset and to fixed Y-position (use Y-offset of parent!)
774 \once \override DynamicText
#'X-offset
= $offsetX
775 \once \override DynamicText
#'Y-offset
=
777 (let
* ((head
(ly
:grob-parent grob Y
))
778 (offset
(ly
:grob-property head
'Y-offset
)))
779 (- posY offset
(-
0.6))))
780 \once \override DynamicLineSpanner
#'Y-offset
= $posY
783 dynamicsUpInside
= #(define-music-function
(parser location offsetX
) (number?
)
784 ((ly
:music-function-extract dynamicsAllInside
) parser location offsetX
1.5)
787 dynamicsDownInside
= #(define-music-function
(parser location offsetX
) (number?
)
788 ((ly
:music-function-extract dynamicsAllInside
) parser location offsetX -
3.5)
791 hairpinOffset
= #(define-music-function
(parser location posY
) (number?
)
793 \once \override DynamicLineSpanner
#'Y-offset
= $posY
794 \once \override DynamicLineSpanner
#'Y-extent
= #(cons +
0 -
0.01)
797 #(define
((line-break-offset before after
) grob
)
798 (let
* ((orig
(ly
:grob-original grob
))
799 ; All siblings if line-broken
:
800 (siblings
(if
(ly
:grob? orig
) (ly
:spanner-broken-into orig
) '() )))
801 (if
(>= (length siblings
) 2)
802 ; W
e have been line-broken
803 (if
(eq?
(car
(last-pair siblings
)) grob
)
805 (ly
:grob-set-property
! grob
'Y-offset after
)
806 ; Others get the before value
:
807 (ly
:grob-set-property
! grob
'Y-offset before
)
813 ffz
= #(make-dynamic-script
"ffz")
814 pf
= #(make-dynamic-script
"pf")
815 sempp
= #(make-dynamic-script
(markup
#:line
( #:with-dimensions
'(0 . 0)
816 '(0 . 0) #:right-align
#:normal-text
#:italic
"sempre" #:dynamic
"pp")))
817 parenf
= #(make-dynamic-script
(markup
#:line
(#:normal-text
#:italic
#:fontsize
2 "(" #:dynamic
"f" #:normal-text
#:italic
#:fontsize
2 ")" )))
818 parenp
= #(make-dynamic-script
(markup
#:line
(#:normal-text
#:italic
#:fontsize
2 "(" #:dynamic
"p" #:normal-text
#:italic
#:fontsize
2 ")" )))
819 pdolce
= #(make-dynamic-script
(markup
#:line
(#:dynamic
"p" #:with-dimensions
'(0 . 0) '(0 . 0) #:normal-text
#:italic
"dolce" )))
823 cresc
= #(make-music
'CrescendoEvent
'span-direction START
'crescendoSpanner
'text
'crescendoText
"cresc.")
824 endcresc
= #(make-span-event
'CrescendoEvent STOP
)
825 dim
= #(make-music
'DecrescendoEvent
'span-direction START
'decrescendoSpanner
'text
'decrescendoText
"dim.")
826 enddim
= #(make-span-event
'DecrescendoEvent STOP
)
827 decresc
= #(make-music
'DecrescendoEvent
'span-direction START
'decrescendoSpanner
'text
'decrescendoText
"decresc.")
828 enddecresc
= #(make-span-event
'DecrescendoEvent STOP
)
834 newOrOldClef
= #(define-music-function
(parser location new old
) (string? string?
)
835 (if
(ly
:get-option
'old-clefs
) #{ \clef $old
#} #{ \clef $new
#})
840 %%% Thanks to "Gilles THIBAULT" <gilles.thibault@free.fr>, there is a way
841 % to remove also the fermata from R1-\fermataMarkup: By filtering the music
842 % and removing the corresponding events.
843 % Documented as an LSR snippet: http://lsr.dsi.unimi.it/LSR/Item?id=372
844 #(define
(filterOneEventsMarkup event
)
845 ( let
( (eventname
(ly
:music-property event
'name
)) )
847 (or ;; add here event name you do NOT want
848 (eq? eventname
'MultiMeasureTextEvent
)
849 (eq? eventname
'AbsoluteDynamicEvent
)
850 (eq? eventname
'TextScriptEvent
)
851 (eq? eventname
'ArticulationEvent
)
852 (eq? eventname
'CrescendoEvent
)
853 (eq? eventname
'DecrescendoEvent
)
858 filterArticulations
= #(define-music-function
(parser location music
) (ly
:music?
)
859 Â Â
(music-filter filterOneEventsMarkup music
)
872 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
873 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
874 %%%%% REST COMBINATION
875 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
876 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
880 %% REST COMBINING, TAKEN FROM http://lsr.dsi.unimi.it/LSR/Item?id=336
883 %% \new Staff \with {
884 %% \override RestCollision #'positioning-done = #merge-rests-on-positioning
885 %% } << \somevoice \\ \othervoice >>
890 %% \override RestCollision #'positioning-done = #merge-rests-on-positioning
895 %% - only handles two voices
896 %% - does not handle multi-measure/whole-measure rests
898 #(define
(rest-score r
)
900 (yoff
(ly
:grob-property-data r
'Y-offset
))
901 (sp
(ly
:grob-property-data r
'staff-position
)))
903 (set
! score
(+ score
2))
904 (if
(eq? yoff
'calculation-in-progress
)
905 (set
! score
(- score
3))))
908 (set
! score
(+ score
2))
909 (set
! score
(- score
(abs
(-
1 sp
)))))
912 #(define
(merge-rests-on-positioning grob
)
913 (let
* ((can-merge
#f)
914 (elts
(ly
:grob-object grob
'elements
))
915 (num-elts
(and
(ly
:grob-array? elts
)
916 (ly
:grob-array-length elts
)))
917 (two-voice?
(= num-elts
2)))
919 (let
* ((v
1-grob
(ly
:grob-array-ref elts
0))
920 (v
2-grob
(ly
:grob-array-ref elts
1))
921 (v
1-rest
(ly
:grob-object v
1-grob
'rest
))
922 (v
2-rest
(ly
:grob-object v
2-grob
'rest
)))
926 (let
* ((v
1-duration-log
(ly
:grob-property v
1-rest
'duration-log
))
927 (v
2-duration-log
(ly
:grob-property v
2-rest
'duration-log
))
928 (v
1-dot
(ly
:grob-object v
1-rest
'dot
))
929 (v
2-dot
(ly
:grob-object v
2-rest
'dot
))
930 (v
1-dot-count
(and
(ly
:grob? v
1-dot
)
931 (ly
:grob-property v
1-dot
'dot-count -
1)))
932 (v
2-dot-count
(and
(ly
:grob? v
2-dot
)
933 (ly
:grob-property v
2-dot
'dot-count -
1))))
936 (number? v
1-duration-log
)
937 (number? v
2-duration-log
)
938 (= v
1-duration-log v
2-duration-log
)
939 (eq? v
1-dot-count v
2-dot-count
)))
941 ;; keep the rest that looks best
:
942 (let
* ((keep-v
1?
(>= (rest-score v
1-rest
)
943 (rest-score v
2-rest
)))
944 (rest-to-keep
(if keep-v
1? v
1-rest v
2-rest
))
945 (dot-to-kill
(if keep-v
1? v
2-dot v
1-dot
)))
946 ;; uncomment if you
're curious of which rest was chosen
:
947 ;;
(ly
:grob-set-property
! v
1-rest
'color green
)
948 ;;
(ly
:grob-set-property
! v
2-rest
'color blue
)
949 (ly
:grob-suicide
! (if keep-v
1? v
2-rest v
1-rest
))
950 (if
(ly
:grob? dot-to-kill
)
951 (ly
:grob-suicide
! dot-to-kill
))
952 (ly
:grob-set-property
! rest-to-keep
'direction
0)
953 (ly
:rest
::y-offset-callback rest-to-keep
)))))))
956 (ly
:rest-collision
::calc-positioning-done grob
))))
962 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
963 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
964 %%%%% TABLE OF CONTENTS
965 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
966 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
969 contentsTitle
= "Inhalt / Contents"
972 tocTitleMarkup
= \markup \fill-line
{
975 \override #(cons
'line-width
(* 7 cm
))
976 \line{ \fill-line
{\piece-title
{\contentsTitle} \null }}
981 tocItemMarkup
= \markup \fill-line
{
984 \override #(cons
'line-width
(* 7 cm
))
985 \line { \fill-line
{\fromproperty #'toc
:text
\fromproperty #'toc
:page
}}
992 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
993 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
994 %%%%% TITLE PAGE / HEADER
995 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
996 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
998 #(define-markup-command
(when-property layout props symbol markp
) (symbol? markup?
)
999 (if
(chain-assoc-get symbol props
)
1000 (interpret-markup layout props markp
)
1001 (ly
:make-stencil
'() '(1 . -
1) '(1 . -
1))))
1003 #(define-markup-command
(vspace layout props amount
) (number?
)
1004 "This produces a invisible object taking vertical space."
1005 (let
((amount
(* amount
3.0)))
1007 (ly
:make-stencil
"" (cons -
1 1) (cons
0 amount
))
1008 (ly
:make-stencil
"" (cons -
1 1) (cons amount amount
)))))
1012 titlePageMarkup
= \markup \abs-fontsize
#10 \when-property
#'header
:title
\column {
1014 \fill-line
{ \fontsize #8 \fromproperty #'header
:composer
}
1016 \fill-line
{ \fontsize #8 \fromproperty #'header
:poet
}
1018 \fill-line
{ \fontsize #10 \bold \fromproperty #'header
:titlepagetitle
}
1020 \fontsize #2 \when-property
#'header
:titlepagesubtitle
{
1021 \fill-line
{ \fromproperty #'header
:titlepagesubtitle
}
1024 \fill-line
{ \postscript #"-20 0 moveto 40 0 rlineto stroke" }
1026 \fill-line
{ \fontsize #5 \fromproperty #'header
:ensemble
}
1028 \fill-line
{ \fontsize #2 \fromproperty #'header
:instruments
}
1030 \fill-line
{ \fontsize #5 \fromproperty #'header
:date
}
1032 \fill-line
{ \fontsize #5 \fromproperty #'header
:scoretype
}
1034 \fontsize #2 \when-property
#'header
:enteredby
{
1035 \fill-line
{ "Herausgegeben von: / Edited by:"}
1037 \fill-line
{ \fromproperty #'header
:enteredby
}
1040 \when-property
#'header
:arrangement
\column {
1042 \fill-line
{ \fontsize #3 \fromproperty #'header
:arrangement
}
1047 titleHeaderMarkup
= \markup {
1048 \override #'(baseline-skip
. 3.5)
1050 \override #'(baseline-skip
. 3.5)
1054 \larger \fromproperty #'header
:title
1057 \large \smaller \bold
1058 \larger \fromproperty #'header
:subtitle
1062 \fromproperty #'header
:subsubtitle
1065 { \large \bold \fromproperty #'header
:instrument
}
1068 \fromproperty #'header
:poet
1069 \fromproperty #'header
:composer
1072 \fromproperty #'header
:meter
1073 \fromproperty #'header
:arranger
1079 titleScoreMarkup
= \markup \piece-title
\fromproperty #'header
:piece
1082 scoreTitleMarkup
= \titleScoreMarkup
1083 bookTitleMarkup
= \titleHeaderMarkup
1088 %%%%%%%%%%%%%% headers and footers %%%%%%%%%%%%%%%%%%%%%%%%%%
1090 #(define
(first-score-page layout props arg
)
1091 (let
* ((label
'first-score-page
)
1092 (table
(ly
:output-def-lookup layout
'label-page-table
))
1093 (label-page
(and
(list? table
) (assoc label table
)))
1094 (page-number
(and label-page
(cdr label-page
)))
1096 (if
(eq?
(chain-assoc-get
'page
:page-number props -
1) page-number
)
1097 (interpret-markup layout props arg
)
1100 #(define no-header-table
'())
1101 thisPageNoHeader
= #(define-music-function
(parser location
) ()
1102 (let
* ((label
(gensym
"header")))
1103 (set
! no-header-table
(cons label no-header-table
))
1106 'page-label label
)))
1109 % TODO: Use the no-header-table!
1110 #(define
(is-header-page layout props arg
)
1111 (let
* ((page-number
(chain-assoc-get
'page
:page-number props -
1))
1113 ;
(if
(and
(> page-number
2) (!= page-number
7))
1114 (if
(> page-number
1)
1115 (interpret-markup layout props arg
)
1118 #(define no-footer-table
'())
1119 thisPageNoFooter
= #(define-music-function
(parser location
) ()
1120 (let
* ((label
(gensym
"footer")))
1121 (set
! no-footer-table
(cons label no-footer-table
))
1124 'page-label label
)))
1126 % TODO: Use the no-footer-table!
1127 #(define
(is-footer-page layout props arg
)
1128 (let
* ((page-number
(chain-assoc-get
'page
:page-number props -
1))
1129 (label
'first-score-page
)
1130 (table
(ly
:output-def-lookup layout
'label-page-table
))
1131 (label-page
(and
(list? table
) (assoc label table
)))
1132 ;
(page-number
(and label-page
(cdr label-page
)))
1134 (if
(and
(> page-number
3) (!= page-number
7))
1135 (interpret-markup layout props arg
)
1139 #(define copyright-footer-table
'())
1140 thisPageCopyrightFooter
= #(define-music-function
(parser location
) ()
1141 (let
* ((label
(gensym
"copyrightfooter")))
1142 (set
! copyright-footer-table
(cons label copyright-footer-table
))
1145 'page-label label
)))
1147 #(define copyright-pg
1)
1148 #(define
(set-copyright-page page
)
1149 (set
! copyright-pg page
)
1152 % TODO: Use the copyright-footer-table!
1153 #(define
(copyright-page layout props arg
)
1154 (if
(= (chain-assoc-get
'page
:page-number props -
1) copyright-pg
)
1155 (interpret-markup layout props arg
)
1160 oddHeaderMarkup
= \markup \fill-line
{
1161 %% force the header to take some space, otherwise the
1162 %% page layout becomes a complete mess.
1164 \on-the-fly
#is-header-page
\fromproperty #'header
:title
1165 \on-the-fly
#is-header-page
\fromproperty #'page
:page-number-string
1167 evenHeaderMarkup
= \markup \fill-line
{
1168 \on-the-fly
#is-header-page
\fromproperty #'page
:page-number-string
1169 \on-the-fly
#is-header-page
\fromproperty #'header
:composer
1173 oddFooterMarkup
= \markup {
1176 %% publisher header field only on title page.
1177 \on-the-fly
#first-page
\fromproperty #'header
:publisher
1180 %% copyright on the first real score page
1181 \on-the-fly
#copyright-page
\fromproperty #'header
:copyright
1182 \on-the-fly
#copyright-page
\null
1185 %% All other pages get the number of the edition centered
1186 \on-the-fly
#is-footer-page
\fromproperty #'header
:scorenumber
1203 % Interpret the given markup with the header fields added to the props.
1204 % This way, one can re-use the same functions (using fromproperty
1205 % #'header:field) in the header block and as top-level markup.
1207 % This function is originally copied from mark-up-title (file scm/titling.scm),
1208 % which is lilypond's internal function to handle the title markups. I needed
1209 % to replace the scopes and manually add the $defaultheader (which is internally
1210 % done in paper-book.cc before calling mark-up-title. Also, I don't extract the
1211 % markup from the header block, but use the given markup.
1213 % I'm not sure if I really need the page properties in props, too... But I
1214 % suppose it does not hurt, either.
1215 #(define-markup-command
(markupWithHeader layout props markup
) (markup?
)
1216 "Interpret the given markup with the header fields added to the props.
1217 This way, one can re-use the same functions (using fromproperty
1218 #'header:field) in the header block and as top-level markup."
1220 ; TODO
: I
f we are inside
a score
, add the score
's local header block
, too
!
1221 ; Currently
, I only use the global header block
, stored in $defaultheader
1222 (scopes
(list $defaultheader
))
1223 (alists
(map ly
:module-
>alist scopes
))
1226 (map
(lambda
(alist
)
1227 (map
(lambda
(entry
)
1229 (string-
>symbol
(string-append
"header:" (symbol-
>string
(car entry
))))
1233 (props
(append prefixed-alist
1235 (layout-extract-page-properties layout
)))
1237 (interpret-markup layout props markup
)
1246 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1247 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1248 %%%%% Equally spacing multiple columns (e.g. for translations)
1249 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1250 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1252 % Credits: Nicolas Sceaux on the lilypond-user mailinglist
1253 #(define-markup-command
(columns layout props args
) (markup-list?
)
1254 (let
((line-width
(/ (chain-assoc-get
'line-width props
1255 (ly
:output-def-lookup layout
'line-width
))
1256 (max
(length args
) 1))))
1257 (interpret-markup layout props
1258 (make-line-markup
(map
(lambda
(line
)
1259 (markup
#:pad-to-box `
(0 . ,line-width
) '(0 . 0)
1260 #:override `
(line-width
. ,line-width
)
1268 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1269 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1270 %%%%% SCORE (HEADER / LAYOUT) SETTINGS
1271 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1272 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1275 % left-margin = 2\cm
1276 % right-margin = 2\cm
1277 % line-width = 17\cm
1278 % bottom-margin = 1\cm
1280 % after-title-space = 0.5\cm
1284 ragged-last-bottom
= ##f
1289 % If only one non-empty staff in a system exists, still print the backet
1290 \override SystemStartBracket
#'collapse-height
= #1
1291 \consists "Instrument_name_engraver"
1295 % If only one non-empty staff in a system exists, still print the backet
1296 \override SystemStartBracket
#'collapse-height
= #1
1297 \consists "Instrument_name_engraver"
1301 \override SystemStartBracket
#'collapse-height
= #1
1302 \consists "Instrument_name_engraver"
1306 % \override VerticalAxisGroup #'keep-fixed-while-stretching = ##t
1310 % \override VerticalAxisGroup #'keep-fixed-while-stretching = ##t
1311 \override VerticalAxisGroup
#'minimum-Y-extent
= #'(0 . 1)
1312 \override VerticalAxisGroup
#'padding
= #0
1316 % Force multi-measure rests to be written as one span
1317 \override MultiMeasureRest
#'expand-limit
= #3
1320 % hairpinToBarline = ##f
1321 \override BarNumber
#'break-visibility
= #end-of-line-invisible
1322 \override CombineTextScript
#'avoid-slur
= #'outside
1323 barNumberVisibility
= #(every-nth-bar-number-visible
5)
1324 \override DynamicTextSpanner
#'dash-period
= #-
1.0
1325 \override InstrumentSwitch
#'font-size
= #-
1
1328 \override RestCollision
#'positioning-done
= #merge-rests-on-positioning
1329 % Auto-Accidentals: Use modern-cautionary style...
1331 autoAccidentals
= #`
(Staff
,(make-accidental-rule
'same-octave
0))
1332 autoCautionaries
= #`
(Staff
,(make-accidental-rule
'any-octave
0)
1333 ,(make-accidental-rule
'same-octave
1))
1334 printKeyCancellation
= ##t
1337 \RemoveEmptyStaffContext
1341 \override VerticalAxisGroup
#'minimum-Y-extent
= #'(0.5 . 0.5)
1349 \type "Engraver_group"
1351 % So that \cresc works, for example.
1353 \consists "Output_property_engraver"
1355 \override VerticalAxisGroup
#'minimum-Y-extent
= #'(-
1 . 1)
1356 pedalSustainStrings
= #'("Ped." "*Ped." "*")
1357 pedalUnaCordaStrings
= #'("una corda" "" "tre corde")
1359 \consists "Piano_pedal_engraver"
1360 \consists "Script_engraver"
1361 \consists "Dynamic_engraver"
1362 \consists "Text_engraver"
1364 \override TextScript
#'font-size
= #2
1365 \override TextScript
#'font-shape
= #'italic
1366 \override DynamicText
#'extra-offset
= #'(0 . 2.5)
1367 \override Hairpin
#'extra-offset
= #'(0 . 2.5)
1369 \consists "Skip_event_swallow_translator"
1371 \consists "Axis_group_engraver"
1376 % \override VerticalAlignment #'forced-distance = #7