v2: light editorial redesign, bilingual (EN-first), preview, front matter, PWA

Design (design-taste-frontend + ui-ux-design-pro + impeccable):
- Warm, flat, light editorial theme (OKLCH), Geist + Geist Mono, single vermilion accent
- Dark mode toggle, persisted; respects prefers-color-scheme
- Prominent focus rings, tactile states, reduced-motion

Features (GitHub-ready):
- i18n EN/DE, English default, persisted
- Live split preview (marked + DOMPurify, sanitized)
- Optional YAML front matter (title/date/source/tags), rendered as metadata block
- Conversion options: links as text, strip images, bullet marker, heading style
- Filename patterns (title+date / date+time), auto/custom indicator
- Drag & drop .html/.md/.txt, reading time
- Installable PWA + service worker (offline), README (EN) + MIT LICENSE

Fix: switch inputs were covered by decorative spans (pointer-events).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-08-11 11:25:42 +00:00
parent f2793a34c3
commit 197376a584
13 changed files with 787 additions and 572 deletions
+64 -29
View File
@@ -1,51 +1,86 @@
# clip2md — Paste to Markdown
Winziges, self-hosted Tool: langen Text (Reddit-Thread, Website, formatierter Content) reinpasten
→ ein Klick / `⌘/Strg+S` → als `.md` speichern. Dateiname wird automatisch aus Titel + Datum vorgeschlagen.
Paste a long Reddit thread, an article, or any formatted web content, and save it as clean
Markdown in a single keystroke. Runs entirely in your browser: nothing is uploaded, no account,
no tracking, works offline.
**Live:** https://clip2md.heidrich-digital.de
**Live demo:** https://clip2md.heidrich-digital.de
## Was es macht
![clip2md](docs/screenshot-light.png)
- **Smart Paste:** Enthält die Zwischenablage formatiertes HTML (Copy aus dem Browser, z.B. Reddit
`⌘A``⌘C`), wird es automatisch über [Turndown](https://github.com/mixmark-io/turndown)
(+ GFM-Plugin für Tabellen/Strikethrough/Task-Lists) zu sauberem Markdown konvertiert.
Reiner Text ohne HTML bleibt 1:1 erhalten.
- **Roh erzwingen:** `⌘/Strg+⇧+V` fügt beim nächsten Paste bewusst als Klartext ein (keine Konvertierung).
- **Auto-Dateiname:** aus der ersten Überschrift/Zeile + Datum, z.B. `2026-08-11-mein-thread.md`.
Editierbar — sobald du selbst tippst, wird nicht mehr überschrieben.
- **Speichern:** Button oder `⌘/Strg+S` lädt die `.md` herunter (Browser-Download, kein Server-Roundtrip).
- **Kopieren / Leeren**, Wort- und Zeichenzähler.
## Why
Alles läuft **komplett clientseitig** — nichts wird an einen Server geschickt.
Copying from the web and getting usable Markdown is usually two or three tools and a lot of
cleanup. clip2md collapses that into: paste, press save. Rich HTML from the clipboard is
converted to tidy Markdown automatically (via [Turndown](https://github.com/mixmark-io/turndown)
with GitHub-flavored tables, strikethrough and task lists); plain text is kept verbatim. The
filename is proposed for you from the first heading plus the date, so it drops straight into an
Obsidian vault, a wiki, or a repo.
## Features
- **Smart paste.** Formatted HTML (copy from a browser, e.g. Reddit `⌘A``⌘C`) is converted to
clean Markdown. Plain text stays raw. Same `⌘V` for both, no mode switch.
- **Force raw.** `⌘/Ctrl+Shift+V` pastes the next clip as plain text, skipping conversion.
- **Live preview.** Toggle a side-by-side rendered Markdown view (marked + DOMPurify).
- **Auto filename.** Derived from the first heading + date, e.g. `2026-08-11-my-thread.md`.
Editable — once you type your own, it stops overwriting. Switch to a date+time pattern in settings.
- **YAML front matter.** Optional: prepend `title`, `date`, `source` URL and `tags` for
knowledge bases like Obsidian.
- **Conversion options.** Links as plain text, strip images, bullet marker (`-` / `*` / `+`),
heading style (ATX `#` / Setext).
- **Drag & drop.** Drop an `.html`, `.md` or `.txt` file to load or convert it.
- **Bilingual.** English and German, switchable in the header.
- **Light & dark.** Warm, flat, editorial light theme by default; dark mode one click away.
- **Save / copy / clear**, word + character count and reading time.
- **Installable PWA**, fully offline after first load.
Everything is **client-side**. No servers, no CDNs, no third-party requests — GDPR-friendly by
construction.
## Keyboard shortcuts
| Action | Shortcut |
| --- | --- |
| Save `.md` | `⌘/Ctrl + S` |
| Paste (smart) | `⌘/Ctrl + V` |
| Paste raw | `⌘/Ctrl + Shift + V` |
| Close settings | `Esc` |
## Tech
- Statische `index.html` (inline CSS/JS, OKLCH-Design, Dark).
- Vendored: `vendor/turndown.js`, `vendor/turndown-plugin-gfm.js` (kein CDN, offline-fähig).
- Ausgeliefert via `nginx:alpine` (siehe `Dockerfile` + `nginx.conf`).
- Single self-contained `index.html` (inline CSS/JS, OKLCH tokens, Geist + Geist Mono).
- Vendored, no CDN: Turndown + GFM plugin, marked, DOMPurify, fonts — all under `vendor/`.
- Served by `nginx:alpine` (`Dockerfile` + `nginx.conf`) with a service worker for offline use.
- No build step, no backend, no database.
## Lokal starten
## Run locally
```bash
docker build -t clip2md .
docker run --rm -p 8080:80 clip2md
# → http://localhost:8080
docker run --rm -p 8080:80 clip2md # http://localhost:8080
```
Oder ganz ohne Docker: `index.html` einfach im Browser öffnen.
Or just open `index.html` in a browser (the service worker only registers over http/https).
## Deployment
## Self-host
Deployt über **Coolify** (Dockerfile-Build) aus diesem Gitea-Repo, Domain via Cloudflare
auf `clip2md.heidrich-digital.de`. Details siehe Outline-Wiki (Tech & Stack → clip2md).
Any static host works — point it at this repo. The reference deployment uses
[Coolify](https://coolify.io) with a Dockerfile build and a reverse proxy for TLS.
## Vendor-Libs aktualisieren
## Update vendored libraries
```bash
npm pack turndown turndown-plugin-gfm
# dist/turndown.js vendor/turndown.js
# dist/turndown-plugin-gfm.js vendor/turndown-plugin-gfm.js
npm pack turndown turndown-plugin-gfm marked dompurify geist
# turndown/dist/turndown.js -> vendor/turndown.js
# turndown-plugin-gfm/dist/turndown-plugin-gfm.js -> vendor/turndown-plugin-gfm.js
# marked/lib/marked.umd.js -> vendor/marked.umd.js
# dompurify/dist/purify.min.js -> vendor/purify.min.js
# geist/dist/fonts/**/*-Variable.woff2 -> vendor/fonts/
```
Lizenz: MIT (Turndown ebenfalls MIT).
Bump the `CACHE` constant in `sw.js` whenever an asset changes so clients pick it up.
## License
[MIT](LICENSE). Turndown, marked, DOMPurify and Geist are under their respective MIT/OFL licenses.