Allgemein > Fragen zu Funktionen

Wiederholungsklammer manuell setzen

<< < (5/5)

xr:
Ich habe jetzt beim erneuten Probieren doch noch mal eine einfache funktionierende Lösung gefunden.


--- Code: ---\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 "||"
}

--- Ende Code ---

xr:
Ich habe nochmal eine Verständnisfrage.

Folgender Code funktioniert:


--- Code: ---\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 "||"
}


--- Ende Code ---


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

Arnold:
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.
--- Ende Zitat ---
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

xr:

--- Zitat ---klingt doch sehr nach »Parameterübergabe als Zeiger, und danach wurde die Struktur wohin der Zeiger zeigt, verändert«.
--- Ende Zitat ---

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)
--- Ende Zitat ---
Wie funktioniert das? Gibts da ein Beispiel?

Arnold:
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:
--- Code: ---#(define (my-info mus)
  (let ((m-name (ly:music-property mus 'name)))
   (if (eq? m-name 'SequentialMusic)
   ...
 )))

\musicMap #my-info \MeineMusik
--- Ende Code ---

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:
--- Code: ---#(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)))
...
 ))
 
--- Ende Code ---

Arnold

Navigation

[0] Themen-Index

[*] Vorherige Sete

Zur normalen Ansicht wechseln