NABI NOTE
یک ویرایشگر WYSIWYG متنباز
NABI NOTE یک ویرایشگر WYSIWYG متنباز است که قالببندی، تراز، جدول، بارگذاری و دیگر امکاناتش در ماژولهای مستقلی به نام بال از هسته جدا شدهاند. میتوانید فقط بالهای لازم را برای ساخت ویرایشگر برگزینید و بالهای خودتان را وصل کنید. این ویرایشگر با JavaScript ساده نوشته شده و در چارچوبهایی مانند React یا Vue بهکار میرود. در صفحههای بدون فرایند ساخت، با کتابخانهٔ CDN فوراً آغاز میشود. قالب سند خودش، NABI TREE، حتی در Node.js بدون DOM مرورگر به HTML تبدیل میشود. سندهای ورودی با قواعد ثبتشده اصلاح میشوند و هنگام ساخت HTML، متن و ویژگیها ایمن میشوند و نشانی پیوندها بررسی میشود. با این حال بالهای سفارشی و دادهٔ رسیده از سرور را باید جداگانه بر پایهٔ سیاست امنیتی برنامه بررسی کرد. متغیرهای CSS و چیدمان مبتنی بر rem امکان تغییر پوسته و اندازه را میدهند و حالت تیره و تنظیم قلم برای چند زبان نیز فراهم است. مرتبسازی جدول، تاریخچهٔ محلی و کارِ سند با کمک AI همگی بر همان مدل سند ادامه مییابند.
قلم
بدون سریف (پیشفرض)، سریف، تکفاصله و دستنویس؛ هر خانواده برای هر خط نوشتاری قلمهای مناسب را میچیند، بنابراین هر زبانی شکل همان خانواده را حفظ میکند و خطی که در آن خانواده قلم دستنویس ندارد به قلم مرورگر بازمیگردد. میزبان قلم پیشفرض را تعیین میکند.
در زیر هر خانواده به زبانهای بسیار.
Sans serif · 산세리프 · ゴシック体 · 无衬线 · Serifenlos · Sans empattement · Sin serifa · Sem serifa · Без засечек · بلا زخارف · सैन्स सेरिफ़ · স্যান্স সেরিফ · سانس سیرف · Tanpa serif · بدون سریف · सॅन्स सेरिफ · Không chân · శాన్స్ సెరిఫ్ · Mara seref · Bila serif · சான்ஸ் செரிஃப் · ไร้เชิง · Senza grazie
Serif · 세리프 · 明朝体 · 衬线 · Avec empattement · Con serifa · Com serifa · С засечками · بزخارف · सेरिफ़ · সেরিফ · سیرف · Berserif · سریف · सेरिफ · Có chân · సెరిఫ్ · Mai seref · Yenye serif · செரிஃப் · มีเชิง · Con grazie
Monoفاصله · 고정폭 · 等幅 · 等宽 · Dicktengleich · Chasse fixe · Monoespaciada · Monoespaçada · Моноширинный · ثابت العرض · मोनोस्पेस · মনোস্পেস · یکساں چوڑائی · Lebar tetap · تکفاصله · Đơn cách · మోనోస్పేస్ · Tazara ɗaya · Eş aralıklı · Nafasi moja · ஒற்றையகலம் · ความกว้างคงที่ · Monospaziato
Cursive · 필기체 · 筆記体 · 手写体 · Schreibschrift · Cursiva · Рукописный · خط اليد · हस्तलिपि · হস্তলিপি · رواں خط · Tulisan tangan · دستنویس · हस्ताक्षर · Chữ viết tay · చేతిరాత · Rubutun hannu · El yazısı · Mwandiko · கையெழுத்து · ลายมือ · Corsivo
اندازهٔ متن
بسیار کوچک
کوچک
بزرگ
بسیار بزرگ
عنوان
در خط خالی # و سپس فاصله را بنویسید تا همانجا به عنوان تبدیل شود.
H1
H2
H3
H4
H5
H6
پررنگ · کج · زیرخط · خطخورده
پررنگ کج زیرخط خطخورده — یک نمونه.
میتوان آنها را روی هم هم گذاشت.
بالانویس و زیرنویس
مساحت ۳٫۵متر2 است و پاورقی چنین افزوده میشود.1
آب H2O است.
رنگ متن · برجستهسازی
پالت در پوستهٔ روشن و تیره خوانا میماند.
رنگ متن سبز · مرجانی · بنفش · کهربایی · آبی
برجستهسازی زرد · سبز · فیروزهای · صورتی · ارغوانی · نارنجی
پیوند
نشانی را وارد کنید تا به پیوند.
میتوانید از نشانیهای http:// و https:// و مسیرهای همین سایت که با . یا / آغاز میشوند استفاده کنید. نشانیهایی مانند javascript: مجاز نیستند.
برای نمونه، https://nabi.saro.me را بنویسید و فاصله یا Enter بزنید؛ همانطور که اینجا میبینید خودش تبدیل میشود.
باز شدن پیوند
سند فقط نشانی پیوند را نگه میدارد و صفحهٔ نمایش تعیین میکند پیوندها چگونه باز شوند.
پیوند پیوست
بارگذاری هر چیز بهجز تصویر، پیوندی به شکل پرونده مانند نمونهٔ زیر میگذارد.
پیوست به همین شکل میماند.
تراز
تراز چپ
تراز وسط
تراز راست
عنوانها هم تراز میشوند.
فهرستها
فهرست نشانهدار
در خط خالی - را بنویسید و فاصله را بزنید تا همانجا فهرست نشانهدار شود.
این یک مورد نشانهدار است
Tab / Shift+Tab تورفتگی را کموزیاد میکند.
فهرست شمارهدار
در خط خالی 1. را بنویسید و فاصله را بزنید تا فهرست شمارهدار بسازید.
اول
دوم
سوم
فهرست کارها
در خط خالی [ ] یا [x] را بنویسید و فاصله را بزنید تا فهرست کارها بسازید.
این مورد انجام شده است.
این یکی هنوز انجام نشده است.
جدول
دکمهٔ جدول در نوار ابزار را بزنید، سپس سطر و ستون اضافه، حذف یا ادغام کنید.
مرتبسازی ستون
پیشنمایش ابتدا باز میشود؛ سپس سرستونهای موجودی و قیمت را بهترتیب بزنید.
مدل | موجودی | قیمت | وزن |
|---|---|---|---|
NB-7 | 1,200 | 349 | 1.2 kg |
NB-9 | 20,000 | 99 | 0.9 kg |
NB-12 | 3,500 | 1,299 | 1.4 kg |
NB-80 | 900 | 8,900 | 2.1 kg |
NB-100 | نامشخص | 12,999 | 2.4 kg |
قیمت فقط عدد است، پس عددی مرتب میشود.
موجودی بهدلیل حروفِ خانهٔ آخر بهصورت متن مرتب میشود.
جداکننده
--- را بنویسید و Enter بزنید تا به جداکننده تبدیل شود.
تصویر
عرض از ۳۰٪ تا ۱۰۰٪ است و میتواند چپ، وسط یا راست قرار بگیرد.
YouTube
بارگذاری
کشیدن تصویر یا پرونده روی ویرایشگر را امتحان کنید.
بارگذاری اینجا آزمایشی است؛ یک تنظیم آن را به سرور شما وصل میکند.
اگر بارگذاری ناموفق شود، تصویر یا پرونده از ویرایشگر حذف میشود.
نقلقول
در خط خالی > را بنویسید و فاصله را بزنید تا کادر نقلقول بسازید.
میتواند چند خط ادامه داشته باشد.
کد
در خط خالی ``` را بنویسید و فاصله یا Enter را بزنید تا کادر کد بسازید.
زبان را هم مانند ```java بنویسید و فاصله یا Enter بزنید تا کادر کد با همان زبان ساخته شود.
import { createNabiWith, defaultWings } from 'nabi-note'
const { nabi } = createNabiWith(defaultWings)
const html = nabi.getHtml()جزئیات
جزئیات از خلاصه و بدنه تشکیل میشود.
میتوانید انتخاب کنید بسته یا باز ذخیره شود.
میانبرها
Shift را دو بار سریع بزنید تا میانبر هر ویژگی در نوار ابزار نمایش داده شود.
قالببندی خودکار
نمونه | کلید عمل | نتیجه |
|---|---|---|
# | فاصله | عنوان |
- | فاصله | فهرست نشانهدار |
1. | فاصله | فهرست شمارهدار |
[ ] · [x] | فاصله | فهرست کارها |
> | فاصله | نقلقول |
``` · ```ts | فاصله · Enter | کادر کد |
--- | Enter | جداکننده |
https://… | فاصله · Enter | پیوند |
تابعهای خروجی
تابع | نتیجه |
|---|---|
getHtml() | HTML |
getJson() | JSON |
بدون DOM هم کار میکند
تبدیل JSON به HTML به DOM نیاز ندارد.
سرور (Node.js) میتواند NABI TREE ذخیرهشده را بخواند و با همان قواعد HTML بسازد.
سازگار با موبایل
رابط موبایل — چیدمان واکنشگرا رابط موبایل را فراهم میکند.
فاصلهٔ صفحهکلید موبایل — با باز شدن صفحهکلید، ارتفاع آن محاسبه میشود.
اندازهگذاری انعطافپذیر — هر اندازه با rem نوشته شده است.
زبانهای بسیار — از چند زبان پشتیبانی میکند.
سفارشیسازی
بال خودتان — اگر به ویژگی نیاز دارید، آن را بسازید و ثبت کنید.
CSS خودتان — رنگها، گوشهها و فاصلهها همگی با --nabi-* تعریف شدهاند؛ پس پوستهٔ تیره، روشن و هر چیز دیگر را خودتان تعیین میکنید.
متنباز — در GitHub متنباز است.
مستندات را بخوانید ← nabi.saro.me
npm install nabi-noteimport {
createNabiWith, mountSurface, mountToolbar, mountContextToolbar,
mountHints, watchSettle, defaultWings, mountUpload, mountUploadView,
browserFileStore, mountFile, parseNodes, mountViewTools,
browserHistoryStorage, mountLocalHistory, openHistoryPanel,
} from 'nabi-note'
import { mountDiffWing } from 'nabi-note/diff'
// The box that asks — without it the core answers "no" to everything (plug in your own)
const ask = { message: (t: string) => alert(t), confirm: (t: string) => confirm(t) }
const selected = [
...defaultWings,
]
const { nabi, registry } = createNabiWith(selected, { ask })
// Bring your own highlighter (Prism, highlight.js, Shiki, …) — the wing stays as it is
// and only the attach is swapped (`makeCodeAttach` ships from the same door)
// { ...codeWing, attach: makeCodeAttach({ highlight: (source, lang) => [{ text: source }] }) }
const root = document.querySelector('.nabi')!
const content = document.querySelector('.nabi-content')!
const view = mountUploadView({ nabi, surface: content })
const upload = mountUpload({
nabi, root: content,
// your upload goes here — report progress with task.onProgress(0–100)
uploader: async (task) => ({ uri: 'https://cdn.example/uploaded' }),
extensions: ['png', 'jpg', 'pdf'], maxFileSize: 10 * 1024 * 1024,
onStart: (tasks) => view.start(tasks),
onProgress: (id, percent) => view.progress(id, percent),
onSettle: () => view.settle(),
onDone: () => view.done(),
})
const file = mountFile({ nabi, registry, store: browserFileStore(document), parse: parseNodes, locale: 'fa', name: () => 'note' })
const history = mountLocalHistory({ nabi, storage: browserHistoryStorage(window) })
const diff = mountDiffWing({ nabi, registry, surface: content, locale: 'fa' })
// The locale also sets the direction — Arabic and Urdu run right to left
mountSurface({ nabi, registry, root: content, locale: 'fa', fileSink: upload.take })
const settle = watchSettle(document, { surface: content })
const shared = { nabi, registry, surface: content, settle, locale: 'fa' }
// A tool that needs a panel comes back to the host — without this the button is dead
const toolbar = mountToolbar({
...shared, root: document.querySelector('#toolbar')!,
file,
onFiles: upload.take,
onHost: (w) => {
if (w === 'diff') { diff.open(); return }
if (w !== 'localHistory') return
openHistoryPanel({
history, surface: content, locale: 'fa', sessionId: history.sessionId,
render: (record) => createNabiWith(selected, { doc: JSON.parse(record.body) }).nabi.getHtml(),
})
},
})
const context = mountContextToolbar({ ...shared, root: document.querySelector('#context')! })
mountHints({ toolbar, context, root, surface: content })
// The preview and fullscreen buttons — they stand their own box at the end of the row
mountViewTools({ ...shared, root, container: document.querySelector('#toolbar')! })
// on every change — hook up your own code here
// nabi.onChange(() => user_callback(nabi.getHtml()))