Allgemein > Fragen zu Funktionen

Wiederholungsklammer manuell setzen

(1/5) > >>

xr:
Hi,

ich bin auf der Suche nach einer Funktion, mit der ich eine Wiederholungsklammer setzen kann, ohne \alternative zu benutzen.
(Da ich meine Noten mittels eines Python Skriptes erzeuge, wäre die Programmierung des gesamten Kontextes  (z.B. \repeat volta 3 \alternative {...} {...} ) inklusive der Verteilung eines Gesangstextes immens kompliziert)

Gibt es die Möglichkeit z.B. mittels einer Scheme-Funktion Klammern zu erzeugen?
Wie muss die aussehen? Kann mir jemand ein einfaches Beispiel zeigen?

Ich würde gern einen Befehl erzeugen wie:

\Klammer_an '#(1 . 3)      % soll Klammer 1 und 3 erzeugen
 ... mein Notentext ...
\Klammer_aus                 % soll die Klammer beenden
\Klammer_an '#(2 . 4)     % soll Klammer 2 und 4 erzeugen
... mein Notentext ...
\Klammer_aus                 % soll die Klammer beenden

Danke für Hilfe im Voraus,
Xaver

Arnold:
Hallo,

in meiner "stradella-toolbox" (siehe https://liarchiv.joonet.de/index.php?topic=1158.0) habe ich rudimentäre Funktionen \pmpStartRepeat, \pmpStartRepeatEx, \pmpEndRepeat und \pmpStartAlternative definiert.
Anwendung: Mit \parallelMusic erzeuge ich mehrere "sequentielle Musiken" mit diesen "Kommandos" drinnen, (denn \repeat volta würde das \parallelMusic durcheinander bringen) und anschließend wird jede dieser "sequentiellen Musiken" an diesen Markierungen zerschnitten und neu (mit \repeat volta) zusammengesetzt.
Wichtig ist: Diese "Steuerkommandos" müssen genau in der gleichen Ebene der sequentiellen Musik vorkommen, nicht in Unterstrukturen gepackt!
Bisher habe ich auch kein Kommando \pmpStartAlternativeEx defniert, mit welcher man den Alternativtext für die Klammerzählung übergibt, aber der existierende Code könnte als Ausgangspunkt dienen. Und #parallel-music-results-postprocess wird sogar nur intern als Scheme-Aufruf gestartet, ist also noch nicht als normale Musikfunction definiert.

Die Anwendung sähe in Endeffekt etwa so aus, wenn man die Funktionen entsprechend erweitert:

--- Code: ---\convertPMPRepeatMarksIntoRepeats {
  \pmpStartRepeat
  ...
  \pmpStartAlternativeEx #"1.+3."
  ...
  \pmpStartAlternativeEx #"2.+4."
  ...
  \pmpEndRepeat
}
--- Ende Code ---

Arnold

xr:
Prima, herzlichen Dank. Schaue ich mir direkt an.

Gruß,
Xaver

xr:
Das Beispiel ist wirklich kompliziert. Und da es, soweit ich es verstehe, gleich zwei Wrapper nutzt, ist es schwierig hinter die Funktionsweise zu kommen.
Ich habe deine Beispieldateien mal soweit reduziert, wie ich konnte. (s.u.)

Wird das, was in den Parser gegeben wird, jetzt soweit umgemodelt, dass für den Lilypond Parser letztlich wieder ein \repeat volta 3 \alternative {...} {...} erscheint?

Ich suche eine Möglichkeit, eine Klammer einfach wie eine Zeichnung zu setzen. Lilypond bräuchte sich um die musikalische Logik nicht weiter zu kümmern.

Hier die reduzierten Beispiele:

--- Code: ---\version "2.15.39"
\include "stradella-toolbox--1.0.ly"

\parallelMusicWithStradella #'(AkkT) {

  \pmpStartRepeat
 
  c 4 e e e       |

  \pmpStartAlternative
  c 4 c' c r |
  \pmpStartAlternative
  e 4  e e r |

  \pmpStartAlternative
  e4 e e e'|
  \pmpStartAlternative
  e4        e e r    |
 
  \mark "Mark"
  \pmpStartRepeat
  e'2.      a'8 b' | 
  \pmpStartAlternative
  e 4 e e e'\p | 
  \pmpStartAlternative
  e 4 e e r |
 
}


\score {
  \new Staff <<   
      \AkkT   
  >>
 
}

--- Ende Code ---


--- Code: ---%{
stradella-toolbox reduced
%}
\version "2.15.30"


