thindf — новый текстовый формат данных (альтернатива JSON)

Файл AppData\Local\Dropbox\info.json:
{
    "personal": {
        "host": 5060852864,
        "is_team": false,
        "subscription_type": "Basic",
        "path": "C:\\Users\\DNS\\Dropbox"
    }
}
В новом формате выглядит так:
 
personal
    host = 5060852864
    is_team = 0B
    subscription_type = Basic
    path = C:\Users\DNS\Dropbox


Конфигурационный файл редактора Sublime Text:
{
    "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"
}
В новом формате выглядит так:
 
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


Немного истории


Данный формат обязан своим появлением другому формату со странным названием 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 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).

В заключение приведу ещё несколько примеров:
Несколько строчек из моего 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": "’"} },
]
С использованием нового формата я бы записал так:
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:
{
    "a": "‘...’",
    "b": "string which ends with a space ",
    "c d": "\n",
    "e ": "3",
    "dirs": [
        ["Doc,Scans", ".t’xt"]
    ],
    "node": null,
    "n" : "N",
    "files": [],
    "f": "[]",
    "ff": [
        []
    ],
    "products": {}
}
 
a = ‘‘...’’
b = ‘string which ends with a space ’
c d = "\n"
‘e ’ = ‘3’
dirs = [
    [‘Doc,Scans’, '‘‘.t’xt’]
]
node = N
n = ‘N’
files = []
f = ‘[]’
ff = [
    []
]
products = {}

Поделиться публикацией

Комментарии 76

    +3
    INI на стероидах?
      0
      — удалено, не та ветка -
      +6
      А можно ещё добавить в статью табличку преимуществ и недостатков по сравнению с json.
      Из преимуществ вроде как большая компактность.
      Из недостатков — гораздо меньшая распространенность, а чтобы победить этот недостаток преимущества должны быть действительно очень значительными. Кавычки и фигурные скобки, как-то не тянут на это.
        +4
        Из преимуществ видится фатальный недостаток других форматов
          –1
          Судя по всему Вы правы.
        +7
        В json можно в одну строчку:
        { "personal": { "host": 5060852864, "is_team": false}}

        В thindf так можно? В статье не увидел примера.
          –2
          В текущей реализации, увы, нельзя.
          Вы [или возможно кто-нибудь другой {хороший пример в любом случае пригодится}] не могли бы привести пример реально использующегося где-либо json файла, в котором такая запись будет лучше, чем:
          personal
              host = 5060852864
              is_team = 0B
          
          ?

          (Предполагаю, должно быть много таких элементов.)
            +3
            В таком формате передаются данные там, где их не надо читать человеком, например клиенту с сервера. Такой формат выбран просто потому, что он занимает меньше места из-за отсутствия пробелов и табуляций. А для человеческих конфигов есть YAML
              +1
              Хм, а вы сами используете YAML?
              ИМХО, это слишком переусложнённый формат.
              Поэтому для конфигов чаще используют JSON и даже XML.
                +1
                Да, использую, и он местами похож на предложенный в статье.
                и даже XML.

                И это ужасно. Его придумали для машинного обмена и там он еще более-менее уместен, но людям его давать негуманно. К счастью, он начал потихоньку исчезать.
                  +1
                  Поэтому для конфигов чаще используют JSON

                  Правда? То-то у AppVeyor и GitVersion конфиги в yml.


                  и даже XML.

                  … это XML-то проще, чем YAML?

                    +2
                    … это XML-то проще, чем YAML?

                    Да, проще.

                    Пример с 013: Tilburg самый клёвый.
                      0

                      Туше.

                    0

                    Очень часто в YAML-файлах используется лишь небольшое надмножество JSON, такие фичи как:


                    • нет необходимости простые ключи и строковые значения в кавычки заключать
                    • нет необходимости ставить [] и {} в многострочных объявлениях, вместо них отступы (в случае [] с '-' после отступа)
                    • комментарии

                    То есть в таком режиме YAML даже проще JSON пишется и читается в общем случае, хотя бывают иногда неоднозначности, обычно при модификации конфига и забывание про добавление кавычек.

                  +1
                  Вы не могли бы привести пример реально использующегося где-либо json файла

                  Основное применение JSON — вовсе не "файлы". А в API и БД, и вообще везде, где не нужно чтение человеком, ровно так и пишут, ибо незачем.

                    0
                    Давайте не будем голословны.
                    Примеры в статье вполне реальны и именно на такое standalone применение и ориентирован новый формат в первую очередь. Но улучшение читаемости не повредит и в применении для всяких API.

                    А там где
                    не нужно чтение человеком
                    лучше подойдёт BSON или Protocol Buffers.
                      +3
                      Примеры в статье вполне реальны и именно на такое standalone применение и ориентирован новый формат в первую очередь.

                      Если "такое применение" — это конфиги, то сравнивайте с форматами для конфиг-файлов. Можно начать с YAML и HOCON.


                      Но улучшение читаемости не повредит и в применении для всяких API.

                      Именно этим JSON прекрасен — можно передавать поток без лишних символов, а потом отформатировать этот поток в читаемый вид во время отображения.


                      лучше подойдёт BSON или Protocol Buffers.

                      … у которых нет встроенной поддержки в браузерах, ага.

                0
                Кто-то думает что формат стал более читабелен? Если нет, то какая разница как там передаются данные, все равно json чаще всего формируют библиотеками а не пишут руками. Да и руками его написать проще, чем вдумываясь куда нужно поставить обратный апостроф (кстати где он на клавиатуре?) и считая количество пробелов.
                  +11
                  YAML, что с тобой?!
                    +1
                    Каким местом это альтернатива JSON, если в браузеры ничего другого толком не завезли?!

                    Выбор в пользу JSON в некоторых продуктах не очевиден, но такие примеры можно для любого формата подыскать. Для конфигов больше предназначен YAML — почему не с ним сравниваете? Чем thindf лучше?
                      –4
                      Ну JSON используется не только в вебе, но и, к примеру, для файлов конфигурации. Именно для таких применений данный формат и создавался в первую очередь.
                        +3
                        Давайте я попробую угадать «правильный» ответ=).
                        У YAML по сравнению с thindf есть два недостатка: первый — это некоторая «излишняя переусложнённость», а второй недостаток фатальный.=)

                        Вообще я открывал эту статью с мыслью, что уж теперь-то, запостив такую статью на хабр, автор, наверно, прикрыл все слабые места и придумал ответы на все каверзные вопросы про сравнение с yaml, про распространённость, про самопальность, про модифицируемость, про скорость… Но нет.

                        К сожалению нет.
                        Как бы ни был бесполезен очередной велосипед, если этот велосипед продуман и сделан хорошо, если он не лишен изящества и не блещет квадратными колёсами, то это уже интересно. Просто как ход мыслей или ход инженерной разработки.
                        Я ожидал в этой статье увидеть сравнительные замеры скорости парсинга, сравнения в эффективности представления тех или иных конструкций (не только с одним json, но и с прочими конкурентами),
                          +1

                          В данном случае колёса треугольные и неравнобедренные, вспоминая русское В в булевых значениях.

                            0
                            Да там не русская буква, это так автор обосновал выбор, что, мол, на обоих языках мнемонически получается.
                              0
                              Почему не русская?
                              В 0В и 1В допускается использовать как английскую, так и русскую В.
                                0
                                а 0В и 1В (здесь В — русская заглавная в) можно связать с 0Выключено и 1Включено.

                                хотя я код не читал, чтобы утверждать наверняка

                                0
                                Кстати, о колёсах. Это ж надо было нормальные пакеты подготовить для основных языков, покрыть тестами код, замеры производительности те же самые.
                                Ещё большое беспокойство вызывает экранирование. Надо, конечно, разбираться и погружаться, но во всяких настройках часто урлы, айпи-адреса, пути встерчаются, всякие уникодные штуки… как с ними этот формат себя поведёт, как синтаксис устоит…
                                Непростое это дело — новые форматы изобретать.
                            +3
                            почти конфиги на основе Lua изобрели
                              +5
                              '‘‘don’t’.
                              — это писец какой-то!
                                +9

                                Зачем?

                                  0
                                  Отличная идея, но есть один фатальный недостаток: многократное увеличение размера. Может быть, для трех уровней отступы лучше (вы убирает пару лишних знаков). Но вот для десяти — хуже(вы заменяет пару знаков на десятки лишних табуляций).
                                  Я так понимаю, что этот формат ориентирован на программиста. Поэтому предлагаю написать транслятор в json.
                                    –1
                                    Отличная идея, но есть один фатальный недостаток: многократное увеличение размера.
                                    Недостаток при сравнении с чем? В человекочитаемых конфигах на JSON используются также отступы в 4 пробела на один уровень.

                                    предлагаю написать транслятор в json.
                                    Это уже возможно в рамках текущей реализации.
                                    Python:
                                    string_in_json = json.dumps(thindf.parse(string_in_thindf))
                                    
                                    JavaScript:
                                    string_in_json = JSON.stringify(thindf.parse(string_in_thindf));
                                    
                                      0

                                      на какие объёмы и на какую вложенность расчитан этот формат?

                                    +1
                                    А чем жсон-то не угодил?
                                    В этот формат комментарии тоже не завезли?
                                    Вопрос о целесообразности русской версии прошу не поднимать

                                    И все же?
                                      0
                                      А чем жсон-то не угодил?
                                      При правке различных конфигов периодически забываю ставить запятые. А также не нравится обязательное заключение параметров и их значения в кавычки.

                                      В этот формат комментарии тоже не завезли?
                                      Хотя явной поддержки комментариев в данной реализации нет, но особенность этого формата такова, что строка:
                                      //font_face = Fira Code
                                      
                                      не является ошибкой, а является по смыслу аналогичной вот такой строки в JSON:
                                      "//font_face": "Fira Code"
                                      

                                      При таком подходе "комментарии" сохраняются автоматически, а не удаляются как происходит к примеру в JSON-парсерах с поддержкой комментариев.

                                      И все же?
                                      Не понял ваш вопрос. Русская версия поддерживается и всё, в чём она заключается, это поддержка русской буквы В в и , а также русская Н в значении null/None.
                                        +1

                                        "сделаем так, чтобы китайцы (подставить любую группу людей по вкусу) не могли редактировать наши конфиги"

                                          0
                                          периодически забываю ставить запятые. А также не нравится обязательное заключение параметров и их значения в кавычки

                                          Да это, прям. антипаттерн какой-то для мотивации создания нового формата.
                                          Эдак если кто ошибается в «ться/тся» постоянно, то можно правила подкорректировать,
                                          Прелесть обязательных кавычек в том, что эти правила останутся неизменными если в ключе у вас встретится "=" по какой-то причине.

                                          Кстати, на счет комментарием в данных — это интересный подход.
                                          Беда форматов типа json с комментариями в том, что при программной обработке и пересериализации данных эти комментарии, как вариативное форматирование исчезают. И не понятно как их вернуть или разместить при программной генерации файла.
                                          Особый формат ключа, конечно, тот ещё способ по универсальности… но занести комментарии или, если смотреть шире, докстринги, прямо в синтаксис — это идея интересная, как мне кажется.
                                        +3
                                        (сарказм) Где картинка про еще один стандарт?
                                          +3
                                          чтобы можно было вместо:
                                          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

                                          }


                                          Сомнительное достижение, на мой взгляд. Во-первых, во втором примере абсолютно не ясно без исходного кода программы, что из себя представляют числа 400, 600, 20, 40, а во-вторых, каким образом тогда можно извлечь все элементы, у которых, например, name начинается с «close*»? Для json хотя бы можно использовать JOLT . И в-третьих, в некоторых приложениях все-таки желательно сочетать метаданные с данными, ибо json все-таки не только в Web используется
                                            0
                                            Мне кажется, вы нашли фатальный недостаток в JSON.

                                            Ещё один [помимо 0В и 1В] спорный/непривычный элемент данного формата — это использование парных кавычек ‘’ для сырых строк [без управляющих последовательностей \ escape sequences].

                                            Вот меня это неистово смущает — должен быть только один способ, иначе это усложнение и будут ошибки.
                                            Да и по самому формату данных тоже как-то все теряется, сложно читается и неоднозначно интерпретируется.
                                              +1
                                              Во-первых как уже сказали вы изобрели конкурента для YAML/INI, а не JSON.
                                              Во-вторых «0В и 1В» это изврат ухудшающий читабельность, для человеческих конфигов true/false самый оптимальный вариант.
                                                0
                                                Вы, сударь, похоже не в курсе обо всех возможностях ямла, раз так говорите. Одни внутренние ссылки и расширяемость чего стоят.
                                                  0
                                                  С другой стороны, увидев что-то подобное в yaml разработчик может решить отказаться от его использования в пользу того же json.
                                                +1
                                                Никаких выдающихся преимуществ над toml.
                                                  0
                                                  Тоже иногда юзаю TOML для создания файлов конфигурации, и он достаточно удобный, эдакий продвинутый INI.
                                                  0

                                                  Сколько байт выигрывает приведённый формат по сравнению с JSON? я предполагаю, что это не более 10-15% в худшем случае, в лучшем около 5%.


                                                  PS: прошу прощение, отступы съедят все преимущества в этом плане. то есть, в том "лучшем" случае будет -10 --15%

                                                  • НЛО прилетело и опубликовало эту надпись здесь
                                                      +1
                                                      Можно пример со списком обьектов?
                                                      [{"name": "Nexus"}, {"name": "Pixel"}]
                                                      
                                                        –1
                                                        [
                                                        .   name = Nexus
                                                        .   name = Pixel
                                                        ]
                                                          0
                                                          Ну… Судя по вашим примера, это вот это…
                                                          [{"name": "Nexus","name": "Pixel"}]
                                                            –1

                                                            Вы привели невалидный JSON. Вообще, я уже упоминал в статье — можно попробовать cконвертировать JSON в новый формат прямо в браузере на веб-странице проекта.

                                                              +1
                                                              Конечно невалидный. Я в подобных конвертациях ожидаю, что оно однозначно и просто конвертируется в обе стороны…
                                                              И тут до меня дошло, что там еще и точки есть… Ну, знаете… Перебор по подводным камням.
                                                            +1
                                                            Ух, ещё и точки?
                                                              +1
                                                              [{"name": "Nexus", "lol": 42}, {},{"name": "Pixel"}]

                                                              Конвертор thindf
                                                              
                                                              [
                                                              .   name = Nexus
                                                                  lol = 42
                                                              .   {}
                                                              .   name = Pixel
                                                              ]
                                                              

                                                              Это нормально?
                                                                –1

                                                                Ну да. Точка является обозначением начала нового подобъекта в массиве (аналогично в YAML используется "-": можете сами попробовать конвертер JSON в YAML).
                                                                А какую бы вы запись предпочли?

                                                                  0
                                                                  Я бы хотел больше консистентности, а не в одном месте обьект это точка, в другом {}.
                                                            +3
                                                            image
                                                              –1
                                                              виндузятиной попахивает
                                                                0
                                                                основное преимущество json не в читаемости или просто внешнем виде (что пытаются улучшить «изобретатели»), а в том что он совместим с js и легко и не принуждённо встраивается в его тело, а так же напрямую пишется-читается. В каком-то смысле json это js в котором хранятся только данные. Так что эта и остальные библиотеки напирают на какие-то второстепенные моменты, из-за улучшения которых никто не перестанет использовать json
                                                                  0
                                                                  а что насчет вложенных объектов?
                                                                    0
                                                                    thindf поддерживает практически всё, что поддерживает JSON.
                                                                      0
                                                                      Практически? JSON сам по себе довольно дубовый, а thindf даже из этого не всё может?
                                                                        0
                                                                        мне просто интересно как это будет выглядеть? граница между вложенным и родительским объектом определяется по количеству отступов?
                                                                          0
                                                                          Можете привести пример на JSON? Я не очень понимаю, что вы имеете в виду.
                                                                            0
                                                                            допустим такое:
                                                                            {
                                                                            «parent»:{
                                                                            «childone»:{
                                                                            «field»:0
                                                                            },
                                                                            «chiltwo»:{
                                                                            «field»:0
                                                                            }
                                                                            }
                                                                            }
                                                                              0
                                                                              Разобрался. Уже не надо.
                                                                      0
                                                                      Похоже на делфийский DFM.
                                                                      Кстати, в Delphi _очень_ быстрая загрузка из DFM-файлов.
                                                                        –1

                                                                        Думаю вам будет небезынтересно глянуть на более продуманный формат: https://habr.com/post/248147/

                                                                          0
                                                                          Да, я уже видел вашу статью. Но, если честно, не очень впечатлили возможности этого формата (нет комменатриев и массивов [а это и правда удобно, когда формат данных гладко ложится на структуры данных используемого языка программирования (или вы при решении задач никогда не пользовались массивами?), и в этом я вижу основную причину такой популярности JSON]).
                                                                          У вас в статье заявлена реализация на TypeScript/JavaScript, но я её не нашёл.
                                                                          И с примерами вы "читерите":
                                                                          Примеры файлов на разных языках: github.com/nin-jin/tree.d/tree/master/formats
                                                                          Берём sample.json:
                                                                          { "users" : [
                                                                          {
                                                                              "name" : "John",
                                                                              "age" : 30
                                                                          },
                                                                          {
                                                                              "name" : "John",
                                                                              "age" : 30
                                                                          }...
                                                                          
                                                                          Сразу мне стало интересно как этот пример, использующий массив users, ляжет на ваш формат, который массивы не поддерживает.
                                                                          В sample.tree видим:
                                                                          user
                                                                              name \John
                                                                              age 30
                                                                          user
                                                                              name \John
                                                                              age 30
                                                                          

                                                                          Ещё интереснее. Как получили строки user? Неужели конвертер настолько умный, что догадался откусить признак множественного числа — последнюю букву 's' в слове users?
                                                                          Оказалось, ничего подобного.
                                                                          Вот результат честной конвертации:
                                                                          ideone.com/9rlHxi:

                                                                          dict * 
                                                                              \users
                                                                              : list 
                                                                                  dict 
                                                                                      * 
                                                                                          \name
                                                                                          : string \John
                                                                                      * 
                                                                                          \age
                                                                                          : int \30
                                                                                  dict 
                                                                                      * 
                                                                                          \name
                                                                                          : string \John
                                                                                      * 
                                                                                          \age
                                                                                          : int \30
                                                                          

                                                                          И вы поставили человекопонятность этому формату пятёрку?

                                                                          P.S. Для ленивых вот результат конвертации sample.json в YAML и thindf:
                                                                          YAML:                            thindf:
                                                                                                           
                                                                          ---                              
                                                                          users:                           users = [          
                                                                          - name: John                     .   name = John    
                                                                            age: 30                            age = 30
                                                                          - name: John                     .   name = John
                                                                            age: 30                            age = 30
                                                                          ...                              ...
                                                                                                           ]
                                                                          
                                                                            0

                                                                            Реализация на TS: https://github.com/eigenmethod/mol/tree/master/tree


                                                                            Смотрите, есть XML — это формат, в нём нет никаких заголовков, параграфов, кругов и прочего. А есть производные от него языки: XHTML, SVG, RDF и прочие, где есть куча идиом, небходимых для соответствующих предметных областей. Так вот, tree — это максимально абстрактный формат, где нет ничего кроме иерархии абстрактных узлов (AST). На его основе вы вольны разрабатывать произвольные языки: dom.tree для представления dom дерева, где нода с именем -- обозначает комментарий; view.tree для описания компонент, где - обозначает комментарий; grammar.tree, где remark обозначает комментарий и так далее. Можете рассматривать формат, как некоторый фреймворк для создания DSL.


                                                                            В упомянутом view.tree есть и массивы, и словари, и прочие идиомы JSON, если они вам нужны. Ваш пример будет выглядеть, например, так:


                                                                            users /
                                                                                *
                                                                                    name \John
                                                                                    age 30
                                                                                *
                                                                                    name \John
                                                                                    age 30

                                                                            Это именованный список с нетипизированными словарями внутри, который однозначно преобразуется в JSON.


                                                                            Однако, важно понимать, в других языках может быть удобным совершенно иное представление. Например, более гибкий и наглядный неименованный список с типизированными узлами:


                                                                            user
                                                                                name \John
                                                                                age 30
                                                                            user
                                                                                name \John
                                                                                age 30

                                                                            В JSON подобное можно представить лишь через костыли:


                                                                            [
                                                                                [ "user" , {
                                                                                    "name" : "John",
                                                                                    "age" : 30
                                                                                } ],
                                                                                [ "user" , {
                                                                                    "name" : "John",
                                                                                    "age" : 30
                                                                                } ]
                                                                            ]

                                                                            [
                                                                                {
                                                                                    "@type" : "user",
                                                                                    "name" : "John",
                                                                                    "age" : 30
                                                                                },
                                                                                {
                                                                                    "@type" : "user",
                                                                                    "name" : "John",
                                                                                    "age" : 30
                                                                                }
                                                                            ]

                                                                            И наоборот, если в словарях в tree нужна поддержка переводов строк внутри ключей (довольно редкий кейс), то представление полностью совместимое с моделью JSON будет немного костыльным:


                                                                            * \users
                                                                                : /
                                                                                    *
                                                                                        \name
                                                                                            : \John
                                                                                        \age
                                                                                            : 30
                                                                                    *
                                                                                        \name
                                                                                            : \John
                                                                                        \age
                                                                                            : 30

                                                                            Тот код, что вы привели думаю стоит переработать. Он делает из JSON какую-то переусложнённую tree структуру.

                                                                          0
                                                                          Ой, кажется, я его сломал.
                                                                          { "bool": [[{}]] }
                                                                          // v.slice is not a function
                                                                          

                                                                          Что-то с большой вложенностью пустых массивов также проблема.
                                                                          { "bool": [[[[]]]] }
                                                                          /*
                                                                          bool = [
                                                                              [‘’]
                                                                          ]
                                                                          */
                                                                          
                                                                          { "bool": [[[[[[[]]]]]]] }
                                                                          /*
                                                                          bool = [
                                                                              [‘’]
                                                                          ]
                                                                          */
                                                                          
                                                                            0
                                                                            Там во вложенности можно и дальше ирать с эффектами
                                                                            { "var": [[[{}]]] }
                                                                            { "var": [[[{"qwe":"qwe"}]]] }
                                                                            /*
                                                                            var = [
                                                                                [[object Object]]
                                                                            ]
                                                                            */
                                                                            
                                                                            { "var": [[[{"qwe":"qwe"},[]]]]}
                                                                            /*
                                                                            А теперь это строка
                                                                            var = [
                                                                                [‘[object Object],’]
                                                                            ]
                                                                            */
                                                                            
                                                                            { "var": [[[{},"0B", true]]]}
                                                                            /*
                                                                            Добавим немного рокировки типов...
                                                                            var = [
                                                                                [[object Object],0B,true]
                                                                            ]
                                                                            */
                                                                            
                                                                            { "var": [[["0B", true, 123]]]}
                                                                            /*
                                                                            var = [
                                                                                [‘0B,true,123’]
                                                                            ]
                                                                            */
                                                                            
                                                                            0
                                                                            Ох. сколько их уже было, только те которые смог вспомнить:

                                                                            Apache Avro, Apache Parquet, Argdata, ASN, Bale, Binn, Bond, Bintoken, BSON, CBOR, CSVb, edn, Ion, Netstringsc, FlatBuffers, MessagePack, Netstrings, OGDL Binary, Protocol Buffers, Sereal, Smile, Structured Data eXchange Formats, INI, Tree, Thrift, transit, YAML, VelocyPack

                                                                            более — менее взлетели только YAML и protobuf

                                                                            Любой школьник взглянув на JSON в первый раз, может за 5 минут придумать синтаксис лучше чем JSON.
                                                                            Но чтобы формат пошёл в народ — проблема не в синтаксисе, а в других аспектах — репутации разработчика, поддержке, коммюнити, какой киллер-продукт уже использует и т.д.

                                                                            Если завтра разработчику кирпич на голову упадёт (не дай бог) не останусь ли я с неподдерживаемой библиотекой?

                                                                            Как и большинство других русских проектов предсказываю, что не раскрутится и не выживет, а через год сайт перестанет открываться.
                                                                              +1
                                                                              Справедливости ради, могу сказать, что Avro и Parquet все-таки цветут и пахнут в среде Hadoop. Нельзя сказать, что они загнулись.
                                                                                0
                                                                                BSON тоже никуда не делся, в mongodb документы в нем хранятся.
                                                                                  0
                                                                                  Ну и tree активно используется в $mol.

                                                                            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                                            Самое читаемое