Javascript-форум (https://javascript.ru/forum/)
-   Ваши сайты и скрипты (https://javascript.ru/forum/project/)
-   -   Snakeskin (https://javascript.ru/forum/project/35057-snakeskin.html)

kobezzza 27.08.2014 12:43

Отказался от идеи реализации типографа, как в mdash.ru.

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

Правила по умолчанию (можно задать свои)
{
	'"': [['«', '»'], ['„', '“']],
	'\'': [['“', '”'], ['‘', '’']],

	'(c)': '©',
	'(tm)': '™',

	'[v]': '☑',
	'[x]': '☒',
	'[_]': '☐',

	'<-': '←',
	'<-|': '↤',
	'->': '→',
	'|->': '↦',
	'<->': '↔',

	'...': '…',
	'-': '−',
	'--': '—'
};


- template foo()
    "Snakeskin -- 'лучший' шаблонный движок!" (c)


Отрендерится как

«Snakeskin — „лучший“ шаблонный движок!» ©


Система макросов удобна тем, что можно вводить свои правила, например для замены смайликов на картинки, но без использования специальных механизмов Snakeskin, таких как вызываемые блоки или прототипы.

{
	':)': '<img src="..."/>'
};


Следует заметить, что такие макросы будут работать только в простом тексте, т.е. внутри строк директир или литералов локализации всё будет как есть, т.к. такое поведение тем может привести в потенциальным ошибкам.

{'[x]'.replace('[x]', 'error')} // данный код не выполнится, т.к. [x] -> ☒


Также будет введена директивы plain, внутри которой текст будет вставляться "как есть" + такое же поведение будет у директив script, style и link

Octane 27.08.2014 13:05

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

да и выдумывать язык разметки символов не лучшая идея, например, что потом каждый результат поиска тоже через препроцессор прогонять, чтобы не видеть там всякие -- и (с)?
помоему лучше сразу нормальные символы использовать, тем более не так много запомнить то надо:
alt+0187
alt+0171
alt+0150
alt+0151
alt+0133
alt+0160
остальное все не часто используется и можно из таблицы символов скопировать

melky 27.08.2014 13:10

kobezzza, это будет будущая фича SS? нифига)

kobezzza 27.08.2014 13:16

Цитата:

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

Цитата:

да и выдумывать язык разметки символов не лучшая идея, например, что потом каждый результат поиска тоже через препроцессор прогонять, чтобы не видеть там всякие -- и (с)?
Ну это опциональная фича, т.е. чтобы включить её работу необходимо будет запустить компиляцию с флагом autoCorrect=true.

Тут плюс в том, что некоторые символы типографии, например, кавычки привязаны к локали, т.е. в Русском языки одни, в Немецком другие и т.д. и если писать символы напрямую, то это сделает проблемным полную локализацию шаблона, а так всё удобно и просто.

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

В общем фича будет, но по умолчанию отключу.

kobezzza 27.08.2014 13:17

Цитата:

kobezzza, это будет будущая фича SS? нифига)
Ну, собственно я уже почти всё написал. Сейчас додумываю, пишу тесты и т.д. Фича войдёт в скорый релиз SS 4.1 .

Octane 27.08.2014 13:26

Цитата:

Сообщение от kobezzza
Потом опять таки замена тех же смайликов: можно вставлять картинки, или теги с символьными классами и т.д.

Тут все нормально, теги <img> вместо текстовых смайлов хранить в базе нет смысла.

kobezzza 27.08.2014 17:17

Решил также добавить директиву macro, которая позволит декларировать макросы прямо в области декларации шаблона. Директиву можно будет писать только в глобальной области.

- macro :) = <img src="..." />
- macro (: = <img src="..." />

- template foo()
    Hello :)

kobezzza 28.08.2014 10:44

Цитата:

Сообщение от kobezzza (Сообщение 327755)
Решил также добавить директиву macro, которая позволит декларировать макросы прямо в области декларации шаблона. Директиву можно будет писать только в глобальной области.

- macro :) = <img src="..." />
- macro (: = <img src="..." />

- template foo()
    Hello :)

Додумал эту концепцию.

Будет введёт ряд директив для установки флагов транслятора, т.е. методу compile мы можем передать, например, флаг inlineIterators и тогда все forEach и forIn итераторы будут скомпилированы в виде циклов или же stringBuffer и т.д.

А теперь будет можно задать эти флаги прямо в шаблоне:

/// Отключить опцию

!- escapeOutput 
!- xml

/// Включить опцию

!+ inlineIterators 

/// Или просто подключение файла настроек

!= params 'myParams.json'

/// Подключение файлов для опций

