% Inspired by Harm’s solution at
% https://www.mail-archive.com/lilypond-user@gnu.org/msg101994.html and
% https://lists.gnu.org/archive/html/lilypond-user/2015-05/msg00416.html
% … and elements of the make-tick-bar-line command at
% https://github.com/lilypond/lilypond/blob/master/scm/bar-line.scm

\version "2.27.1"

% From https://github.com/lilypond/lilypond/blob/master/scm/bar-line.scm
#(define (bar-line::calc-blot thickness extent grob)
  "Calculate the blot diameter for a rounded box, taking the extent
into account."
  (let ((blot-diameter (layout-blot-diameter grob))
        (height (interval-length extent)))

    (cond ((< thickness blot-diameter) thickness)
          ((< height blot-diameter) height)
          (else blot-diameter))))

% From https://github.com/lilypond/lilypond/blob/master/scm/bar-line.scm
#(define (layout-blot-diameter grob)
  "Get the blot diameter of the @var{grob}'s corresponding layout."
  (let* ((layout (ly:grob-layout grob))
         (blot-diameter (ly:output-def-lookup layout 'blot-diameter)))

    blot-diameter))

% Draw a tick above the staff:
#(define (make-up-tick-bar-line is-span grob extent)
  (let* ((line-thickness (layout-line-thickness grob))
         (thickness (* (ly:grob-property grob 'hair-thickness 1)
                       line-thickness))
         (staff-symbol (ly:grob-object grob 'staff-symbol))
         (line-pos (ly:grob-property staff-symbol 'line-positions))
         (line-count (length line-pos))
         (staff-space (ly:staff-symbol-staff-space grob))
         (half-staff (* 1/2 staff-space))
         (quarter-staff (* 1/4 staff-space)))
    
    ;; The tick is
    ;; expected to touch the top staff line, so we must find it. If
    ;; there are fewer than two lines, we allow floating ticks so that
    ;; they are not confused with short bar lines.
    (if (>= line-count 2)
        (set! center (+ quarter-staff (* (apply max line-pos) half-staff))))

    (ly:round-filled-box
     (cons 0 thickness) ; x
     (coord-translate (symmetric-interval quarter-staff) center) ; y
     (bar-line::calc-blot thickness extent grob))))

% Draw a tick below the staff:
#(define (make-down-tick-bar-line is-span grob extent)
  (let* ((line-thickness (layout-line-thickness grob))
         (thickness (* (ly:grob-property grob 'hair-thickness 1)
                       line-thickness))
         (staff-symbol (ly:grob-object grob 'staff-symbol))
         (line-pos (ly:grob-property staff-symbol 'line-positions))
         (line-count (length line-pos))
         (staff-space (ly:staff-symbol-staff-space grob))
         (half-staff (* 1/2 staff-space))
         (quarter-staff (* 1/4 staff-space))
         (bottom (interval-start extent)))

    ; (if (>= line-count 2)
    ;     (set! center (- quarter-staff (* (apply min line-pos) half-staff))))

    (ly:round-filled-box (cons 0 thickness)
                         (ordered-cons bottom (- bottom half-staff))
                         0)))

% Combine the two stencils into a single stencil:
#(define (make-both-tick-bar-line is-span grob extent)
  (ly:stencil-add
    (make-up-tick-bar-line is-span grob extent)
    (make-down-tick-bar-line is-span grob extent)))

#(add-bar-glyph-print-procedure "u" make-up-tick-bar-line)
#(define-bar-line "u" "u" #f #f)

#(add-bar-glyph-print-procedure "d" make-down-tick-bar-line)
#(define-bar-line "d" "d" #f #f)

#(add-bar-glyph-print-procedure "b" make-both-tick-bar-line)
#(define-bar-line "b" "b" #f #f)

%%%%%%%%%%%%%%%%%%
%% EXAMPLE
%%%%%%%%%%%%%%%%%%

\relative c' {
  \time 2/1
  \clef "treble_8"
  \key bes \major
  r1 bes1.
  bes2 ees2 c2 |
  d4 ees f d ees f g2 |
}

\layout {
  \set Timing.measureBarType = "b"
  
  % Ideally the make-down-tick-bar-line command
  % should still work (i.e., the lower tick
  % should still touch the bottom line)
  % when we enable the following:
  % \override Staff.StaffSymbol.line-count = #2
  
  \context {
    \Voice
    \consists Melody_engraver
  }
}