Файл 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: | |
|
|