Як написати плагін для TiddlyWiki

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>>

Зберіг тиддлер і помилувався результатом:

image

Схема виявилася принципово робочої. Але мала купу невідповідностей вихідним вимогам. І виправити це було поки не можна з-за крайньої обмеженості створення макросів за допомогою формату 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>>

А це він же в відмалювати вигляді:

image

Варто звернути увагу на дві речі. По-перше, посилання надані курсивом, тому що ні плагіна, ні скрипта, який входить до його складу, поки що не існує. По-друге, прогрессбар теж поки не отрисован — з тієї ж причини.

Щоб налаштувати автоматичне відображення тиддлера при відкритті сторінки треба додати його в список Default tiddlers. Його можна знайти або в що відкривається за замовчуванням тиддлере GettingStarted, або знайти в сайдбарі піктограму у вигляді шестерні і натиснути її. В панелі налаштувань шукаємо Default tiddlers і прописуємо туди наш HelloThere.

image

Все, перша частина готова. Тепер треба створити тиддлеры плагіна і скрипта. Почнемо з плагіна.

Щоб створити тиддлер, досить клацнути по посиланню на нього. З'являється заготівля тиддлера, натискаємо «Редагувати» і редагуємо.

Як підказує документація, в плагіні повинні бути прописані такі поля:
Поле
dependents
Список розділених пробілами плагінів, від яких залежить наш плагін
(для назв з пробілами використовувати квадратні дужки)
description
Опис плагіна
plugin-type
Для звичайного плагіна «plugin», для теми «theme», а для мовного пакета «language»
type
Поставте «application/json»
version
Номер версії плагіна (наприклад, «0.0.1»)
Заповнюємо поля, а в тілі плагіна пишемо:

{"tiddlers": {}}

image

Зберігаємо тиддлер. Третину роботи виконана.

Аналогічним чином поступаємо з другої посиланням, скриптом макросу. Клацаємо по ній, натискаємо «Редагувати», заповнюємо поля:
Поле
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: не впевнений у правильності вибору хабів, бо не зовсім розумію, навіщо вони потрібні. Якщо щось зробив неправильно, буду вдячний за роз'яснення в коментарях.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.