Flügel
StandardschriftartAbstand


NABI NOTE

Ein Open-Source-WYSIWYG-Editor


NABI NOTE ist ein Open-Source-WYSIWYG-Editor, dessen Formatierung, Ausrichtung, Tabellen, Uploads und weitere Funktionen vom Kern getrennt als eigenständige Module namens wings leben. Sie können nur die benötigten wings auswählen, um einen Editor zusammenzustellen, und selbst gebaute wings anbinden. Er ist in reinem JavaScript geschrieben und kann deshalb in Frameworks wie React oder Vue verwendet werden. Auf Seiten ohne Build-Einrichtung können Sie sofort mit der CDN-Bibliothek starten. Das eigene Dokumentformat, NABI TREE, lässt sich auch in Node.js-Umgebungen ohne Browser-DOM in HTML umwandeln. Eingabedokumente werden über registrierte Regeln repariert; beim Erzeugen von HTML werden Text und Attribute escapet und Link-Adressen geprüft. Eigene wings und Daten vom Server müssen dennoch zusätzlich nach der Sicherheitsrichtlinie der Anwendung geprüft werden. CSS-Variablen und ein rem-basiertes Layout helfen dabei, Theme und Größe anzupassen; außerdem gibt es Dark Mode und Schriftfamilien-Einstellungen für mehrere Sprachen. Tabellensortierung, lokale Historie und KI-gestützte Dokumentarbeit laufen alle auf demselben Dokumentmodell weiter.


Schriftart

Serifenlos (Standard), Serif, Monospace und Schreibschrift — jede Familie stapelt Schriften je Schriftsystem, sodass jede Sprache die Form dieser Familie behält; ein Schriftsystem ohne Handschrift in dieser Familie fällt auf die Browser-Schrift zurück. Der Host bestimmt die Standardschrift.


Unten wird jede Familie in vielen Sprachen gezeigt.


Serifenlos · Sans empattement · Sin serifa · Sem serifa · Без засечек · بلا زخارف · सैन्स सेरिफ़ · স্যান্স সেরিফ · سانس سیرف · Tanpa serif · بدون سریف · सॅन्स सेरिफ · Không chân · శాన్స్ సెరిఫ్ · Mara seref · Sans serif · Bila serif · சான்ஸ் செரிஃப் · ไร้เชิง · Senza grazie · 산세리프 · ゴシック体 · 无衬线


Serif · Avec empattement · Con serifa · Com serifa · С засечками · بزخارف · सेरिफ़ · সেরিফ · سیرف · Berserif · سریف · सेरिफ · Có chân · సెరిఫ్ · Mai seref · Yenye serif · செரிஃப் · มีเชิง · Con grazie · 세리프 · 明朝体 · 衬线


Dicktengleich · Chasse fixe · Monoespaciada · Monoespaçada · Моноширинный · ثابت العرض · मोनोस्पेस · মনোস্পেস · یکساں چوڑائی · Lebar tetap · تک‌فاصله · Đơn cách · మోనోస్పేస్ · Tazara ɗaya · Eş aralıklı · Nafasi moja · ஒற்றையகலம் · ความกว้างคงที่ · Monospaziato · Monospace · 고정폭 · 等幅 · 等宽


Schreibschrift · Cursive · Cursiva · Рукописный · خط اليد · हस्तलिपि · হস্তলিপি · رواں خط · Tulisan tangan · دست‌نویس · हस्ताक्षर · Chữ viết tay · చేతిరాత · Rubutun hannu · El yazısı · Mwandiko · கையெழுத்து · ลายมือ · Corsivo · 필기체 · 筆記体 · 手写体



Textgröße

Sehr klein

Klein

Groß

Sehr groß



Überschrift

Tippen Sie in einer leeren Zeile # und danach ein Leerzeichen, um sie direkt in eine Überschrift zu verwandeln.

H1

H2

H3

H4

H5
H6



Fett · Kursiv · Unterstrichen · Durchgestrichen

Fett kursiv unterstrichen durchgestrichen — ein Beispiel.

Sie können auch übereinandergelegt werden.

Hoch- und Tiefstellung

Die Fläche beträgt 3,5 m2, und eine Fußnote wird so hinzugefügt.1

Wasser ist H2O.



Textfarbe · Hervorhebung

Die Palette ist so gewählt, dass sie in hellem und dunklem Modus lesbar bleibt.

Textfarbe Grün · Koralle · Violett · Bernstein · Blau

Hervorhebung Gelb · Grün · Cyan · Pink · Lila · Orange



Link

Geben Sie eine Adresse ein, dann wird daraus ein Link.

Sie können http://- und https://-URLs sowie gleichseitige Pfade verwenden, die mit . oder / beginnen. Adressen wie javascript: sind nicht erlaubt.

Tippen Sie zum Beispiel https://nabi.saro.me und drücken Sie Leerzeichen oder Enter — wie hier zu sehen, wird es automatisch umgewandelt.

Links öffnen

Das Dokument speichert nur die Link-Adresse; die Seite, die das Dokument anzeigt, entscheidet, wie Links geöffnet werden.

Anhang-Link

Wenn etwas anderes als ein Bild hochgeladen wird, bleibt ein dateiförmiger Link wie unten.

