Am 05.06.2012 08:29, schrieb Marc Hohl:
Hi all,
Am 03.06.2012 22:58, schrieb Thomas Morley:
Hi,
together with Marc Hohl I was working on Issue 1320 for a couple of
weeks.
Now we have a first working version using a new approach to design
BarLines:
Only simple BarLines are predefined e.g "|" "." ":" etc (plus some
exceptions).
Some defaults for the line-break and the SpanBars are predefined, too.
All is stacked together on-the-fly.
Harm has sent me the latest version of the file with some minor
improvements:
Ok, and here is the file ;-)
Regards,
Marc
\version "2.15.36"
#(use-modules (srfi srfi-1))
% Helpers
#(define (positions-in-list obj ls)
"Search the positions of obj in ls"
(define (positions-in-list-helper obj ls ls1 bypassed)
(if (null? ls)
(reverse ls1)
(if (equal? obj (car ls))
(begin
(set! ls1 (cons bypassed ls1))
(positions-in-list-helper obj (cdr ls) ls1 (+ bypassed 1)))
(positions-in-list-helper obj (cdr ls) ls1 (+ bypassed 1)))))
(positions-in-list-helper obj ls '() 0))
#(define (clear-list ls)
(remove (lambda (x) (equal? " " x)) ls))
#(define (string->string-list strg)
(define (helper-1 strg ls)
"
Converts a string into a list of strings,
every string of the list has string-length 1
e.g "1234" -> '("1" "2" "3" "4")
"
(if (= (string-length strg) 0)
(begin
(set! ls '(""))
ls)
(begin
(set! ls (cons (substring strg 0 1) ls))
(if (>= (string-length (string-drop strg 1)) 1)
(helper-1 (string-drop strg 1) ls)
(clear-list (reverse ls))))))
(helper-1 strg '()))
#(define (string-list->string ls)
(define (helper-2 ls strg)
"
Converts a list of strings into a string,
every string of the list has string-length 1
e.g '("1" "2" "3" "4") -> "1234"
"
(if (null? ls)
strg
(begin
(set! strg (string-append strg (car ls)))
(if (null? (cdr ls))
strg
(helper-2 (cdr ls) strg)))))
(helper-2 ls ""))
#(define (replace-list-elts ls-1 ls-2 ls-3)
"
ls-3 is supposed to be a list containing several elements to be replaced.
ls-1 is supposed to be a list containing the elements to be inserted into ls-3
ls-2 is supposed to be a list containing numbers indicating which position of ls-3
should be replaced.
"
(set! ls-3
(append (reverse (cons (car ls-1) (cdr (reverse (list-head ls-3 (+ 1 (car ls-2)))))))
(list-tail ls-3 (+ 1 (car ls-2)))))
(if (or (null? (cdr ls-1)) (null? (cdr ls-2)))
ls-3
(replace-list-elts (cdr ls-1) (cdr ls-2) ls-3)))
#(define (make-new-list l1 alist)
(let ((l2 '()))
(map
(lambda (x) (if (equal? x (caar alist))
(set! l2 (cons (cdar alist) l2))
(set! l2 (cons x l2))))
l1)
(if (null? (cdr alist))
(reverse l2)
(begin
(set! l1 (reverse l2))
(make-new-list l1 (cdr alist))))))
#(define (convert-strings-of-list ls)
(map
(lambda (z) (string-list->string z))
(map
(lambda (y) (make-new-list y replace-alist))
(map (lambda (x) (string->string-list x)) ls))))
#(define (make-alist ls proc)
"Constructs an alist,
e.g. (make-alist '(1 2 3) 'x)
-> ((1 . x) (2 . x) (3 . x))"
(cond ((string? proc)
(map
(lambda (x) (cons x proc))
ls))
((equal? ls proc)
(map
(lambda (x y) (cons x y))
ls proc))
((and (list? ls) (list? proc) (not (equal? ls proc)))
(if (= (length ls) (length proc))
(map
(lambda (x y) (cons x y))
ls proc)
(display "Warning: lengths of lists doesn't fit")))
))
#(define-macro (append-to-alist! ls-1 ls-2 proc)
"Appends a new constructed alist to another list"
`(set! ,ls-1 (append ,ls-1 (make-alist ,ls-2 ,proc))))
#(define (set-new-alist! ls-1 ls-2 proc)
(for-each (lambda (x) (set! ls-1 (acons x proc ls-1))) ls-2)
ls-1)
#(define (insert-strg l1 strg)
(define (helper-3 l1 l2 strg)
"l1 is supposed to be a list of strings.
insert-strg will return a new list, build of the
elements of l1, inserting strg between them.
e.g.: (insert-strg '("a" "b" "c") "_")
-> ("a" "_" "b" "_" "c")
"
(set! l2 (cons strg (cons (car l1) l2)))
(if (= (length l1) 2)
(reverse (cons (car (last-pair l1)) l2))
(helper-3 (cdr l1) l2 strg)))
(helper-3 l1 '() strg))
#(define (count-equal-signs-left strg strg-1)
(define (helper strg strg-1 counter)
"
Returns the number of equal signs at string-begin.
"
(if (or (= (string-length strg) 0) (not (equal? (substring strg 0 1) strg-1)))
counter
(begin
(set! counter (+ 1 counter))
(helper (string-drop strg 1) strg-1 counter))))
(helper strg strg-1 0))
% End of Helpers
#(define (stack-simple-barlines grob stencil print-proc kern ls)
(set! stencil (ly:stencil-combine-at-edge stencil X RIGHT (car print-proc) kern))
(if (null? (cdr print-proc))
stencil
(stack-simple-barlines grob stencil (cdr print-proc) kern ls)))
#(define-public (make-round-filled-box x1 x2 y1 y2 blot-diameter)
(let* ((width (- x2 x1))
(height (- y2 y1))
(blot-diameter (cond ((< width blot-diameter) width)
((< height blot-diameter) height)
(else blot-diameter))))
(ly:make-stencil (list 'round-filled-box (- x1) x2 (- y1) y2 blot-diameter)
(cons x1 x2)
(cons y1 y2))))
#(define-public (bar-line::calc-anchor grob)
(let* ((staff-line-thickness (ly:staff-symbol-line-thickness grob))
(glyph (ly:grob-property grob 'glyph-name))
(type-ls (string-split glyph #\_))
(type (car type-ls))
(reverse-type (string-reverse type))
(nmbr (count-equal-signs-left type ":"))
(reverse-nmbr (count-equal-signs-left reverse-type ":"))
(strg-lngth (string-length type))
(first-sub-strg (if (and (not (null? type-ls)) (> strg-lngth 1))
(substring type 0 1)
""))
(last-sub-strg (if (and (not (null? type-ls)) (> strg-lngth 1))
(substring reverse-type 0 1)
""))
(kern (* (ly:grob-property grob 'kern 1) staff-line-thickness))
(x-extent (ly:stencil-extent (bar-line::custom-print grob) X))
;;(segno-width (+ (interval-length
;; (ly:stencil-extent
;; (ly:font-get-glyph
;; (ly:grob-default-font grob)
;; "scripts.varsegno")
;; X))
;; kern))
;;(tick-width (+ staff-line-thickness kern))
(dot-width (+ (interval-length
(ly:stencil-extent
(ly:font-get-glyph
(ly:grob-default-font grob)
"dots.dot")
X))
kern))
(anchor 0.0))
(if (> (interval-length x-extent) 0)
(begin
(set! anchor (interval-center x-extent))
(cond ((and (string=? last-sub-strg ":") (string=? first-sub-strg ":"))
(set! anchor (+ anchor
(/ (* nmbr dot-width) 2.0)
(/ (* reverse-nmbr dot-width) -2.0))))
((string=? first-sub-strg ":")
(set! anchor (+ anchor (/ (* nmbr dot-width) 2.0))))
((string=? last-sub-strg ":")
(set! anchor (+ anchor (/ (* reverse-nmbr dot-width) -2.0))))
; ((string=? first-sub-strg "S")
; (set! anchor (+ anchor (/ segno-width 2.0))))
; ((string=? first-sub-strg "'")
; (set! anchor (+ anchor (/ tick-width 2.0))))
)
))
anchor))
#(define (bar-line::bar-y-extent grob refpoint)
(let* ((extent (ly:grob-property grob 'bar-extent '(0 . 0)))
(rel-y (ly:grob-relative-coordinate grob refpoint Y))
(y-extent (coord-translate extent rel-y)))
y-extent))
% Simple BarLine-print-definitions
#(define-public (make-simple-bar-line grob width extent rounded)
(let* ((height (interval-length extent))
(blot-diameter (if rounded
(ly:output-def-lookup (ly:grob-layout grob) 'blot-diameter)
0)))
(ly:round-filled-box (cons 0 width)
extent
blot-diameter)))
#(define-public (make-thick-bar-line grob width extent rounded)
(let* ((staff-line-thickness (ly:staff-symbol-line-thickness grob))
(fatline (* (ly:grob-property grob 'thick-thickness 1) staff-line-thickness)))
(make-simple-bar-line grob fatline extent rounded)))
#(define-public (make-tick-bar-line grob width extent rounded)
(let ((half-staff (* 1/2 (ly:staff-symbol-staff-space grob)))
(stafflinethick (ly:staff-symbol-line-thickness grob))
(height (interval-length extent))
(blot (if rounded
(ly:output-def-lookup (ly:grob-layout grob) 'blot-diameter)
0)))
(ly:stencil-translate-axis
(make-round-filled-box 0 stafflinethick (- height half-staff) (+ height half-staff) blot)
(interval-start extent) Y)))
#(define-public (make-dotted-bar-line grob extent)
(let* ((position (round (* (interval-end extent) 2)))
(correction (if (even? position) 0.5 0.0))
(stencil empty-stencil))
(let ((e (round (+ (interval-end extent) (- 0.5 correction)))))
(do ((i (round (+ (interval-start extent) (- 0.5 correction)))
(1+ i)))
((>= i e))
(set! stencil
(ly:stencil-add stencil
(ly:stencil-translate-axis
(ly:font-get-glyph (ly:grob-default-font grob) "dots.dot")
(+ i correction)
Y)))))
stencil))
#(define-public (make-dashed-bar-line grob extent thickness)
(let* ((staff-symbol (ly:grob-object grob 'staff-symbol))
(staff-extent (ly:grob-extent staff-symbol staff-symbol Y))
(blot (ly:output-def-lookup (ly:grob-layout grob) 'blot-diameter))
(line-thickness (ly:staff-symbol-line-thickness grob))
(staff-space (ly:staff-symbol-staff-space grob))
(height (- (interval-length extent) 0 ))
(staff-height (interval-length staff-extent))
(dash-size (- 1.0 (ly:grob-property grob 'gap 0.3)))
(num (ceiling (/ (* 1.5 height) (+ dash-size staff-space))))
(factors-lst
(map
(lambda (x) (+ (/ num 100) (* 0.983 (/ height (1- (* 2 num))) x)))
(iota (* 2 num))))
(factors (reverse (cdr (reverse (cdr factors-lst)))))
(stencil empty-stencil)
(stencil-2 (ly:stencil-add
(ly:stencil-translate-axis
(make-round-filled-box 0 thickness (/ dash-size -2) 0 blot)
(+ (interval-end extent)(* 0.5 line-thickness))
Y)
(ly:stencil-translate-axis
(make-round-filled-box 0 thickness 0 (/ dash-size 2) blot)
(- (interval-start extent) (* 0.5 line-thickness))
Y)))
(line-count (ly:grob-property staff-symbol 'line-count 0))
(diff (- height staff-height)))
(define (helper args)
(set! stencil-2
(ly:stencil-add stencil-2
(ly:stencil-translate-axis
(make-round-filled-box 0 (/ thickness 1)
(car args) (cadr args) blot)
(interval-start extent)
Y)))
(if (null? (cddr args))
stencil-2
(helper (cddr args))))
(if (<= diff 0)
(let ((blot (ly:output-def-lookup (ly:grob-layout grob) 'blot-diameter))
(half-space (/ staff-space 2.0))
(bar empty-stencil))
(do ((i (1- line-count) (- i 2)))
((< i (- 1 line-count)))
(let ((top-y (min (* (+ i dash-size) half-space)
(+ (* (1- line-count) half-space) (/ line-thickness 2.0))))
(bot-y (max (* (- i dash-size) half-space)
(- 0 (* (1- line-count) half-space) (/ line-thickness 2.0)))))
(set! bar (ly:stencil-add bar
(make-round-filled-box 0 thickness bot-y top-y blot)))))
bar)
(if (zero? num)
empty-stencil
(helper factors)))))
#(define-public (make-colon-bar-line grob)
(let* ((dot (ly:font-get-glyph (ly:grob-default-font grob) "dots.dot"))
(staff-symbol (ly:grob-object grob 'staff-symbol))
(line-count (ly:grob-property staff-symbol 'line-count 0))
(staff-space (ly:staff-symbol-staff-space grob))
(dist (cond ((odd? line-count) 1)
((= line-count 0) 1)
((< staff-space 2) (* 2 staff-space))
(else (* 0.5 staff-space))))
(colon empty-stencil))
(set! colon (ly:stencil-add colon dot))
(set! colon (ly:stencil-translate-axis colon dist Y))
(set! colon (ly:stencil-add colon dot))
(set! colon (ly:stencil-translate-axis colon (/ dist -2) Y))
colon))
#(define-public (make-segno-bar-line grob width rounded)
(let* ((staff-line-thickness (ly:staff-symbol-line-thickness grob))
(glyph (ly:grob-property grob 'glyph))
(kern (* (ly:grob-property grob 'kern 1) staff-line-thickness))
(thinkern (* (ly:grob-property grob 'thin-kern 1) staff-line-thickness))
(thin-stil (make-simple-bar-line grob width extent rounded))
(double-line-stencil (ly:stencil-combine-at-edge
thin-stil X LEFT thin-stil thinkern))
(double-line-stencil-x-length (interval-length (ly:stencil-extent double-line-stencil X)))
(segno-stil (ly:stencil-add
(ly:font-get-glyph (ly:grob-default-font grob) "scripts.varsegno")
(ly:stencil-translate-axis
double-line-stencil
(* 0.5 thinkern)
X))))
segno-stil))
#(define-public (make-segno-span-bar-line grob width rounded)
(let* ((staff-line-thickness (ly:staff-symbol-line-thickness grob))
(glyph (ly:grob-property grob 'glyph))
(kern (* (ly:grob-property grob 'kern 1) staff-line-thickness))
(thinkern (* (ly:grob-property grob 'thin-kern 1) staff-line-thickness))
(thin-stil (make-simple-bar-line grob width extent rounded))
(double-line-stencil (ly:stencil-combine-at-edge
thin-stil X LEFT thin-stil thinkern))
(segno-stil (ly:font-get-glyph (ly:grob-default-font grob) "scripts.varsegno"))
(segno-stil-x-extent (ly:stencil-extent segno-stil X))
(dummy-stil (ly:make-stencil "" segno-stil-x-extent (cons 0 0)))
(double-line-stencil-x-length (interval-length (ly:stencil-extent double-line-stencil X)))
(segno-span-stil (ly:stencil-add
dummy-stil
(ly:stencil-translate-axis
double-line-stencil
(* 0.5 thinkern)
X))))
segno-span-stil))
#(define-public (make-kievan-bar-line grob)
(let* ((font (ly:grob-default-font grob))
(stencil (ly:font-get-glyph font "scripts.barline.kievan")))
stencil))
#(define-public (make-space-bar-line extent grob)
(let ((space-bar-stencil (ly:make-stencil "" extent (cons 0 0))))
space-bar-stencil))
#(define-public (make-bracket-right-bar-line grob width extent rounded)
(let* ((staff-line-thickness (ly:staff-symbol-line-thickness grob))
(fatline (* (ly:grob-property grob 'thick-thickness 1) staff-line-thickness))
(bracket-tip-up (ly:font-get-glyph (ly:grob-default-font grob) "brackettips.up"))
(bracket-tip-up-y-length (interval-length (ly:stencil-extent bracket-tip-up Y)))
(tip-up (grob-interpret-markup grob
(markup #:with-dimensions '(0 . 0) `(0 . ,bracket-tip-up-y-length)
#:stencil (ly:font-get-glyph (ly:grob-default-font grob) "brackettips.up"))))
(tip-down (grob-interpret-markup grob
(markup #:with-dimensions '(0 . 0) `(0 . ,bracket-tip-up-y-length)
#:stencil (ly:font-get-glyph (ly:grob-default-font grob) "brackettips.down"))))
(thick-bar (make-thick-bar-line grob width extent rounded))
(thin-bar (make-simple-bar-line grob width extent rounded))
(staff-line (ly:output-def-lookup (ly:grob-layout grob) 'line-thickness))
(kern (* (ly:grob-property grob 'kern) staff-line))
(stencil (ly:stencil-add
thick-bar
(ly:stencil-translate-axis
tip-up
(interval-end extent) Y)
(ly:stencil-translate-axis
tip-down
(interval-start extent) Y))))
stencil))
#(define-public (make-bracket-left-bar-line grob width extent rounded)
(ly:stencil-scale (make-bracket-right-bar-line grob width extent rounded) -1 1))
% End of simple BarLine-print-definitions
#(define basic-glyph-list '("|" ":" "*" "!" "" ";" "'" "S" "k" "-" "x" "[" "]"))
#(define (bar-glyph-print-procedures grob thickness extent rounded)
`(("|" . ,(make-simple-bar-line grob thickness extent rounded))
("*" . ,(make-dotted-bar-line grob extent))
(":" . ,(make-colon-bar-line grob))
("!" . ,(make-thick-bar-line grob thickness extent rounded))
("'" . ,(make-tick-bar-line grob thickness extent rounded))
(";" . ,(make-dashed-bar-line grob extent thickness))
("S" . ,(make-segno-bar-line grob thickness rounded))
("k" . ,(make-kievan-bar-line grob))
("" . ,empty-stencil)
("-" . ,(make-segno-span-bar-line grob thickness rounded))
("x" . ,(make-space-bar-line extent grob))
("[" . ,(make-bracket-right-bar-line grob thickness extent rounded))
("]" . ,(make-bracket-left-bar-line grob thickness extent rounded))
))
#(define extent '(0 . 0))
#(define-public (bar-line::print-simple-barlines bar-line)
(let* ((glyph-name (ly:grob-property bar-line 'glyph-name))
(strg-ls (string->string-list glyph-name))
(staff-line (ly:output-def-lookup (ly:grob-layout bar-line) 'line-thickness))
(kern (* (ly:grob-property bar-line 'kern) staff-line))
(thickness (* 1.0 (ly:grob-property bar-line 'hair-thickness) staff-line))
(print-proc (map
(lambda (x) (assoc-get x
(if (member x basic-glyph-list)
(bar-glyph-print-procedures bar-line thickness extent #t)
(user-bar-glyph-print-procedures extent bar-line))
))
strg-ls))
(stencil empty-stencil))
(let ((compound-stencil (cond ((equal? ":|!" glyph-name)
(ly:stencil-combine-at-edge
(ly:stencil-combine-at-edge
(make-thick-bar-line bar-line thickness extent #t)
X LEFT
(make-simple-bar-line bar-line thickness extent #t)
kern)
X LEFT (make-colon-bar-line bar-line) kern)
)
((and (= 1 (length strg-ls)) (equal? "" (car strg-ls)))
empty-stencil)
((and (= 1 (length strg-ls)) (member (car strg-ls) bar-glyph-signs-list))
(car print-proc))
((> (length strg-ls) 1)
(set! stencil (stack-simple-barlines bar-line stencil print-proc kern strg-ls))
stencil)
)))
compound-stencil)))
#(define bar-glyph-signs-list
'("|" ":" "*" "!" ";" "'" "S" "k" "" "||" "-"
"|:" "!|:" ":|" ":|!" ":|:" ":!!:" "x" "[" "]"))
#(define bar-glyph-alist '(
("|" . ("|" . ()))
(";" . (";" . ()))
(":" . (":" . ()))
("*" . ("*" . ()))
("!" . ("!" . ()))
("'" . ("'" . ()))
("S" . ("||" . "S"))
("k" . ("k" . ()))
("" . ("" . ""))
("[" . ("|" . "["))
("]" . ("]" . ()))
("||" . ("||" . ()))
("|:" . ("|" . "|:"))
("!|:" . ("|" . "!|:"))
(":|" . (":|" . ()))
(":|!" . (":|!" . ()))
(":|:" . (":|" . "|:"))
(":!!:" . (":|!" . "!|:"))
))
#(define bar-glyph-print-functions `())
#(set! bar-glyph-print-functions
(set-new-alist! bar-glyph-print-functions bar-glyph-signs-list
bar-line::print-simple-barlines))
#(define-public (bar-line::custom-print grob)
(let* ((glyph-name (ly:grob-property grob 'glyph-name))
(print-proc (assoc-get glyph-name bar-glyph-print-functions))
(bar-extent (ly:grob-property grob 'bar-extent '(0 . 0))))
(set! extent bar-extent)
(if (procedure? print-proc)
(print-proc grob)
(print-proc grob)
;(ly:bar-line::print grob)
)))
#(define (set-bar-glyph-alist! custom-type)
(let* ((type-ls (string-split custom-type #\_))
(type-ls-lngth (length type-ls))
(type (car type-ls))
(strg-lngth (string-length type))
(strg-ls (string->string-list type))
(custom-type-left (if (> type-ls-lngth 2)
(cadr type-ls)
(car type-ls)))
(custom-type-right (if (> type-ls-lngth 2)
(caddr type-ls)
'()))
(type-left (if (and (> strg-lngth 1) (equal? (car (reverse strg-ls)) ":"))
(string-take type (- strg-lngth 1))
type))
(type-right-default "!|:")
(segno-type-left (if (and (> strg-lngth 1) (member "S" strg-ls))
(let* ((ls-lngth (string-length (string-list->string (cdr (member "S" strg-ls))))))
(string-take type (- strg-lngth ls-lngth)))
type))
(segno-type-right (if (and (> strg-lngth 1) (member "S" strg-ls))
(string-list->string (cdr (member "S" strg-ls)))
type)))
(if (assoc-get type bar-glyph-alist)
#f
(if (= type-ls-lngth 1)
(cond ((= strg-lngth 1)
(if (equal? type "S")
(set! bar-glyph-alist (acons type `("||" . "S") bar-glyph-alist))
(set! bar-glyph-alist (acons type `(,type . ()) bar-glyph-alist))
))
((and (> strg-lngth 1) (equal? (car (reverse strg-ls)) ":"))
(if (member "S" strg-ls)
(set! bar-glyph-alist (acons type `(,segno-type-left . ,segno-type-right) bar-glyph-alist))
(set! bar-glyph-alist (acons type `(,type-left . ,type-right-default) bar-glyph-alist))))
(else
(set! bar-glyph-alist (acons type `(,type . ()) bar-glyph-alist))))
(set! bar-glyph-alist (acons type `(,custom-type-left . ,custom-type-right) bar-glyph-alist))
)
)))
#(define (set-bar-glyph-print-functions! custom-type)
(let* ((type-ls (string-split custom-type #\_))
(type-ls-lngth (length type-ls))
(type (car type-ls))
(strg-lngth (string-length type))
(strg-ls (string->string-list type))
(custom-type-left (if (> type-ls-lngth 2)
(cadr type-ls)
(car type-ls)))
(custom-type-right (if (> type-ls-lngth 2)
(caddr type-ls)
'()))
(type-left (if (and (> strg-lngth 1) (equal? (car (reverse strg-ls)) ":"))
(string-take type (- strg-lngth 1))
type))
(type-right-default "!|:")
(segno-type-left (if (and (> strg-lngth 1) (member "S" strg-ls))
(let* ((ls-lngth (string-length (string-list->string (cdr (member "S" strg-ls))))))
(string-take type (- strg-lngth ls-lngth)))
type))
(segno-type-right (if (and (> strg-lngth 1) (member "S" strg-ls))
(string-list->string (cdr (member "S" strg-ls)))
type)))
(if (assoc-get type bar-glyph-print-functions)
#f
(begin
(set! bar-glyph-print-functions (acons type bar-line::print-simple-barlines bar-glyph-print-functions))
(if (= type-ls-lngth 1)
(begin
(set! bar-glyph-print-functions (acons type-left bar-line::print-simple-barlines bar-glyph-print-functions))
(set! bar-glyph-print-functions (acons type-right-default bar-line::print-simple-barlines bar-glyph-print-functions))
(set! bar-glyph-print-functions (acons segno-type-left bar-line::print-simple-barlines bar-glyph-print-functions))
(set! bar-glyph-print-functions (acons segno-type-right bar-line::print-simple-barlines bar-glyph-print-functions)))
(begin
(set! bar-glyph-print-functions (acons custom-type-left bar-line::print-simple-barlines bar-glyph-print-functions))
(set! bar-glyph-print-functions (acons custom-type-right bar-line::print-simple-barlines bar-glyph-print-functions)))))
)
))
% new \bar-function
bar =
#(define-music-function (parser location custom-type) (string?)
(_i "Insert a bar line of type @var{type}")
(let* ((type-ls (string-split custom-type #\_))
(type (car type-ls)))
(set-bar-glyph-alist! custom-type)
(set-bar-glyph-print-functions! custom-type)
(set-span-bar-glyphs-alist! custom-type)
(context-spec-music
(make-property-set 'whichBar type)
'Timing)))
% Line-break
#(define (index-cell cell dir)
(if (equal? dir 1)
(cdr cell)
(car cell)))
#(define-public (bar-line::custom-calc-glyph-name grob)
(let* ((glyph (ly:grob-property grob 'glyph))
(dir (ly:item-break-dir grob))
(result (assoc-get glyph bar-glyph-alist))
(glyph-name (if (= dir CENTER)
glyph
(if (and result
(string? (index-cell result dir)))
(index-cell result dir)
#f))))
glyph-name))
#(define-public (bar-line::custom-calc-break-visibility grob)
(let* ((glyph (ly:grob-property grob 'glyph))
(result (assoc-get glyph bar-glyph-alist)))
(if result
(vector (string? (car result)) #t (string? (cdr result)))
all-invisible)))
% Span-bar
#(define-public (bar-line::print-simple-custom-span-bars bar-line)
(let* ((glyph-name (ly:grob-property bar-line 'glyph-name))
(alist-glyph (car (assoc glyph-name span-bar-glyphs-alist)))
;(alist-glyph (assoc glyph-name span-bar-glyphs-alist))
;(alist-glyph (pair? alist-glyph))
(new-glyph-name (if (equal? glyph-name alist-glyph)
(cdr (assoc glyph-name span-bar-glyphs-alist))
glyph-name))
(orig-strg-ls (string->string-list glyph-name))
(strg-ls (string->string-list new-glyph-name))
(staff-line (ly:output-def-lookup (ly:grob-layout bar-line) 'line-thickness))
(kern (* (ly:grob-property bar-line 'kern) staff-line))
(thickness (* 1.0 (ly:grob-property bar-line 'hair-thickness) staff-line))
(positions-of-x-in-orig-strg-ls (positions-in-list "x" strg-ls))
(to-be-replaced (map
(lambda (y) (list-ref orig-strg-ls y))
positions-of-x-in-orig-strg-ls))
(to-be-replaced-stencils (map
(lambda (x) (assoc-get x
(if (member x basic-glyph-list)
(bar-glyph-print-procedures bar-line thickness extent #t)
(user-bar-glyph-print-procedures extent bar-line))
))
to-be-replaced))
(stil-ext-ls (map (lambda (c) (ly:stencil-extent c X)) to-be-replaced-stencils))
(dummy-stils-ls (map (lambda (d) (make-space-bar-line d bar-line)) stil-ext-ls))
(print-proc (map
(lambda (x) (assoc-get x
(if (member x basic-glyph-list)
(bar-glyph-print-procedures bar-line thickness extent #t)
(user-bar-glyph-print-procedures extent bar-line))
))
strg-ls))
(new-print-proc (if (null? dummy-stils-ls)
print-proc
(replace-list-elts dummy-stils-ls positions-of-x-in-orig-strg-ls print-proc)))
(stencil empty-stencil))
(let ((compound-stencil (cond ((equal? ":|!" glyph-name)
(ly:stencil-combine-at-edge
(ly:stencil-combine-at-edge
(make-thick-bar-line bar-line thickness extent #t)
X LEFT
(make-simple-bar-line bar-line thickness extent #t)
kern)
X LEFT (make-space-bar-line extent bar-line) kern)
)
((and (= 1 (length strg-ls)) (equal? "" (car strg-ls)))
empty-stencil)
((and (= 1 (length strg-ls)) (member (car strg-ls) bar-glyph-signs-list))
(car print-proc))
((> (length strg-ls) 1)
(set! stencil (stack-simple-barlines bar-line stencil new-print-proc kern strg-ls))
stencil))))
compound-stencil)))
#(define span-bar-glyph-print-functions '())
#(define span-bar-glyph-signs-list
'("|" ":" "*" "!" ";" "'" "S" "k" "" "||" "-"
"|:" "!|:" ":|" ":|!" ":|:" ":!!:" "x" "[" "]"))
#(set! span-bar-glyph-print-functions
(set-new-alist! span-bar-glyph-print-functions span-bar-glyph-signs-list
bar-line::print-simple-custom-span-bars))
#(define replace-alist '((":" . "x")
("S" . "x")
("'" . "x")
("u" . "x")
("m" . "x")
("s" . "x")
("k" . "x")
("[" . "x")
("]" . "x")
))
#(define (set-span-bar-glyphs-alist! custom-type)
(let* ((ls (string-split custom-type #\_))
(type-ls (convert-strings-of-list ls))
(type-ls-lngth (length type-ls))
(type (if (>= type-ls-lngth 4)
(cadddr ls)
(car ls)))
(strg-lngth (string-length type))
(strg-ls (string->string-list type))
(new-type (car type-ls))
(segno-type-span (car (convert-strings-of-list (list type))))
(segno-type-left-bar (if (and (> strg-lngth 1) (member "S" strg-ls))
(let* ((ls-lngth (string-length (string-list->string (cdr (member "S" strg-ls))))))
(string-take type (- strg-lngth ls-lngth)))
type))
(segno-type-left-span (car (convert-strings-of-list (list segno-type-left-bar))))
(segno-type-right-bar (if (and (> strg-lngth 1) (member "S" strg-ls))
(string-list->string (cdr (member "S" strg-ls)))
type))
(segno-type-right-span (car (convert-strings-of-list (list segno-type-right-bar))))
(type-left-bar (if (and (> strg-lngth 1) (equal? (car (reverse strg-ls)) ":"))
(string-take type (- strg-lngth 1))
type))
(type-left-span (car (convert-strings-of-list (list type-left-bar ))))
(type-right-bar (if (and (> strg-lngth 1) (equal? (car (reverse strg-ls)) ":"))
(string-drop type 1)
type))
(type-right-span-default "")
(xy-1 (if (or (string-contains (car ls) ":")
(string-contains (car ls) "k")
(string-contains (car ls) "'"))
(car type-ls)
(car ls)))
(xy-2 (cond ((and (> type-ls-lngth 1) (> (length ls) 1))
(if (or (string-contains (car ls) ":")
(string-contains (car ls) "k")
(string-contains (car ls) "'"))
(cadr type-ls)
(cadr type-ls)))))
(xy-3 (cond ((and (> type-ls-lngth 1) (> (length ls) 1))
(if (or (string-contains (car ls) ":")
(string-contains (car ls) "k")
(string-contains (car ls) "'"))
(caddr type-ls)
(caddr type-ls)))))
)
(cond ((= type-ls-lngth 1)
(cond ((member "S" strg-ls)
(begin
(if (member type span-bar-glyph-signs-list)
#f
(set! span-bar-glyphs-alist (acons type segno-type-span span-bar-glyphs-alist)))
(if (member segno-type-left-span span-bar-glyph-signs-list)
#f
(set! span-bar-glyphs-alist (acons segno-type-left-bar segno-type-left-span span-bar-glyphs-alist)))
(if (member segno-type-right-span span-bar-glyph-signs-list)
#f
(set! span-bar-glyphs-alist (acons segno-type-right-bar segno-type-right-span span-bar-glyphs-alist)))
))
((> strg-lngth 1)
(set! span-bar-glyphs-alist (acons type-right-bar type-right-span-default span-bar-glyphs-alist))
(set! span-bar-glyphs-alist (acons (car ls) xy-1 span-bar-glyphs-alist))
(set! span-bar-glyphs-alist (acons type-left-bar type-left-span span-bar-glyphs-alist))
)))
((and (= type-ls-lngth 3)(= (length ls) 3))
(set! span-bar-glyphs-alist (acons (car ls) xy-1 span-bar-glyphs-alist))
(set! span-bar-glyphs-alist (acons (cadr ls) xy-2 span-bar-glyphs-alist))
(set! span-bar-glyphs-alist (acons (caddr ls) xy-3 span-bar-glyphs-alist)))
((and (= type-ls-lngth 6)
(= (length ls) 6))
(begin
(set! span-bar-glyphs-alist (acons (cadr ls) (cadr (reverse type-ls)) span-bar-glyphs-alist))
(set! span-bar-glyphs-alist (acons (caddr ls) (car (reverse type-ls)) span-bar-glyphs-alist))
(set! span-bar-glyphs-alist (acons (car ls) (cadddr type-ls) span-bar-glyphs-alist))
))
)
))
%% span-bar-defaults:
#(define-public span-bar-glyphs-alist `())
#(let ((l1 '("'" ":" "k" "" "[" "]"))
(l2 '("|" "||" ";" "*" "!"))
(l3 '("S"))
(l4 '("!|:" ":|!" ":!!:" "|:"))
(l5 '("!|x" "x|!" "x!!x" "|x"))
)
(append-to-alist! span-bar-glyphs-alist l1 "x")
(append-to-alist! span-bar-glyphs-alist l2 l2)
(append-to-alist! span-bar-glyphs-alist l3 "-")
(append-to-alist! span-bar-glyphs-alist l4 l5))
% defined in scm/music-functions.scm
#(define-public (vector-extend v x)
"Make a new vector consisting of V, with X added to the end."
(let* ((n (vector-length v))
(nv (make-vector (+ n 1) '())))
(vector-move-left! v 0 n nv 0)
(vector-set! nv n x)
nv))
#(define-public (span-bar::print grob)
(let* ((elts (ly:grob-object grob 'elements))
(refp (ly:grob-common-refpoint-of-array grob elts Y))
(glyph (ly:grob-property grob 'glyph-name))
(span-bar empty-stencil))
(if (string? glyph)
(let* ((extents (make-vector 0 '()))
(make-span-bar (make-vector 0 '()))
(model-bar #f)
(elts-size (ly:grob-array-length elts)))
(do ((i (1- elts-size) (1- i)))
((< i 0))
(let* ((bar (ly:grob-array-ref elts i))
(ext (bar-line::bar-y-extent bar refp))
(staff-symbol (ly:grob-object bar 'staff-symbol)))
(if (ly:grob? staff-symbol)
(let ((refp-extent (ly:grob-extent staff-symbol refp Y)))
(set! ext (cons (min (car ext) (car refp-extent))
(max (cdr ext) (cdr refp-extent))))
(if (> (interval-length ext) 0)
(begin
(set! extents (vector-extend extents ext))
(set! make-span-bar (vector-extend make-span-bar
(ly:grob-property bar 'allow-span-bar)))
(set! model-bar bar)))))))
(if (not model-bar)
(set! model-bar grob))
(do ((i 1 (1+ i)))
((> i (1- (vector-length extents))))
(let ((prev-extent (vector-ref extents (1- i)))
(curr-extent (vector-ref extents i))
(l (cons 0 0)))
(if (> (interval-length prev-extent) 0)
(begin
(set! l (cons (cdr prev-extent)
(car curr-extent)))
(set! extent l)
(if (or (zero? (interval-length l))
(not (vector-ref make-span-bar i)))
(begin
;; There is overlap between the bar lines. Do nothing.
)
(set! span-bar
(ly:stencil-add
span-bar
(bar-line::print-simple-custom-span-bars model-bar)
)))))))
(set! span-bar (ly:stencil-translate-axis
span-bar
(- (ly:grob-relative-coordinate grob refp Y))
Y))))
span-bar))
myLayout =
\layout {
\context {
\Staff
% \override BarLine #'layer = #10
\override BarLine #'break-align-anchor = #bar-line::calc-anchor
\override BarLine #'glyph-name = #bar-line::custom-calc-glyph-name
\override BarLine #'break-visibility = #bar-line::custom-calc-break-visibility
\override BarLine #'stencil = #bar-line::custom-print
}
\context {
\Score
\override SpanBar #'stencil = #span-bar::print
%\override BarNumber #'self-alignment-X = #CENTER
\override BarNumber #'break-visibility = #'#(#f #t #t)
startRepeatType = "!|:"
endRepeatType = ":|!"
doubleRepeatType = ":!!:"
}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%------- test
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\layout {
\myLayout
ragged-right = ##t
}
% If you want to create a bar-line with the predefined print-procedures,
% you can write:
%
% (1)
% \bar ":'''|!!|''':"
% That will use the predefined defaults at line-break and for SpanBars.
%
% (2)
% \bar ":'''|!!|''':1_:'''|!_!|''':"
% That will use custom-defined behaviour at line-break and predefined defaults for SpanBars.
%
% (3)
% ":'''|!!|''':2_:'''|!2_!|''':2_xxxx;xx;xxxx_xxxx|x_**xxxx"
% That will use custom-defined behaviour at line-break and custom-defined behaviour for SpanBars.
% "x" is a placeholder with no visible output.
% The extent of "x" is the same as the corresponding substring from the BarLine-glyph.
%
% Note that the numbers don't cause any printed output, they are identifiers.
% Otherwise one setting would override an other, different setting of the same glyph.
%
% (4)
% Of course you can put it in avariable:
myBarI = { \bar ":'''|!!|''':2_:'''|!2_!|''':2_xxxx;xx;xxxx_xxxx|x_**xxxx" }
myBreak = \break
\markup \fill-line { \bold "Testing predefined print-procedures" }
%%{
mus¹ = \relative c' {
d1 \bar ":'''|!!|''':"
d \bar ":'''|!!|''':"
\override Score.RehearsalMark #'break-visibility = #'#(#t #f #f)
\mark\markup \fontsize #-5 \center-column { \vspace #2 "default-line-break" "is bad," "specify it!" "See below." }
\myBreak
e \bar ":'''|!!|''':1_:'''|!1_!|''':1"
e \bar ":'''|!!|''':1_:'''|!1_!|''':1" \myBreak
f \bar ":'''|!!|''':2_:'''|!2_!''':2_xxxx;xx;xxxx_xxxx|x_**xxxx"
f \bar ":'''|!!|''':2_:'''|!2_!''':2_xxxx;xx;xxxx_xxxx|x_**xxxx" \myBreak
g \myBarI
g \myBarI \myBreak
a \bar "[|:_|_[|:_xx_|_xx"
a \bar "[|:_|_[|:_xx_|_xx" \myBreak
b \bar ":|]_:|]_x_xxx_xxx_x"
b \bar ":|]_:|]_x_xxx_xxx_x" \myBreak
c \bar ":|][|:_:|]_[|:_xxxxxx_xxx_xxx"
c \bar ":|][|:_:|]_[|:_xxxxxx_xxx_xxx" \myBreak
cis \bar ":|]S[|:_:|]_S[|:_xxxxxxx_xxx_xxxx"
cis \bar ":|]S[|:_:|]_S[|:_xxxxxxx_xxx_xxxx" \myBreak
d
}
\score {
\new StaffGroup <<
\new Staff \mus¹
\new Staff \mus¹
\new Staff \transpose c c'' \mus¹
>>
}
%%{
\markup \fill-line { \bold "Testing custom-defined print-procedures" } \noPageBreak
% If you want to create a bar-line with a custom-defined print-procedure:
% (1) define the print-procedure. e.g.:
% Custom-stencil-1
#(define-public (make-my-bar-line grob)
(let* ((font (ly:grob-default-font grob))
(stencil (ly:font-get-glyph font "scripts.segno")))
stencil))
% Custom-stencil-2 (from the user-list, slightly modified)
#(define (my-print-proc grob)
(let* ((staff-line (ly:output-def-lookup (ly:grob-layout grob) 'line-thickness))
(kern (* (ly:grob-property grob 'kern) staff-line)))
(ly:make-stencil
`(path 0.5
`(rmoveto 0 -2
rlineto 0 4
rlineto 1 2
rmoveto -1 -6
rlineto 1 -2
))
(cons 0 kern)
(cons -4 4))))
%}
% (2) assign a glyph and the print-procedure
#(define (user-bar-glyph-print-procedures extent grob)
`(("u" . ,(my-print-proc grob))
("m" . ,(make-my-bar-line grob))
))
%%{
% (3) append the custom-glyphs to bar-glyph-signs-list and span-bar-glyphs-alist.
#(set! bar-glyph-signs-list (cons "u" bar-glyph-signs-list))
#(set! bar-glyph-signs-list (cons "m" bar-glyph-signs-list))
#(set! span-bar-glyphs-alist (acons "u" "x" span-bar-glyphs-alist))
#(set! span-bar-glyphs-alist (acons "m" "x" span-bar-glyphs-alist))
% Because there should be no Spanbar at "u" and "m", they are paired with "x".
mus² = \relative c' {
d1 \bar "u_|_u"
d \bar "u_|_u" \myBreak
e \bar "m_|_m_x_;_x"
e \bar "m_|_m_x_;_x" \myBreak
f \bar "u|:_|_u|:_xxx_|_xxx"
f \bar "u|:_|_u|:_xxx_|_xxx" \myBreak
g \bar ":|!mu_:|!_mu"
g \bar ":|!mu_:|!_mu" \myBreak
a
}
\score {
\new StaffGroup <<
\new Staff \mus²
\new Staff \mus²
\new Staff \transpose c c''' \mus²
>>
}
%}
%%{
\markup \fill-line { \bold "Testing alternative syntax" } \noPageBreak
% Alternatively you can use the following:
#(define (new-bar ls)
(string-list->string (insert-strg ls "_")))
#(define myCuriousBarI (new-bar '(":|!S!|:*:|!S!|:" ":|!S!|:*" "*:|!S!|:")))
#(define myCuriousBarII (new-bar
'(":|!S!|:*:|!S!|:1"
":|!S!|:*1"
"*:|!S!|:1"
"x;xxx;x*x;xxx;x"
"x;xxx;*x"
"x*;xxx;x")))
mus³ = \relative c' {
d1 \bar \myCuriousBarI
d \bar \myCuriousBarI \myBreak
e \bar \myCuriousBarII
e \bar \myCuriousBarII \myBreak
a \bar ":|||!*!*!*!*!"
}
\score {
\new StaffGroup <<
\new Staff \mus³
\new Staff \transpose c c'' \mus³
\new Staff \transpose c c''' \mus³
>>
}
%}
_______________________________________________
lilypond-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/lilypond-devel