TiddlyWiki — очень хорошая штука и я давно ею пользуюсь. Тем не менее, некоторых вещей в ней нет, и это минус. Но её можно творчески допилить напильником, и это плюс.
Понадобился мне прогрессбар. Применений у него куча: показывать степень готовности поста, например. Или количество выполненных дел по сравнению с оставшимися. Да и вообще, наглядная штука.
Поскольку прогрессбара из коробки нет, начал я думать, как бы его добавить. И, для начала, сформулировал к нему требования. В прогрессбаре должна быть возможность задать следующие параметры:
- цвет заполнения;
- размер;
- подсказку при наведении.
Если какой-то параметр не задан, то он должен вычисляться автоматически.
Для решения подобных задач в TiddlyWiki существуют макросы. Это заранее заданный фрагмент текста, куда можно передать параметры и подставить их в нужные места.
В рамках эксперимента, я набросал пробный макрос, выводящий прогрессбар:
\define progressbar(count:"0" total:"10") <svg width="$total$5" height="15"> <g> <title>$count$ из $total$</title> <rect x="1.5" y="4.5" height="10" width="$count$0" rx="3" ry="3" style="fill: green; stroke: none" /> <rect x="1.5" y="4.5" height="10" width="$total$0" rx="3" ry="3" style="fill: none; stroke: green" /> </g> </svg> \end
В том же тиддлере (так в TiddlyWiki называется фрагмент текста) дописал внизу вызов этого макроса:
Прогрессбар: <<progressbar 3 4>>
Сохранил тиддлер и полюбовался результатом:
Схема оказалась принципиально рабочей. Но имела кучу несоответствий исходным требованиям. И исправить это было пока нельзя из-за крайней ограниченности создания макросов с помощью формата WikiText. Пришлось разбираться дальше.
В документации обнаружилось упоминание, что макросы можно писать и на JavaScript. Для этого тиддлер макроса должен содержать поле module-type
со значением macro
(поля в TiddlyWiki представляют собой метаданные и могут назначаться любому тиддлеру). Скрипт макроса должен экспортировать следующие свойства:
name
: Строка, представляющая собой имя, по которому будут вызывать макросparams
: Массив объектов со следующими свойствами:
name
: имя параметраdefault
: (необязательно) значение параметра по умолчанию
run
: Функция, которая будет вызываться при запуске макроса. Параметры извлекаются из вызова макроса и располагаются согласно массиву params. Функцияrun
должна вернуть строковое значение макроса. При вызовеthis
указывает на узел виджета, вызвавшего макрос.
Если массив params
пуст или отсутствует, то все параметры будут просто переданы в метод run()
.
Это уже было хорошо. Но в TiddlyWiki нельзя просто взять и сделать тиддлер с куском JavaScript-а. Вернее, можно, но работать не будет. Чтобы конструкция заработала, её следует надлежащим образом оформить. Например, сделать плагин.
Что есть плагин в терминологии TiddlyWiki? Это некая совокупность тиддлеров, собранная в единое целое, которая помечена как скрытая и не отображается в обычном списке тиддлеров, может встраиваться в систему и запускаться на выполнение, а также может импортироваться из одной wiki в другую парой щелчков.
Первоначально для написания плагинов требовалось развернуть довольно сложную инфраструктуру с использованием node.js. Я когда-то пробовал это делать, но не получилось (не помню уже, по какой причине). Однако, на данный момент разработчик добавил возможность писать плагины прямо в браузере, чем я воспользовался и сейчас расскажу вам, как это делается.
Итак, уважаемые читатели, давайте приступим к созданию плагина. Сверяясь с документацией, скачаем чистый файл TiddlyWiki и начнём делать из него заготовку для плагина.
Первое, что надо сделать, это создать тиддлер HelloThere, настроить его автоматическое отображение при открытии страницы и прописать в нём ссылки на тиддлеры плагина.
Путь к плагину, согласно документации, должен выглядеть так:
$:/plugins/ваше_имя/название_плагина
Путь к скриптам, входящим в плагин, формируется подобным же образом:
$:/plugins/ваше_имя/название_плагина/имя_скрипта.js
Вот так выглядит мой вариант тиддлера HelloThere:
* [[$:/plugins/morthan/progress]] * [[$:/plugins/morthan/progress/progressbar.js]] Прогрессбар получает следующие параметры: ; `count` : Количество выполненного ; `total` : Количество всего ; `width` : Если указано --- длина прогрессбара в пикселях ; `color` : Цвет заполнения (стандартно --- зелёный) ; `title` : Подсказка, которая выводится при наведении мыши (по умолчанию --- '{count} из {total}') <<progressbar 30 42 80>>
А это он же в отрисованном виде:
Стоит обратить внимание на две вещи. Во-первых, ссылки даны курсивом, потому что ни плагина, ни скрипта, входящего в его состав, пока не существует. Во-вторых, прогрессбар тоже пока не отрисован — по той же причине.
Чтобы настроить автоматическое отображение тиддлера при открытии страницы надо добавить его в список Default tiddlers. Его можно обнаружить либо в открывающемся по умолчанию тиддлере GettingStarted, либо найти в сайдбаре пиктограмму в виде шестерёнки и нажать её. В появившейся панели настроек ищем Default tiddlers и прописываем туда наш HelloThere.
Всё, первая часть готова. Теперь надо создать тиддлеры плагина и скрипта. Начнём с плагина.
Чтобы создать тиддлер, достаточно щёлкнуть по ссылке на него. Появляется заготовка тиддлера, нажимаем «Редактировать» и редактируем.
Как подсказывает документация, в плагине должны быть прописаны такие поля:
Поле | Значение |
---|---|
dependents |
Список разделённых пробелами плагинов, от которых зависит наш плагин (для названий с пробелами используйте квадратные скобки) |
description |
Описание плагина |
plugin-type |
Для обычного плагина «plugin», для темы «theme», а для языкового пакета «language» |
type |
Задайте «application/json» |
version |
Номер версии плагина (например, «0.0.1») |
Заполняем поля, а в теле плагина пишем:
{"tiddlers": {}}
Сохраняем тиддлер. Треть работы выполнена.
Аналогичным образом поступаем со второй ссылкой, скриптом макроса. Щёлкаем по ней, нажимаем «Редактировать», заполняем поля:
Поле | Значение |
---|---|
type |
«application/javascript» |
module-type |
«macro» |
Теперь само тело скрипта (под спойлером):
/*\ title: $:/plugins/morthan/progress/progressbar.js type: application/javascript module-type: macro Macro to display progressbar \*/ (function(){ /*jslint node: true, browser: true */ /*global $tw: false */ "use strict"; /* Information about this macro */ exports.name = "progressbar"; exports.params = [ {name: "count"}, {name: "total"}, {name: "width", default: ""}, {name: "color", default: "green"}, {name: "title", default: "{count} из {total}"} ]; /* Run the macro */ exports.run = function(count, total, width, color, title) { count = parseInt(count); total = parseInt(total); width = (width == '') ? total * 10 : parseInt(width); var html = [svg(width), '<g>', tagTitle(count, total, title), innerRect(count, total, width, color), outerRect(width), '</g>', '</svg>']; return html.join("\n"); }; function svg(width) { width += 5; return '<svg width="' + width + '" height="15">'; }; function rect(width, fill) { return '<rect x="1.5" y="4.5" height="10" width="' + width + '" rx="3" ry="3" style="fill: ' + fill + '; stroke: green" />'; }; function outerRect(width) { return rect(width, 'none'); }; function innerRect(count, total, width, color) { var dx = 0; if (count > 0 && count != total) { dx = count * width / total; } else if (count == total) { dx = width; } return rect(dx, color); }; function tagTitle(count, total, title) { if (title == '') return ''; return '<title>' + title.replace('{count}', count).replace('{total}', total) + '</title>'; }; })();
Я джаваскриптер не настоящий, пишу на этом языке от случая к случаю, поскольку идиотский сишный синтаксис с фигурными скобками меня очень раздражает. И вообще, это только пример написания плагина.
В общем, сохраняем готовый тиддлер. Всё, что нужно, уже написано. Но не работает, потому что не оформлено.
А сейчас — магия! Открываем консоль JavaScript в браузере и пишем там вот что:
$tw.utils.repackPlugin('$:/plugins/morthan/progress', ['$:/plugins/morthan/progress/progressbar.js'])
Первый аргумент это имя плагина, который подлежит перепаковке. Второй — список тиддлеров, которые будут включены в плагин. Нажимаем Enter. Браузер говорит, что всё прошло успешно и для того, чтобы изменения возымели действие, надо сохранить и перезагрузить wiki.
Так и сделаем. После переоткрытия в тиддлере HelloThere внезапно появляется красивый зелёненький прогрессбар.
Заключение
В новой версии TiddlyWiki появилась возможность писать плагины прямо не выходя из бассейна браузера. Это позволяет творчески доработать систему под себя, открывает неограниченные горизонты и ещё на один маленький шаг приближает нас к мировому господству.
PS: не уверен в правильности выбора хабов, ибо не совсем понимаю, зачем они нужны. Если что-то сделал неправильно, буду благодарен за разъяснения в комментариях.
ссылка на оригинал статьи http://habrahabr.ru/post/260657/
Добавить комментарий