thindf - neues Textdatenformat (Alternative zu JSON)

Datei AppData \ Local \ Dropbox \ info.json:
{ "personal": { "host": 5060852864, "is_team": false, "subscription_type": "Basic", "path": "C:\\Users\\DNS\\Dropbox" } } 
Im neuen Format sieht es so aus:
 personal host = 5060852864 is_team = 0B subscription_type = Basic path = C:\Users\DNS\Dropbox 
Sublime Text Editor-Konfigurationsdatei:
 { "added_words": [ "plugin", "habrahabr", "" ], "default_line_ending": "unix", //"font_face": "Fira Code", "font_size": 11, "ignored_packages": [ "Sublimerge Pro", "Vintage" ], "ignored_words": [ "utf" ], "line_numbers": false, "show_encoding": true, "show_line_endings": true, "tab_size": 4, "theme": "Default.sublime-theme" } 
Im neuen Format sieht es so aus:
 added_words = [ plugin habrahabr  ] default_line_ending = unix //font_face = Fira Code font_size = 11 ignored_packages = [ Sublimerge Pro Vintage ] ignored_words = [ utf ] line_numbers = 0B show_encoding = 1B show_line_endings = 1B tab_size = 4 theme = Default.sublime-theme 

Ein bisschen Geschichte


Dieses Format verdankt sein Aussehen einem anderen Format mit dem seltsamen Namen blockpar.
Blockpar wurde von Alexey Dubovoi (einem der Gründer von Elemental Games) während der Arbeit am Spiel Space Rangers entwickelt. Anschließend entschied sich Alexander Zeberg (ehemaliger Hauptprogrammierer von Katauri Interactive [ nachdem er das Unternehmen für Katauri Interactive und Elemental Games verlassen hatte, ging er zu Katauri ] ), dieses Format für das Spiel King's Bounty: Legend of the Knight zu verwenden.

Die Definition jedes Spielobjekts wurde im Blockpar-Format in einer separaten Datei mit der Erweiterung .atom gespeichert. Hier ist beispielsweise ein Ausschnitt aus der Datei data / data.kfs / spider.atom :
 main { class=chesspiece model=spider.bma cullcat=0 } arena_params { race=neutral cost=24 level=1 leadership=14 attack=4 defense=4 ... resistances { physical=20 poison=0 magic=0 fire=-10 } ... } ... 

Anschließend [ während ich am Royal Quest-Projekt arbeitete ] habe ich dieses Format ein wenig erweitert, so dass anstelle von:
 button { name=close pos=400,600 size=200,40 image=button_close.png anchors=0,0,100,0 } 
schreibe so:
 button=close,400,600,200,40 { image=button_close.png anchors=0,0,100,0 } 

Ich habe auch Unterstützung für mehrzeilige Zeichenfolgenwerte durch den hinteren Apostroph (backtick - `) hinzugefügt:
 button=... { onmouseover=` ... ` } 
Warum habe ich "in umgekehrten Apostrophen eingeschlossene Saiten" abgelehnt?
Im Parameterwert ist es zulässig, den Skriptcode direkt einzufügen, und in den Kommentaren im Code verwende ich inverse Apostrophe in derselben Bedeutung wie in Markdown und PC-Markup . Zum Beispiel:
 if len(indentation_levels) and indentation_levels[-1][0] == -1: #    `{`    ,       `}` 

Und schließlich hat mich die Idee, geschweifte Klammern abzulehnen, aufgrund meiner Bekanntschaft mit Python so fasziniert, dass ich beschlossen habe, das Blockpar-Format weiter zu vereinfachen [indem ich auf die erforderlichen geschweiften Klammern verzichte ] .

Auch beeinflusst von:
  • Das Textspeicherformat in der vom Royal Quest-Client verwendeten weiteren Serialisierungsbibliothek .
  • Das Format der Nginx-Konfigurationsdatei (ich lehnte jedoch die Idee ab, das Trennzeichen (Symbol = oder : zwischen dem Parameternamen und seinem Wert ( warum ) aufzugeben).
  • YAML (nämlich die zu verwendende Idee . Vor dem Namen des Array-Elements [ in YAML wird - ] verwendet ).

Warum 0V und 1V?
  • Oft wird wahr / falsch mit Ja / Nein (JA / NEIN wird in Ziel-C verwendet) , Ein / Aus oder Aktivieren / Deaktivieren verwendet (zum Beispiel: Sie können Show-Zeilenenden aktivieren ; Protokollierung aktivieren / deaktivieren; ist Ziffer? Ja ) und in der Booleschen Algebra werden 0 und 1 verwendet, so dass die Verwendung der Schlüsselwörter true und false in den meisten Fällen ziemlich umstritten ist.
  • Ich mag wahr / falsch in der russischen Version des Formats nicht, und 0B und 1B (hier ist B der russische Großbuchstabe c) können mit 0Off und 1On assoziiert werden. [ Ich bitte Sie, die Frage nach der Angemessenheit der russischen Version nicht zu stellen. ]]
  • 0B und 1B werden in der Programmiersprache 11l aus den in der Dokumentation angegebenen Gründen verwendet.

Zeichenfolgen in einfachen Anführungszeichen


Ein weiteres [ zusätzlich zu 0B und 1B ] kontroverses / ungewöhnliches Element dieses Formats ist die Verwendung von doppelten Anführungszeichen für rohe Zeichenfolgen [ ohne Escape-Sequenzen \ Escape-Sequenzen ] .
Meine Wahl ist jedoch durch die Tatsache gerechtfertigt, dass das Unicode-Konsortium dieses Jahr als Code für das erste einfache doppelte Anführungszeichen genehmigt hat.

Wie Sie solche Anführungszeichen auf der Tastatur eingeben, finden Sie hier .

Wenn die Zeile ungepaarte Anführungszeichen enthält, müssen Sie den "Zeilenausgleich" auf dieselbe Weise wie im PC-Markup durchführen, um HTML-Code einzufügen.
Zum Beispiel gibt es eine Zeile don't .
Da es ein unausgeglichenes Schlusszitat enthält, fügen Sie ganz am Anfang der Zeile ein ausgleichendes Eröffnungszitat hinzu: ' don't .
Wir setzen die ausgeglichene Zeichenfolge in doppelte Anführungszeichen: ' 'don't ' .
Jetzt müssen Sie dem Parser irgendwie zeigen, dass das links hinzugefügte Zitat nicht in der Zeichenfolge enthalten sein sollte, da es nur zur Wiederherstellung des Gleichgewichts benötigt wird. Verwenden Sie dazu das maschinengeschriebene Apostrophsymbol ', das für jedes ausgleichende Anführungszeichen ein Stück setzen muss [ ein maschinengeschriebenes Apostroph „isst“ also ein paar Anführungszeichen ] . In diesem Fall muss es am Anfang der Zeile stehen: '''don't' .
Sie können eine ausgeglichene Zeile wie in anderen Zeilen in doppelte Anführungszeichen einfügen:
'text = '''don't'' .

Verwenden Sie


Derzeit gibt es eine Implementierung in Python und in JavaScript (Sie können versuchen, JSON direkt im Browser auf der Projektwebseite in ein neues Format zu konvertieren).

Für Python - wie gewohnt installieren:
 pip install thindf 

Für JavaScript:
 npm install thindf node const thindf = require('thindf'); 

Und benutze:
  • thindf.to_thindf(object, indent = 4) , um eine Zeichenfolge im thindf-Format zu erhalten, die dem übergebenen Objekt entspricht (analog zu json.dumps und JSON.stringify ).
  • thindf.parse(str) , um ein Objekt aus einem String im thindf-Format abzurufen (analog zu json.loads und JSON.parse ).

Abschließend möchte ich noch einige Beispiele nennen:
Ein paar Zeilen aus meiner Standard (Windows) .sublime-Keymap :
 [ { "keys": ["f4"], "command": "f4" }, { "keys": ["shift+f4"], "command": "f4", "args": {"shift_key_pressed": true} }, { "keys": ["alt+shift+`"], "command": "insert", "args": {"characters": "`"} }, // ( { "keys": [":", ")"], "command": "insert_snippet", "args": {"contents": ":)(:"} }, { "keys": ["alt+9"], "context": [{"key": "selector", "operator": "equal", "operand": "text.pq"}], "command": "insert_pq" }, // ' (for balance) { "keys": ["alt+0"], "context": [{"key": "selector", "operator": "equal", "operand": "text.pq"}], "command": "insert", "args": {"characters": "'"} }, ] 
Mit dem neuen Format würde ich folgendes schreiben:
 f4 = on_f4() shift+f4 = on_f4(shift_key_pressed' 1B) alt+shift+` = insert(characters' '`') // ( :,) = insert_snippet(contents' ':)(:') alt+9 = if selector == 'text.pq' {insert_pq()} else 0B // ' (for balance) alt+0 = if selector == 'text.pq' {insert(characters' "'")} else 0B 

Ein Stück aus der d.json- Datei [ aus dem Repository des Plugin-Managers für Sublime Text ] :
 { "schema_version": "3.0.0", "packages": [ { "name": "Django Lookup Snippets", "details": "https://github.com/icycandle/sublime-django-lookup", "releases": [ { "sublime_text": "*", "tags": true } ] }, { "name": "Django Manage Commands", "details": "https://github.com/vladimirnani/DjangoCommands", "labels": ["Django", "python", "web", "management"], "releases": [ { "sublime_text": "<3000", "tags": "st2-" }, { "sublime_text": ">=3000", "tags": "st3-" } ] } ] } 
Im neuen Format sieht es so aus:
 schema_version = '3.0.0' packages = [ . name = Django Lookup Snippets details = https://github.com/icycandle/sublime-django-lookup releases = [ . sublime_text = * tags = 1B ] . name = Django Manage Commands details = https://github.com/vladimirnani/DjangoCommands labels = [ Django python web management ] releases = [ . sublime_text = <3000 tags = st2- . sublime_text = >=3000 tags = st3- ] ] 

Einige Eckfälle:
 { "a": "'...'", "b": "string which ends with a space ", "cd": "\n", "e ": "3", "dirs": [ ["Doc,Scans", ".t'xt"] ], "node": null, "n" : "N", "files": [], "f": "[]", "ff": [ [] ], "products": {} } 
 a = ''...'' b = 'string which ends with a space ' cd = "\n" 'e ' = '3' dirs = [ ['Doc,Scans', '''.t'xt'] ] node = N n = 'N' files = [] f = '[]' ff = [ [] ] products = {} 

Source: https://habr.com/ru/post/de419361/


All Articles