Файл 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=` ... ` }
Почему я отказался от `строк, заключённых в обратные апострофы`
В значении параметров допустимо непосредственно вставлять код скриптов, а в комментариях в коде я использую обратные апострофы в том же значении, как они применяются в Markdown и пк-разметке. Например:
if len(indentation_levels) and indentation_levels[-1][0] == -1: # сразу после символа `{` идёт новый произвольный отступ, который действует вплоть до парного символа `}`
И наконец в результате моего знакомства с Python-ом идея отказа от фигурных скобок настолько захватила меня, что я решил, что формат blockpar можно ещё больше упростить [отказавшись от обязательных фигурных скобок].
Также влияние на меня оказали:
- Текстовый формат хранения в Yet Another Serialization Library, использующейся в клиенте Royal Quest.
- Формат файла конфигурации nginx (впрочем, я отбросил идею отказаться от разделителя (символа
=или:) между именем параметра и его значением (почему)). - YAML (а именно идея использовать
.перед именем элемента массива [в YAML используется-]).
Почему 0В и 1В?
- Зачастую 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В используются в языке программирования 11l по причинам обозначенным в документации.
Строки в одиночных парных кавычках
Ещё один [помимо 0В и 1В] спорный/непривычный элемент данного формата — это использование парных кавычек
‘’ для сырых строк [без управляющих последовательностей \ escape sequences].Но мой выбор оправдывает тот факт, что Консорциум Юникода утвердил этот год — кодом открывающей одиночной парной кавычки.
Как такие кавычки набирать на клавиатуре — смотрите здесь.
Если в строке присутствуют непарные кавычки, тогда нужно выполнить "балансировку строки" аналогично тому, как это делается в пк-разметке для вставки HTML-кода.
Например есть строка
don’t.Так как в ней присутствует несбалансированная закрывающая кавычка, добавим балансирующую открывающую кавычку в самое начало строки:
‘don’t.Сбалансированную строку заключаем в парные кавычки:
‘‘don’t’.Теперь необходимо как-то показать парсеру, что добавленную слева кавычку не следует включать в строку, так как она нужна только для восстановления баланса. Для этого используется символ машинописного апострофа ', который нужно поставить по одной штуке на каждую балансирующую кавычку [таким образом, один машинописный апостроф "съедает" одну парную кавычку], в данном случае его необходимо поставить в начало строки:
'‘‘don’t’.Сбалансированную строку можно как есть вставлять в другие строки в парных кавычках:
‘text = '‘‘don’t’’.Использование
В данный момент есть реализация на Python и на JavaScript (можно попробовать cконвертировать JSON в новый формат прямо в браузере на веб-странице проекта).
Для Python — устанавливаем как обычно:
pip install eldf
Для JavaScript:
npm install eldf node const eldf = require('eldf');
И используем:
eldf.to_eldf(object, indent = 4)для получения строки в формате ELDF соответствующей переданному объекту (аналогjson.dumpsиJSON.stringify).eldf.parse(str)для получения объекта из строки в формате ELDF (аналогjson.loadsиJSON.parse).
В заключение приведу ещё несколько примеров:
Несколько строчек из моего Default (Windows).sublime-keymap:
Кусочек из файла d.json [из репозитория менеджера плагинов для Sublime Text]:
С использованием нового формата я бы записал так:[ { "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: | |
|
|