!= language 'myLang.json'
!= macros 'myMacros.json'

- template helloWorld()
	Hello World


Крутость такого подхода в том, что данные директивы будут распространятся только на отдельные странички, т.е. если страничка A включает страничку Б, то у них будут свои настройки, а при задачи параметров в метод compile настройки ставятся глобально.

В главной странице можно будет также задать глобальные настройки, для этого будет синтаксис:

@- escapeOutput 
@- xml
@+ inlineIterators


и т.д.

Локальные настройки будут расширять глобальные.

kobezzza 28.08.2014 12:05

Значение замены для макроса можно также задавать функцией, например,

- template foo()
    Today: %D


Snakeskin.compile(<шаблон>, {
	macros: {
		'%D': function () { return new Date(); }
	}
});


Кейзов для такой фичи не так много, но добавить её было так просто, что я подумал "а почему бы и нет?".

kobezzza 29.08.2014 11:19

Snakeskin 4.1.0 вышел!

Нововведения:

*) Поддержка макросов: 2 новых параметра компилятора: autoReplace (true включает макросы) и macros (таблица для задания своих макросов);

Базовые макросы:

let def = {
			'@quotes': {
				'"': [['«', '»'], ['‘', '’']],
				'\'': [['“', '”'], ['„', '“']]
			},

			'@shorts': {
				'(c)': '©',
				'(tm)': '™',

				'[v]': '☑',
				'[x]': '☒',
				'[_]': '☐',

				'<-': '←',
				'<-|': '↤',
				'->': '→',
				'|->': '↦',
				'<->': '↔',

				'...': {
					inline: true,
					value: '…'
				},

				'-': {
					inline: true,
					value: '−'
				},

				'--': {
					inline: true,
					value: '—'
				}
			},

			'@adv': {
				'%lorem%': 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolor dolores error facilis iusto magnam nisi praesentium voluptas. Delectus laudantium minus quia sapiente sunt temporibus voluptates! Explicabo iusto molestias quis voluptatibus.'
			},

			'@symbols': {
				'\\n': '\\n',
				'\\r': '\\r',
				'\\s': '&nbsp;'
			}
		};


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

// Отключим пакет @shorts
Snakeskin.compile(<шаблон>, {autoReplace: true, macros: {'@shorts': null}})


*) Добавлен фильтр default, который позволяет задать значение по умолчанию для выражения с undefined;
*) Фильтру truncate добавлен второй параметр, который означает, что символ многоточия должен выводится в виде мнемоника;
*) Множество исправлений ошибок.

****

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

kobezzza 29.08.2014 11:26

Пример использования макросов
http://jsfiddle.net/NAPWB/12/

melky 29.08.2014 11:34

kobezzza, операторы "-" "<" обязательны ?

kobezzza 29.08.2014 11:35

Цитата:

Сообщение от melky (Сообщение 328060)
kobezzza, операторы "-" "<" обязательны ?

Всмысле?

melky 29.08.2014 11:38

Цитата:

Сообщение от kobezzza (Сообщение 328062)
Всмысле?

намёк на то, что трудно у каждой конструкции писать префиксы :)

kobezzza 29.08.2014 11:40

Цитата:

Сообщение от melky (Сообщение 328063)
намёк на то, что трудно у каждой конструкции писать префиксы :)

Опять не понял, скажи подробно :)

UPD: кажется понял о чём ты. https://github.com/kobezzza/Snakeski...%D0%B8%D 1%81 - непонятно зачем я вообще писал документацию :(

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

template foo()
    if i want


В Jade предлагается использовать | в таких случаях, мол экранируй строку, но это бред: представь ты скопировал текст из ворда вставил в шаблонку и ничего не работает, и ты думаешь "ой наверное где-то в тексте есть if который нужно проэкранировать".

