Deutsches Lilypond Forum (Archiv)

Allgemein => Fragen zu Funktionen => Thema gestartet von: xr am Dienstag, 31. Januar 2017, 14:24

Titel: Wiederholungsklammer manuell setzen
Beitrag von: xr am Dienstag, 31. Januar 2017, 14:24
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
Titel: Re: Wiederholungsklammer manuell setzen
Beitrag von: Arnold am Dienstag, 31. Januar 2017, 16:15
Hallo,

in meiner "stradella-toolbox" (siehe https://liarchiv.joonet.de/index.php?topic=1158.0 (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:
\convertPMPRepeatMarksIntoRepeats {
  \pmpStartRepeat
  ...
  \pmpStartAlternativeEx #"1.+3."
  ...
  \pmpStartAlternativeEx #"2.+4."
  ...
  \pmpEndRepeat
}

Arnold
Titel: Re: Wiederholungsklammer manuell setzen
Beitrag von: xr am Dienstag, 31. Januar 2017, 18:08
Prima, herzlichen Dank. Schaue ich mir direkt an.

Gruß,
Xaver
Titel: Re: Wiederholungsklammer manuell setzen
Beitrag von: xr am Mittwoch, 1. Februar 2017, 09:48
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:
\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   
  >>
 
}

%{
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))
       )
      )))

Xaver
Titel: Re: Wiederholungsklammer manuell setzen
Beitrag von: Arnold am Mittwoch, 1. Februar 2017, 09:50
O.K.

Und alle mit weniger Scheme-Programmier-Erfahrung durfen das hier ausprobieren:
\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''
}

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
Titel: Re: Wiederholungsklammer manuell setzen
Beitrag von: Arnold am Mittwoch, 1. Februar 2017, 10:03
Hallo xr,

es wird die übergebene »sequentielle Musik« Schritt für Schritt durchgegangen - aber nur in der obersten Ebene - und an den »Markierungen« wird die Liste in Einzellisten unterteilt, um daraus die eingebetteten \repeat volta Strukturen einzufügen.
Dadurch kann später auch \unfoldRepeats angewandt werden, z. Bsp. um Midi zu erzeugen.

Wollte man nur die Grafik, könnte man sich eine Liste der in Handbuch nachzulesenden manuellen Wiederholungszeichen- und Voltenklammern in einer eigenen Datei zusammenstellen (und in jedes neue Projekt mittels \include einbinden). Jedes dort abgelegte Schnipsel enthält alles was an einem "Taktstrich" zu passieren hat, im einfachsten Fall nur die Taktstrichdefinition, meistens Taktstrich- und Volta-Definition zusammen.

Arnold.
Titel: Re: Wiederholungsklammer manuell setzen
Beitrag von: xr am Mittwoch, 1. Februar 2017, 10:19
Zitat
Wollte man nur die Grafik, könnte man sich eine Liste der in Handbuch nachzulesenden manuellen Wiederholungszeichen- und Voltenklammern in einer eigenen Datei zusammenstellen (und in jedes neue Projekt mittels \include einbinden). Jedes dort abgelegte Schnipsel enthält alles was an einem "Taktstrich" zu passieren hat, im einfachsten Fall nur die Taktstrichdefinition, meistens Taktstrich- und Volta-Definition zusammen.

Das ist quasi die Antwort. Ich habe nämlich nicht gesehen, dass man eine Voltenklammer auch manuell erzeugen kann. Die Befehle lauten ganz einfach:
\set Score.repeatCommands = #'((volta "2"))
\set Score.repeatCommands = #'((volta #f))

Es ist natürlich ganz einfach, daraus eine Funktion zu basteln.

Vielen Dank,
Xaver
Titel: Re: Wiederholungsklammer manuell setzen
Beitrag von: Manuela am Mittwoch, 1. Februar 2017, 13:56
Wieder was gelernt  :)
Titel: Re: Wiederholungsklammer manuell setzen
Beitrag von: xr am Mittwoch, 1. Februar 2017, 17:32
Da die Funktionen doch nicht so einfach zu erzeugen waren, wie ich behauptet habe - zumindest nicht für mich - poste ich nun doch noch die Lösung:

