Allgemein > Fragen zu Funktionen
Phrasierungsbögen an Text ausrichten / Custom TextSpannerEngraver
xr:
--- Zitat ---Siehe:
https://liarchiv.joonet.de/index.php?topic=1762.msg9753#msg9753
( Thema: scheme - very basic: quote, unquote, quasiquote bzw ' oder , oder ` )
--- Ende Zitat ---
Das sollte unbedingt in die Dokumentation. Via Google ist das nicht zu finden.
Und dann habe ich den Threadtitel verändert. Der ursprüngliche Titel hat ja mit dem weiteren Verlauf überhaupt nichts mehr zu tun. Und wo ich gerade bei Googlebarkeit bin ...
Manuela:
--- Zitat von: xr am Mittwoch, 1. März 2017, 12:46 ---
--- Zitat ---Siehe:
https://liarchiv.joonet.de/index.php?topic=1762.msg9753#msg9753
( Thema: scheme - very basic: quote, unquote, quasiquote bzw ' oder , oder ` )
--- Ende Zitat ---
Das sollte unbedingt in die Dokumentation. Via Google ist das nicht zu finden.
--- Ende Zitat ---
Das findet man aber in diversen Scheme-Dokus und Tutorials.
xr:
Hallo Manuela,
stimmt, zu quote, unquote, quasiquote findet man sofort was.
Zum Komma und zum Gravis habe ich aber nichts gefunden, zumindest nicht in den einführenden Tutorial.
"Scheme Gravis" z.B. liefert auch eher Links zu einem Autoverleih. ;)
Deshalb ernsthaft: Komma und Gravis kommen in Lilypond häufiger vor, daher wärs gut, wenn die in der Lilypond Scheme Dokumentation auch mal erwähnt würden.
EDIT: Dass Komma und Gravis auch Kurzschreibweisen sind, habe ich tatsächlich erst jetzt gelesen - wahrscheinlich war ich mal wieder blind.
Gruß,
Xaver
harm6:
Hallo Xaver,
hier mein Versuch.
Ich fand Dein Vorgehen zu un-schemish :))
Woher kommt nur die Manie alles in einen string zu hauen... lol
--- Code: ---\version "2.19.52"
%% 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 name-list '(Hallo Welt A))
% rename path to your file, which holds the engraver code
\include "template-scheme-text-spanner-engraver2-harm.ly"
\layout {
\context {
\Global
\grobdescriptions #all-grob-descriptions
}
\context {
\Voice
\consists #HalloTextSpanner
\consists #WeltTextSpanner
\consists #ATextSpanner
}
}
\relative {
\override HalloTextSpanner.to-barline = ##f
\override HalloTextSpanner.bound-details.left.text = #"hall"
\override HalloTextSpanner.bound-details.right.text = #"lo"
\override WeltTextSpanner.bound-details.left.text = #"we"
\override WeltTextSpanner.bound-details.right.text = #"lt"
\override ATextSpanner.bound-details.left.text = #"A"
\override ATextSpanner.bound-details.right.text = #"A"
a4 b\hallo-start c\welt-start d
a4 b c d
a4 \a-start b c\hallo-stop d \welt-stop \break
a4\hallo-start \welt-start b d \a-stop c
a4 b\hallo-stop c d \welt-stop
a1
}
--- Ende Code ---
--- Code: ---%% 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’
\version "2.19.52"
#(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)))))
%% TODO find easier method to create this list, better structure, etc
#(define (namings names)
(map
(lambda (name)
(list
(cons
(string->symbol (format #f "~aTextSpanEvent" name))
(ly:camel-case->lisp-identifier
(string->symbol (format #f "~aTextSpanEvent" name))))
(cons
(string->symbol (format #f "~aTextSpanner" name))
(string->symbol (format #f "~aTextSpannerEngraver" name)))
(cons
(string->symbol (string-downcase (format #f "~a-start" name)))
(string->symbol (string-downcase (format #f "~a-stop" name))))))
names))
#(for-each
(lambda (text-span-event-name)
(define-event-class
text-span-event-name
'span-event))
(map cdar (namings name-list)))
#(for-each
(lambda (g-name)
(add-grob-definition
g-name
`(
(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)))))))
(map caadr (namings name-list)))
#(define scheme-event-spanner-types
(map
(lambda (x)
(cons
(car x)
(list
'(description . "Used to signal where scheme text spanner brackets start and stop.")
(cons 'types
(list 'post-event
(cdr x)
'span-event
'event)))))
(map car (namings name-list))))
#(set!
scheme-event-spanner-types
(map (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)))
scheme-event-spanner-types))
#(set! music-descriptions
(append scheme-event-spanner-types music-descriptions))
#(set! music-descriptions
(sort music-descriptions alist<?))
#(for-each
(lambda (name-event)
(module-define! (current-module) (car name-event)
(lambda (context)
(let ((span '())
(my-ev (cdr name-event))
(finished '())
(event-start '())
(event-stop '()))
`(
(listeners
(,my-ev
.
,(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 (car name-event) 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 '()))))))))))
(map
(lambda (p) (cons (caadr p) (cdar p)))
(namings name-list)))
%% TODO merge the next two def (too tired right now)
#(for-each
(lambda (elt)
(module-define! (current-module) (car elt)
(make-span-event (cdr elt) START)))
(map (lambda (p) (cons (car (last p)) (caar p)))(namings name-list)))
#(for-each
(lambda (elt)
(module-define! (current-module) (car elt)
(make-span-event (cdr elt) STOP)))
(map (lambda (p) (cons (cdr (last p)) (caar p)))(namings name-list)))
--- Ende Code ---
Ich bin zu müde für irgenwelche Erklärungen ...
Morgen abend wieder.
Gruß,
Harm
xr:
Hallo harm,
--- Zitat ---Woher kommt nur die Manie alles in einen string zu hauen... lol
--- Ende Zitat ---
Kommt daher, weil ich für den Ausdruck (listeners ((scheme-text-span-event engraver event) keine Möglichkeit gefunden habe, das scheme-text-span-event zu ersetzen. Also habe ich es kurzerhand in einen String umgewandelt, dort ausgetauscht und dann wieder evaluiert. Und ihm dann verboten, mich weiterhin zu nerven und aufzuhalten. ;D
Derart kann man natürlich schlecht in dem Code weitere Änderungen vornehmen.
Aber du hast ja jetzt eine prima Lösung gepostet. Könntest du genau diesen Teil später nochmal genauer kommentieren?
--- Code: ---#(for-each
(lambda (name-event)
(module-define! (current-module) (car name-event)
(lambda (context)
(let ((span '())
(my-ev (cdr name-event))
(finished '())
(event-start '())
(event-stop '()))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; Hier hätte ich gerne nähere Erläuterungen über das Folgende
;;;; Auch gern zu Komma und gravis. Ist das wirklich nur die Kurzform von quasiquote und unquote?
`(
(listeners
(,my-ev
.
,(lambda (engraver event)
--- Ende Code ---
Mich interessiert, was die Konstruktion mit quasiquote und ,my-ev aus my-ev macht. Ich konnte my-ev nicht abfangen und erhielt bei (display my-ev) einen Fehler. Welche ein Typ ist das? Mir schien, als würde das im Parser wie ein String oder Symbol interpretiert, ohne jedoch wirklich Symbol oder String zu sein.
Grüße,
Xaver
Navigation
[0] Themen-Index
[#] Nächste Seite
[*] Vorherige Sete
Zur normalen Ansicht wechseln