Поэтому в SS есть строгий набор для декларации директивы (- и #), а для директив, которые поддерживают короткое сокращение можно писать сразу его.

Также в Jade считается, что первое слово - это имя тега, но по причине озвученной выше в SS это нужно также декларировать явно (директива tag, поддерживает короткое сокращение < ).

В отличии от Jade в SS нет никакой синтаксической магии и всё подчиняется строгому набору правил в рамках движка.

***

Блин тока сделал релиз, вроде всё проверил, прогнал тесты ... и теперь нашёл баг :(

melky 29.08.2014 14:19

Цитата:

Сообщение от kobezzza
UPD: кажется понял о чём ты. https://github.com/kobezzza/Snakeski...%D0%B8%D 1%81 - непонятно зачем я вообще писал документацию

я её прочитал раньше. там нет ничего об этом (короткая форма записи чутка не то)

Цитата:

Сообщение от kobezzza
Касаемо необходимости явной декларации директив - это обязательное условие, ибо иначе мы получаем дорогу в ад.

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

... Snakeskin.addDirective нет в документации, он не предназначен для использования извне?

kobezzza 29.08.2014 14:37

Цитата:

я её прочитал раньше. там нет ничего об этом (короткая форма записи чутка не то)
Ок, улучшу эту часть.

Цитата:

Snakeskin.addDirective нет в документации, он не предназначен для использования извне?
В принципе можно, но я подумал, что возможность расширять шаблонку мало кому нужна, если есть кейзы, то опиши их и тогда можно будет подумать над вынесением в вики инфы.

kobezzza 29.08.2014 15:17

Фух, выпустил 4.1.1 с исправлением 2-х серьёзных багов.

upd: блин... опять нашёл баг сразу после релиза, кароче 4.1.2 :)

***

Обращаю внимание на полезный макрос %lorem% - он генерит текст

"Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolor dolores error facilis iusto magnam nisi praesentium voluptas. Delectus laudantium minus quia sapiente sunt temporibus voluptates! Explicabo iusto molestias quis voluptatibus."

который уже по старой традиции используется как "рыба" в макетах.

kobezzza 29.08.2014 15:44

Нашёл интересное поведение директивы attr, которое я не закладывал и по сути - это баг, но больно похож на фичу и наверно я оставлю его :)

{attr ng(foo = 1)}
{attr ng-(foo = 1)}


Даст один и тот же результат :)

Т.е. если явно не задан символ разделитель (допускается - : и _), то используется - и его можно не задавать :)

kobezzza 30.08.2014 11:27

Приснилась замечательная директива cdn, которая будет содержать снипеты для подключения популярных модулей js, css и т.д. из популярных CDN google, yandex и т.д.

Пример использования:

{cdn google jquery}
{cdn yandex jquery 1.8}

/// Если не задать явно CDN, то берётся первый имеющийся
{cdn fontawesome}


/// Уставновка CDN по умолчанию
{set cdn yandex}
{cdn jquery}


***

Развивая тему снипетов подумал, что было бы здорово создать снипеты для подключения метрик, вроде Яндекс.Метрика или Google Analytics.

{metrika google номерСчётчика}

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

---

Как считаете?

Aetae 30.08.2014 12:02

Цитата:

Сообщение от kobezzza (Сообщение 328183)
Это избавило бы разработчики от необходимости следить за изменениями в коде счётчика,

Зато заставило следить за этим автора движка.) И скорость реакции на внезапные критические изменения таки будет медленней.

kobezzza 30.08.2014 12:35

Цитата:

Сообщение от Aetae (Сообщение 328186)
Зато заставило следить за этим автора движка.) И скорость реакции на внезапные критические изменения таки будет медленней.

Тоже верно, посмотреть есть ли API у сервисов для получения кода счётчика, хотя можно парсить страничку с примером, но это не надёжно, т.к. вёрстку могут также поменять.

kobezzza 30.08.2014 12:45

Вообще для Snakeskin прям напрашивается boilerplate либа, которая реализует, например, макеты на bootstrap и пласт полезных функций, аля

- proto base->icon(type)
    < span class = fa #{type}

-template base()
    - doctype
    < html
        < head
            < title :: {title = 'Заголовок' ?}
            - block scripts
                < cdn bootstrap
                < cdn fontawesome
        < body
            - block body

- proto classic->menu(list)
    - forEach list => @el
        ...

-template classic() extends base
    - block scripts
        - super
        < cdn jquery-ui

    - block body
        /// Тут идёт вёрстка макета и разбинение на блоки для наследования


И уже при самой разработке можно было бы просто подключать нужный файл и наследовать шаблон от него.

Тоже самое и для UI, причём шаблоны удобно делать как метод класса UI контрола,

- template Button.prototype.tpl() extends Base.prototype.tpl
    ...

- template SuperButton.prototype.tpl() extends Button.prototype.tpl
    ...

melky 30.08.2014 12:52

Цитата:

Сообщение от kobezzza
Как считаете?

имхо, не нужно переизобретать стандарт Web Components (не то чтобы ты этим занимаешься, но эти директивы уже на 99% похожи на кастомный элемент, а это уже другая стизя)

есть ли способ дополнить этот стандарт или засахарить его?

