\version "2.18.2"
#(define-markup-command (bar-line layout props strg)(string?)
  #:properties ((font-size 0)
                (add-height 0))
              
  (define (string->string-list str)
    "Convert a string into a list of strings with length 1.
  @code{"aBc"} will be converted to @code{("a" "B" "c")}.
  An empty string will be converted to a list containing @code{""}."
    (if (and (string? str)
             (not (zero? (string-length str))))
        (map (lambda (s)
                     (string s))
             (string->list str))
        (list "")))
              
  (define (make-bar-line thickness height fontsize blot-diameter)
    "Draw a simple bar line."
    (ly:round-filled-box 
      (cons 0 (* (magstep font-size) thickness))
      (interval-widen (cons 0 (+ add-height height)) (magstep font-size))
      blot-diameter))
                           
  (define (make-colon-bar-line height fontsize)
    (let* ((font
             (ly:paper-get-font layout
               (cons '((font-encoding . fetaMusic)) props)))
           (dot (ly:font-get-glyph font "dots.dot")))
    (ly:stencil-add
        dot
        (ly:stencil-translate-axis
          dot
          (magstep (+ (/ add-height 2) font-size))
          Y))))
             
  (define (make-bracket-bar-line height fontsize dir thick-bar )
    "Draw a bracket-style bar line. If @var{dir} is set to @code{LEFT}, the
     opening bracket will be drawn, for @code{RIGHT} we get the 
     closing bracket."
    (let* ((font
              (ly:paper-get-font layout
                (cons '((font-encoding . fetaMusic)) props)))
           (brackettips-up (ly:font-get-glyph font "brackettips.up"))
           (brackettips-down (ly:font-get-glyph font "brackettips.down"))
           ;; the x-extent of the brackettips must not be taken into account
           ;; for bar line constructs like "[|:", so we set new bounds:
           (tip-up-stil 
             (ly:make-stencil 
               (ly:stencil-expr brackettips-up)
               (cons 0 0)
               (ly:stencil-extent brackettips-up Y)))
           (tip-down-stil 
             (ly:make-stencil 
               (ly:stencil-expr brackettips-down)
               (cons 0 0)
               (ly:stencil-extent brackettips-down Y)))
           (stencil 
             (ly:stencil-add
               thick-bar
               (ly:stencil-translate-axis 
                 tip-up-stil 
                 (+ (/ (+ add-height height) 2) (magstep fontsize)  )
                 Y)
               (ly:stencil-translate-axis 
                 tip-down-stil
                 (* -1 (+ (/ (+ add-height height) 2) (magstep fontsize) ))
                 Y))))
        (if (eq? dir LEFT)
            stencil
            (ly:stencil-scale stencil -1 1))))
            
  (define (make-brace-bar-line height fontsize)
    (let* ((new-height (max (* add-height height) 12))
           (font 
             (ly:paper-get-font layout
               (cons '((font-encoding . fetaBraces)
                       (font-name . #f))
                     props)))
           (glyph-count (1- (ly:otf-glyph-count font)))
           (scale (ly:output-def-lookup layout 'output-scale))
           (scaled-size (+ add-height (magstep fontsize) (/ (ly:pt new-height) scale)))
           (glyph 
             (lambda (n)
               (ly:font-get-glyph 
                 font 
                 (string-append "brace" (number->string n)))))
           (get-y-from-brace 
             (lambda (brace)
               (interval-length
                (ly:stencil-extent (glyph brace) Y))))
           (find-brace 
             (binary-search 0 glyph-count get-y-from-brace scaled-size))
           (glyph-found (glyph find-brace)))

    (if (or (null? (ly:stencil-expr glyph-found))
            (< scaled-size 
               (interval-length (ly:stencil-extent (glyph 0) Y)))
            (> scaled-size 
               (interval-length (ly:stencil-extent (glyph glyph-count) Y))))
        (begin
          (ly:warning (_ "no brace found for point size ~S ") new-height)
          (ly:warning (_ "defaulting to ~S pt")
          (/ (* scale (interval-length (ly:stencil-extent glyph-found Y)))
             (ly:pt 10)))))
    glyph-found))
              
    (let* ((line-thickness (ly:output-def-lookup layout 'line-thickness))
           (size (ly:output-def-lookup layout 'text-font-size 12))
           ;; Numerical values taken from the IR
           (thin-thickness (* line-thickness 1.9))
           (kern (* line-thickness 3.0))
           (thick-thickness (* line-thickness 6.0))
           (blot (ly:output-def-lookup layout 'blot-diameter))
           ;; Not sure about the numerical value, found it by try and error.
           (thin-bar-line 
             (ly:stencil-aligned-to 
               (make-bar-line thin-thickness (/ size 9) font-size blot) 
               Y CENTER))
           (thick-bar-line 
             (ly:stencil-aligned-to 
               (make-bar-line thick-thickness (/ size 9) font-size blot) 
               Y CENTER))
           (colon-bar-line 
             (ly:stencil-aligned-to 
               (make-colon-bar-line (/ size 9) font-size) 
               Y CENTER))
           (bracket-left-bar-line
             (ly:stencil-aligned-to 
               (make-bracket-bar-line (/ size 9) font-size -1 thick-bar-line) 
               Y CENTER))
           (bracket-right-bar-line
             (ly:stencil-aligned-to 
               (make-bracket-bar-line (/ size 9) font-size 1 thick-bar-line) 
               Y CENTER))
           (brace-left-bar-line
             (ly:stencil-aligned-to 
               (make-brace-bar-line (/ size 9) font-size) 
               Y CENTER))
           (strg-list (string->string-list strg))
           (find-bar-line-proc 
              (lambda (x) (cond ((string=? ":" x) colon-bar-line)
                                ((string=? "|" x) thin-bar-line)
                                ((string=? "." x) thick-bar-line)
                                ((string=? "[" x) bracket-left-bar-line)
                                ((string=? "]" x) bracket-right-bar-line)
                                ((string=? "{" x) brace-left-bar-line)
                                (else empty-stencil))))
           (bar-line-stils 
             (remove ly:stencil-empty? (map find-bar-line-proc strg-list)))
           (stil 
             (stack-stencils X 
                             RIGHT 
                             (* (magstep font-size) kern) 
                             bar-line-stils))
           (stil-y-length (interval-length (ly:stencil-extent stil Y))))
      ;; Hm, should the stencil-translate be hard-coded?
      (ly:stencil-translate-axis
        stil
        (/ stil-y-length 4)
        Y)))

%#(use-modules (ice-9 pretty-print))
%#(use-modules (srfi srfi-1))

#(define get-grob-name 
  (lambda (x) (if (ly:grob? x) (assq-ref (ly:grob-property x 'meta) 'name))))

#(define (get-grob-most-left-relative-coordinate ref-point)
  (lambda (grob)
      (cond
        ((eq? (get-grob-name grob) 'NoteColumn)
           (let* ((note-heads-array (ly:grob-object grob 'note-heads))
                  (note-heads-grobs 
                    (if (not (null? note-heads-array))
                        (ly:grob-array->list note-heads-array)
                        '()))
                  (note-heads-refpoints 
                    (map
                      (lambda (nh)
                        (ly:grob-relative-coordinate nh ref-point X))
                      note-heads-grobs))
                  (sorted-note-heads-refpoints (sort note-heads-refpoints <)))
            (if (not (null? sorted-note-heads-refpoints))
                (car sorted-note-heads-refpoints))))
         ((eq? (get-grob-name grob) 'AccidentalPlacement)
            (let* ((acc-list (ly:grob-object grob 'accidental-grobs))
                   (acc-refpoints 
                     (map
                       (lambda (acc)
                         (ly:grob-relative-coordinate (cadr acc) ref-point X))
                       acc-list))
                   (sorted-acc-refpoints (sort acc-refpoints <)))
             (if (not (null? sorted-acc-refpoints))
                 (car sorted-acc-refpoints))))
         (else 
           (if (ly:grob? grob) 
               (ly:grob-relative-coordinate grob ref-point X))))))
               
#(define* (duration-line #:optional (equal-start? #f))
   (lambda (grob)
     (let* ((line-thickness (ly:staff-symbol-line-thickness grob))
            (staff-space (ly:staff-symbol-staff-space grob))
            (refp (ly:grob-system grob))
            (note-head? (lambda (x) (eq? (get-grob-name x) 'NoteHead)))
            (half-gliss-thick (- (/ staff-space 2) line-thickness))
            (thickness 
              ;; (- half-gliss-thick 0.23) is my personal taste
              ;; If other value wanted, use common 'thickness override
              (ly:grob-property grob 'thickness (- half-gliss-thick 0.23)))
            (blot-diameter 
              (ly:output-def-lookup (ly:grob-layout grob) 'blot-diameter))
       ;;;; left NoteColumn
            (left-Y (assoc-get 'Y (ly:grob-property grob 'left-bound-info)))
            (left-bound (ly:spanner-bound grob LEFT))
            (left-note-column (ly:grob-parent left-bound X))
            (left-note-col-X-ext 
              (ly:grob-extent left-note-column left-note-column X))
            (left-note-column-coord 
              (ly:grob-relative-coordinate left-note-column refp X))
       ;;;; DotColumn of left NoteColumn
            (dot-column-left (ly:note-column-dot-column left-note-column))
            (dot-column-left-X-extent 
              (if (ly:grob? dot-column-left) 
                  (ly:grob-extent dot-column-left dot-column-left X)
                  '(0 . 0)))
       ;;;; right NoteColumn
            (right-bound (ly:spanner-bound grob RIGHT))
            (right-bound-info (ly:grob-property grob 'right-bound-info))
            (right-note-column (ly:grob-parent right-bound X))
            (most-left-note-head-coord
             ((get-grob-most-left-relative-coordinate refp) right-note-column))
       ;;;; AccidentalPlacement of right NoteColumn
            (acc-placement (ly:note-column-accidentals right-note-column))
            (most-left-note-acc-coord
             ((get-grob-most-left-relative-coordinate refp) acc-placement))
       ;;;; Arpeggio of right NoteColumn
            (arpeggio (ly:grob-object right-note-column 'arpeggio))
            (arpeggio-coord 
              (if (ly:grob? arpeggio)
                  (ly:grob-relative-coordinate arpeggio refp X)))
       ;;;; calculate most right left-bound coord 
            (most-right-left-bound-coord
              (+ left-note-column-coord 
                (cdr left-note-col-X-ext)
                (cdr dot-column-left-X-extent)))
       ;;;; catch most left right-bound coord
            (right-bound-coords-lst 
              (list 
                arpeggio-coord 
                most-left-note-acc-coord
                most-left-note-head-coord))
            (cleared-right-bound-coords-lst
                (sort 
                  (remove (lambda (x) (not (number? x))) right-bound-coords-lst) 
                  <)))

    ;; create a flat glissando
    (ly:grob-set-nested-property! grob '(right-bound-info Y) left-Y)
    
    ;; Let all glissandi start at the same vertical position
    (if (and (note-head? left-bound) equal-start?)
        (ly:grob-set-nested-property! 
          grob 
          '(left-bound-info X) 
          most-right-left-bound-coord))
        
    ;; Let all glissandi end at the same vertical position
    (if (note-head? right-bound)
        (ly:grob-set-nested-property! 
          grob 
          '(right-bound-info X) 
          (car cleared-right-bound-coords-lst)))

    ;; print new stencil
    (let* ((stencil (ly:line-spanner::print grob))
           (stencil-x-ext 
             (if (ly:stencil? stencil)
                 (ly:stencil-extent stencil X)
                 '(0 . 0)))
           (new-stencil 
             (ly:round-filled-box 
                stencil-x-ext
                (interval-widen (cons left-Y left-Y) thickness)
                blot-diameter)))
     new-stencil))))
     
gliss-length =
#(define-music-function (parser location lngth)(number?)
#{
  \once \override Glissando.minimum-length = #lngth
#})
     
durationLine =
#(define-music-function (parser location equal-start? left-right-padding)
   ((boolean? #f) pair?)
#{
  \override Glissando.stencil = #(duration-line equal-start?)
  \override Glissando.bound-details.left.padding = #(car left-right-padding)
  \override Glissando.bound-details.right.padding = #(cdr left-right-padding)
  \override Glissando.bound-details.left-broken.padding = #0.5
  \override Glissando.bound-details.right-broken.padding = #0.3    
#})

durationLineSettings = {
  \durationLine #'(-0.5 . 0.6)
  %% For equal glissando-start with little padding use:
  % \durationLine ##t #'(0.5 . 0.6)
  
  %% other possible settings
  %\override Glissando.thickness = #0.2
  \override Glissando.breakable = ##t
  \override Glissando.after-line-breaking = ##t
  \override Glissando.springs-and-rods = #ly:spanner::set-spacing-rods 
  
  %% construction helpers, DELETE ME
  %\override Glissando.layer = #20
  %\override Glissando.color = #red
}

\relative c' {
\grace s^\markup {\hspace #1 \fontsize #-4 \bar-line #".|:"} 
\cadenzaOn \once \override Script #'padding = #.5 \gliss-length #6 g8\glissando->\fermata_\markup 
{\dynamic f {\override #'(font-name . "vollkorn medium italic") 
                                   \fontsize #1 \italic "decresc. e rit"}} 
 [\set fingeringOrientations = #'(left) fis'-2 \gliss-length #6 fis\glissando a-0 
\gliss-length #6 a\glissando \once \override TextScript.extra-offset = #'(0 . .8)
bes'^\markup {\hspace #1 \fontsize #-4 \bar-line #":|."}] 
}
 \layout {
          %\override NoteHead.duration-log = #2
          \durationLineSettings
          line-width = 80
  }