Allgemein > Allgemeine Diskussion
ly -> JSON ?
jps:
Guten Abend!
Als 2. Scheme-Etüde (nicht besonders musikspezifisch) habe ich nun mal den Rahmen für ein Miniprogramm zusammengeschraubt, das Infos aus einer Lilypond-Datei (die im Normalfall natürlich aus den musikalischen Kontexten einzusammeln wären) in eine JSON-Datei schreiben könnte - zwecks leichteren Datenaustausches, zur Weiterverarbeitung in anderen Programmen (z.B. auch im Browser).
Auch, wenn es offenbar auf diese Weise funktioniert, bin ich für jegliche Hinweise, die vielleicht zu einem besseren und eleganteren Code führen, dankbar.
Insbesondere haben sich die folgenden Fragen ergeben:
1. Kann man den absoluten Pfad zur aktuellen Datei tatsächlich nur über den Zugriff auf die command line auslesen, oder geht das auch direkter?
2. Wie kann man in Scheme/Guile einen garantiert universell funktionierenden path separator ansprechen? – Aus der guile-Referenz bin ich da nicht ganz schlau geworden.
3. Gibt es evtl. schon so etwas à la „ly2json“? - Dann bräuchte man das Rad ja nicht neu zu erfinden.
--- Code: ---\version "2.19.37"
% Zur Übung sollen hier die Elemente aus der folgenden Liste in eine JSON-Datei kopiert werden,
% die im gleichen Verzeichnis liegen soll wie die vorliegende Lilypond-Datei:
#(define elemente_als_liste '("Element 1"
"Element 2"
"Element 3"
"Element 4"
"Element 5"
"Element 6"
"Element 7"
"Element 8"))
% Die Funktion "command-line" gibt offenbar eine in Klammern eingefasste String-Liste zurück,
% deren letztes Element der absolute Dateipfad der vorliegenden Lilypond-Datei ist:
#(define (generiere_neuen_absoluten_pfad_zu_einer_js_datei_im_gleichen_verzeichnis)
(let ((kommandozeile (object->string (command-line))))
(string-append
(substring kommandozeile
(+ (string-rindex kommandozeile #\sp) 2)
(+ (string-rindex kommandozeile #\/) 1))
"Und hier ist das neue JSON-Objekt.js")))
#(define (erstelle_ein_json_objekt_und_schreibe_es_in_die_datei)
(let ((elemente_als_string "")
(ausgabe ""))
; In rekursiven Aufrufen entnimmt die folgende Funktion ein Element nach dem anderen von vorne aus der Liste
; und fügt die Elemente zu einem String zusammen (dazwischen jeweils: ", "):
(define (verarzte_das_naechste_element_aus_der_liste aktuelle_liste)
(cond ((null? aktuelle_liste) aktuelle_liste)
(else
(set! elemente_als_string
(string-append elemente_als_string (car aktuelle_liste) "\", \""))
(verarzte_das_naechste_element_aus_der_liste (cdr aktuelle_liste)))))
; Um daraus ein rechtschaffenes JSON-Objekt zu machen, sind noch ein paar umschließende Elemente erforderlich,
; wobei zuvor am Ende drei überflüssige Zeichen (, ") zu löschen sind:
(define (stoepsele_das_json_objekt_zusammen)
(set! ausgabe
(string-append
"{\n \"Inhalt der Lilypond-Liste\": [\""
(substring elemente_als_string 0 (- (string-length elemente_als_string) 3))
"]\n}")))
; Der Parameter "w" beim Öffnen des Ausgabeports sorgt dafür, dass bereits vorhandene Dateiinhalte überschrieben werden
; (der Parameter "a" würde den neuen String an den vorhandenen Inhalt anhängen):
(define (übertrage_das_neugeschaffene_kunstwerk_in_die_datei)
(let (
(ausgabeport
(open-file
(generiere_neuen_absoluten_pfad_zu_einer_js_datei_im_gleichen_verzeichnis) "w")))
(format ausgabeport ausgabe)
(close ausgabeport)
(display "\nDie JSON-Datei wurde im gleichen Pfad wie die Lilypond-Datei erstellt (bzw. dort ueberschrieben).")))
(verarzte_das_naechste_element_aus_der_liste elemente_als_liste)
(stoepsele_das_json_objekt_zusammen)
(übertrage_das_neugeschaffene_kunstwerk_in_die_datei)))
#(erstelle_ein_json_objekt_und_schreibe_es_in_die_datei)
--- Ende Code ---
Danke und herzliche Grüße
Jost
harm6:
Hallo Jost,
Dein Code compiliert bei mir nicht:
--- Zitat ---error: GUILE signaled an error for the expression beginning here
#
(erstelle_ein_json_objekt_und_schreibe_es_in_die_datei)
Value out of range 54 to 67: 43
--- Ende Zitat ---
Ganz generell: es ist in guile üblich "-" in Namen zu verwenden und nicht "_". Das wäre eher was für C++
Bei
(verarzte_das_naechste_element_aus_der_liste aktuelle_liste)
kam mir string-join als wahrscheinlich simplere Vorgehensweise in den Sinn.
„ly2json“ gibt es meines Wissens nach nicht.
Mehr weiß ich im Moment nicht, ohne das file zum kompilieren zu bringen.
Aber so wie ich mich kenne würde ich es dann wohl komplett neu schreiben.
Wie David Kastrup mal sagte: "Dann weiß ich wenigstens wo die bugs sind" :D
Gruß,
Harm
harm6:
Folgendes scheint zu klappen:
--- Code: ---\version "2.19.36"
#(define elemente-als-liste '("Element 1"
"Element 2"
"Element 3"
"Element 4"
"Element 5"
"Element 6"
"Element 7"
"Element 8"))
#(define
(neuer-absoluter-pfad-zu-einer-js-datei-im-gleichen-verzeichnis)
(string-join (drop-right (string-split (last (command-line)) #\/) 1) "/"))
#(define my-name (ly:parser-output-name)) %% oder ein anderer deiner Wahl
#(let ((port
(open-file
(format #f
"~a/~a.json"
(neuer-absoluter-pfad-zu-einer-js-datei-im-gleichen-verzeichnis)
my-name)
"w")))
(format port
"{\n \"Inhalt der Lilypond-Liste\": [\"~a\"]\n}"
(string-join elemente-als-liste "\", \""))
(close port))
--- Ende Code ---
Aber zu Deinen Fragen weiß ich sonst nichts beizutragen. :(
Gruß,
Harm
jps:
Das mir der fehlschlagenden Kompilierung ist eigenartig. Bei mir läuft es auf mehreren PCs auf Anhieb problemlos (wenn die ly-Datei in einem Verzeichnis liegt, auf das Zugriffsrechte bestehen, und wenn nicht auf ein temporäres Verzeichnis verwiesen wird). Deshalb kann ich auch zunächst mal nicht testen, woran der Fehler liegen könnte. Hab allerdings Lilypond bisher nur unter Windows, noch nicht unter Linux installiert. Ich bleib da mal dran.
Danke für die Alternativcodes an dieser und anderer Stelle. Die werde ich mir der Reihe nach mal in Ruhe zu Gemüte führen.
Herzliche Grüße
Jost
harm6:
Ich weiß, daß die Angabe von Dateipfaden auf verschiedenen OS durchaus sehr problematisch sein kann.
Ich bin auf Linux, insoweit würde es mich sehr interessieren, ob mein code auf Deinem windows-system funktioniert.
Oder ob wir uns gegenseitig code präsentieren, der für den jeweils anderen unbrauchbar ist...
Gruß,
Harm
Navigation
[0] Themen-Index
[#] Nächste Seite
Zur normalen Ansicht wechseln