Skip to content
kpmy edited this page Dec 11, 2015 · 10 revisions

Object Template Language (o.t.)

О проекте

Object template language (o.t.) это экспериментальный человекочитаемый язык описания данных, структур и шаблонов. Основная идея в том, чтобы совместить типизацию, структурированность и простоту синтаксиса языков описания данных (json, yaml) с гибкостью, расширяемостью и возможностями шаблонизации языков разметки (xml и xml-based языки в основном, jsp и т.д.).

Так же планируется вторая часть эксперимента, встраивание одного или нескольких языков программирования, для выполнения в режиме модификации объекта-шаблона на этапе загрузки шаблона из текстового/бинарного представления (шаблона).

Синтаксис

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

Пустое пространство (whitespace)

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

Комментарии

Комментарии в исходном тексте шаблона обрамляются символами (* и *), эти символы должны быть сбалансированы. Всё содержимое внутри комментариев игнорируется.

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

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

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;
  `Здравствуй` `, ` `Дружок` `!`
;