Framework-agnostic
Web Components, όχι wrapper. Δουλεύει σε plain HTML, React, Vue, Svelte, Astro, Rails, WordPress — οτιδήποτε μπορεί να φορτώσει ένα script.
0 dependenciesMarkdown platform · writer-ir.v1
Ο Writer είναι ένας premium, framework-agnostic Markdown editor με Web Components, ένα σταθερό ενδιάμεσο μοντέλο και SDKs για JavaScript/TypeScript, PHP και Python. Γράφεις μία φορά· το ίδιο document βγαίνει παντού ίδιο.
Sanitization στο IR boundary σε JS, PHP και Python, first-party @writer/pdf, wrappers για React/Vue/Svelte, server examples και 32 conformance fixtures. Χωρίς DOCX/EPUB ή CRDT — μόνο ό,τι είναι πραγματικά έτοιμο.
Χαρακτηριστικά
Ό,τι βλέπεις είναι markdown. Ό,τι βγαίνει είναι δομημένο. Χωρίς framework, χωρίς lock-in, χωρίς δεύτερο draft για το preview.
Web Components, όχι wrapper. Δουλεύει σε plain HTML, React, Vue, Svelte, Astro, Rails, WordPress — οτιδήποτε μπορεί να φορτώσει ένα script.
0 dependenciesΈνα document, πέντε modes. Οι αλλαγές στο DOM γράφονται πίσω σε Markdown — όχι σε ένα δεύτερο, αποσυγχρονισμένο draft.
one documentΈνα σταθερό JSON contract (writer-ir.v1) ανάμεσα σε parser, editor και renderers. Επαληθευμένο σε 32 fixtures × 3 γλώσσες.
Πέντε themes, μεταβλητές, font faces και print CSS. Η ίδια τυπογραφία από τον editor στο HTML και στο PDF — όχι διαφορετικό “κάπως έτσι”.
5 themesAlignment, εισαγωγή/διαγραφή γραμμών και στηλών, header toggle, CSV/TSV paste και keyboard navigation. Πίνακες, όχι σωροί από pipes.
real tablesProviders, όχι hardcoded uploads: memory, HTTP, PHP/Python (local/FTP/SFTP/S3) ή το Writer Media Protocol. Το media manager τρέχει και ως standalone component.
outside the editorBootstrap, Tailwind, Bulma, Foundation, UIkit. Detection, grid classes, buildGrid() και lint — χωρίς να μαντεύεις class names.
Callouts, footnotes, task lists, TOC, math, mark, attrs, figures, code fences με line highlights. Στο preset ή opt-in — πάντα δομημένα.
FULL_PRESETΤο @writer/pdf δίνει first-party engine με ενσωματωμένες γραμματοσειρές (DejaVu)· εναλλακτικά Dompdf/ReportLab ή print HTML. Χωρίς renderer ή engine, το asPDF() επιστρέφει NO_PDF_ENGINE — δεν μεταμφιέζει HTML σε PDF.
Αρχιτεκτονική
Ο Writer δεν μετατρέπει HTML σε Markdown ελπίζοντας για το καλύτερο. Κρατά ένα κανονικοποιημένο IR και χτίζει όλες τις εξόδους από αυτό.
WYSIWYG, source ή split. Το ίδιο document, όχι αντίγραφα.
mdast → IR με σταθερά IDs, σειρά και attributes. Deterministic.
Commands, plugins, tables, media. Κάθε αλλαγή περνά από το ιστορικό.
HTML, IR, JSON, Markdown, text, print/PDF. Ίδια δομή, ίδιο περιεχόμενο.
Render lab
Γράψε αριστερά. Το preview, το HTML, το IR και το JSON είναι το ίδιο document — χωρίς server, χωρίς build step.
SDKs
Ο editor στο browser, το rendering στον server. Τα τρία SDKs μοιράζονται το ίδιο IR και τα ίδια conformance fixtures.
import { WriterRender } from '@writer/core';
const html = WriterRender(markdown).asHTML();
const ir = WriterRender(markdown).asIR();
const json = WriterRender(markdown).asJSON({}, true);
const pdf = await WriterRender(markdown).asPDF();
use Writer\Writer;
$html = WriterRender($markdown)->asHTML();
$ir = WriterRender($markdown)->asIR();
$json = WriterRender($markdown)->asJSON(true);
$pdf = WriterRender($markdown)->asPDF(); // dompdf
from writer import WriterRender
html = WriterRender(markdown).as_html()
ir = WriterRender(markdown).as_ir()
json = WriterRender(markdown).as_json(pretty=True)
pdf = WriterRender(markdown).as_pdf()
Quickstart
Το ίδιο bundle είναι self-hosted στο /assets/writer/. Ένα script tag, ή ένα import — διαλέγεις εσύ.
<link rel="stylesheet" href="https://writer.gr/assets/writer/writer.css">
<script src="https://writer.gr/assets/writer/writer.min.js"></script>
<div id="editor"></div>
<script>
const editor = Writer.mount('#editor', {
value: '# Hello',
theme: 'serif-editorial'
});
editor.addEventListener('wr-change', () => {
console.log(editor.getMarkdown());
});
</script>
import { useEffect, useRef } from 'react';
import { mount } from '@writer/editor';
export function Editor({ value }: { value: string }) {
const host = useRef<HTMLDivElement>(null);
useEffect(() => {
const editor = mount(host.current!, {
value,
theme: 'serif-editorial'
});
return () => editor.destroy();
}, []);
return <div ref={host} />;
}
<?php
require 'vendor/autoload.php';
$html = WriterRender($markdown)->asHTML();
$ir = WriterRender($markdown)->asIR();
$pdf = WriterRender($markdown)->asPDF(); // DompdfEngine
from writer import WriterRender
html = WriterRender(markdown).as_html()
ir = WriterRender(markdown).as_ir()
pdf = WriterRender(markdown).as_pdf()
Live demos
Τα demos τρέχουν το πραγματικό bundle — όχι screenshots. Άλλαξε mode, άνοιξε panels, ανέβασε αρχείο, δες το IR.
Modes, themes, chrome, panels, IR inspector και event log — με πραγματικό editor.
Άνοιξε το playgroundStandalone component, έξω από τον editor. Folders, upload, insert — με custom provider.
Δες το componentΧωρίς editor. Μόνο core: HTML, IR, JSON, text, Markdown και PDF test.
Άνοιξε το render labFAQ
@writer/pdf στο JS (ενσωματωμένες γραμματοσειρές, απευθείας από το IR) ή με engine/print HTML· στις PHP/Python εκδόσεις υπάρχουν Dompdf/ReportLab. Αν δεν υπάρχει renderer ή engine, το asPDF() αποτυγχάνει με NO_PDF_ENGINE αντί να επιστρέψει HTML με κατάληξη .pdf.writer.min.js είναι ≈130 kB gzip (editor + core). Το writer-core.min.js, για render-only σελίδες, είναι ≈100 kB gzip. Και τα δύο είναι self-contained — χωρίς framework runtime.Δοκίμασε τον editor, δες το IR, διάλεξε SDK — ή κατέβασε το bundle και ξεκίνα.