Harm hat mir mal vor einigen Jahren dieses Skript (um)geschrieben.
\version "2.24.0"
\language "deutsch"
%% Example for creating multiple custom text spanners
%% Based on:
% http://lilypond.org/doc/v2.18/input/regression/collated-files.html
% look for:
% 'scheme-text-spanner.ly'
#(define (add-grob-definition grob-name grob-entry)
(let* ((meta-entry (assoc-get 'meta grob-entry))
(class (assoc-get 'class meta-entry))
(ifaces-entry (assoc-get 'interfaces meta-entry)))
(set-object-property! grob-name 'translation-type? ly:grob-properties?)
(set-object-property! grob-name 'is-grob? #t)
(set! ifaces-entry (append (case class
((Item) '(item-interface))
((Spanner) '(spanner-interface))
((Paper_column) '((item-interface
paper-column-interface)))
((System) '((system-interface
spanner-interface)))
(else '(unknown-interface)))
ifaces-entry))
(set! ifaces-entry (uniq-list (sort ifaces-entry symbol<?)))
(set! ifaces-entry (cons 'grob-interface ifaces-entry))
(set! meta-entry (assoc-set! meta-entry 'name grob-name))
(set! meta-entry (assoc-set! meta-entry 'interfaces
ifaces-entry))
(set! grob-entry (assoc-set! grob-entry 'meta meta-entry))
(set! all-grob-descriptions
(cons (cons grob-name grob-entry)
all-grob-descriptions))))
#(define (add-bound-item spanner item)
(if (null? (ly:spanner-bound spanner LEFT))
(ly:spanner-set-bound! spanner LEFT item)
(ly:spanner-set-bound! spanner RIGHT item)))
#(define (axis-offset-symbol axis)
(if (eqv? axis X) 'X-offset 'Y-offset))
#(define (set-axis! grob axis)
(if (not (number? (ly:grob-property grob 'side-axis)))
(begin
(set! (ly:grob-property grob 'side-axis) axis)
(ly:grob-chain-callback
grob
(if (eqv? axis X)
ly:side-position-interface::x-aligned-side
side-position-interface::y-aligned-side)
(axis-offset-symbol axis)))))
#(define (scheme-event-spanner-types-proc class-lst type-lst)
(map
(lambda (x y)
(cons
x
(list
'(description
.
"Used to signal where scheme text spanner brackets start and stop.")
(cons 'types
(list 'post-event
y
'span-event
'event)))))
class-lst
type-lst))
#(define scheme-event-spanner-type
(lambda (x)
(set-object-property! (car x)
'music-description
(cdr (assq 'description (cdr x))))
(let ((lst (cdr x)))
(set! lst (assoc-set! lst 'name (car x)))
(set! lst (assq-remove! lst 'description))
(hashq-set! music-name-to-property-table (car x) lst)
(cons (car x) lst))))
#(define spanner-props
`(
(bound-details . ((left . ((Y . 0)
(padding . 0.25)
(attach-dir . ,LEFT)
))
(left-broken . ((end-on-note . #t)))
(right . ((Y . 0)
(padding . 0.25)
))
))
(dash-fraction . 0.2)
(dash-period . 3.0)
(direction . ,UP)
(font-shape . italic)
(left-bound-info . ,ly:line-spanner::calc-left-bound-info)
(outside-staff-priority . 350)
(right-bound-info . ,ly:line-spanner::calc-right-bound-info)
(staff-padding . 0.8)
(stencil . ,ly:line-spanner::print)
(style . dashed-line)
(meta . ((class . Spanner)
(interfaces . (font-interface
line-interface
line-spanner-interface
outside-staff-interface
side-position-interface))))))
#(define define-engraver
(lambda (engr-name g-name event-types)
(module-define! (current-module) engr-name
(lambda (context)
(let ((span '())
(finished '())
(event-start '())
(event-stop '()))
`((listeners
(,event-types
.
,(lambda (engraver event)
(if (= START (ly:event-property event 'span-direction))
(set! event-start event)
(set! event-stop event)))))
(acknowledgers
(note-column-interface
.
,(lambda (engraver grob source-engraver)
(if (ly:spanner? span)
(begin
(ly:pointer-group-interface::add-grob
span 'note-columns grob)
(add-bound-item span grob)))
(if (ly:spanner? finished)
(begin
(ly:pointer-group-interface::add-grob
finished 'note-columns grob)
(add-bound-item finished grob))))))
(process-music
.
,(lambda (trans)
(if (ly:stream-event? event-stop)
(if (null? span)
(ly:warning "You're trying to end a scheme text spanner
but you haven't started one.")
(begin
(set! finished span)
(ly:engraver-announce-end-grob
trans finished event-start)
(set! span '())
(set! event-stop '()))))
(if (ly:stream-event? event-start)
(begin
(set! span
(ly:engraver-make-grob trans g-name event-start))
(set-axis! span Y)
(set! event-start '())))))
(stop-translation-timestep
.
,(lambda (trans)
(if (and (ly:spanner? span)
(null? (ly:spanner-bound span LEFT)))
(ly:spanner-set-bound! span LEFT
(ly:context-property context 'currentMusicalColumn)))
(if (ly:spanner? finished)
(begin
(if (null? (ly:spanner-bound finished RIGHT))
(ly:spanner-set-bound! finished RIGHT
(ly:context-property
context
'currentMusicalColumn)))
(set! finished '())
(set! event-start '())
(set! event-stop '())))))
(finalize
.
,(lambda (trans)
(if (ly:spanner? finished)
(begin
(if (null? (ly:spanner-bound finished RIGHT))
(ly:spanner-set-bound! finished RIGHT
(ly:context-property
context
'currentMusicalColumn)))
(set! finished '())))
(if (ly:spanner? span)
(begin
(ly:warning
"I think there's a dangling scheme text spanner :-)")
(ly:grob-suicide! span)
(set! span '())))))))))))
createSpannersAndEngravers =
#(define-void-function (name-list)(list?)
(let* ((naming-lst
(map
(lambda (name)
(list
(string->symbol (format #f "~aTextSpanEvent" name))
(ly:camel-case->lisp-identifier
(string->symbol (format #f "~aTextSpanEvent" name)))
(string->symbol (format #f "~aTextSpanner" name))
(string->symbol (format #f "~aTextSpannerEngraver" name))
(string->symbol (string-downcase (format #f "~a-start" name)))
(string->symbol (string-downcase (format #f "~a-stop" name)))))
name-list))
(new-scheme-event-spanner-types
(scheme-event-spanner-types-proc
(map car naming-lst)
(map second naming-lst)))
(scheme-event-spanner-types
(map
scheme-event-spanner-type
new-scheme-event-spanner-types)))
(set! music-descriptions
(append scheme-event-spanner-types music-descriptions))
(set! music-descriptions
(sort music-descriptions alist<?))
(for-each
(lambda (evt
text-span-event-name
g-name
engr-name
cmd-start
cmd-stop)
(define-event-class text-span-event-name 'span-event)
(add-grob-definition g-name spanner-props)
(define-engraver engr-name g-name text-span-event-name)
(module-define! (current-module) cmd-start
(make-span-event evt START))
(module-define! (current-module) cmd-stop
(make-span-event evt STOP)))
(map car naming-lst)
(map second naming-lst)
(map third naming-lst)
(map fourth naming-lst)
(map fifth naming-lst)
(map sixth naming-lst))
(newline)
(pretty-print
(cons
"The following events (class and type), grobs, engravers and
start/stop-commands are created"
naming-lst))))
\createSpannersAndEngravers #'(Barre Liegen )
\layout {
\context {
\Global
\grobdescriptions #all-grob-descriptions
}
\context {
\Voice
\consists \BarreTextSpannerEngraver
\consists \LiegenTextSpannerEngraver
}
}
%Barrè
Prefix = \markup {
%% uncomment/comment these lines for C, C slashed, B or B slashed prefix :
\roman C
%\combine \roman C \translate #'(0.65 . -0.25) \override #'(thickness . 1.2) \draw-line #'(0 . 1.8)
%\roman B
%\combine \roman B \translate #'(0.65 . -0.25) \override #'(thickness . 1.2) \draw-line #'(0 . 1.8)
%%%%%%%%%%%%
\hspace #0.2
}
startBarre =
#(define-event-function (parser location arg-string-qty str rechts)
((integer?) markup? number?)
(let* ((pre-fix
(if arg-string-qty #{ \markup \prefix #arg-string-qty #} Prefix))
(mrkp (markup #:upright #:concat (pre-fix str #:hspace 0.3))))
(define (width grob text-string)
(let* ((layout (ly:grob-layout grob))
(props (ly:grob-alist-chain
grob
(ly:output-def-lookup layout 'text-font-defaults))))
(interval-length
(ly:stencil-extent
(interpret-markup layout props (markup text-string))
X))))
#{
\tweak after-line-breaking
#(lambda (grob)
(let* ((mrkp-width (width grob mrkp))
(line-thickness (ly:staff-symbol-line-thickness grob)))
(ly:grob-set-nested-property!
grob
'(bound-details left padding)
(+ (/ mrkp-width -4) (* line-thickness 2)))))
\tweak font-size -2
\tweak color #(x11-color 'sienna2)
\tweak style #'line
\tweak bound-details.left.text #mrkp
\tweak bound-details.left.attach-dir -1
\tweak bound-details.left-broken.text ##f
\tweak bound-details.left-broken.attach-dir -1
%% adjust the numeric values to fit your needs:
\tweak bound-details.left.stencil-align-dir-y #CENTER
\tweak bound-details.left-broken.padding 1.5
\tweak bound-details.right-broken.padding 0
\tweak bound-details.right.padding #rechts
\tweak bound-details.left.padding -1
\tweak bound-details.right.attach-dir 2
\tweak bound-details.right-broken.text ##f
\tweak bound-details.right.text
\markup
\with-dimensions #'(0 . 0) #'(-1.5 . 0)
\draw-line #'(0 . -1)
\barre-start
#}))
stopBarre = \barre-stop
LieStart =
#(define-scheme-function
(parser location mrkp tr-val mag-nmbr )
(markup? pair? number? )
#{
\tweak bound-details.left-broken.text #'()
\tweak extra-offset #tr-val %eingreifen
\tweak LiegenTextSpanner.font-size #-3
\tweak LiegenTextSpanner.font-series #'bold
\tweak LiegenTextSpanner.font-shape #'normal
\tweak LiegenTextSpanner.style #'dashed-line
\tweak LiegenTextSpanner.dash-fraction #0.3
\tweak LiegenTextSpanner.dash-period #1
\tweak LiegenTextSpanner.color #darkmagenta
\tweak LiegenTextSpanner.thickness #2
\tweak bound-details.right.padding #mag-nmbr %eingreifen
\tweak bound-details.left.text
\markup
\with-dimensions #'(0 . -0.27) #'(0 . 2)
{
%\override #'(on . 2)
\override #'(off . .1)
\draw-dashed-line #'(0 . 1.5) \raise #0.25 #mrkp
}
\liegen-start
#})
LieStop = \liegen-stop
{ a \startBarre "II" #-1 a \stopBarre a}
Das hat auch sehr lange funktioniert. Jetzt habe ich vor Kurzem auf hiesige Empfehlung auf
2.24.0 installiert. Ergebnis, dieses Skript funktioniert nicht mehr. Convert.ly in Frescobaldi ausgeführt ändert auch nichts. Verwende ich aber älter Lilypondversionen, dann geht das Skript noch.
Kann ich das Skript irgendwie updaten oder einfach bei den alten Versionen bleiben?
Um es für 2.24. lauffähig zu bekommen tausche die Definition von spanner-props zu:
#(define spanner-props
`(
(bound-details . ((left . ((Y . 0)
(padding . 0.25)
(attach-dir . ,LEFT)
))
(left-broken . ((end-on-note . #t)))
(right . ((Y . 0)
(padding . 0.25)
))
))
(dash-fraction . 0.2)
(dash-period . 3.0)
(direction . ,UP)
(font-shape . italic)
(left-bound-info . ,ly:horizontal-line-spanner::calc-left-bound-info)
(outside-staff-priority . 350)
(right-bound-info . ,ly:horizontal-line-spanner::calc-right-bound-info)
(staff-padding . 0.8)
(stencil . ,ly:line-spanner::print)
(style . dashed-line)
(meta . ((classes . (Spanner))
(class . Spanner)
(interfaces . (font-interface
line-interface
horizontal-line-spanner-interface
outside-staff-interface
side-position-interface))))))
Allerdings funktioniert es mit 2.25.21 wieder nicht, da haben sich Interna zu den fonts geändert.
Irgendwann muss man solche Sachen von Grund auf neu schreiben...
Aber nicht heute abend ;)
Gruß,
Harm
Ja. Danke. Ich muss schauen, ob ich verstehe, was Du gemacht hast.
ZitatAllerdings funktioniert es mit 2.25.21 wieder nicht, da haben sich Interna zu den fonts geändert.
Wenn du innerhalb von
startBarre die Definition
(define (width grob text-string) ...) veränderst zu:
(define (width grob text-string)
(interval-length
(ly:stencil-extent
(grob-interpret-markup grob (markup text-string))
X)))
klappt es auch mit 2.25.
Allerdings gibt es mit
\prefix ein markup-command(?), welches nicht in deinem post definiert ist.
Es wirft nur deshalb keinen Fehler aus, weil es im Beispiel nicht benutzt wird...
Gruß,
Harm
Zitat von: harm6 am Samstag, 9. November 2024, 23:10ZitatAllerdings funktioniert es mit 2.25.21 wieder nicht, da haben sich Interna zu den fonts geändert.
Wenn du innerhalb von startBarre die Definition (define (width grob text-string) ...) veränderst zu:
(define (width grob text-string)
(interval-length
(ly:stencil-extent
(grob-interpret-markup grob (markup text-string))
X)))
Es wirft nur deshalb keinen Fehler aus, weil es im Beispiel nicht benutzt wird...
Gruß,
Harm
Danke. Muss ich mir anschauen. Es hat sich in meiner Header-Datei im Laufe der Jahre so viel angesammelt, dass ich froh war, überhaupt noch zu erkennen, wo das Problem und ist und wie ich es zusammenkürze. Vermutlich falsch gekürzt.