Allgemein > Hilfe beim Einstieg in Lilypond

Variablennamen durch Stringoperationen zusammensetzen (GELÖST)

<< < (2/2)

ingmar:
Ah! Logisch. Dazu braucht man natürlich eine Funktion.

Danke, Gruß,
--ingmar

ingmar:

--- Zitat ---fugenkomponist: Falls du aus irgendeinem Grund \score tatsächlich brauchst, ...

--- Ende Zitat ---

Doch, \score hätte sich schon gern dabei - auch mehr:

--- Code: ---\version "2.19.37"

MUSIC = \relative { g a b c d1 }
TEXT = "Bitteschön!"

pointermusic = "MUSIC"
pointertext = "TEXT"
soso = #(define-scheme-function () ()
   #{
     \score {
       \new Staff { #(ly:parser-include-string (string-append "\\" pointermusic )) }
     }
     \header {
      piece =  \markup #(ly:parser-include-string (string-append "\\" pointertext )) }
   #})


\soso

--- Ende Code ---

\score klappt prima, \header leider nicht. Ich verstehe leider nicht warum. Wo liegt mein Denkfehler?


Danke, Gruß,
--ingmar

fugenkomponist:
Eine Funktion kann nur einen Wert zurückgeben, nicht zwei (\score und \header). Du kannst aber den \header-Block in den \score-Block packen, dann geht das.
--- Code: ---soso = #(define-scheme-function () ()
          #{
            \score {
              \header {
                piece = \TEXT
              }
              \new Staff { #(ly:parser-include-string (string-append "\\" pointermusic )) }
            }
          #})
--- Ende Code ---
Es ergibt sich allerdings ein anderes Problem: ly:parser-include-string funktioniert anscheinend so nicht in markups, hier

--- Code: ---piece = \markup #(ly:parser-include-string (string-append "\\" pointertext))
--- Ende Code ---
beschwert LilyPond sind über „not a markup“.

Da
--- Code: ---piece = \markup \TEXT
--- Ende Code ---
genauso funktioniert wie ohne \markup, hab ich also auch das mal ohne probiert:

--- Code: ---piece = #(ly:parser-include-string (string-append "\\" pointertext))
--- Ende Code ---
Das liefert aber weder nen Fehler, noch wird irgendetwas als piece-Header ausgegeben, keine Ahnung, warum …

fugenkomponist:
So, hab ne Lösung:

Statt nen String zusammen zu basteln und den an den LilyPond-Parser zu füttern, damit LilyPond am \ eine Variable erkennt und den Inhalt der Variable dieses Namens holt, gehts mit ein bisschen weniger Umweg direkt in Scheme: Der String wird zu nem Symbol gemacht und Scheme holt den Inhalt der Variable dieses Namens.

--- Code: ---\version "2.19.37"

MUSIC = \relative { g a b c d1 }
TEXT = "Bitteschön!"

pointermusic = "MUSIC"
pointertext = "TEXT"

soso = #(define-scheme-function () ()
          #{
            \score {
              \header {
                piece = #(module-ref (current-module) (string->symbol pointertext))
              }
              \new Staff { #(ly:parser-include-string (string-append "\\" pointermusic )) }
            }
          #})

\soso
--- Ende Code ---
Das funktioniert auch an anderen Stellen (sodaß hier ly:parser-include-string und string-append gar nicht mehr nötig sind), außerdem kann man sich string->symbol sparen, wenn man gleich Symbole definiert:

--- Code: ---\version "2.19.37"

MUSIC = \relative { g a b c d1 }
TEXT = "Bitteschön!"

pointermusic = #'MUSIC
pointertext = #'TEXT

soso = #(define-scheme-function () ()
          #{
            \score {
              \header {
                piece = #(module-ref (current-module) pointertext)
              }
              \new Staff {
                #(module-ref (current-module) pointermusic)
              }
            }
          #})

\soso
--- Ende Code ---

Edit: Das Stichwort, wonach ich gesucht hab, lautet „Reflection“ (gibts auch in anderen Programmiersprachen wie z. B. Java). Gefunden hab ich dann diesen Abschnitt der Guile-Dokumentation, wo module-ref und current-module (sowie weitere Funktionen) dokumentiert sind.
2. Edit: Ich habs tatsächlich nicht da gefunden, sondern im entsprechenden Abschnitt der Guile-2.0-Dokumentation. Warum das in 1.8 auch funktioniert, aber anscheinend nicht dokumentiert ist (ich hatte den Link oben angegeben, ohne nochmal den genauen Inhalt der Seite zu prüfen), ist mir nicht klar …

harm6:

--- Zitat von: fugenkomponist ---Warum das in 1.8 auch funktioniert, aber anscheinend nicht dokumentiert ist (ich hatte den Link oben angegeben, ohne nochmal den genauen Inhalt der Seite zu prüfen), ist mir nicht klar …
--- Ende Zitat ---

Es gibt jede Menge undokumentierte procedures, etc in guile. Wer wirklich tief einsteigen möchte wird wohl nicht umhin kommen das guile-git-repository runter zu laden.

Wenn man aber weiß (oder vermutet), daß etwas existieren könnte kann man so vorgehen:


--- Zitat von: "Mein terminal ;)" ---guile> (version)
"1.8.8"
guile> module-ref
#<procedure module-ref (module name . rest)>
guile> (procedure-source module-ref)
(lambda (module name . rest) (let* ((variable (module-variable module name))) (if (and variable (variable-bound? variable)) (variable-ref variable) (if (null? rest) (error "No variable named" name (quote in) module) (car rest)))))
guile> (help module-ref)
No documentation found for:
(guile): module-ref
guile>

--- Ende Zitat ---

Den Code kann man jetzt natürlich noch besser formatieren ...

Darüberhinaus wird auch die guile-Doku laufend verbessert, passiert mit LilyPond ja glaichfalls. Allerdings wird die guilev1.8.8-Doku wohl nicht mehr verändert, umso ärgerlicher, daß wir das upgrade auf guilev2 nicht hinbekommen. Liegt aber meiner Kenntnis nach eben nicht nur an uns, sondern wir werden auch von den guile-Leuten links liegen gelassen.
Zumindest drängt sich dieser Eindruck auf...

Gruß,
  Harm

Navigation

[0] Themen-Index

[*] Vorherige Sete

Zur normalen Ansicht wechseln