Вспомните себя в те времена, когда вы только знакомились с информационными технологиями. Что вы чувствовали, начиная работать с XML, JSON, TOML, YAML и другими языками разметки?

Лично мне поначалу было крайне сложно работать с HTML, особенно без подсветки. Позже пришлось разбираться с кавычками и скобками JSON, которые виделись мне сущим кошмаром. Впоследствии я осознал гениальность этих языков, но осадочек остался. Поэтому время от времени я возвращался к мысли о создании понятного для человека языка Универсальной Нотации Объектов. И получилось. Познакомьтесь, пожалуйста, это UNO — и ваше участие в его развитии будет весьма полезно.

Даже коту понятно
Даже коту понятно

Как появился UNO

Однажды мне потребовалось завести небольшие структурированные описания некоторых сущностей в обычных текстовых файликах. Предполагалось, что их будут заполнять и обычные люди, не знакомые с IT. Что ставило под сомнение выполнимость задачи. Сдаваться? Да ни в коем случае, вызов принят. Тем более, задача воспринималась как тренировка мышления.

Я стал размышлять так и эдак. Посмотрел на другие языки разметки, вроде YAML был попроще, но какие-то сложности меня отпугнули. Ещё мне хотелось и от кавычек избавиться, и явно указывать числа. После некоторых размышлений меня посетила гениальная в своей простоте мысль: использовать двоеточие для текста, а знак равенства для чисел. Как оказалось позже, дуализм делителя дал гораздо больше, чем простую синтаксическую типизацию.

Я стал углубляться в тему и много работать над этим проектом. По ходу работы открывались новые грани и слои. Постепенно, сами собой появились метаданные, импорты, модификаторы, проверочные схемы. Всё это дополняло друг друга и складывалось в некий единый механизм. В какой-то момент я остановил поток идей и решил попросить ряд советов у искушенной аудитории — у вас.

Визуальная чистота и типобезопасность

«Родила царица в ночь

Не то сына, не то дочь;

Не мышонка, не лягушку,

А неведому зверюшку».

На самом деле УНО получился исключительно минималистичным и при этом наглядным.

В нём можно использовать ключи и значения без кавычек (за некоторым небольшим исключением):

Имя питомца: Лисик
Возраст= 1
Окрас: Рыжий с белым
Здоров= yes

Многострочный текст всегда начинается с начала строки, вне зависимости от иерархии ключа — это позволяет легко копировать и вставлять данные:

key1:
	key2:
		О питомце:
'
Весёлый, беззаботный котик.
Очень ласковый, в игре почти не выпускает когти.
'

Списки также интуитивно понятны, даже не скажешь, что это какой-то формат представления данных:

Любимые игрушки:
- Крышечка от бутылки
- Мыши

При этом есть возможность строго указать, например, числовые значения:

Вес по месяцам:
= 360
= 520

Объект содержит записи на следующих строках, а принадлежность записей к нему отражается знаком табуляции:

Питомец:
	Кличка: Лис
	Вес= 3200

Точечная нотация тоже поддерживается:

Питомец.Кличка: Лис
Питомец.Вес= 3200

Списки могут быть отдельными записями и даже вложенными объектами. Такой список отражается с помощью точки, она здесь маркер элемента списка, но некая преемственность смыслов прослеживается:

Добыча:
. Мыши= 37
. Крысы= 4
. Птицы= 2

Вот пример списка объектов:

Питомцы:
.
	Кличка: Киря
	Вес= 4900
.
	Кличка: Лис
	Вес= 3200

Как вы можете видеть, синтаксис получился максимально лаконичным, но при этом он без труда описывает структуры любой глубины и сложности. Но продолжим.

Благодаря двойственному разделителю мы без труда можем определять даты и время.

Дата рождения= 2025-05

А ещё есть спаренное значение! Это то, чего я давно и страстно желал. Вместо нескольких разрозненных строчек со значением и единицей измерения, которые могут находиться где угодно в файле и непонятно по какому принципу сочетаться, в UNO величина и единица измерения могут находиться в одной строке:

Вес питомца= 3200 грамм

Что эквивалентно записи:

Вес питомца:
	val= 3200
	unit: грамм

Шах и Мат!

Недостатки

Основной архитектурный недостаток UNO — это его вертикально-ориентированный синтаксис. Он не позволяет реализовать хаотичный XML «компот» из мелких вложенных тегов в одну строчку и неизбежно раздувает «лесенку» отступов при проектировании слишком глубоких иерархий.

Впрочем, этот минус компенсируется высокой наглядностью: формат сам вынуждает разработчика задуматься об адекватности имеющейся у него структуры данных. Кроме того, встроенные инструменты сборки (о которых я расскажу позже) позволяют элегантно решить эту проблему, грамотно разделив данные на несколько независимых файлов.

Комментарии

С комментариями всё просто:

// Однострочный комментарий, разрешен только в отдельной строке для скорости парсера.

/'
Многострочный комментарий размещается по аналогии с текстом.
Но отступы разрешены.
'/

Метаданные

Постойте, чуть не забыл про метаданные! А ведь они могут быть крайне полезными. Во-первых, это информация о самом документе (автор, версия, дата создания), а во-вторых — системная информация, расширяющая контекст любого прикладного объекта без засорения его структуры (аналог атрибутов в XML). В UNO метаданные отделяются префиксом `#`.

Давайте посмотрим, как это выглядит на нашем любимом примере с котиком:

# Документ: Карточка питомца
# Составитель: Пётр Иванов
# Дата составления= 2026-08-27
# id= 97823

Имя питомца: Лисик
Вид: Домашняя кошка
Пол: Самец
	# Кастрация: no
Возраст= 14 месяц
Прививки:
. Панлейкопения: no
	# Важность: Обязательно
. Бешенство: no
	# Важность: Для выезда на природу

Обратите внимание на эстетику: вложенные метаданные скромно расположились непосредственно под целевым свойством с отступом, образуя с ним как-бы единый объект. Это позволяет человеку сканировать левый край файла по ключевым параметрам, полностью игнорируя служебную информацию, если она в данный момент не нужна.

Давайте сравним, как одну и ту же задачу разметки решают три разных формата: классический XML, редкий функциональный EDN и UNO.

Задача: описать блок статьи с техническими маркерами (класс и ID для движка сайта) и контентом.

В XML метаданные становятся «атрибутами»:

<article class="post" id="p123">
    <h1>Заголовок статьи</h1>
    <p>Текст статьи</p>
</article>

В EDN метаданные выглядят как-то так:

^{:class "post" :id "p123"}
:article
{
  :h1 "Заголовок статьи"
  :p  "Текст статьи"
}

В UNO получается отобразить данные целостно и минималистично. Даже отсутствие подсветки не сильно мешает.

article:
	# class: post
	# id: p123
	h1: Заголовок статьи
	p: Текст статьи

На этом с базовой спецификацией UNO Core мы разобрались. Но прежде, чем двигаться дальше, мне бы очень хотелось узнать ваше мнение.

Как вам идея использовать принципиально разные знаки препинания для текста и строгих типов данных? Что вы думаете о синтаксисе списков и общей компоновке управляющих символов? Понравилась ли вам концепция метаданных?

Делитесь своими мыслями и критикой в комментариях — ваше участие очень поможет проекту развиваться. А в следующей части разберу продвинутые возможности UNO Advanced, расскажу об общей архитектуре выражения УНО, о модификаторах, импортах, а может заодно и о валидации, но там уже будет посложнее. Для нетерпеливых оставлю ссылку на проект.