Файл AppData\Local\Dropbox\info.json:
|
В новом формате выглядит так:
|
Конфигурационный файл редактора Sublime Text:
|
В новом формате выглядит так:
|
Немного истории
Данный формат обязан своим появлением другому формату со странным названием blockpar.
Blockpar разработал Алексей Дубовой (один из основателей Elemental Games) в процессе работы над игрой Космические рейнджеры. Впоследствии Александр Зеберг (бывший ведущий программист Katauri Interactive [после «распада» компании на Katauri Interactive и Elemental Games он ушёл в Katauri]) решил использовать данный формат для игры King’s Bounty: Легенда о рыцаре.
Определение каждого игрового объекта хранилось в формате blockpar в отдельном файле с расширением .atom, например вот вырезка из файла 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 } ... } ...
Впоследствии [во время работы над проектом Royal Quest] я немного расширил этот формат, чтобы можно было вместо:
button { name=close pos=400,600 size=200,40 image=button_close.png anchors=0,0,100,0 }
писать так:
button=close,400,600,200,40 { image=button_close.png anchors=0,0,100,0 }
Также я добавил поддержку многострочных строковых значений посредством обратного апострофа (backtick — `):
button=... { onmouseover=` ... ` }
if len(indentation_levels) and indentation_levels[-1][0] == None: # сразу после символа `{` идёт новый произвольный отступ, который действует вплоть до парного символа `}`
И наконец в результате моего знакомства с Python-ом идея отказа от фигурных скобок настолько захватила меня, что я решил, что формат blockpar можно ещё больше упростить [отказавшись от обязательных фигурных скобок].
Также влияние на меня оказали:
- Текстовый формат хранения в Yet Another Serialization Library, использующейся в клиенте Royal Quest.
- Формат файла конфигурации nginx (впрочем, я отбросил идею отказаться от разделителя (символа
=или:) между именем параметра и его значением (почему)). - YAML (а именно идея использовать
.перед именем элемента массива [в YAML используется-]).
- Зачастую true/false используются в значении yes/no (YES/NO используется в Objective-C), on/off или enable/disable (например: you can enable show line endings; turn logging on/off; is digit? yes), а в булевой алгебре используются 0 и 1, так что использование ключевых слов true и false в большинстве случае довольно спорно.
- Мне не нравится истина/ложь в русской версии формата, а 0В и 1В (здесь В — русская заглавная в) можно связать с 0Выключено и 1Включено. [Вопрос о целесообразности русской версии прошу не поднимать.]
Строки в одиночных парных кавычках
Ещё один [помимо 0В и 1В] спорный/непривычный элемент данного формата — это использование парных кавычек ‘’ для сырых строк [без управляющих последовательностей \ escape sequences].
Но мой выбор оправдывает тот факт, что Консорциум Юникода утвердил этот год — кодом открывающей одиночной парной кавычки.
Как такие кавычки набирать на клавиатуре — смотрите здесь.
Если в строке присутствуют непарные кавычки, тогда нужно выполнить «балансировку строки» аналогично тому, как это делается в пк-разметке для вставки HTML-кода.
Например есть строка don’t.
Так как в ней присутствует несбалансированная закрывающая кавычка, добавим балансирующую открывающую кавычку в самое начало строки: ‘don’t.
Сбалансированную строку заключаем в парные кавычки: ‘‘don’t’.
Теперь необходимо как-то показать парсеру, что добавленную слева кавычку не следует включать в строку, так как она нужна только для восстановления баланса. Для этого используется символ машинописного апострофа ‘, который нужно поставить по одной штуке на каждую балансирующую кавычку [таким образом, один машинописный апостроф «съедает» одну парную кавычку], в данном случае его необходимо поставить в начало строки: '‘‘don’t’.
Сбалансированную строку можно как есть вставлять в другие строки в парных кавычках:
‘text = '‘‘don’t’’.
Использование
В данный момент есть реализация на Python и на JavaScript (можно попробовать cконвертировать JSON в новый формат прямо в браузере на веб-странице проекта).
Для Python — устанавливаем как обычно:
pip install thindf
Для JavaScript:
npm install thindf node const thindf = require('thindf');
И используем:
thindf.to_thindf(object, indent = 4)для получения строки в формате thindf соответствующей переданному объекту (аналогjson.dumpsиJSON.stringify).thindf.parse(str)для получения объекта из строки в формате thindf (аналогjson.loadsиJSON.parse).
[ { "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": "’"} }, ]
С использованием нового формата я бы записал так:
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
Кусочек из файла d.json [из репозитория менеджера плагинов для 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-" } ] } ] }
В новом формате выглядит так:
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- ] ]
| Some corner cases: | |
|
|
ссылка на оригинал статьи https://habr.com/post/419361/
Добавить комментарий