\version "2.22.0" %%% COLON BARLINE & AL EXTRACTED FROM bar-line.scm %%% AS THAT ONE IS NOT PUBLIC! #(define (staff-symbol-line-span grob) (let ((line-pos (ly:grob-property grob 'line-positions '())) (iv (cons 0.0 0.0))) (if (pair? line-pos) (begin (set! iv (cons (car line-pos) (car line-pos))) (for-each (lambda (x) (set! iv (cons (min (car iv) x) (max (cdr iv) x)))) (cdr line-pos))) (let ((line-count (ly:grob-property grob 'line-count 0))) (set! iv (cons (- 1 line-count) (- line-count 1))))) iv)) #(define (staff-symbol-line-positions grob) "Get or compute the @code{'line-positions} list from @var{grob}." (let ((line-pos (ly:grob-property grob 'line-positions '()))) (if (not (pair? line-pos)) (let* ((line-count (ly:grob-property grob 'line-count 0)) (height (- line-count 1.0))) (set! line-pos (map (lambda (x) (- height (* x 2))) (iota line-count))))) line-pos)) #(define (get-staff-symbol grob) "Return the staff symbol corresponding to Grob @var{grob}." (if (grob::has-interface grob 'staff-symbol-interface) grob (ly:grob-object grob 'staff-symbol))) #(define (make-colon-bar-line grob extent) "Draw repeat dots." (let* ((staff-space (ly:staff-symbol-staff-space grob)) (line-thickness (ly:staff-symbol-line-thickness grob)) (dot (ly:font-get-glyph (ly:grob-default-font grob) "dots.dot")) (dot-y-length (interval-length (ly:stencil-extent dot Y))) (stencil empty-stencil) ;; the two dots of the repeat sign should be centred at the ;; middle of the staff and neither should collide with staff ;; lines. ;; the required space is measured in line positions, ;; i.e. in half staff spaces. ;; dots are to fall into distict spaces, except when there's ;; only one space (and it's big enough to hold two dots and ;; some space between them) ;; choose defaults working without any staff (center 0.0) (dist (* 4 dot-y-length))) (if (> staff-space 0) (begin (set! dist (/ dist staff-space)) (let ((staff-symbol (get-staff-symbol grob))) (if (ly:grob? staff-symbol) (let ((line-pos (staff-symbol-line-positions staff-symbol))) (if (pair? line-pos) (begin (set! center (interval-center (staff-symbol-line-span staff-symbol))) ;; fold the staff into two at center (let* ((folded-staff (sort (map (lambda (lp) (abs (- lp center))) line-pos) <)) (gap-to-find (/ (+ dot-y-length line-thickness) (/ staff-space 2))) (first (car folded-staff))) ;; find the first space big enough ;; to hold a dot and a staff line ;; (a space in the folded staff may be ;; narrower but can't be wider than the ;; corresponding original spaces) (set! dist (or (any (lambda (x y) (and (> (- y x) gap-to-find) (+ x y))) folded-staff (cdr folded-staff)) (if (< gap-to-find first) ;; there's a central space big ;; enough to hold both dots first ;; dots should go outside (+ (* 2 (last folded-staff)) (/ (* 4 dot-y-length) staff-space)))))))))))) (set! staff-space 1.0)) (let* ((stencil empty-stencil) (stencil (ly:stencil-add stencil dot)) (stencil (ly:stencil-translate-axis stencil (* dist (/ staff-space 2)) Y)) (stencil (ly:stencil-add stencil dot)) (stencil (ly:stencil-translate-axis stencil (* (- center (/ dist 2)) (/ staff-space 2)) Y))) stencil))) %%% END OF EXTRACTED STUFF #(define ((make-custom-dot-bar-line dot-positions) grob extent) (let* ((staff-space (ly:staff-symbol-staff-space grob)) (dot (ly:stencil-scale (ly:font-get-glyph (ly:grob-default-font grob) "noteheads.s2neomensural") 0.6 0.6)) (stencil empty-stencil) (det (ly:grob-property grob 'details)) (calbl? (assoc-get 'calvin-repeat det))) (if calbl? (for-each (lambda (dp) (set! stencil (ly:stencil-add stencil (ly:stencil-translate-axis dot (* dp (/ staff-space 2)) Y)))) dot-positions) (set! stencil (make-colon-bar-line grob extent))) stencil)) #(add-bar-glyph-print-procedure ":" (make-custom-dot-bar-line '(-1 1))) calvinBL = { \override Score.BarLine.bar-extent = #'(-1 . 1) \override Score.BarLine.details.calvin-repeat = ##t } { b'1 \bar ":..:" \once\calvinBL b'1 \bar ":..:" }