и ещё .. подсветка кода!!! :(

kobezzza 30.08.2014 12:56

Цитата:

имхо, не нужно переизобретать стандарт Web Components (не то чтобы ты этим занимаешься, но эти директивы уже на 99% похожи на кастомный элемент, а это уже другая стизя)
Но ведь это не директивы UI, а снипеты подключения, например cdn bootstrap подключит с CDN твиттера сразу и jquery, bootstrap.js, bootstrap.css последней версии, это же оч удобно.

Цитата:

и ещё .. подсветка кода!!!
Ну, в WS хужо бедно всё норм: подсветка и автокомплит настраиваются, обработка ошибок на уровне FileWatcher и отладчика SS.

В notepad++ подсветку также настроить легко через настройки->добавить язык. А вот в sublime я просто хз, но я не думаю, что там что прям эпик.

Вот что действительно нужно добавить, т.к. это флаг --watch для компилятора, чтобы он сам пересобирал необходимые шаблоны, т.к. всякие File Watcher -ры делают это не совсем корректно, например,


base.ss
...


foo.ss
- include 'base.ss'


Файл foo.ss зависит от base.ss и при изменении base.ss нужно перекомпилить также foo.ss, но простой Watcher это не сделает, т.к. он не в курсе про граф отношений файлов - это знает только SS.

И конечно нужно доработать модули, без этого никак.

kobezzza 30.08.2014 13:10

Цитата:

имхо, не нужно переизобретать стандарт Web Components
Стандарта ещё нет толком и не факт, что он будет конфетой.

Я в своём проекте использую похожий подход, есть

.styl
.b-button {
    @extends i-base;
    ...
}


.ss
- template bButton.prototype.tpl() extends iBase.prototype.tpl
   ...


.js
// ES6 торт :)
class bButton extends iBase {
   ...
}


А подключение того или иного модуля делается через b-button.json, где описаны зависимости и т.д.

{
	"block": "b-button",
	"extends": "i-base",
	"use": [
		"logic",
		"style",
		"tpl"
	]
}


Вызов такого блока в другом шаблоне выглядит примерно так:

/// директива bem - это часть фреймворка
- bem b-button value: '...', size: 'xxl', style: 'dark'


Дополнительная крутость в том, что SS поддерживает БЭМ и локализацию на уровне синтаксиса, а блок может быть полностью отрендерен как на сервере, так и на клиенте без внесения изменений в код. Восхваляемый всеми Jade не умеет и 1/10 от фич SS - это объективный факт.

Удобнее такого подхода за 7 лет проганья на JS я пока не видел :)

kobezzza 30.08.2014 13:23

Для меня в WebComponents самое ценное - это Shadow DOM, а остальное странные приблуды (те же кастомные элементы уже 100 лет как можно юзать, и более того их уже давно юзают, см гугло или яндекс карты). В лучшем случае эти модули можно будет использовать как пласт для более абcтрактных фреймворков, а не как конечный API.

kobezzza 30.08.2014 16:36

Улучшил доку, добавил новые главы.

kobezzza 05.09.2014 20:59

Одной из новых фич, которые войдут в будующий релиз Snakeskin будет новый вариант трансляции шаблонов - в императивный DOM, т.е.

< span.foo
    hello world!


Превратится в

var _ = document.createElement('span');
_.setAttribute('class', 'foo');
_.appendChild(document.createTextNode('hello world'));


Такое расширение уже поддерживается движком Snakeskin, поэтому фича довольно легко реализуемая.

kobezzza 05.09.2014 21:51

Также в SS 4.2 будут серьёзно доработаны модули, т.к. сейчас они сделаны лишь наполовину, например появится такая важная возможность, как

- include 'foo.ss' as placehoder
- include 'foo.ss' as interface


Т.е. все шаблоны в подключаемом файле будут представлены либо как placeholder, либо как interface.

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

kobezzza 05.09.2014 21:57

В SS 4.2 будут введены внешние вызываемые блоки, по аналогии с внешними прототипами:

- block foo->calc(a, b)
    - a + b

- template foo()
    - call blocks.calc(1, 2)


Также, как и внешние прототипы, такие блоки можно будет указывать до декларации самого шаблона.

kobezzza 14.09.2014 16:14

Опубликовал roadmap SS 5

ЗЫ: т.к. для версионирования используется semver, то цифра 5 просто означает внесение некоторых несовместимостей с версией 4.1, но они минимальны.

kobezzza 15.09.2014 11:50

Немного дополнил roadmap.

Вообще SS 5 практически не вводит новых фич, а улучшает старые, например, макросы можно будет задавать по шаблону регулярки, а не только простым текстом, а в функции замены будет передавать найденный шаблон - это позволит делать штуки вроде:

$D:%d.%m.%Y


->

15.09.2014


По сути, макросы - это упрощённые и облегчённые прототипы.

PS: Если есть какие хотелки, то не стесняйтесь :)

