%%% -*- Mode: scheme -*- %%% %%% Tagging functions %%% #(use-modules (srfi srfi-1)) #(define* (has-some-member? list1 list2 #:key (test eqv?)) "Return a true value iif there exists an element of list1 that also belongs to list2 under test." (if (null? list1) #f (or (member (car list1) list2 test) (has-some-member? (cdr list1) list2 #:test test)))) #(define (symbol-or-symbols? x) (or (null? x) (symbol? x) (and (list? x) (every symbol? x)))) keepWithTag = #(define-music-function (parser location tags music) (symbol-or-symbols? ly:music?) (music-filter (lambda (m) (let ((m.tags (ly:music-property m 'tags))) (cond ((symbol? tags) (or (null? m.tags) (memq tags m.tags))) ((null? tags) (null? m.tags)) ((list? tags) (or (null? m.tags) (has-some-member? tags m.tags))) (else #t)))) music)) tag = #(define-music-function (parser location tags arg) (symbol-or-symbols? ly:music?) "Add @var{tags} (a single tag or a list of tags) to the @code{tags} property of @var{arg}." (set! (ly:music-property arg 'tags) (if (symbol? tags) (cons tags (ly:music-property arg 'tags)) (append tags (ly:music-property arg 'tags)))) arg) %%% %%% Repeat alternatives %%% firstAndSecondTime = #(define-music-function (parser location first second) (ly:music? ly:music?) #{ \set Score.repeatCommands = #'((volta "1.")) $first \bar ":|" \set Score.repeatCommands = #'((volta #f) (volta "2.")) $second \set Score.repeatCommands = #'((volta #f)) #}) %%% %%% smaller notes %%% smallNotes = #(define-music-function (parser location music) (ly:music?) (let ((first-chord-already-found #f) (last-chord #f) (start-beam (make-music 'BeamEvent 'span-direction -1)) (end-beam (make-music 'BeamEvent 'span-direction 1)) (note-count 0)) ;; Add [ beaming directive to the first chord (music-map (lambda (event) (cond ((eqv? (ly:music-property event 'name) 'EventChord) (cond ((not first-chord-already-found) ;; the first ChordEvent: add start beam (set! first-chord-already-found #t) (set! (ly:music-property event 'elements) (cons start-beam (ly:music-property event 'elements)))) (else (set! last-chord event)))) ((eqv? (ly:music-property event 'name) 'NoteEvent) (set! note-count (1+ note-count)))) event) music) ;; Add ] beaming directive to the last chord (set! (ly:music-property last-chord 'elements) (cons end-beam (ly:music-property last-chord 'elements))) ;; If there are 3 notes, add a *2/3 duration factor (if (= note-count 3) (music-map (lambda (event) (if (eqv? (ly:music-property event 'name) 'NoteEvent) (let* ((duration (ly:music-property event 'duration)) (dot-count (ly:duration-dot-count duration)) (log (ly:duration-log duration))) (set! (ly:music-property event 'duration) (ly:make-duration log dot-count 2 3)))) event) music))) #{ \override Voice.NoteHead #'font-size = #-3 \override Voice.Stem #'font-size = #-3 \override Voice.NoteHead #'font-size = #-3 \override Voice.Accidental #'font-size = #-4 $music \revert Voice.NoteHead #'font-size \revert Voice.Stem #'font-size \revert Voice.NoteHead #'font-size \revert Voice.Accidental #'font-size #}) %%% %%% Custos note heads %%% custosNote = #(define-music-function (parser location note) (ly:music?) (make-music 'SequentialMusic 'elements (list #{ \once \override Voice.NoteHead #'stencil = #ly:text-interface::print \once \override Voice.NoteHead #'text = #(markup #:null #:raise 0.0 #:musicglyph "custodes.mensural.u0") \once \override Voice.Stem #'stencil = ##f #} note))) cosmeticPageBreak = #(define-music-function (parser location sym) (symbol?) (if (or (eqv? sym 'all) (and (eqv? sym 'letter) (ly:get-option 'letter)) (and (eqv? sym 'a4) (not (ly:get-option 'letter)))) (make-music 'EventChord 'page-marker #t 'line-break-permission 'force 'page-break-permission 'force) (make-music 'Music 'void #t)))