%§ post processing marks for the extended parallelMusic
pmpStartRepeat = #(define-music-function (parser location) () (make-music 'MarkEvent
 'label "<parallel-music-results-postprocess:start repeat volta 2>"))
pmpStartRepeatEx = #(define-music-function (parser location count) (integer?) (make-music 'MarkEvent
 'label (string-append "<parallel-music-results-postprocess:start repeat volta " (number->string count) ">")))
pmpEndRepeat = #(define-music-function (parser location) () (make-music 'MarkEvent
 'label "<parallel-music-results-postprocess:end repeat>"))
pmpStartAlternative = #(define-music-function (parser location) () (make-music 'MarkEvent
 'label "<parallel-music-results-postprocess:start alternative>"))

#(define (pmpMark mus)
  (if (ly:music? mus)
   (let
    ((eventtype (ly:music-property mus 'name))
     (labeltext (ly:music-property mus 'label))
    )
    (if (and (eq? eventtype 'MarkEvent) (string? labeltext))
     (let*
      ((head "<parallel-music-results-postprocess:")
       (headlen (string-length head))
       (labellen (string-length labeltext)))
      (if (<= labellen headlen) 0
       (let*
        ((labelhead (string-copy labeltext 0 headlen))
         (labelpost (string-copy labeltext headlen))
         (postlen (string-length labelpost))
         (labelshortpost (string-copy labelpost 0 (min postlen 19)))
        )
        (if (string=? labelhead head)
         (if (string=? labelshortpost "start repeat volta ") 1
          (if (string=? labelpost "end repeat>") 2
           (if (string=? labelpost "start alternative>") 3
            0)))
         0))))
     0))
   0))


#(define (parallel-music-results-postprocess mus)
  (let ((eventtype (ly:music-property mus 'name)))
   (if (eq? eventtype 'SequentialMusic)
    (let
     ((es (ly:music-property mus 'elements))
      (new-es '())
      (active-dest 0)
      (rep-collect '())
      (alt-collect '())
      (alt-list-collect '())
      (rep-count 2)
     )
     (for-each (lambda (ese)
       (let ((etype (pmpMark ese)))
        (if (eq? etype 2) ;; end repeat ;;
         (begin
          (if (eq? active-dest 3)
           (set! alt-list-collect (append alt-list-collect (cons (make-music 'SequentialMusic 'elements alt-collect) '()))))
          (set! new-es (append new-es (cons
           (make-music 'VoltaRepeatedMusic 'repeat-count rep-count
            'element (make-music 'SequentialMusic 'elements rep-collect) 'elements alt-list-collect) '())))
          (set! active-dest 0)
          (set! rep-collect '())
          (set! alt-collect '())
          (set! alt-list-collect '())))
        (if (eq? etype 1) ;; start repeat ;;
         (begin
          (if (eq? active-dest 3)
           (set! alt-list-collect (append alt-list-collect (cons (make-music 'SequentialMusic 'elements alt-collect) '()))))
          (if (>= active-dest 1) ;; terminate existing repeat and start new repeat block
           (set! new-es (append new-es (cons
            (make-music 'VoltaRepeatedMusic 'repeat-count rep-count
             'element (make-music 'SequentialMusic 'elements rep-collect) 'elements alt-list-collect) '()))))
          (set! active-dest 1)
          (set! rep-collect '())
          (set! alt-collect '())
          (set! alt-list-collect '())))
        (if (and (eq? etype 3) (>= active-dest 1)) ;; start alternative (only when repeat allready started) ;;
         (if (eq? active-dest 3) ;; next alternative ;;
          (begin
           (set! alt-list-collect (append alt-list-collect (cons (make-music 'SequentialMusic 'elements alt-collect) '())))
           (set! alt-collect '()))
          (set! active-dest 3)))
        (if (eq? etype 0)
         (begin
          (if (eq? active-dest 0)
           (set! new-es (append new-es (cons ese '()))))
          (if (eq? active-dest 1)
           (set! rep-collect (append rep-collect (cons ese '()))))
          (if (eq? active-dest 3)
           (set! alt-collect (append alt-collect (cons ese '()))))))))
      es)
     (if (eq? active-dest 1) ;; start repeat is open ;;
      (set! new-es (append new-es (cons
       (make-music 'VoltaRepeatedMusic 'repeat-count rep-count
        'element (make-music 'SequentialMusic 'elements rep-collect) 'elements alt-list-collect) '()))))
     (if (eq? active-dest 3) ;; start alternative is open ;;
      (begin
       (set! alt-list-collect (append alt-list-collect (cons (make-music 'SequentialMusic 'elements alt-collect) '())))
       (set! new-es (append new-es (cons
        (make-music 'VoltaRepeatedMusic 'repeat-count rep-count
         'element (make-music 'SequentialMusic 'elements rep-collect) 'elements alt-list-collect) '())))))
     (ly:music-set-property! mus 'elements new-es)
     mus)
    mus)))



%§ \paralleMusic with \stradellaMode applied to the last voice
% and another postprocessor applied to all voices
parallelMusicWithStradella =
#(define-void-function (parser location voice-ids music) (list? ly:music?)
  (let ((parmus (ly:parser-lookup parser 'parallelMusic)))
   
     (let ((parex (ly:music-function-extract parmus)))
      (parex parser location voice-ids music)     
         
      (let ((counter 0))
       (for-each (lambda (voice-id)
         (let ((pme (ly:parser-lookup parser voice-id)))
         
           (if (eq? counter 0)
           
            (ly:parser-define! parser voice-id
             (parallel-music-results-postprocess
              pme)
             
             )
 
         )
           )
         )
           
        (reverse voice-ids))
       )
      )))

--- Ende Code ---

Xaver

Arnold:
O.K.

Und alle mit weniger Scheme-Programmier-Erfahrung durfen das hier ausprobieren:

--- Code: ---\version "2.18.2"

pmpStartRepeat = #(define-music-function (parser location) () (make-music 'MarkEvent
 'label "<parallel-music-results-postprocess:start repeat volta 2>"))
pmpStartRepeatEx = #(define-music-function (parser location count) (integer?) (make-music 'MarkEvent
 'label (string-append "<parallel-music-results-postprocess:start repeat volta " (number->string count) ">")
 'extra-int count))
pmpEndRepeat = #(define-music-function (parser location) () (make-music 'MarkEvent
 'label "<parallel-music-results-postprocess:end repeat>"))
pmpStartAlternative = #(define-music-function (parser location) () (make-music 'MarkEvent
 'label "<parallel-music-results-postprocess:start alternative>"))
pmpStartAlternativeEx = #(define-music-function (parser location s) (string?) (make-music 'MarkEvent
 'label (string-append "<parallel-music-results-postprocess:start named alternative:" s ">")
 'extra-text s))

#(define (pmpMark mus)
  (if (ly:music? mus)
   (let
    ((eventtype (ly:music-property mus 'name))
     (labeltext (ly:music-property mus 'label))
    )
    (if (and (eq? eventtype 'MarkEvent) (string? labeltext))
     (let*
      ((head "<parallel-music-results-postprocess:")
       (headlen (string-length head))
       (labellen (string-length labeltext)))
      (if (<= labellen headlen) 0
       (let*
        ((labelhead (string-copy labeltext 0 headlen))
         (labelpost (string-copy labeltext headlen))
         (postlen (string-length labelpost))
         (labelshortpost (string-copy labelpost 0 (min postlen 19)))
        )
        (if (string=? labelhead head)
         (if (string=? labelshortpost "start repeat volta ") 1
          (if (string=? labelpost "end repeat>") 2
           (if (string=? labelpost "start alternative>") 3
            (if (string=? labelshortpost "start named alterna") 4
             0))))
         0))))
     0))
   0))

#(define (pmpMarkRepeatCount mus)
  (if (ly:music? mus)
   (let
    ((eventtype (ly:music-property mus 'name))
     (labeltext (ly:music-property mus 'label)))
    (if (and (eq? eventtype 'MarkEvent) (string? labeltext))
     (let*
      ((head "<parallel-music-results-postprocess:")
       (headlen (+ (string-length head) 19))
       (labellen (string-length labeltext)))
      (if (<= labellen headlen) 2
       (let*
        ((labelhead (string-copy labeltext 0 headlen))
         (labelpost (string-copy labeltext headlen (- labellen 1)))
         (labelterm (string-copy labeltext (- labellen 1))))
        (if (string=? labelterm ">") (string->number labelpost)
         2))))
     2))
   2))

#(define (parallel-music-results-postprocess mus)
  (let ((eventtype (ly:music-property mus 'name)))
   (if (eq? eventtype 'SequentialMusic)
    (let
     ((es (ly:music-property mus 'elements))
      (new-es '())
      (active-dest 0)
      (rep-collect '())
      (alt-collect '())
      (alt-list-collect '())
      (rep-count 2)
     )
     (for-each (lambda (ese)
       (let ((etype (pmpMark ese)))
        (if (eq? etype 2) ;; end repeat ;;
         (begin
          (if (eq? active-dest 3)
           (set! alt-list-collect (append alt-list-collect (cons (make-music 'SequentialMusic 'elements alt-collect) '()))))
          (set! new-es (append new-es (cons
           (make-music 'VoltaRepeatedMusic 'repeat-count rep-count
            'element (make-music 'SequentialMusic 'elements rep-collect) 'elements alt-list-collect) '())))
          (set! active-dest 0)
          (set! rep-collect '())
          (set! alt-collect '())
          (set! alt-list-collect '())))
        (if (eq? etype 1) ;; start repeat ;;
         (begin
          (if (eq? active-dest 3)
           (set! alt-list-collect (append alt-list-collect (cons (make-music 'SequentialMusic 'elements alt-collect) '()))))
          (if (>= active-dest 1) ;; terminate existing repeat and start new repeat block
           (set! new-es (append new-es (cons
            (make-music 'VoltaRepeatedMusic 'repeat-count rep-count
             'element (make-music 'SequentialMusic 'elements rep-collect) 'elements alt-list-collect) '()))))
          (set! active-dest 1)
          (set! rep-collect '())
          (set! alt-collect '())
          (set! rep-count (ly:music-property ese 'extra-int 2))
          (set! alt-list-collect '())))
        (if (and (eq? etype 3) (>= active-dest 1)) ;; start alternative (only when repeat allready started) ;;
         (if (eq? active-dest 3) ;; next alternative ;;
          (begin
           (set! alt-list-collect (append alt-list-collect (cons (make-music 'SequentialMusic 'elements alt-collect) '())))
           (set! alt-collect '()))
          (set! active-dest 3)))
        (if (and (eq? etype 4) (>= active-dest 1)) ;; start named alternative (only when repeat allready started) ;;
         (begin
          (if (eq? active-dest 3) ;; next alternative ;;
           (set! alt-list-collect (append alt-list-collect (cons (make-music 'SequentialMusic 'elements alt-collect) '())))
          (set! active-dest 3))
         (set! alt-collect (cons
           (make-music 'ApplyContext
            'procedure (lambda (ctx)
                        (let ((score-ctx (ly:context-find ctx 'Score)))
                         (if (ly:context? score-ctx)
                          (let ((old-rc (ly:context-property score-ctx 'repeatCommands '())))
                           (ly:context-set-property! score-ctx 'repeatCommands (cons (list 'volta (ly:music-property ese 'extra-text "?")) old-rc)))))))
           '()))))
        (if (eq? etype 0)
         (begin
          (if (eq? active-dest 0)
           (set! new-es (append new-es (cons ese '()))))
          (if (eq? active-dest 1)
           (set! rep-collect (append rep-collect (cons ese '()))))
          (if (eq? active-dest 3)
           (set! alt-collect (append alt-collect (cons ese '()))))))))
      es)
     (if (eq? active-dest 1) ;; start repeat is open ;;
      (set! new-es (append new-es (cons
       (make-music 'VoltaRepeatedMusic 'repeat-count rep-count
        'element (make-music 'SequentialMusic 'elements rep-collect) 'elements alt-list-collect) '()))))
     (if (eq? active-dest 3) ;; start alternative is open ;;
      (begin
       (set! alt-list-collect (append alt-list-collect (cons (make-music 'SequentialMusic 'elements alt-collect) '())))
       (set! new-es (append new-es (cons
        (make-music 'VoltaRepeatedMusic 'repeat-count rep-count
         'element (make-music 'SequentialMusic 'elements rep-collect) 'elements alt-list-collect) '())))))
     (ly:music-set-property! mus 'elements new-es)
     mus)
    mus)))

LinearToVoltaRepeats =
#(define-music-function (parser location m) (ly:music?)
  (parallel-music-results-postprocess m))


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\LinearToVoltaRepeats {
  c'1
  \pmpStartRepeat
  d'
  \pmpStartAlternative
  e'
  \pmpStartAlternative
  f'
  \pmpStartRepeat
  g'
  \pmpStartAlternative
  a'
  \pmpStartAlternative
  b'
  \pmpStartRepeatEx #5
  c''
  \pmpStartAlternativeEx #"1., 3."
  d''
  \pmpStartAlternativeEx #"2., 4."
  e''
  \pmpStartAlternative
  f''
  \pmpEndRepeat
  g''
}

--- Ende Code ---

A propos, bis jetzt sind nur Zeichenketten (Strings, unformatierte Texte) als Klammerbenennung möglich, keine markups (z. Bsp. um das Wörtchen »Fine« in eine Klammer zu setzen.)

Arnold

Navigation

[0] Themen-Index

[#] Nächste Seite

Zur normalen Ansicht wechseln