Handwrite
pendingby 3mpt7wh1te
Handwrite notes via Xournal++ and insert as PNG into Markdown or Canvas.
Obsidian Handwrite
An Obsidian plugin that lets you create handwritten notes using Xournal++ and seamlessly insert them as PNG images into your Markdown documents and Canvas.
Desktop only — requires Xournal++ installed locally (Windows).
Note: The plugin UI is currently in Chinese (Simplified). English localization is planned for a future release.
Features
- Markdown integration — Right-click in any Markdown editor to insert a handwritten note. The PNG is automatically saved to your attachment folder and embedded.
- Canvas integration — A pencil button is added to the Canvas card menu. Click to insert at viewport center, or drag to position the handwritten card precisely.
- Size & background selection — Choose canvas dimensions, background color (white, black, pastel colors, transparent), and texture (plain, lined, ruled, graph) before writing.
- Custom file naming — Name your handwritten files or let the plugin auto-generate timestamps. Duplicate names are automatically deduplicated.
- Re-edit — Right-click on an existing handwritten image (in Markdown or Canvas) to re-edit it in Xournal++.
- Live placeholder — While you're writing in Xournal++, a placeholder widget shows in the editor so you know where the image will appear.
How It Works
Obsidian Xournal++
│ │
├─ Create temp .xopp file ────────────▶│
├─ Write meta.json (id, size) ────────▶│
├─ Launch Xournal++ ──────────────────▶│
│ ├─ User writes...
│ ├─ Press Ctrl+L or "发送到 Obsidian"
│ ├─ Export PNG to temp dir
│ ◀──────────── Write .done signal ───┤
├─ Detect signal (polling) │
├─ Copy PNG to vault attachments │
├─ Insert ![[ink-xxx.png]] or │
│ canvas file node │
└─ Cleanup temp files │
The plugin includes a companion Xournal++ Lua plugin (xournal-plugin/ObsidianHandwrite/) that handles the export-and-signal flow from the Xournal++ side.
Installation
Prerequisites
Install the Obsidian Plugin
Manual installation:
- Download
main.js,styles.css, andmanifest.jsonfrom the latest release. - Create a folder
<your-vault>/.obsidian/plugins/obsidian-handwrite/. - Copy the three files into that folder.
- Restart Obsidian and enable "Handwrite" in Settings → Community Plugins.
With BRAT:
- Install the BRAT plugin.
- Add
FrankHumingtao/ObsidianHandWriteas a beta plugin.
Install the Xournal++ Plugin
Copy the xournal-plugin/ObsidianHandwrite folder to your Xournal++ plugins directory:
- Windows:
%APPDATA%\xournalpp\plugins\Copy-Item -Recurse xournal-plugin\ObsidianHandwrite "$env:APPDATA\xournalpp\plugins\"
Restart Xournal++ after installing.
Usage
In Markdown
- Right-click in the editor and select "插入手写" (Insert Handwrite).
- Choose canvas size, background color/texture, and optionally set a file name.
- Xournal++ opens — write your notes.
- Press Ctrl+L (or click the toolbar button "发送到 Obsidian") in Xournal++ to send the result back.
- The handwritten image is inserted at the cursor position.
In Canvas
- Click the pencil icon in the Canvas card menu, or drag it to a position.
- Follow the same flow — choose size, write, send back.
- The image node appears on the canvas.
Re-editing
Right-click on any ink-*.png image (in Markdown or Canvas node menu) and select "重新编辑手写" to re-edit it.
Settings
| Setting | Description |
|---|---|
| Xournal++ path | Path to the Xournal++ executable. Auto-detected if left blank. |
| Attachment directory | Where exported PNG files are saved (relative to vault root). Default: attachments. |
| Default width/height | Default canvas dimensions in pixels. |
Development
# Install dependencies
npm install
# Build for development (watch mode)
npm run dev
# Build for production
npm run build
Project Structure
├── src/
│ ├── main.ts # Plugin entry point
│ ├── settings.ts # Settings tab & Xournal++ auto-detection
│ ├── xournal.ts # Xournal++ launch, export, signal polling
│ ├── canvas-integration.ts # Canvas card menu & node management
│ ├── md-integration.ts # Markdown editor context menu
│ ├── size-modal.ts # Size/background selection modal
│ ├── file-naming.ts # File name generation & deduplication
│ ├── placeholder-widget.ts # CodeMirror placeholder extension
│ └── combobox.ts # Combobox UI component
├── xournal-plugin/
│ └── ObsidianHandwrite/
│ ├── main.lua # Xournal++ Lua plugin
│ └── plugin.ini # Plugin metadata
├── manifest.json # Obsidian plugin manifest
├── styles.css # Plugin styles
├── main.js # Compiled output
├── esbuild.config.mjs # Build configuration
├── package.json
└── tsconfig.json
License
For plugin developers
Search results and similarity scores are powered by semantic analysis of your plugin's README. If your plugin isn't appearing for searches you'd expect, try updating your README to clearly describe your plugin's purpose, features, and use cases.