Allgemein > Fragen zu Funktionen

Phrasierungsbögen an Text ausrichten / Custom TextSpannerEngraver

<< < (6/7) > >>

harm6:
Hallo Xaver,


--- Zitat ---Aber du hast ja jetzt eine prima Lösung gepostet. Könntest du genau diesen Teil später nochmal genauer kommentieren?
[...]
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?

--- Ende Zitat ---

Lass uns mal ein einfacheres Beispiel betrachten. Einen simplen listener. Er soll solch eine Variable annehmen, als Ausgabe nur melden, falls eine Note gefunden wurde.

Man sollte sich klar machen, daß ein engraver erstmal nur eine Liste ist, die via \consist in einen Context eingefügt wird.
Das make-engraver-makro vereinfacht die Syntax, vernebelt aber die Basis...

Im Code unten habe ich 3 solche engraver definiert.
test-engr benutzt make-engraver
test-I-engr verwendet eine direkt sichtbare Liste aber die Kürzel für quote, quasiquote und unquote
test-II-engr verwendet `list` und `cons` um die Liste zu erstellen quote nur für tatsächliche symbols
Alle drei greifen auf ein vordefiniertes symbol zu, `ev`, versuchen es zu verarbeiten und ins terminal zu schreiben.

Resultat:
Der erste, mit make-engraver erstellte scheitert. Die beiden anderen funktionieren.

Konsequenzen:
(1) Beim Vergleich von test-I-engr mit test-II-engr sollte klar werden, daß das unquote wirklich nur eben das macht. De Versuch es im Terminal anzeigen zu lassen sollte an geeigneter Stelle erfolgen.
(2) test-engr mit make-engraver ist gescheitert die Variable zu nutzen.
make-engraver ist ein noch nicht so altes makro und wird von nicht vielen Personen verwendet. Es ist nicht überraschend, daß man irgendwann eine Schwäche findet.
Ich werde dieses Problem mal auf der devel-mailing-list vorstellen.

Hier der Testcode:

--- Code: ---\version "2.19.52"

#(define ev 'note-event)

