Как стать автором
Поиск
Написать публикацию
Обновить

Что такое OT?

Время на прочтение6 мин
Количество просмотров8.4K

Неделя самописных языков разметки на Хабрахабре. Статья про AXON напомнила мне про мой проектик o.t — object template language. В нём я соединил интересные идеи из XML, YAML и прочих.


Что, ещё один?


Велосипеды бывают разные. Мне, например, было интересно попробовать создать именно язык описания данных и в какой-то степени язык разметки.


TL;DR


<note status="saved">
  <to>Tove</to>
  <from>Jani</from>
  <heading>Reminder</heading>
  <body>Don't forget me this weekend!</body>
</note>

note:
  status :: saved;
  to: "Tove";
  from: "Jani";
  heading: 'Reminder';
  body: `Don't forget me this weekend!`;
;

Концепция


Изначально хотелось что-то типа языка программирования внутри DOM, чтобы код всегда выполнялся в контексте того или иного узла, чтобы можно было осуществлять навигацию по DOM управляющими инструкциями языка, переменные и объекты рантайм маппит в DOM-узел контекста и т.д. и т.п. В итоге первый вариант концепции успешно вылетел из памяти.


Второй вариант намного проще и вообще не про программирование как таковое. Он скорее про шаблоны в том виде, в котором они представлены в технологии JSP, когда xhtml перемешивается с управляющими элементами. При этом замечено, что jsp неплохо подходит для чистой шаблонизации без программирования. Но там же XML, великий и ужасный.


А что есть на замену кроме JSON, YAML и TOML (.ini на стероидах)? Первый описывает примитивные типы, объекты и массивы javascript, второй делает то же самое, но без курли-скобочек, а третий вообще не о том.


От XML их всех отличает только одно, они описывают объект через его свойства. Предполагается при этом, что при необходимости пользователь добавит объекту поле type и опишет класс объекта. В XML объект описывается непосредственно как экземпляр класса и потом при необходимости могут быть указаны дополнительные поля, типа идентификатора.


Что же будет, если объединить простоту YAML и концепцию объектов из XML? Правильно — object template language, экспериментальный человекочитаемый язык описания данных, структур и шаблонов.


O.T.


Схематически весь OT можно описать одной строчкой module~class(id): content; то есть это модульный язык рекурсивных объектных шаблонов. Кроме этого, присутствуют дополнительные типы данных помимо строк и отсутствуют ассоциативные массивы, которые типа объекты из JSON, как неконцептуальная сущность.


Помимо текстовых идентификаторов, строковых, булевых, целочисленных и вещественных констант присутствуют некоторые символы, позволяющие описывать древовидные структуры объектов (object model). Так же присутствует ссылочный тип для построения других видов структур-графов.


Любое пустое пространство между идентификаторами, группами идентификаторов, символами разметки и константами игнорируется и используется для разделения значимых символов, но не включается в содержимое объекта. Внутри символов-кавычек любое пустое пространство учитывается.


Объектная модель


Любой шаблон представляет собой один объект, который является корневым. Любой объект, в т.ч. корневой, представляется как минимум идентификатором класса объекта и опционально идентификаторами модуля и уникальным идентификатором объекта:


module~class(id)

Например, для html-страницы существует объект класса body, который может быть предварен идентификатором модуля, из которого взят этот класс (html~body). Этот объект наделяется идентификатором index-page, по которому можно установить связь с объектом через ссылку @index-page.


body
html~body
html~body(index-page)
@index-page

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


html:
  body
;

Внутреннее содержимое объекта начинается после символа :. Всё содержимое вплоть до соответствующего символа ; будет считаться принадлежащим объекту-родителю. Если объект не предполагает содержимого, символы :; не указываются.


При этом важно помнить, что обязательным для любого объекта является идентификатор класса объекта, то есть, два и более одинаковых идентификатора класса в шаблоне будут соответствовать двум и более экземплярам класса.