Klammer =
#(define-music-function
    (parser location num)
    (number?)

    (define liste '(list (volta "1")) )
   
    (set! nr (integer->char (+ 48 num)) )
    (set! nr (make-string 1 nr))
    (set-car! (cdr(car (cdr liste)))   nr)
       
    #{       
    \set Score.repeatCommands = # liste
    #})


Klammer_aus =
#(define-music-function
    (parser location)
    ()
   
    #{
     \set Score.repeatCommands = #'((volta #f))
    #})

Das funktioniert für die Zahlen 1 - 9, für höhere müsste man den Code erweitern.
Gibt es in Scheme eine einfache Funktion, um Integer jeglicher Größe in Strings umzuwandeln?

Titel: Re: Wiederholungsklammer manuell setzen
Beitrag von: Manuela am Mittwoch, 1. Februar 2017, 17:40
Ja, gibt es, hier z.B. nachzulesen (https://ds26gte.github.io/tyscheme/index-Z-H-4.html#node_sec_2.2.4)
Titel: Re: Wiederholungsklammer manuell setzen
Beitrag von: xr am Mittwoch, 1. Februar 2017, 18:02
Ok, dann gehts doch einfacher für jede Zahl:

nr = ""

Klammer =
#(define-music-function
    (parser location num)
    (number?)

    (define liste '(list (volta "1")) )
   
    (set! nr (number->string num))
    (set-car! (cdr(car (cdr liste)))   nr)
       
    #{       
    \set Score.repeatCommands = # liste
    #})
Titel: Re: Wiederholungsklammer manuell setzen
Beitrag von: Manuela am Mittwoch, 1. Februar 2017, 18:09
Mein Scheme ist wieder eingerostet, aber das geht sicher noch einfacher.

Was genau macht dein Programm, hängt es num als String an die Liste?
Titel: Re: Wiederholungsklammer manuell setzen
Beitrag von: xr am Mittwoch, 1. Februar 2017, 18:21
Ich habe hier nochmal den vollständigen Code. Funktioniert leider immer noch nicht. Statt Klammer 1 und Klammer 2 wird 2x Klammer 2 ausgegeben. Außerdem bekomme ich folgende Fehlermeldung:
Warnung: Wiederholungsklammer bereits vorhanden, wird vorzeitig beendet

\version "2.18.2"
         
#(define liste '(list (volta "1")) )         

txt = ""


Klammer =
#(define-music-function
    (parser location num)
    (number?)

    (set! txt (number->string num))
    (set-car! (cdr(car (cdr liste)))   txt)
       
    #{       
    \set Score.repeatCommands = # liste
    #})


Klammer-aus =
#(define-music-function
    (parser location)
    ()
   
    #{
     \set Score.repeatCommands = #'((volta #f))
    #})


\score {
 
    <<
      \relative {   
       
        \time 4/4 
       
        f'4 g f f 
       
        \Klammer 1
        e4 f e e
        g4 e e e
        f4 g f f 
        \Klammer-aus
        \bar ":|."
       
        \Klammer 2
        e4 f e e
        g4 e e e
        \Klammer-aus
       
        c4 d c c     
      }
 
    >>
 
}
Titel: Re: Wiederholungsklammer manuell setzen
Beitrag von: xr am Mittwoch, 1. Februar 2017, 21:19
So, Stunden später habe ich jetzt endlich eine funktionierende Lösung.
Von C oder Python kommend, kann einen Scheme echt in die Verzweiflung treiben.

\version "2.18.2"


txt = ""

Klammer =
#(define-music-function
    (parser location num)
    (number?)
   
    (define listeA '(list  (volta "1")) )
    (define listeB '( (volta #f) (volta "2")) )
   
    (newline)
   
    ( if ( < num 2)
        (begin
            (set! txt (number->string num))
            (set-car! (cdr(car(cdr listeA))) txt)

            #{       
            \set Score.repeatCommands = #listeA
            #}
        )
   
        (begin
            (set! txt (number->string num))
            (set-car!(cdr(car(cdr listeB))) txt )
       
            #{       
            \set Score.repeatCommands = #listeB
            #}
        )   
    )
)

Klammer-aus =
#(define-music-function
    (parser location)
    ()   
    #{
     \set Score.repeatCommands = #'((volta #f))
    #})


\score { 
    <<
      \relative {   
       
        \time 4/4 
       
        f'4 g f f 
       
        \Klammer 1
        e4 f e e
        g4 e e e
        f4 g f  f 
        \Klammer-aus
        \bar ":|."
       
        \Klammer 3
        e4 f e e
        g4 e e e
        \Klammer-aus
       
        c4 d c c     
      }
 
    >>
}
[code]
Titel: Re: Wiederholungsklammer manuell setzen
Beitrag von: xr am Mittwoch, 1. Februar 2017, 21:32
Ah - ich werde doch noch wahnsinnig!
Dummerweise überschreibt immer die letzte Zahl alle Zahlen der vorangegangenen Klammern. Das fällt natürlich erst bei mehreren Klammern auf.

Weiß irgendwer warum das so ist? Werden Variablen an den Lilypond Parser übergeben und erst am Schluss ausgewertet? Oder was mache ich falsch?
Titel: Re: Wiederholungsklammer manuell setzen
Beitrag von: xr am Mittwoch, 1. Februar 2017, 22:20
Meine Lösung, die nun wirklich funktioniert, wird jetzt nicht mehr berechnet, sondern ist fest vorgegeben. Geht wohl schneller, als mir noch weiter über Lösungsmöglichkeiten den Kopf zu zerbrechen.

\version "2.18.2"


Klammer =
#(define-music-function
    (parser location num)
    (number?)
   
    (define listeA '((volta "1")) )
    (define listeB '( (volta #f) (volta "2")) )
    (define listeC '( (volta #f) (volta "3")) )
    (define listeD '( (volta #f) (volta "4")) )
    (define listeE '( (volta #f) (volta "5")) )
    (define listeF '( (volta #f) (volta "6")) )
    (define listeG '( (volta #f) (volta "7")) )
    (define listeH '( (volta #f) (volta "8")) )
    (define listeI '( (volta #f) (volta "9")) )
   
    ( cond
      (( = num 1)
            #{ \set Score.repeatCommands = #listeA #})
      (( = num 2)
            #{ \set Score.repeatCommands = #listeB #})
      (( = num 3)
            #{ \set Score.repeatCommands = #listeC #})
      (( = num 4)
            #{ \set Score.repeatCommands = #listeD #})
      (( = num 5)
            #{ \set Score.repeatCommands = #listeE #})
      (( = num 6)
            #{ \set Score.repeatCommands = #listeF #})
      (( = num 7)
            #{ \set Score.repeatCommands = #listeG #})
      (( = num 8)
            #{ \set Score.repeatCommands = #listeH #})
      (( = num 9)
            #{ \set Score.repeatCommands = #listeI #})   
    )
)

Klammer-aus =
#(define-music-function
    (parser location)
    ()   
    #{
     \set Score.repeatCommands = #'((volta #f))
    #})


\score { 
    <<
      \relative {   
       
        \time 4/4 
       
        f'4 g f f 
       
        \Klammer 1
        e4 f e e
        g4 e e e
        f4 g f  f 
        \Klammer-aus
        \bar ":|."
       
        \Klammer 2
        e4 f e e
        g4 e e e
        \Klammer-aus
        \bar ":|."
        \Klammer 7
        e4 f e e
        g4 e e e
        \Klammer-aus
        c4 d c c     
      }
 
    >>
}
Titel: Re: Wiederholungsklammer manuell setzen
Beitrag von: harm6 am Mittwoch, 1. Februar 2017, 22:31
Zitat
Dummerweise überschreibt immer die letzte Zahl alle Zahlen der vorangegangenen Klammern. Das fällt natürlich erst bei mehreren Klammern auf.
Weiß irgendwer warum das so ist?

\set Score.repeatCommands setzt das context-property 'repeatCommands'.
Mehrere davon zur selben Zeit überschreiben sich gegenseitig, ist völlig normal und auch bei jedem override so.
Für overrides gibts mittlerweile eine Funktion, die den default (falls vorhanden) ausliest und dann mit dem gewünschten Wert erweitert. Für context-properties gibts das meines Wissens nach nicht.

In Deinem Fall mußt Du die bisherigen Setzungen von repeatCommands zum gegebenen Zeitpunkt auslesen, Deine Werte hinzufügen und neu zuweisen.

Such mal hier im Forum nach setRepeatCommand

Ob mein damaliger 2.16.-code heute noch funktioniert habe ich allerdings nicht getestet.


Gruß,
  Harm


Titel: Re: Wiederholungsklammer manuell setzen
Beitrag von: xr am Donnerstag, 2. Februar 2017, 06:58
Danke für deinen Hinweis.
Darum kümmere ich mich allerdings erst wieder, wenn nochmal ein ähnliches Problem auftaucht.

Xaver
Titel: Re: Wiederholungsklammer manuell setzen
Beitrag von: Arnold am Donnerstag, 2. Februar 2017, 09:56
Hallo,

und jetzt gebe ich nochmal meinen Senf dazu - Schwerpunkt meine forgestellten Funktionen:
Wenn ich das alles habe, werde ich es hier veröffentlichen. Voraussichtlich Anfang nächster Woche.

Arnold
Titel: Re: Wiederholungsklammer manuell setzen
Beitrag von: Arnold am Montag, 6. Februar 2017, 09:14
So, jetzt meine aktualiserite Version:
\version "2.18.2"
#(define (string-or-markup? x) (or (string? x) (markup? x)))

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-or-markup?) (make-music 'MarkEvent
 'label (string-append "<parallel-music-results-postprocess:start named alternative:" (if (markup? s) "(markup)" 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 (max rep-count (length alt-list-collect))
            '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 (max rep-count (length alt-list-collect))
             '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 '())) ; (boolean? (cadr v))
                                 (filtered-rc (filter (lambda (v)
                                    (or (not (pair? v)) (not (eq? (car v) 'volta)) (boolean? (cadr v)) )) old-rc)))
                           (ly:context-set-property! score-ctx 'repeatCommands
                            (cons (list 'volta (ly:music-property ese 'extra-text "?")) filtered-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 (max rep-count (length alt-list-collect))
        '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 (max rep-count (length alt-list-collect))
         '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))

setVoltaText =
#(define-music-function (parser location on-ctx str) ((symbol? 'Score) string-or-markup?)
  (make-music 'ApplyContext
   'procedure (lambda (ctx)
     (let ((this-ctx (ly:context-find ctx on-ctx)))
      (if (ly:context? this-ctx)
       (let* ((old-rc (ly:context-property this-ctx 'repeatCommands '())) ; (boolean? (cadr v))
              (filtered-rc (filter (lambda (v)
                 (or (not (pair? v)) (not (eq? (car v) 'volta)) (boolean? (cadr v)) )) old-rc)))
        (ly:context-set-property! this-ctx 'repeatCommands
         (cons (list 'volta str) filtered-rc))))))))

setVoltaEndInContext =
#(define-music-function (parser location on-ctx) (symbol?)
  (for-each display (list "\n on-ctx = " on-ctx " "))
  (make-music 'ApplyContext
   'procedure (lambda (ctx)
     (let ((this-ctx (ly:context-find ctx on-ctx)))
      (if (ly:context? this-ctx)
       (let* ((old-rc (ly:context-property this-ctx 'repeatCommands '())) ; (boolean? (cadr v))
              (already-in-rc (filter (lambda (v)
                 (and (pair? v) (eq? (car v) 'volta) (boolean? (cadr v)) (not (cadr v)) )) old-rc)))
        (if (null? already-in-rc)
         (ly:context-set-property! this-ctx 'repeatCommands
          (cons (list 'volta #f) old-rc)))))))))

setVoltaEnd =
#(define-music-function (parser location) ()
  (make-music 'ApplyContext
   'procedure (lambda (ctx)
     (let ((this-ctx (ly:context-find ctx 'Score)))
      (if (ly:context? this-ctx)
       (let* ((old-rc (ly:context-property this-ctx 'repeatCommands '())) ; (boolean? (cadr v))
              (already-in-rc (filter (lambda (v)
                 (and (pair? v) (eq? (car v) 'volta) (boolean? (cadr v)) (not (cadr v)) )) old-rc)))
        (if (null? already-in-rc)
         (ly:context-set-property! this-ctx 'repeatCommands
          (cons (list 'volta #f) old-rc)))))))))

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

\LinearToVoltaRepeats {
  c'1
  \pmpStartRepeat
  d'
  \pmpStartAlternative
  e'
  \pmpStartAlternative
  f'
  \pmpStartRepeatEx #3  % impizit wird die zuletzt gestartete Wiederholung
  g'
  \pmpStartAlternative
  a'
  \pmpStartAlternativeEx #(make-text-markup (make-bold-markup (make-fontsize-markup 2 "Fine")))
  b'
  \bar "|."
  \pmpStartAlternativeEx #"2."
  c''
  \pmpStartRepeatEx #5
  d''
  \pmpStartAlternativeEx #"1., 3."
  e''
  \pmpStartAlternativeEx #"2., 4."
  f''
  \pmpStartAlternative
  g''
  \pmpEndRepeat
  a''
  \bar "|."
  \once \override Score.RehearsalMark.direction = #DOWN
  \once \override Score.RehearsalMark.self-alignment-X = #RIGHT
  \once \override Score.RehearsalMark.break-visibility = #begin-of-line-invisible
  \mark \markup \fontsize #-2 "D.C. al Fine"
}

\LinearToVoltaRepeats {
  g1
  \pmpStartRepeat
  a
  \pmpStartRepeat
  b
  \pmpEndRepeat
  c'
  \pmpStartRepeatEx #3
  d'
  \pmpStartAlternative
  e'
  \pmpStartAlternative
  f'
  \pmpStartRepeat
  g'
  \pmpStartAlternative
  a'
  \pmpStartAlternative
  b'
  \pmpStartRepeat
  c''
  \pmpStartAlternative
  d''
  \pmpStartAlternative
  e''
  \pmpStartAlternative
  f''
  \pmpEndRepeat
  \bar "|."
}

RM = {
  \repeat volta 2 {
    c'1 cis'
  } \alternative { {
    \setVoltaText #"7."
    d' dis'1
  } {
    \setVoltaText #"3."
    e'2 e' es'1
  } }
}

RMx = {
  \repeat volta 2 {
    c'1 cis'
  } \alternative { {
    \setVoltaText #'Staff #"777."
    d' dis'
  } {
    \setVoltaText #'Staff #"333."
    e' es'
  } }
}

RMxu = {
  \repeat volta 2 {
    c'1 cis'
  } \alternative { {
    \setVoltaText #'Staff #"777."
    d' \unset Staff.repeatCommands dis'
  } {
    \setVoltaText #'Staff #"333."
    << { e' } { s2 \unset Staff.repeatCommands } >> es'1
  } }
}

\score {
  <<
    \new Staff { \RM \bar "|." }
    \new Staff \with {
      \consists Volta_engraver
    } { \RM \bar "|." }
  >>
  \header {
    piece = \markup \justify {
      Mit \bold "\\setVoltaText" kann man den Starttext
      der Volte überschreiben, ohne die anderen \bold repeatCommands
      zu überschreiben. Implizit bedeutet das immer auch einen Start
      der Volta.
    }
  }
}

\defineBarLine "|-V" #'("|" "" "|")
\allowVoltaHook "|-V"
LM = {
  c'1 \bar ".|:"
  d'
  \setVoltaText "7."
  e'
  \bar ":|."
  \setVoltaEnd
  \setVoltaText "3."
  f'
  \setVoltaEnd
  g'
  \setVoltaText #(make-text-markup (make-bold-markup (make-fontsize-markup 2 "bis")))
  a' b'
  \setVoltaEnd \bar "|-V"
  c''
  \bar "|."
}

\score {
  <<
    \new Staff { \LM \bar "|." }
    \new Staff \with {
      \consists Volta_engraver
    } { \LM \bar "|." }
  >>
  \header {
    piece = \markup \column { \justify {
      Mit \bold "\\setVoltaEnd" kann man das Ende der Voltenklammer
      festlegen. Legt man außderdem die Wiederholungszeichen über \bold "\\bar"
      fest, so kann man damit alle (zu druckenden) Wiederholungen ohne Nutzung von
      \bold "\\repeat volta" beschreiben. Folglich werden diese auch nicht
      durch \bold "\\unfoldRepeats" aufgelöst.
    }
    \vspace #0.3
    \justify {
      Übrigens, \bold »bis« ist eine alte Bezeichnung, diesen (kurzen) Abschnitt
      zwei Mal zu spielen. Damit die benutzte »Voltenklammer« am Schluß an dem
      einfachen Taktstrich auch heruntergezogen wird, in den anderen Fällen aber
      nicht, wurde eine »neuer Taktstrich-Satz« mittels \bold "\\defineBarLine"
      definiert und an diesem per \bold "\\allowVoltaHook" der Schlußstrich der
      Voltenklammer aktiviert.
    }
  }}
}

\score {
  <<
    \new Staff { \RM \RM \RM \bar "|." }
    \new Staff \with {
      \consists Volta_engraver
    } { \RM \RMx \RM \bar "|." }
  >>
  \header {
    piece = \markup \justify {
      Im Prizip kann man auch in jeder Notenzeile
      (d. h. in jedem Staff-Kontext)
      einen anderen Text setzen, wäre da nicht noch
      das eine oder andere kleine, störende Problemchen.
    }
  }
}

\score {
  <<
    \new Staff { \RM \RM \RM \bar "|." }
    \new Staff \with {
      \consists Volta_engraver
    } { \RM \RMxu \RM \bar "|." }
  >>
  \header {
    piece = \markup \justify {
      Ein \bold "\\unset Staff.repeatCommands" kurz nach
      \bold "\\setVoltaText" hilft erst einmal. Aber dieses
      \italic { kurz danach } muß auch die Zeitschritte der anderen
      Stimmen mit einschließen, und die Score-weit gesetzte
      Bezeichnung geht auch noch verloren!
    }
  }
}
Dabei mußte ich feststellen, daß ich mit \setVoltaText zwar unterschiedliche Bezeichner in die Voltaklammern auf jeder Notenzeile (Staff) setzen kann, aber mit \consists Volta_engraver allein im Staff-Kontext dann doch noch eingies durcheinander kommt.

Arnold
Titel: Re: Wiederholungsklammer manuell setzen
Beitrag von: xr am Mittwoch, 8. Februar 2017, 00:12
Ich habe jetzt beim erneuten Probieren doch noch mal eine einfache funktionierende Lösung gefunden.

\version "2.18.2"

volta =
#(define-scheme-function
    (parser location num)
    (string?)

    (define voltaTxt "")
    (set! voltaTxt num)

    #{       
    \set Score.repeatCommands = #(list (list 'volta voltaTxt) )
    #})

volta-ende = {
    \set Score.repeatCommands = #'((volta #f))
}


\relative c' {
  c1
  \volta "1. wandeln"
  c4 b d e
  \volta-ende
  \bar ":|."
 
  \volta "8,4 hallo Volta"
  a4 b c d
  a4 b c d
  \bar ":|."
  \volta-ende
 
  a4 g f g
  \volta "12, 53"
  e d c g
  \volta-ende
  \bar "||"
}
Titel: Re: Wiederholungsklammer manuell setzen
Beitrag von: xr am Mittwoch, 8. Februar 2017, 08:22
Ich habe nochmal eine Verständnisfrage.

Folgender Code funktioniert:

\version "2.18.2"

volta =
#(define-scheme-function
    (parser location num)
    (number?)
   
   
    (define nr "")
    (define voltaTxt (list (list 'volta "neu") ))
    ;(define voltaTxt '( (volta "neu") ))
   
    (set! nr (number->string num))
   
    (display voltaTxt)
    (set-car! (cdar voltaTxt) nr)
    (newline)

    #{       
    \set Score.repeatCommands = #voltaTxt
    #})



volta-ende = {
    \set Score.repeatCommands = #'((volta #f))
}


\relative c' {
  c1
  \volta 1
  c4 b d e
  \volta-ende
  \bar ":|."
  c4 b d e
  \volta 2
  a4 b c d
  a4 b c d
  \bar ":|."
  \volta-ende
 
  a4 g f g
  \volta 5
  e d c g
  \volta-ende
  \bar "||"
}



Wenn ich allerdings die Definition (define voltaTxt (list (list 'volta "neu") ))   durch die auskommentierte Zeile (define voltaTxt '( (volta "neu") )) ersetze, funktioniert der Code nicht mehr.
(Das war mein ursprünglich nicht funktionierender Code)

Ich erhalte als Text unter der Klammer immer den zuletzt eingegebenen Wert.
(display voltaTxt) zeigt mir bei jedem Aufruf veränderte Werte, obwohl voltaTxt doch jedesmal neu definiert wird und keine globale Variable sein sollte. Das verstehe ich nicht.

Den Ausruck '( (volta "neu") ) verstehe ich ohnehin nicht. Was bedeutet das Apostroph vor der Klammer?
Wenn ich es richtig verstehe, sollte es eigentlich so sein:
Ein Apostroph vor einem String ist die Kurzform von "String".
Ein Apostroph vor einer Klammer gibt eine Liste an.
Verstehe ich das falsch?

Gruß,
Xaver
Titel: Re: Wiederholungsklammer manuell setzen
Beitrag von: Arnold am Mittwoch, 8. Februar 2017, 09:10
Hallo xr,

auch wenn ich auf die Schnelle nicht im Detail antworten kann,
Zitat
Ich erhalte als Text unter der Klammer immer den zuletzt eingegebenen Wert.
klingt doch sehr nach »Parameterübergabe als Zeiger, und danach wurde die Struktur wohin der Zeiger zeigt, verändert«.
Solch eine Änderung (ohne die Daten zu kopieren) machen vor allem die Scheme-Funktionen mit dem Ausrufezeichen, wie z. Bsp. set-car!.
Und die ly:music-Struktur wird ja erst dann durch die Engraver analysiert, wenn die ly:music-Datenstruktur mit allen deinen Kommandos komplett erstellt ist. \displayMusic sollte auch anzeigen, daß da jetzt das gleiche drin steht, aber genauso eine selbstgeschriebene Scheme-Funktion, welche die Daten komplett anzeigen würde (z. Bsp. mittels \musicMap).

Arnold
Arnold
Titel: Re: Wiederholungsklammer manuell setzen
Beitrag von: xr am Mittwoch, 8. Februar 2017, 15:42
Zitat
klingt doch sehr nach »Parameterübergabe als Zeiger, und danach wurde die Struktur wohin der Zeiger zeigt, verändert«.

Für mich klingt das auch so.

Mich wundert nur, dass
(define voltaTxt (list (list 'volta "neu") ))
etwas anderes erzeugt, als
(define voltaTxt '( (volta "neu") ))

Display voltaTxt zeigt mir für beide Zeilen beim ersten Durchlauf das Gleiche an. Allerdings könnten es auch andere Datentypen sein, was ich so ja nicht sehe.
Außerdem wundert mich, wie oben geschrieben, dass beim erneuten Aufruf die zweite Zeile geändert wurde, obwohl sie doch neu definiert wurde. Meines Erachtens müsste sie also wieder den Ausgangscode beinhalten, was sie aber nicht tut.

Zitat
eine selbstgeschriebene Scheme-Funktion, welche die Daten komplett anzeigen würde (z. Bsp. mittels \musicMap)
Wie funktioniert das? Gibts da ein Beispiel?
Titel: Re: Wiederholungsklammer manuell setzen
Beitrag von: Arnold am Freitag, 10. Februar 2017, 13:05
Hallo xr,

\musicMap ist eigentlich ganz einfach:
Definiere eine Scheme-Funktion mit einen einzigen Aufrufparameter (ly:music?), die auch wieder ein ly:music? zurückgibt.
Wenn nichts verändert wurde, gebe das Original vom Aufruf zurück, sonst die Änderung bzw. den mit make-musik erstelleten Ersatz.
In der Funktion frage zuerst nach dem Music-Property 'name, dann entscheide was du damit tun willst (z. Bsp. informationen ausgeben oder nicht)
Die Scheme-Variante von \musicMap nennt sich music-map - kaum zu glauben :-).
Deine Funktion wird dann "bottom-up" vom \musicMap angewandt.
Kurzes Rumpf-Beispiel:#(define (my-info mus)
  (let ((m-name (ly:music-property mus 'name)))
   (if (eq? m-name 'SequentialMusic)
   ...
 )))

\musicMap #my-info \MeineMusik

Im anderen Fall schreibt man eine Scheme-Funktion, welche sich rekursiv aufruft - am besten dann mit zwei Aufrufparametern, einem "Tiefenzähler" der bei den Textausgaben für ein Einrücken genutzt werden kann, und dann der (obligatorische) ly:music-Parameter.
Auch hier ist die erste Aktion, den Typ des Elements herauszufinden, und bei entsprechenden Type dann 'element und/oder 'elements weiter untersuchen zu lassen.
Grob skizziert:#(define (my-struct-info indent mus)
  (let ((m-name (ly:music-property mus 'name)))
   (for-each display (list "\n" indent " Typ = " m-name " "))
   (if (eq? m-name 'SequentialMusic)
    (for-each (lambda (m) (my-struct-info (+ indent 1) x)) (ly:music-property mus 'elements)))
   (if (eq? m-name 'SimultaneousMusic)
    (for-each (lambda (m) (my-struct-info (+ indent 1) x)) (ly:music-property mus 'elements)))
...
 ))
 

Arnold