Hello Calvin,

we can use grob properties to change the behaviour of the function. This 
example uses the flag details.calvin-repeat to switch to this behaviour. Else 
it default to make-colon-bar-line (which is not public, so we need to extract 
it from bar-line.scm).

This would be easier if Lilypond had a bit more scheme functionality for not 
only setting stuff in internal alists, but also for retrieving and removing 
such things. If we had something like this we could do

#(define default (get-bar-glyph-print-procedure))
#(define ((...) ...)
  ...
  (if customized? ... (default ...)+

Cheers,
Valentin

Am Mittwoch, 2. März 2022, 06:22:01 CET schrieb Calvin Ransom:
> Hello everyone,
> Can I have some help making a repeat sign that looks like the image
> attached? I figured out how to reduce the height of the bar lines, but I am
> unable to properly change the dots to diamonds. Right now, I have adapted
> the code from LSR 913<https://lsr.di.unimi.it/LSR/Item?id=913> by changing
> the dots.dot glyph to noteheads.s2neomensural. The only issue with this is
> that it changes all of the repeat dots throughout the score, and I am
> looking for a function that works like \once \override. I have attached a
> snippet showing the work I have done so far. If you know a better way to do
> this, please let me know!
> 
> Thank you,
> 
> Calvin Ransom

\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 ":..:"
}


Attachment: signature.asc
Description: This is a digitally signed message part.

Reply via email to