kobezzza 17.09.2014 23:37

Новости с полей :)

Сегодня в рамках работы над SS 5 сделал новый параметр компилятора и режим рендеринга, теперь вместо stringBuffer введён параметр renderMode:

*) stringConcat - шаблон возвращает строку, для конкатенации строк используется оператор +

*) stringBuffer - шаблон возвращает строку, для конкатенации строк используется класс Snakeskin.StringBuffer (из коробки простой Array с push / join)

*) dom - шаблон возвращает document fragment и рендерится как последовательность вызова DOM API, но есть некоторые ограничения:

1) Нельзя использовать директиву doctype (на самом деле я просто хз, как её императивно создать :D)
2) Для создания тегов обязательно использовать директиву tag (очень не хочется писать отдельный парсер самой разметки), т.е.

- template foo()
    <h1>Hello</h1>



отобразится как текст, а не разметка.

А вот так:

- template foo()
    < h1 :: Hello


уже как разметка.

Safort 19.09.2014 15:01

Начал подбираться к SS. Полез в доки и малясь подфигел - их там тонны! Довольно подробно)

Но есть пара вопросов:
1. как на клиенте использовать шаблоны хранящиеся в *.ss? В доках только про Ноду нашёл.
2. SS такой толстый, не отразится ли это на скорости компиляции? Фич-то всё больше и больше. SS уже не шаблонизатор, SS уже ЯП, нафиг! *Епифанцев.jpg*

kobezzza 19.09.2014 17:03

Цитата:

как на клиенте использовать шаблоны хранящиеся в *.ss? В доках только про Ноду нашёл.
https://github.com/kobezzza/Snakeski...%D 0%B8%D1%8F

http://www.youtube.com/watch?v=wVt_L...ature=youtu.be

Вообще кейзов использования несколько:

1) Runtime-компиляция шаблонов;
2) Прекомпиляция шаблонов и последующие использование как простого JS;
3) Генерация статических страниц, аля Github Pages.

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

Цитата:

SS такой толстый, не отразится ли это на скорости компиляции? Фич-то всё больше и больше. SS уже не шаблонизатор, SS уже ЯП, нафиг! *Епифанцев.jpg*
Да, ЯП, я уже писал об этом, но ЯП заточенный под написание шаблонов.

Не отразится, SS не только самый функциональный движок шаблонов, но и один из самых быстрых. К тому же трансляция делается только один раз.

Safort 19.09.2014 18:03

kobezzza,
Цитата:

Но компилить шаблоны на стороне клиента не стоит, т.к. придётся тащить 14к строк кода транслятора + дополнительная нагрузка на трансляцию
Вот блин, я именно так и хотел сделать -_-

Цитата:

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

спасибо за подробный ответ)


Кстати, как там плагин для Галпа поживает?)

kobezzza 19.09.2014 18:33

Цитата:

Вот блин, я именно так и хотел сделать -_-
Ну ты можешь так делать, но сам понимаешь, что это не очень эффективно :)

Цитата:

Про скомпилированный шаблон видел, просто, думал, что так тоже норм)
Ну прост зачем тащить дополнительные 30кб? А вообще: конечно так можно делать.

Цитата:

Кстати, как там плагин для Галпа поживает?)
Я думал сделать его вместе с релизом SS 5, пока не начинал, но если очень нужно, то могу завтра сделать, а сегодня я решил сделать выходной :)

Safort 19.09.2014 18:55

Вложений: 1
kobezzza,
Цитата:

Ну прост зачем тащить дополнительные 30кб?
30? В аттаче такого нет. Или ты про другое?

Цитата:

Я думал сделать его вместе с релизом SS 5, пока не начинал, но если очень нужно, то могу завтра сделать, а сегодня я решил сделать выходной
Нужно, но пока что не срочно. Я ведь только начал разбираться с SS, так что не тороплюсь)


А когда планируешь 5 релиз, не напомнишь?

kobezzza 19.09.2014 19:01

Цитата:

30? В аттаче такого нет. Или ты про другое?
Ну, вместе с GZIP же, но я всё равно наврал, сейчас посмотрел - уже 43кб, как jQuery в общем, а то и поболее.

Цитата:

Нужно, но пока что не срочно. Я ведь только начал разбираться с SS, так что не тороплюсь)
Оки, сделаю раньше.

Цитата:

А когда планируешь 5 релиз, не напомнишь?
Вообще хотел на этой недели, но затянул работу по доке Collection 5.2 + лень :) Так что на след недели, думаю ближе к концу.

Можно следить за этом разработки: https://github.com/kobezzza/Snakeskin/issues


Часовой пояс GMT +3, время: 21:21.