|
@@ -1,167 +1,167 @@
|
|
|
-Неделя самописных языков разметки на Habrahabr. Статья про AXON напомнила мне про мой проектик `o.t` - object template language. В нём я соединил интересные идеи из XML, yaml и прочих.
|
|
|
-
|
|
|
-### Что, ещё один?
|
|
|
-
|
|
|
-Велосипеды бывают разные. Мне например, было интересно попробовать создать именно язык описания данных и в какой-то степени язык разметки.
|
|
|
-
|
|
|
-<cut text="что из этого получилось" />
|
|
|
-
|
|
|
-### TL;DR
|
|
|
-````xml
|
|
|
-<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, который стал основой для языка описания структурных атомов в языке... а впрочем это уже другая история.
|
|
|
-
|
|
|
-### Ссылки
|
|
|
-
|
|
|
-* Репозиторий https://github.com/kpmy/ot
|
|
|
-* Дополнительные примеры в виде недотестов https://github.com/kpmy/ot/blob/master/ot_test.go
|
|
|
-* Обсуждение zbase32 http://philzimmermann.com/docs/human-oriented-base-32-encoding.txt
|
|
|
+Неделя самописных языков разметки на Habrahabr. Статья про AXON напомнила мне про мой проектик `o.t` - object template language. В нём я соединил интересные идеи из XML, yaml и прочих.
|
|
|
+
|
|
|
+### Что, ещё один?
|
|
|
+
|
|
|
+Велосипеды бывают разные. Мне например, было интересно попробовать создать именно язык описания данных и в какой-то степени язык разметки.
|
|
|
+
|
|
|
+<cut text="что из этого получилось" />
|
|
|
+
|
|
|
+### TL;DR
|
|
|
+````xml
|
|
|
+<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, который стал основой для языка описания структурных атомов в языке... а впрочем это уже другая история.
|
|
|
+
|
|
|
+### Ссылки
|
|
|
+
|
|
|
+* Репозиторий https://github.com/kpmy/ot
|
|
|
+* Дополнительные примеры в виде недотестов https://github.com/kpmy/ot/blob/master/ot_test.go
|
|
|
+* Обсуждение zbase32 http://philzimmermann.com/docs/human-oriented-base-32-encoding.txt
|