NABI NOTE
Penyunting WYSIWYG sumber terbuka
NABI NOTE adalah penyunting WYSIWYG sumber terbuka yang memisahkan fungsi seperti format, perataan, tabel, dan unggahan dari inti menjadi modul mandiri bernama wing. Pengembang dapat memilih wing yang diperlukan dan menghubungkan wing buatan sendiri. Ditulis dengan JavaScript murni, ia dapat digunakan bersama React, Vue, maupun kerangka kerja lain. Pada halaman tanpa lingkungan build, pustaka CDN dapat langsung digunakan. Format dokumennya sendiri, NABI TREE, dapat diubah menjadi HTML bahkan di lingkungan Node.js tanpa DOM peramban. Dokumen masukan dirapikan mengikuti aturan yang terdaftar, sedangkan saat membuat HTML teks dan atribut di-escape serta alamat tautan diperiksa. Wing buatan sendiri dan data dari server tetap perlu ditinjau sesuai kebijakan keamanan aplikasi. Variabel CSS dan tata letak berbasis rem memudahkan pengaturan tema serta ukuran, termasuk mode gelap dan font untuk berbagai bahasa. Pengurutan tabel, riwayat lokal, dan pekerjaan dokumen berbantuan AI juga berada pada satu model dokumen.
Jenis huruf
Tanpa kait (bawaan), berkait, lebar tetap, dan tulisan tangan — setiap keluarga menumpuk fon menurut sistem aksara, jadi bahasa apa pun tetap memakai wajah keluarga itu; aksara yang tak punya wajah tulisan tangan di keluarga itu kembali ke font bawaan browser. Font bawaan ditentukan oleh induknya.
Di bawah ini setiap keluarga ditunjukkan dalam berbagai bahasa.
Tanpa serif · بدون سریف · सॅन्स सेरिफ · Không chân · శాన్స్ సెరిఫ్ · Mara seref · Sans serif · Bila serif · சான்ஸ் செரிஃப் · ไร้เชิง · Senza grazie · 산세리프 · ゴシック体 · 无衬线 · Serifenlos · Sans empattement · Sin serifa · Sem serifa · Без засечек · بلا زخارف · सैन्स सेरिफ़ · স্যান্স সেরিফ · سانس سیرف
Berserif · سریف · सेरिफ · Có chân · సెరిఫ్ · Mai seref · Serif · Yenye serif · செரிஃப் · มีเชิง · Con grazie · 세리프 · 明朝体 · 衬线 · Avec empattement · Con serifa · Com serifa · С засечками · بزخارف · सेरिफ़ · সেরিফ · سیرف
Lebar tetap · تکفاصله · मोनोस्पेस · Đơn cách · మోనోస్పేస్ · Tazara ɗaya · Eş aralıklı · Nafasi moja · ஒற்றையகலம் · ความกว้างคงที่ · Monospaziato · Monospace · 고정폭 · 等幅 · 等宽 · Dicktengleich · Chasse fixe · Monoespaciada · Monoespaçada · Моноширинный · ثابت العرض · মনোস্পেস · یکساں چوڑائی
Tulisan tangan · دستنویس · हस्ताक्षर · Chữ viết tay · చేతిరాత · Rubutun hannu · El yazısı · Mwandiko · கையெழுத்து · ลายมือ · Corsivo · Cursive · 필기체 · 筆記体 · 手写体 · Schreibschrift · Cursiva · Рукописный · خط اليد · हस्तलिपि · হস্তলিপি · رواں خط
Ukuran huruf
Sangat kecil
Kecil
Besar
Sangat besar
Judul
Di baris kosong ketik # lalu tekan spasi — seketika menjadi judul.
H1
H2
H3
H4
H5
H6
Tebal · Miring · Garis bawah · Coret
Tebal miring garis bawah coret — contohnya begini.
Bisa juga ditumpuk.
Superskrip dan subskrip
Luasnya 3,5 m2, dan catatan kaki ditulis seperti ini1
Air itu H2O.
Warna teks · Stabilo
Paletnya dipilih agar tetap terbaca baik di mode terang maupun gelap.
Warna teks Hijau · Koral · Ungu · Ambar · Biru
Stabilo Kuning · Hijau · Sian · Merah muda · Ungu · Jingga
Tautan
Masukkan alamat, maka jadilah tautan.
Hanya http:// dan https:// yang diterima; hal seperti javascript: tak akan lolos.
Misalnya ketik https://nabi.saro.me lalu tekan spasi atau Enter — ia berubah sendiri, seperti terlihat di sini.
Cara membuka tautan
Secara bawaan tautan seasal terbuka di jendela ini, situs lain di jendela baru; aturan ini bisa ditetapkan saat penyunting dideklarasikan.
Tautan lampiran
Kalau yang diunggah bukan gambar, tersisa tautan berbentuk berkas seperti di bawah.
Lampiran begitulah bentuk yang tersisa.
Perataan
Rata kiri
Rata tengah
Rata kanan
Judul pun bisa diratakan.
Daftar
Daftar berbutir
Di baris kosong ketik - lalu tekan spasi — seketika menjadi daftar berbutir.
Ini sebuah butir
Tab / Shift+Tab untuk menjorokkan dan mengembalikan.
Daftar bernomor
Di baris kosong ketik 1. lalu tekan spasi — jadilah daftar bernomor.
Pertama
Kedua
Ketiga
Daftar centang
Di baris kosong ketik [ ] atau [x] lalu tekan spasi — jadilah daftar centang.
Yang ini sudah dikerjakan.
Yang ini belum.
Tabel
Buat lewat tabel di bilah alat; baris dan kolom bisa ditambah, dihapus, dan digabung.
Pengurutan kolom
Pratinjau lalu tekan kepala kolom Stok dan Harga satu per satu.
Model | Stok | Harga | Berat |
|---|---|---|---|
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 | Belum ditentukan | 12,999 | 2.4 kg |
Harga seluruhnya angka, jadi diurutkan sebagai angka.
Stok diurutkan sebagai teks karena sel terakhirnya berisi huruf.
Garis pemisah
Ketik --- lalu tekan Enter — berubah menjadi garis pemisah.
Gambar
Lebarnya bisa diatur dari 30% sampai 100%, dan bisa diletakkan di kiri, tengah, atau kanan.
YouTube
Unggah
Cobalah seret gambar atau berkas ke atas penyunting.
Unggahan pada demo ini hanya tiruan; lewat pengaturan ia tersambung ke peladen Anda.
Kalau unggahan gagal, gambar atau berkas itu dikeluarkan dari penyunting.
Kutipan
Di baris kosong ketik > lalu tekan spasi — jadilah kotak kutipan.
Ia boleh menempati beberapa baris.
Kode
Di baris kosong ketik ``` lalu tekan spasi atau Enter — jadilah kotak kode.
Tulis sekalian bahasanya, seperti ```java, lalu spasi atau Enter — kotaknya memakai bahasa itu.
import { createNabiWith, defaultWings } from 'nabi-note'
const { nabi } = createNabiWith(defaultWings)
const html = nabi.getHtml()Lipatan
Lipatan terdiri dari judul dan isi.
Anda bisa menentukan apakah ia disimpan dalam keadaan tertutup atau terbuka.
Pintasan
Tekan Shift dua kali cepat, maka bilah alat menampilkan pintasan tiap fungsi.
Format otomatis
Contoh | Tombol | Hasil |
|---|---|---|
# | Spasi | Judul |
- | Spasi | Daftar berbutir |
1. | Spasi | Daftar bernomor |
[ ] · [x] | Spasi | Daftar centang |
> | Spasi | Kutipan |
``` · ```ts | Spasi · Enter | Kotak kode |
--- | Enter | Garis pemisah |
https://… | Spasi · Enter | Tautan |
Fungsi keluaran
Fungsi | Hasil |
|---|---|
getHtml() | HTML |
getJson() | JSON |
Berjalan tanpa DOM
Mengubah JSON menjadi HTML tidak memerlukan DOM.
Peladen (Node.js) membaca pohon nabi yang tersimpan apa adanya dan menyusun HTML sambil menahan XSS.
Ramah ponsel
Antarmuka ponsel — tata letak responsif menopang antarmuka ponsel.
Koreksi papan ketik — saat papan ketik muncul, tingginya dikoreksi.
Ukuran lentur — semua ukuran ditulis dalam rem.
Multibahasa — mendukung banyak bahasa.
Penyesuaian
Sayap buatan sendiri — kalau ada fungsi yang kurang, buat sendiri lalu daftarkan.
CSS buatan sendiri — warna, sudut, dan jarak semuanya didefinisikan dengan --nabi-*, gelap maupun terang terserah Anda.
Sumber terbuka — terbuka di GitHub.
Lihat dokumentasi → 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: 'id', name: () => 'note' })
const history = mountLocalHistory({ nabi, storage: browserHistoryStorage(window) })
const diff = mountDiffWing({ nabi, registry, surface: content, locale: 'id' })
// The locale also sets the direction — Arabic and Urdu run right to left
mountSurface({ nabi, registry, root: content, locale: 'id', fileSink: upload.take })
const settle = watchSettle(document, { surface: content })
const shared = { nabi, registry, surface: content, settle, locale: 'id' }
// 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: 'id', 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()))