A block markdown editor built for practical wisdom: Lezer-parsed, ProseMirror-rendered, structurally correct. It infers tasks, callouts, tables, and refs from what you type — and gets out of the way the moment you're focused on writing.
|
|
1 هفته پیش | |
|---|---|---|
| .forgejo | 1 هفته پیش | |
| apps | 1 هفته پیش | |
| packages | 1 هفته پیش | |
| .editorconfig | 1 ماه پیش | |
| .envrc | 1 ماه پیش | |
| .gitignore | 1 ماه پیش | |
| AGENTS.md | 1 هفته پیش | |
| README.md | 1 هفته پیش | |
| biome.json | 1 هفته پیش | |
| devenv.lock | 1 ماه پیش | |
| devenv.nix | 1 ماه پیش | |
| devenv.yaml | 1 ماه پیش | |
| package.json | 1 ماه پیش | |
| pnpm-lock.yaml | 1 هفته پیش | |
| pnpm-workspace.yaml | 1 ماه پیش | |
| skills-lock.json | 1 ماه پیش |
A high-performance block markdown editor built with Vue 3, TypeScript, ProseMirror, and the Lezer parsing framework.
Documents are structured as distinct, interactive Blocks rather than a single flat string. Each block is a self-contained ProseMirror editor instance that stores raw markdown as plain text — no AST conversion, no mark storage. A Lezer-based 3-stage parsing pipeline renders syntax as visual decorations in real time, enabling live-preview editing of Obsidian-style references, task states, callouts, headings, and inline formatting.
The editor is designed for the philosophy that plain text should stay plain text — formatting is purely decorative, never structural. This makes it ideal for note-taking apps, knowledge bases, and any tool that needs to edit rich markdown with programmatic access to the raw source.
Enesis is being built as a complete block-editing substrate:
| Phase | Feature | Status |
|---|---|---|
| 1–5 | Core editor: clean content model, keyboard boundaries, focus/cursor, inline + block decorations, Lezer-only AST pipeline | Done |
| 6 | Code block node views with CodeMirror 6, inline/block LaTeX with KaTeX | Next |
| 7 | Toolbar handler API — toggleBold, insertLink, setHeading, toggleTask from Lezer tree queries |
Planned |
| 8 | Asset handling — image drop, upload protocol, inline preview | Planned |
| 9 | Reference interactivity — clickable [[page]], ((block)), #tag chips with preview |
Planned |
| 10 | Multi-block editing — shared toolbar, drag handle, suggestion/mention menus | Planned |
| 11 | WCAG 2.1 AA compliance, screen reader support, RTL, high contrast | Planned |
| 12 | Third-party decoration plugin system | Planned |
| 13 | History orchestration API across blocks | Planned |
**bold** to <strong>. What you type is what's stored.@lezer/markdown AST walk with custom extensions for Obsidian-style elements.split, merge-previous, arrow-up-from-start, etc.) — no shared state.├── apps/
│ └── dev/ Development sandbox (Vue 3 + Vite)
│ ├── src/
│ │ ├── components/
│ │ │ ├── Editor.vue Main playground
│ │ │ └── AppLogo.vue Enesis brand mark
│ │ ├── pages/
│ │ │ └── EditorView.vue Route page
│ │ ├── App.vue Shell layout (Nuxt UI)
│ │ ├── main.ts App bootstrap
│ │ └── style.css Tailwind v4 + Nuxt UI theme
│ ├── public/ Static assets
│ └── vite.config.ts Vite with Nuxt UI plugin
│
├── packages/
│ └── editor/ Core headless engine
│ ├── src/
│ │ ├── index.ts Public API (Block component + plugin)
│ │ ├── components/
│ │ │ └── Block.vue Self-contained ProseMirror block editor
│ │ ├── composables/
│ │ │ ├── useMarkdownDecorations.ts ProseMirror decoration plugin
│ │ │ ├── useBlockKeyboardHandlers.ts Keyboard handler (Enter, Backspace, arrows)
│ │ │ └── usePatternPlugin.ts Pattern detection ([[, ((, /, #)
│ │ └── lib/
│ │ ├── markdown-parser.ts Lezer parser configuration
│ │ ├── markdown-extensions.ts Custom Lezer extensions
│ │ ├── content-model.ts Markdown ↔ ProseMirror conversion
│ │ ├── schema.ts Minimal ProseMirror schema
│ │ └── markdown-rules/
│ │ ├── engine.ts MarkdownRuleEngine (3-stage pipeline)
│ │ ├── types.ts Shared type interfaces
│ │ ├── inline-rules.ts Inline syntax rules
│ │ ├── block-rules.ts Block syntax rules
│ │ └── block-classifier.ts First-line regex classifier
│ ├── vite.config.ts Library build (ESM, tailwind, vue)
│ └── vitest.config.ts Test runner configuration
│
├── .forgejo/
│ └── workflows/
│ └── deploy.yml CI: build + deploy to Codeberg Pages
│
├── package.json Workspace root
├── pnpm-workspace.yaml pnpm workspace definition
├── AGENTS.md Project conventions for AI coding agents
└── biome.json Linting & formatting
pnpm install
pnpm dev # Start the dev sandbox at localhost:5173
pnpm test # Run editor unit tests (Vitest)
pnpm check # Lint & format check (Biome)
| Script | Description |
|---|---|
pnpm dev |
Start Vite dev server for @enesis/dev sandbox |
pnpm build |
Build @enesis/editor library (ESM + type declarations) |
pnpm test |
Run unit tests for @enesis/editor |
pnpm check |
Run Biome lint & format check across the workspace |
On push to master, a Forgejo Actions workflow builds the dev app and deploys it to Codeberg Pages at https://enesismd.codeberg.page/editor/.
| Layer | Technology |
|---|---|
| Framework | Vue 3 (Composition API, <script setup>) |
| Editor Engine | ProseMirror (view, state, model, transform, keymap, gapcursor) |
| Parsing | Lezer (@lezer/markdown + GFM + custom extensions) |
| Styling | Tailwind CSS v4 + Nuxt UI v4 |
| Type Safety | TypeScript (strict: true) |
| Testing | Vitest with jsdom |
| Formatting | Biome |
| Package Manager | pnpm workspaces |
| CI/CD | Forgejo Actions → Codeberg Pages |
MIT