Markdown Reader is a clean and intuitive Markdown editor/reader with real-time preview support and dark mode toggle. It is compatible with macOS and Windows desktop environments and built with pure Python and Tkinter.
- Tabbed Markdown editing with real-time HTML preview.
- AI-Powered Translation: Translate Markdown documents while preserving formatting (supports OpenRouter, OpenAI, and Anthropic).
- Secure API Key Management: Missing or rejected provider keys trigger an in-app dialog, and keys can be saved in the OS-provided secure credential store instead of depending on
.env. - Progressive Translation Rendering: Long translations are split into smaller chunks, inserted into the editor as they complete, auto-scrolled into view, and tracked with a progress bar.
- Dark mode toggle.
- Advanced Table Editor: Interactive table insertion with customizable rows and columns.
- Dual PDF Conversion: Fast PyMuPDF mode or advanced Docling mode for complex documents.
- Built with pure Python, Tkinter, and ttkbootstrap — cross-platform.
- Can be bundled as a macOS app using
py2app. - Opens preview automatically and avoids multiple browser tabs for a smoother experience.
- Multi-provider AI failover: Automatically switches to fallback providers on rate limits.
git clone https://github.com/petertzy/markdown-reader.git
cd markdown-reader
python -m venv venv
source venv/bin/activate # macOS/Linux
# .\venv\Scripts\activate # Windows (cmd/powershell)
For Mac users, you should first complete the preparation steps described in the PrepareForMacUser file.
For Windows users, WeasyPrint requires additional system libraries. Complete the preparation steps described in the PrepareForWindowsUser file before running pip install.
pip install -r requirements.txt
python app.py
- Open File: Choose
.md,.markdown,.html,.htm, or.pdffrom the "File → Open File" menu. - Dark Mode: Toggle via "View → Toggle Dark Mode".
- Preview: Automatically opens in your web browser, only one tab is opened per session.
- AI Translation:
- Translate selected text: "Edit → Translate with AI → Translate Selected Text with AI"
- Translate full document: "Edit → Translate with AI → Translate Full Document with AI"
- Select source and target languages from dropdown menus
- Configure provider/model/API keys: "Settings → AI Provider & API Keys..."
- If
.envis missing or a key is rejected, the app prompts for the correct provider key and can save it securely in the OS-provided credential store - Large translations appear progressively in the editor with automatic scrolling and a visible progress bar
- Table Insertion: Use "Table → Insert Table" to create custom tables with interactive cell editing.
- PDF Conversion Modes:
- Fast mode (default): Uses PyMuPDF for quick extraction
- Advanced mode: Enable "Tools → Use Advanced PDF Conversion (Docling)" for complex documents
- View mode info: "Tools → PDF Converter Info"
To bundle this app as a .app, use the included setup.py script:
rm -rf build dist
python setup.py py2app
The generated app will be located in the dist/ folder. You can launch it by double-clicking. To use it like a regular app, move it to your Applications folder.
deactivate
git add .
git commit -m "Update" # Replace "Update" with a meaningful commit message
git push
- GUI:
tkinter,ttkbootstrap - Markdown Engine:
markdown2 - HTML Preview: Dynamically generated HTML opened in the default browser
- File Conversion:
html2textfor HTML,PyMuPDFanddoclingfor PDF import (pypdfis used as a fallback when PyMuPDF is unavailable) - PDF Export:
weasyprint - AI Translation:
requestsfor API communication with OpenRouter, OpenAI, and Anthropic - Configuration: Environment variables via
.envfile or secure OS credential storage viakeyring - Auto-failover: Automatically switches AI providers on rate limits or errors
Python >= 3.10
To enable AI-powered translation features, you need to set up API keys:
# Copy the example configuration file
cp .env.example .env
How to get API keys:
- OpenRouter (recommended for free tier): openrouter.ai
- OpenAI: platform.openai.com
- Anthropic: console.anthropic.com
If the app is packaged and .env is unavailable, translation will prompt for the needed key at runtime and you can configure provider/model/API keys directly in "Settings → AI Provider & API Keys...".
The app will automatically switch to a fallback provider if the primary provider hits rate limits.
This project is licensed under the MIT License.
See the LICENSE file for the full text.
All contributions are welcome, including:
- Bug reports
- Feature suggestions
- Pull requests
- Documentation improvements
Please see our CONTRIBUTING guide for more details on how to get started, submit changes, or report issues.