#(define test-engr
  (lambda (context)
    (make-engraver
      (listeners
        (
         (ev engraver event)
         ;(note-event engraver event)
           (write ev)
           (format #t "\n\nnote-event found from control-engraver\n"))))))
       
#(define test-I-engr
  (lambda (context)
    `((listeners
        (
         ,ev
         ;note-event
          .
          ,(lambda (engraver event)
             (write ev)
             (format #t "\n\nnote-event found from test-I-engraver\n")))))))     
             
#(define test-II-engr
  (lambda (context)
    (list
      (cons 'listeners
        (list
          (cons
            ev
            ;'note-event
            (lambda (engraver event)
               (write ev)
               (format #t "\n\nnote-event found from test-II-engraver\n"))))))))
\layout {
  \context {
    \Voice
    \consists #test-engr
    \consists #test-I-engr
    \consists #test-II-engr
  }
}

{
  c'4
}

--- Ende Code ---

HTH,
  Harm

harm6:
Ansonsten habe ich den code noch mal überarbeitet. Die ganze Sache wird jetzt über ein aufrufbare Funktion geregelt.

Das Test-file:

--- 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’

% rename path to your file, which holds the engraver code
\include "multiple-spanner-grobs-engravers.ly"

\createSpannersAndEngravers  #'(Hallo Welt A)

\layout {
  \context {
    \Global
    \grobdescriptions #all-grob-descriptions
  }
  \context {
    \Voice
    \consists \HalloTextSpannerEngraver
    \consists \WeltTextSpannerEngraver
    \consists \ATextSpannerEngraver
  }
}

\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 ---

Das zu inkludierende file (auch im Anhang):

--- 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)))))
         
#(define (namings names)
  (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)))))
    names))
   
#(define (scheme-event-spanner-types-proc 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)))))
    (map car (namings lst))
    (map second (namings 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 (namings name-list)))

  (for-each
    (lambda (text-span-event-name)
      (define-event-class text-span-event-name 'span-event))
    (map second naming-lst))
 
  (for-each
    (lambda (g-name) (add-grob-definition g-name spanner-props))
    (map third naming-lst))
 
  (let* ((new-scheme-event-spanner-types
           (scheme-event-spanner-types-proc name-list))
         (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)))
                 new-scheme-event-spanner-types)))
 
    (set! music-descriptions
           (append scheme-event-spanner-types music-descriptions))
   
    (set! music-descriptions
           (sort music-descriptions alist<?)))
         
  ;; Create engravers
  (for-each
    define-engraver
    (map fourth naming-lst)
    (map third naming-lst)
    (map second naming-lst))
       
  ;; Create spanner-start/stop-commands
  ;; Example a-start/a-stop
  ;;
  ;; cmd-start: <spanner-name>-start
  ;; cmd-stop: <spanner-name>-stop
  ;; evt: <SpannerName>TextSpanEvent 
  (for-each
    (lambda (cmd-start cmd-stop evt)
      (module-define! (current-module) cmd-start
        (make-span-event evt START))
      (module-define! (current-module) cmd-stop
        (make-span-event evt STOP)))
    (map fifth naming-lst)
    (map sixth naming-lst)
    (map car naming-lst))

  (newline)
  (pretty-print
  (cons
    "The following events (class and type), grobs, engravers and
start/stop-commands are created"
    naming-lst))))

--- Ende Code ---

HTH,
  Harm

xr:
Hallo harm,

zunächst einmal mein herzlichster Dank für deine wirklich hervorragende Hilfe! Deine Beispiele sind ganz prima und ich habe in kurzer Zeit wirklich einiges gelernt! Danke.

Mit den Engravern habe ich auch noch weiter herumgespielt. Und in den regression tests fand ich auch noch dies. Ebenfalls fürs Verständnis hilfreich.
https://github.com/lilypond/lilypond/blob/master/input/regression/scheme-engraver.ly

Allerdings glaube ich, dass Phrasierungsbögen mit id für meine Belange doch ausreichend sind. Ich habe mir mal die Regeln notiert, an denen ich entlangprogrammieren will.

--- Code: ---tmp={\mark"
---- REGELN -------

Phrasing-Slur spanner-id

leer Bogen keine Änderung
\=1 Bogen wechselt Stimme
\=2 übergreifender Bogen, sitzt oberhalb

Abkürzungen
X:
    kW  (kein Wechsel)
    VN  (Vorgänger oder Nachfolger, je nach Seite)
    aR  (am Rand - NonMusicPaperColumn)
    WR  (Wortrand)
    WR+ (Wortrand plus geringer Abstand)
    max (Hälfte des Zwischenraumes, max Maximalabstand)

Y:
    WU  (Wechsel nach unten)
    WO  (Wechsel nach oben)
    ein (Y zur Mittelzeile hin eingezogen)


- Bogen in einer Zeile:
    -links + rechts:
        -kW,VN: x:max, Y:ein
        -kw,aR: x:WR+,  Y:ein
    -links:
        -WU x:WR Y:WR+
        -WO,VN X:max Y:ein
        -WO,aR X:WR Y:ein
    -rechts:
        -WU,VN X:max Y:ein
        -WU,aR X:WR+ Y:ein
        -WO X:WR Y:WR+

- Bogen gesplittet, Anfang:
    -links wie Bogen in einer Zeile
    -rechts:
        - Krümmung verringert

- Bogen gesplittet, Ende:
    wie Anfang seitenverkehrt

- Bogen gesplittet, Mittelzeile
    - Krümmung an Seiten verringert

- übergreifender Bogen:
    -immer oben
    -gleiche Regeln wie bei Vorgängern,
     sollte etwas höher sitzen

"}
--- Ende Code ---

Allerdings wird das nun wohl was länger dauern, da ich gerade anderweitig viel zu tun habe. Wenn ich damit durch bin, poste ich das Beispiel.

Grüße,
Xaver

xr:
Ich dachte, ich hätte mal eine Property gesehen, die mir anzeigt, in welcher Systemzeile ich mich befinde. Aber ich kann die nicht mehr finden.
Gibts die oder habe ich das falsch in Erinnerung?

harm6:

--- Zitat von: harm ---Ich werde dieses Problem mal auf der devel-mailing-list vorstellen.
--- Ende Zitat ---
http://lilypond.1069038.n5.nabble.com/limitation-in-make-engraver-td200649.html


--- Zitat von: xr ---zunächst einmal mein herzlichster Dank für deine wirklich hervorragende Hilfe! Deine Beispiele sind ganz prima und ich habe in kurzer Zeit wirklich einiges gelernt! Danke.
--- Ende Zitat ---
Gern geschehen.


--- Zitat von: xr ---Mit den Engravern habe ich auch noch weiter herumgespielt. Und in den regression tests fand ich auch noch dies. Ebenfalls fürs Verständnis hilfreich.
https://github.com/lilypond/lilypond/blob/master/input/regression/scheme-engraver.ly

--- Ende Zitat ---
Ich würde direkt in die regression-tests verlinken:
lilypond.org/doc/v2.19/input/regression/b1/lily-58429201.ly


--- Zitat von: xr ---Allerdings glaube ich, dass Phrasierungsbögen mit id für meine Belange doch ausreichend sind.
--- Ende Zitat ---
Ich bin gespannt auf das Ergebnis ;)


--- Zitat von: xr ---Ich dachte, ich hätte mal eine Property gesehen, die mir anzeigt, in welcher Systemzeile ich mich befinde. Aber ich kann die nicht mehr finden.
Gibts die oder habe ich das falsch in Erinnerung?
--- Ende Zitat ---
Kannst Du den Zusammenhang erläutern, d.h. wo brauchst Du das? In einer Funktion?

Ansonsten hab ich den engraver-code nochmal bearbeitet, schien mir noch nicht elegant genug zu sein. lol


--- 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)))))
   
#(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))))
     
%%%%%%%%%%%%%%%%%%%%%%%
%% Example
%%%%%%%%%%%%%%%%%%%%%%%
%{
       
%% rename path to your file, which holds the engraver code
% \include "multiple-spanner-grobs-engravers.ly"

\createSpannersAndEngravers  #'(Hallo Welt A)

\layout {
  \context {
    \Global
    \grobdescriptions #all-grob-descriptions
  }
  \context {
    \Voice
    \consists \HalloTextSpannerEngraver
    \consists \WeltTextSpannerEngraver
    \consists \ATextSpannerEngraver
  }
}

\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 ---


Gruß,
  Harm





Navigation

[0] Themen-Index

[#] Nächste Seite

[*] Vorherige Sete

Zur normalen Ansicht wechseln