html:
  body: br br br;
;

Повторное использование


Для объектов, содержимое которых может быть описано в нескольких местах шаблона, возможно указать такой режим описания содержимого, при котором создание нового экземпляра класса не будет производиться, и всё содержимое будет принадлежать одному экземпляру данного класса в рамках родительского объекта. Это достигается использованием символа :: открывающего содержимое.


xml:
  attr ::
    id: "my-xml";
  ;
  attr ::
    xmlns: "urn:oberon:ot";
  ;
;

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


Другое содержимое


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


html:
  head:
    title: "Привет, Мир!";
  ;
  body:
    p: 2 "+" 2 "=" 4.0;
    concat: "Hello":':':"World":"!";
  ;
;

Текстовое содержимое указывается в кавычках разных типов: ', ", и `, при этом возможно указание отдельного символа текста в одинарных кавычках ' и с помощью шестнадцатеричного кода (например 0DU) с модификатором U на конце. Текст может содержать переносы строки и любые другие символы unicode. Есть возможность конкатенации строки и символов с помощью символа : расположенного между двумя и более частями строк. Результирующая строка будет представлена в объектной модели как одна строка.


Модульность


Модульность в самом простом виде позволяет визуально разделять одноименные классы объектов различной природы. Например, html~body и human~body. Модульность в объектной модели предполагает так же наличие поддержки контекстом некоторых модулей, расширенная функциональность которых позволяет расширить возможности работы с шаблоном в рантайме.


Стандартные модули и классы


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


core

Модуль core является встроенным модулем, а так же базовым модулем. Для начала использования модуля core необходимо создать экземпляр класса core~template как корневой объект шаблона. Тем самым всё содержимое корневого элемента сможет обращаться к классам модуля core. В других случаях функциональность модуля core отключена.


core~template:
  (* ваше содержимое *)
;

Модуль core предоставляет класс import, который позволяет описывать зависимости шаблона от сторонних шаблонов (стандартных, пользовательских, виртуальных и т.д.).


core~template:
  import: context;
;

Внутри объекта типа core~template действует неявное указание модуля для известных классов, таких как import и для импортированных классов действует такое же правило, поэтому нет необходимости (но возможность остаётся) указывать модуль core и другие импортированные модули каждый раз.


Например:


core~template:
  import: html;
  html: body: p: "Привет, Мир!";;;
;

Классы html, body и p принадлежат модулю html и их принадлежность контролируется рантаймом, но при этом указывать их модуль явно не требуется.


Шаблонизация и пользовательские данные


context


Модуль core предоставляет класс context который является идентификатором модуля context.
Модуль context предоставляет доступ к данным контекста существования объектной модели. Обращение к объектам модели через специальные классы модуля context позволит размещать в содержимом шаблона данные из рантайма.


Например, класс context~$ позволяет обратиться к данным контекста по идентификатору или иерархическому набору идентификаторов.


core~template:
  import: context;
  $(hello-world-text)`, `$(user-names/hello-world-user)`!`
;

Таким образом, в зависимости от данных, размещенных в контексте каким-либо образом и доступных по заданным идентификаторам, после обработки текста шаблона и построения объектной модели мы получим итоговый объект с заданными значениями.


core~template:
  import: context;
  `Здравствуй` `, ` `Дружок` `!`
;

Реализация


Первый прототип парсера был написан на golang, рядом были реализованы некоторые шаблонные модули, core конечно, и ещё модуль хранения бинарной информации в виде zbase32-строки, отличный формат, заслуживает отдельного упоминания дизайн-документ этого формата, как тщательно люди анализировали ситуацию с форматами baseXXX.
В дальнейшем, был реализован неполный прототип парсера OT для javascript, который стал основой для языка описания структурных атомов в языке… а впрочем это уже другая история.


Ссылки


Теги:
Хабы:
Всего голосов 11: ↑8 и ↓3+5
Комментарии6

Публикации

Ближайшие события