thindf - nuevo formato de datos de texto (alternativa a JSON)

Archivo AppData \ Local \ Dropbox \ info.json:
{ "personal": { "host": 5060852864, "is_team": false, "subscription_type": "Basic", "path": "C:\\Users\\DNS\\Dropbox" } } 
En el nuevo formato, se ve así:
 personal host = 5060852864 is_team = 0B subscription_type = Basic path = C:\Users\DNS\Dropbox 
Archivo de configuración del editor de texto sublime:
 { "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" } 
En el nuevo formato, se ve así:
 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 

Un poco de historia


Este formato debe su apariencia a otro formato con el extraño nombre blockpar.
Blockpar fue desarrollado por Alexey Dubovoi (uno de los fundadores de Elemental Games) en el proceso de trabajar en el juego Space Rangers. Posteriormente, Alexander Zeberg (ex programador principal de Katauri Interactive [ después de dejar la compañía para Katauri Interactive y Elemental Games, se fue a Katauri ] ) decidió usar este formato para el juego King's Bounty: Legend of the Knight.

La definición de cada objeto del juego se almacenó en formato blockpar en un archivo separado con la extensión .atom, por ejemplo, aquí hay un recorte del archivo 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 } ... } ... 

Posteriormente [ mientras trabajaba en el proyecto Royal Quest ] amplié este formato un poco para que en lugar de:
 button { name=close pos=400,600 size=200,40 image=button_close.png anchors=0,0,100,0 } 
escribe así:
 button=close,400,600,200,40 { image=button_close.png anchors=0,0,100,0 } 

También agregué soporte para valores de cadena de varias líneas a través del apóstrofe posterior (backtick - `):
 button=... { onmouseover=` ... ` } 
¿Por qué rechacé `cadenas encerradas en apóstrofos inversos '
En el valor del parámetro, está permitido pegar directamente el código del script, y en los comentarios en el código uso apóstrofos inversos en el mismo significado que se usan en Markdown y marcado de PC . Por ejemplo:
 if len(indentation_levels) and indentation_levels[-1][0] == -1: #    `{`    ,       `}` 

Y finalmente, como resultado de mi conocimiento de Python, la idea de rechazar las llaves me cautivó tanto que decidí que el formato blockpar podría simplificarse aún más [al abandonar las llaves requeridas ] .

También influenciado por:
  • El formato de almacenamiento de texto en la Otra biblioteca de serialización utilizada por el cliente Royal Quest.
  • El formato del archivo de configuración nginx (sin embargo, rechacé la idea de abandonar el delimitador (símbolo = o : entre el nombre del parámetro y su valor ( por qué )).
  • YAML (es decir, la idea de usar . Antes del nombre del elemento de matriz [ en YAML usa - ] ).

¿Por qué 0V y 1V?
  • A menudo, verdadero / falso se usa con sí / no (SÍ / NO se usa en Objective-C) , activar / desactivar o activar / desactivar (por ejemplo: puede activar mostrar finales de línea; activar / desactivar el registro; ¿es dígito? y en álgebra booleana, se usan 0 y 1, por lo que usar las palabras clave verdadero y falso en la mayoría de los casos es bastante discutible.
  • No me gusta verdadero / falso en la versión rusa del formato, y 0B y 1B (aquí B es la letra mayúscula rusa c) pueden asociarse con 0Off y 1On. [ Le pido que no plantee la cuestión de la conveniencia de la versión rusa. ]
  • 0B y 1B se utilizan en el lenguaje de programación 11l por los motivos indicados en la documentación .

Cadenas entre comillas simples


Otro [ además de 0B y 1B ] elemento controvertido / inusual de este formato es el uso de comillas dobles '' para cadenas en bruto [ sin secuencias de escape \ secuencias de escape ] .
Pero mi elección está justificada por el hecho de que el Consorcio Unicode aprobó este año como el código para la doble comilla simple de apertura .

Cómo escribir esas citas en el teclado: consulte aquí .

Si hay comillas sin emparejar en la línea, debe realizar el "equilibrio de línea" de la misma manera que en el marcado de la PC para insertar el código HTML.
Por ejemplo, hay una línea don't .
Como contiene una cita de cierre desequilibrada, agregue una cita de apertura equilibrada al comienzo de la línea: ' don't .
Incluimos la cadena equilibrada entre comillas dobles: ' 'don't ' .
Ahora debe mostrar de alguna manera al analizador que la cita agregada a la izquierda no debe incluirse en la cadena, ya que solo es necesaria para restablecer el equilibrio . Para hacer esto, use el símbolo de apóstrofo mecanografiado ', que se debe poner una pieza para cada comilla de equilibrio [por lo tanto, un apóstrofo mecanografiado' come 'una comilla de par ] , en este caso se debe poner al comienzo de la línea: '''don't' .
Puede insertar una línea equilibrada como está en otras líneas entre comillas dobles:
'text = '''don't'' .

Uso


Por el momento, hay una implementación en Python y en JavaScript (puede intentar convertir JSON a un nuevo formato directamente en el navegador en la página web del proyecto ).

Para Python: instale como de costumbre:
 pip install thindf 

Para JavaScript:
 npm install thindf node const thindf = require('thindf'); 

Y uso:
  • thindf.to_thindf(object, indent = 4) para obtener una cadena en formato thindf correspondiente al objeto pasado (análogo de json.dumps y JSON.stringify ).
  • thindf.parse(str) para obtener un objeto de una cadena en formato thindf (análogo a json.loads y JSON.parse ).

En conclusión, daré algunos ejemplos más:
Algunas líneas de mi Default (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": "'"} }, ] 
Usando el nuevo formato, escribiría esto:
 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 

Una pieza del archivo d.json [ del repositorio del administrador de complementos para 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-" } ] } ] } 
En el nuevo formato, se ve así:
 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- ] ] 

Algunos casos de esquina:
 { "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/es419361/


All Articles