Anhang bleibt so erhalten.



Ausrichtung

Linksbündig

Zentriert

Rechtsbündig

Auch Überschriften lassen sich ausrichten.



Listen

Aufzählung

Tippen Sie in einer leeren Zeile - und drücken Sie Leerzeichen — daraus wird direkt eine Aufzählung.

  • Das ist ein Aufzählungspunkt

    • Tab / Umschalt+Tab rücken ein und aus.

Nummerierte Liste

Tippen Sie in einer leeren Zeile 1. und drücken Sie Leerzeichen, um eine nummerierte Liste zu erstellen.

  1. Erstens

  2. Zweitens

  3. Drittens

Checkliste

Tippen Sie in einer leeren Zeile [ ] oder [x] und drücken Sie Leerzeichen, um eine Checkliste zu erstellen.

  • Dieser Punkt ist erledigt.

  • Dieser Punkt ist noch offen.



Tabelle

Klicken Sie in der Werkzeugleiste auf die Tabellen-Schaltfläche, um eine Tabelle zu erstellen; danach können Sie Zeilen und Spalten hinzufügen, löschen und verbinden.

Spalten sortieren

Öffnen Sie zuerst die Vorschau und klicken Sie dann nacheinander auf die Kopfzellen Bestand und Preis.

Modell

Bestand

Preis

Gewicht

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

Offen

12,999

2.4 kg

Preis besteht nur aus Zahlen und wird deshalb numerisch sortiert.

Bestand wird wegen der Buchstaben in der letzten Zelle als Text sortiert.



Trennlinie

Tippen Sie --- und drücken Sie Enter, um daraus eine Trennlinie zu machen.




Bild

Die Breite reicht von 30 % bis 100 %, und das Bild kann links, zentriert oder rechts stehen.



YouTube



Upload

Ziehen Sie ein Bild oder eine Datei in den Editor.

Der hier verwendete Upload ist ein Mock-up; über eine Einstellung verbinden Sie ihn mit Ihrem Server.

Wenn ein Upload fehlschlägt, wird das Bild oder die Datei aus dem Editor entfernt.



Zitat

Tippen Sie in einer leeren Zeile > und drücken Sie Leerzeichen, um einen Zitatblock zu erstellen.

Er kann über mehrere Zeilen laufen.



Code

Tippen Sie in einer leeren Zeile ``` und drücken Sie Leerzeichen oder Enter, um einen Codeblock zu erstellen.

Schreiben Sie auch die Sprache dazu, etwa ```java, und drücken Sie Leerzeichen oder Enter, um einen Codeblock mit dieser Sprache zu erhalten.

import { createNabiWith, defaultWings } from 'nabi-note'

const { nabi } = createNabiWith(defaultWings)
const html = nabi.getHtml()



Details

Details besteht aus Zusammenfassung und Inhalt.

Sie können festlegen, ob es eingeklappt oder geöffnet gespeichert wird.



Tastenkürzel

Drücken Sie zweimal schnell Shift, um in der Werkzeugleiste die Tastenkürzel jeder Funktion zu sehen.



Autoformat

Beispiel

Auslösetaste

Ergebnis

#

Leerzeichen

Überschrift

-

Leerzeichen

Aufzählung

1.

Leerzeichen

Nummerierte Liste

[ ] · [x]

Leerzeichen

Checkliste

>

Leerzeichen

Zitat

``` · ```ts

Leerzeichen · Enter

Codeblock

---

Enter

Trennlinie

https://…

Leerzeichen · Enter

Link



Ausgabefunktionen

Funktion

Ergebnis

getHtml()

HTML

getJson()

JSON



Funktioniert ohne DOM

Die Umwandlung von JSON nach HTML braucht kein DOM.

Ein Server (Node.js) kann den gespeicherten NABI TREE lesen und nach denselben Regeln HTML erzeugen.


Mobilfreundlich

  • Mobile UI — ein responsives Layout trägt die mobile Oberfläche.

  • Inset der mobilen Tastatur — wenn die Tastatur geöffnet wird, wird ihre Höhe berücksichtigt.

  • Flexible Größen — jede Größe ist in rem geschrieben.

  • Viele Sprachen — mehrere Sprachen werden unterstützt.


Anpassung

  • Eigener wing — wenn Sie eine Funktion brauchen, bauen und registrieren Sie sie selbst.

  • Eigenes CSS — Farben, Ecken und Abstände sind alle als --nabi-* definiert; Dark, Light und alles Weitere bestimmen Sie.

  • Open Source — das Projekt ist Open Source auf GitHub.


Dokumentation lesen → nabi.saro.me

HTMLEditor wird geladen…
JSONnabi-treeEditor wird geladen…
Installation
npm install nabi-note
Code
import {
  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: 'de', name: () => 'note' })
const history = mountLocalHistory({ nabi, storage: browserHistoryStorage(window) })
const diff = mountDiffWing({ nabi, registry, surface: content, locale: 'de' })

// The locale also sets the direction — Arabic and Urdu run right to left
mountSurface({ nabi, registry, root: content, locale: 'de', fileSink: upload.take })

const settle = watchSettle(document, { surface: content })
const shared = { nabi, registry, surface: content, settle, locale: 'de' }
// 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: 'de', 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()))