Markdown Editor: Offline, schnell, produktiv
Desktop-Editor mit Live-Vorschau, Tabs und Syntax-Highlighting
Python
markdown2
PyQt
🚀 Ihr Desktop-Markdown-Editor. Offline. Produktiv.
💰 Warum ein Desktop-Markdown-Editor?
Online-Editoren sind praktisch — aber bei sensiblen Dokumenten oder schlechter Internetverbindung ist ein lokaler Editor unschlagbar. Volle Kontrolle, null Abhängigkeiten.
Offline-first
Keine Cloud, keine Datenübertragung — Ihre Dokumente bleiben auf Ihrem Rechner.
Tab-Support
Mehrere Dokumente gleichzeitig offen — wie in VS Code, aber fokussiert auf Markdown.
Syntax-Highlighting
Markdown-Syntax farbig hervorgehoben — Überschriften, Fett, Code, Links sofort erkennbar.
Multi-Export
Export als HTML, PDF oder direkt als formatierte Markdown-Datei für GitHub & Co.
⚙️ So funktioniert's
Linke Seite: Editor mit Highlighting. Rechte Seite: Live-Vorschau. Dazwischen: Alles lokal.
Schreiben & Formatieren
Volle Markdown-Unterstützung: Überschriften, Fett/Kursiv, Listen, Tabellen, Code-Blöcke, Blockquotes.
Live-Vorschau
Sekündliche Aktualisierung der HTML-Vorschau — sehen Sie sofort, wie Ihr Dokument aussieht.
Suchen & Ersetzen
Regex-basierte Suche mit Replace-Funktion — für schnelles Refactoring langer Dokumente.
💻 Technische Umsetzung
🐍 Python-Backend mit markdown2
import markdown2
import os
from pathlib import Path
class MarkdownEngine:
def __init__(self):
self.extras = [
'fenced-code-blocks',
'tables',
'break-on-newline',
'header-ids',
'footnotes',
'strike',
'task_list',
'code-friendly'
]
def render(self, md_text: str) -> str:
"""Konvertiert Markdown zu HTML"""
html = markdown2.markdown(md_text, extras=self.extras)
return self._wrap_html(html)
def _wrap_html(self, body: str) -> str:
"""Wrapper mit GitHub-Markdown-CSS"""
return f'''<!DOCTYPE html>
<html>
<head><meta charset="utf-8">
<style>
body {{ font-family: -apple-system, sans-serif; max-width: 800px; margin: auto; }}
pre {{ background: #f6f8fa; padding: 16px; border-radius: 6px; overflow-x: auto; }}
table {{ border-collapse: collapse; width: 100%; }}
th, td {{ border: 1px solid #ddd; padding: 8px; text-align: left; }}
</style>
</head>
<body>{body}</body>
</html>'''
def export_html(self, md_text: str, output_path: str) -> str:
"""Exportiert als vollständige HTML-Datei"""
html = self.render(md_text)
with open(output_path, 'w', encoding='utf-8') as f:
f.write(html)
return output_path
def get_toc(self, md_text: str) -> list:
"""Extrahiert Inhaltsverzeichnis aus Überschriften"""
import re
headers = re.findall(r'^(#{1,6})\s+(.+)$', md_text, re.MULTILINE)
return [{'level': len(h[0]), 'title': h[1]} for h in headers]
# Nutzung
engine = MarkdownEngine()
markdown = """# Mein Projekt
## Einleitung
Das ist ein **wichtiges** Projekt.
| Feature | Status |
|---------|--------|
| Login | ✅ |
```python
print("Hello World")
```
"""
html = engine.render(markdown)
engine.export_html(markdown, 'doku.html')
toc = engine.get_toc(markdown)
print(f"Inhaltsverzeichnis: {len(toc)} Einträge")
⚡ In 2 Tagen zum Desktop-Markdown-Editor.
Maßgeschneiderter Markdown-Editor?
Mit Ihren Features, Ihrer Marke, Ihrem Workflow. Jetzt unverbindlich anfragen.
💻 Code-Einblicke
Generische Code-Beispiele für Desktop-Editor.
🖥️ Tkinter Editor-UI
import tkinter as tk
from tkinter import ttk, filedialog
class MarkdownEditor:
def __init__(self, root):
self.root = root
self.root.title("Markdown Editor")
# Textbereich
self.text = tk.Text(root, wrap=tk.WORD)
self.text.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
# Datei-Browser
self.file_list = tk.Listbox(root)
self.file_list.pack(side=tk.RIGHT, fill=tk.Y)
# Menü
menubar = tk.Menu(root)
file_menu = tk.Menu(menubar, tearoff=0)
file_menu.add_command(label="Öffnen", command=self.open_file)
menubar.add_cascade(label="Datei", menu=file_menu)
root.config(menu=menubar)
def open_file(self):
path = filedialog.askopenfilename(filetypes=[("Markdown", "*.md")])
if path:
with open(path, 'r') as f:
self.text.delete(1.0, tk.END)
self.text.insert(1.0, f.read())
💾 Auto-Save
def auto_save(self):
content = self.text.get(1.0, tk.END)
temp_path = self.current_file + '.autosave'
with open(temp_path, 'w') as f:
f.write(content)
self.status_bar.config(text="Auto-gespeichert")
# Alle 30 Sekunden auto-saven
self.root.after(30000, self.auto_save)