+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; measure counter
+
+(define-public (measure-counter-stencil grob)
+ "Print a number for a measure count. Broken measures are numbered in
+parentheses."
+ (let* ((num (make-simple-markup
+ (number->string (ly:grob-property grob 'count-from))))
+ (orig (ly:grob-original grob))
+ (siblings (ly:spanner-broken-into orig)) ; have we been split?
+ (num
+ (if (or (null? siblings)
+ (eq? grob (car siblings)))
+ num
+ (make-parenthesize-markup num)))
+ (num (grob-interpret-markup grob num))
+ (num (ly:stencil-aligned-to
+ num X (ly:grob-property grob 'self-alignment-X)))
+ (left-bound (ly:spanner-bound grob LEFT))
+ (right-bound (ly:spanner-bound grob RIGHT))
+ (refp (ly:grob-common-refpoint left-bound right-bound X))
+ (spacing-pair
+ (ly:grob-property grob
+ 'spacing-pair
+ '(break-alignment . break-alignment)))
+ (ext-L (ly:paper-column::break-align-width left-bound
+ (car spacing-pair)))
+ (ext-R (ly:paper-column::break-align-width right-bound
+ (cdr spacing-pair)))
+ (num
+ (ly:stencil-translate-axis
+ num
+ (+ (* 0.5 (- (car ext-R)
+ (cdr ext-L)))
+ (- (cdr ext-L)
+ (ly:grob-relative-coordinate grob refp X)))
+ X)))
+ num))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; HorizontalBracketText
+
+(define-public (ly:horizontal-bracket-text::print grob)
+ (let ((text (ly:grob-property grob 'text)))
+ (if (or (null? text)
+ (equal? text "")
+ (equal? text empty-markup))
+ (begin
+ (ly:grob-suicide! grob)
+ '())
+ (let* ((orig (ly:grob-original grob))
+ (siblings (ly:spanner-broken-into orig))
+ (text
+ (if (or (null? siblings)
+ (eq? grob (car siblings)))
+ text
+ (if (string? text)
+ (string-append "(" text ")")
+ (make-parenthesize-markup text)))))
+ (grob-interpret-markup grob text)))))
+
+(define-public (ly:horizontal-bracket-text::calc-direction grob)
+ (let* ((bracket (ly:grob-object grob 'bracket))
+ (bracket-dir (ly:grob-property bracket 'direction DOWN)))
+ bracket-dir))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; make-engraver helper macro
+
+(defmacro-public make-engraver forms
+ "Helper macro for creating Scheme engravers.
+
+The usual form for an engraver is an association list (or alist)
+mapping symbols to either anonymous functions or to another such
+alist.
+
+@code{make-engraver} accepts forms where the first element is either
+an argument list starting with the respective symbol, followed by the
+function body (comparable to the way @code{define} is used for
+defining functions), or a single symbol followed by subordinate forms
+in the same manner. You can also just make an alist pair
+literally (the @samp{car} is quoted automatically) as long as the
+unevaluated @samp{cdr} is not a pair. This is useful if you already
+have defined your engraver functions separately.
+
+Symbols mapping to a function would be @code{initialize},
+@code{start-translation-timestep}, @code{process-music},
+@code{process-acknowledged}, @code{stop-translation-timestep}, and
+@code{finalize}. Symbols mapping to another alist specified in the
+same manner are @code{listeners} with the subordinate symbols being
+event classes, and @code{acknowledgers} and @code{end-acknowledgers}
+with the subordinate symbols being interfaces."
+ (let loop ((forms forms))
+ (if (or (null? forms) (pair? forms))
+ `(list
+ ,@(map (lambda (form)
+ (if (pair? (car form))
+ `(cons ',(caar form) (lambda ,(cdar form) ,@(cdr form)))
+ `(cons ',(car form) ,(loop (cdr form)))))
+ forms))
+ forms)))