- (make-harp-pedal layout props (harp-pedals-parse-string definition-string)))
-
-
-;; There is also a \harp-pedal-verbose version, which takes a list of -1/0/1
-;; directions, o and a possible |. It's commented out, because it has some
-;; issues (see below) and does not add any new functionality over \harp-pedal
-;; The caveats:
-;; 1) the | cannot be given as a string "|" but as a character #\| and
-;; the "o" has to be given as #\o.
-;; 2) if one wants to use directions like UP, CENTER or DOWN, one cannot use
-;; '(UP DOWN CENTER #\| ....), because the contents of that list are
-;; never evaluated to -1/0/1. Instead one has to explicitly create a
-;; list like (list UP DOWN CENTER #\| ....)
-;;
-;; (define-builtin-markup-command (harp-pedal-verbose layout props pedal-list) (list?)
-;; instrument-specific-markup ; markup type
-;; ((size 1.0)
-;; (harp-pedal-details)
-;; (thickness 0.5))
-;; "Make a harp pedal diagram containing the directions indicated in @var{pedal-list}."
-;; (make-harp-pedal layout props pedal-list))
-
-
+ (let* ((pedal-list (harp-pedals-parse-string definition-string))
+ (details (begin (harp-pedal-check pedal-list) harp-pedal-details))
+ (dy (* size (assoc-get 'box-offset details 0.8))) ; offset of the box center from the line
+ (line-width (* (ly:output-def-lookup layout 'line-thickness)
+ (chain-assoc-get 'thickness props 0.5)))
+ (box-width (* size (assoc-get 'box-width details 0.4)))
+ (box-hheight (* size (/ (assoc-get 'box-height details 1.0) 2))) ; half the box-height, saves some divisions by 2
+ (spacebeforedivider (* size (assoc-get 'space-before-divider details 0.8))) ; full space between boxes before the first divider
+ (spaceafterdivider (* size (assoc-get 'space-after-divider details 0.8))) ; full space between boxes
+ (circle-thickness (* (ly:output-def-lookup layout 'line-thickness)
+ (assoc-get 'circle-thickness details 0.5)))
+ (circle-x-padding (* size (assoc-get 'circle-x-padding details 0.15)))
+ (circle-y-padding (* size (assoc-get 'circle-y-padding details 0.2)))
+ (box-x-dimensions (lambda (prev-x p space) (cons (+ prev-x space)
+ (+ prev-x space box-width))))
+ (box-y-dimensions (lambda (prev-x p space) (cons (- (* p dy) box-hheight)
+ (+ (* p dy) box-hheight))))
+ (divider-stencil (lambda (xpos) (make-line-stencil line-width
+ xpos (- 0 dy box-hheight)
+ xpos (+ dy box-hheight))))
+ (result (let process-pedal ((remaining pedal-list)
+ (prev-x 0)
+ (stencils '())
+ (circled #f)
+ (space spacebeforedivider))
+ ;; Terminal condition of the recursion, return (final-x . stencil-list)
+ (if (null? remaining)
+ (cons (+ prev-x space) (reverse stencils))
+
+ (case (car remaining)
+ ((1 0 -1) ; Pedal up/neutral/down
+ (let* ((p (car remaining))
+ (stencil (make-filled-box-stencil
+ (box-x-dimensions prev-x p space)
+ (box-y-dimensions prev-x p space)))
+ (pedal-stencil
+ (if circled
+ (oval-stencil stencil circle-thickness
+ circle-x-padding circle-y-padding)
+ stencil))
+ (new-prev-x (+ prev-x space box-width)))
+ (process-pedal (cdr remaining) new-prev-x
+ (cons pedal-stencil stencils) #f space)))
+ ((#\|) ; Divider line
+ (let* ((xpos (+ prev-x space))
+ (stencil (divider-stencil xpos))
+ (new-prev-x (+ prev-x space)))
+ (process-pedal (cdr remaining) new-prev-x
+ (cons stencil stencils)
+ circled spaceafterdivider)))
+ ((#\o) ; Next pedal should be circled
+ (process-pedal (cdr remaining) prev-x stencils #t space))
+ (else
+ (ly:warning "Unhandled entry in harp-pedal: ~a"
+ (car remaining))
+ (process-pedal (cdr remaining)
+ prev-x stencils circled space))))))
+ (final-x (car result))
+ (stencils (cdr result)))
+ ;; Add the horizontal line and combine all stencils:
+ (apply ly:stencil-add
+ (make-line-stencil line-width 0 0 final-x 0) ; the horizontal line
+ (make-transparent-box-stencil ; space for absent boxes
+ (cons 0 final-x)
+ (interval-widen '(0 . 0) (+ box-hheight dy)))
+ stencils)))