Skip to content

Commit c4d0194

Browse files
kasey6801claude
andcommitted
Initial release: MarkItDown Local Frontend v0.42
Single-file Flask web app that converts PDF, DOCX, PPTX, XLSX, images, audio, and URLs to Markdown locally using Microsoft's MarkItDown library. Features: drag-and-drop UI, live preview, token estimator, Quit button, PyInstaller macOS .app bundle with ad-hoc code signing. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
0 parents  commit c4d0194

File tree

7 files changed

+1497
-0
lines changed

7 files changed

+1497
-0
lines changed

.claude/launch.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"version": "0.0.1",
3+
"configurations": [
4+
{
5+
"name": "MarkItDown Flask",
6+
"runtimeExecutable": ".venv/bin/python",
7+
"runtimeArgs": ["app.py"],
8+
"port": 5001
9+
}
10+
]
11+
}

.gitignore

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Python virtual environment
2+
.venv/
3+
4+
# PyInstaller build artifacts
5+
build/
6+
dist/
7+
*.spec.bak
8+
9+
# Python cache
10+
__pycache__/
11+
*.pyc
12+
*.pyo
13+
14+
# macOS
15+
.DS_Store
16+
.AppleDouble
17+
.LSOverride
18+
19+
# Legacy / alternate app file
20+
markitdown_app.py

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 MarkItDown Local Frontend Contributors
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

MarkItDown.spec

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# -*- mode: python ; coding: utf-8 -*-
2+
from PyInstaller.utils.hooks import collect_all
3+
4+
datas = []
5+
binaries = []
6+
hiddenimports = []
7+
8+
for pkg in [
9+
'markitdown', 'markitdown.converters',
10+
'flask', 'werkzeug',
11+
'mammoth', 'puremagic', 'pdfminer', 'pptx', 'openpyxl',
12+
'xlrd', 'olefile', 'lxml', 'bs4', 'PIL',
13+
'pydub', 'speech_recognition', 'youtube_transcript_api',
14+
'charset_normalizer', 'certifi',
15+
]:
16+
try:
17+
d, b, h = collect_all(pkg)
18+
datas += d
19+
binaries += b
20+
hiddenimports += h
21+
except Exception:
22+
pass # skip packages that are not installed
23+
24+
hiddenimports += [
25+
'markitdown',
26+
'flask',
27+
'werkzeug',
28+
'werkzeug.serving',
29+
'werkzeug.routing',
30+
'email.mime.multipart',
31+
'email.mime.text',
32+
'xml.etree.ElementTree',
33+
'sqlite3',
34+
'pydub.audio_segment',
35+
'speech_recognition',
36+
'lxml.html',
37+
'lxml.etree',
38+
'bs4',
39+
'PIL.Image',
40+
'PIL.PngImagePlugin',
41+
'PIL.JpegImagePlugin',
42+
'PIL.GifImagePlugin',
43+
'PIL.TiffImagePlugin',
44+
'PIL.BmpImagePlugin',
45+
'PIL.WebPImagePlugin',
46+
'openpyxl.cell._writer',
47+
]
48+
49+
a = Analysis(
50+
['app.py'],
51+
pathex=[],
52+
binaries=binaries,
53+
datas=datas,
54+
hiddenimports=hiddenimports,
55+
hookspath=[],
56+
hooksconfig={},
57+
runtime_hooks=[],
58+
excludes=[
59+
'tkinter',
60+
'matplotlib',
61+
'IPython',
62+
'notebook',
63+
'pytest',
64+
'test',
65+
'unittest',
66+
],
67+
noarchive=False,
68+
optimize=0,
69+
)
70+
71+
pyz = PYZ(a.pure)
72+
73+
exe = EXE(
74+
pyz,
75+
a.scripts,
76+
[],
77+
exclude_binaries=True,
78+
name='MarkItDown',
79+
debug=False,
80+
bootloader_ignore_signals=False,
81+
strip=False,
82+
upx=False, # UPX corrupts Python 3.14 dylibs on Apple Silicon
83+
console=False, # No terminal window when launched from Finder
84+
disable_windowed_traceback=False,
85+
argv_emulation=False,
86+
target_arch=None,
87+
codesign_identity=None,
88+
entitlements_file=None,
89+
)
90+
91+
coll = COLLECT(
92+
exe,
93+
a.binaries,
94+
a.datas,
95+
strip=False,
96+
upx=False,
97+
upx_exclude=[],
98+
name='MarkItDown',
99+
)
100+
101+
app = BUNDLE(
102+
coll,
103+
name='MarkItDown.app',
104+
icon=None,
105+
bundle_identifier='com.markitdown.app',
106+
version='0.42',
107+
info_plist={
108+
'NSPrincipalClass': 'NSApplication',
109+
'NSHighResolutionCapable': True,
110+
'LSBackgroundOnly': False,
111+
'NSHumanReadableCopyright': 'MarkItDown Local — MIT License',
112+
'CFBundleShortVersionString': '0.42',
113+
'CFBundleVersion': '42',
114+
'LSMinimumSystemVersion': '12.0',
115+
},
116+
)

README.md

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
# ⚡ MarkItDown Local Frontend
2+
3+
**v0.42** — Convert documents, PDFs, Office files & more to Markdown — locally.
4+
5+
A self-contained web app built on Microsoft's [MarkItDown](https://github.com/microsoft/markitdown) library. All conversion happens on your machine — no files or URLs are ever sent to an external server.
6+
7+
---
8+
9+
## Features
10+
11+
- **Drag-and-drop or browse** to upload files
12+
- **URL conversion** — paste a YouTube link or any web page URL
13+
- **Live Markdown preview** alongside the raw output
14+
- **Copy to clipboard** or **download as `.md`**
15+
- **Stats bar** — characters, words, lines, and estimated token range
16+
- **Quit button** — shuts down the server cleanly from the browser
17+
18+
### Supported formats
19+
20+
| Category | Formats |
21+
|---|---|
22+
| Documents | PDF, DOCX, PPTX, XLSX, XLS, EPUB |
23+
| Data | CSV, JSON, XML |
24+
| Web | HTML, YouTube URLs, web pages |
25+
| Archives | ZIP |
26+
| Images | JPG, PNG |
27+
| Audio | WAV, MP3 |
28+
29+
**Max file size:** 100 MB
30+
31+
---
32+
33+
## Option 1 — Run as a macOS App (recommended)
34+
35+
A pre-built `MarkItDown.app` is included in `dist/`. No Python installation required.
36+
37+
### Steps
38+
39+
1. Download or clone this repository.
40+
2. Open `dist/` in Finder.
41+
3. **Right-click** `MarkItDown.app`**Open** → click **Open** in the dialog.
42+
> This one-time step is required because the app is not signed with an Apple Developer ID. After the first launch you can double-click as normal.
43+
4. Your default browser opens automatically to `http://127.0.0.1:5001`.
44+
5. To quit, click the **Quit** button in the top-right corner of the UI.
45+
46+
### Requirements
47+
48+
- macOS 12 (Monterey) or later
49+
- Apple Silicon (arm64) or Intel Mac
50+
51+
---
52+
53+
## Option 2 — Run from Source (Python)
54+
55+
Use this if you want to modify the app or the pre-built `.app` doesn't work on your system.
56+
57+
### Requirements
58+
59+
- macOS 12 or later (also works on Windows)
60+
- Python 3.10 or higher
61+
62+
Check your Python version in Terminal:
63+
```bash
64+
python3 --version
65+
```
66+
67+
If you have 3.9 or lower, download the latest Python from [python.org](https://www.python.org/downloads/).
68+
69+
### One-time setup (macOS)
70+
71+
Open **Terminal** (`Cmd + Space` → type Terminal → press Enter) and run each command:
72+
73+
```bash
74+
# 1. Navigate to the project folder
75+
cd /path/to/CC_Markdown
76+
77+
# 2. Create a virtual environment
78+
python3 -m venv .venv
79+
80+
# 3. Activate it (your prompt will show (.venv) when active)
81+
source .venv/bin/activate
82+
83+
# 4. Install dependencies
84+
pip install "markitdown[all]" flask
85+
```
86+
87+
> **Tip:** If you see an Xcode prompt, click Install and wait for it to finish, then re-run the `pip install` command.
88+
89+
### Running the app
90+
91+
```bash
92+
cd /path/to/CC_Markdown
93+
source .venv/bin/activate
94+
python app.py
95+
```
96+
97+
The app starts a local server and opens `http://127.0.0.1:5001` in your browser automatically.
98+
99+
To stop, click the **Quit** button in the UI, or press `Control + C` in Terminal.
100+
101+
### One-time setup (Windows)
102+
103+
Open **Command Prompt** (`Win + R` → type `cmd` → Enter):
104+
105+
```bat
106+
cd C:\path\to\CC_Markdown
107+
python -m venv .venv
108+
.venv\Scripts\activate
109+
pip install "markitdown[all]" flask
110+
```
111+
112+
> **Note:** If Python is not found, re-run the installer from [python.org](https://www.python.org/downloads/) and check **"Add Python to PATH"**.
113+
114+
Run:
115+
```bat
116+
python app.py
117+
```
118+
119+
---
120+
121+
## Option 3 — Build the macOS App Yourself
122+
123+
Use this to rebuild `MarkItDown.app` after making changes to `app.py`.
124+
125+
### Additional requirement
126+
127+
```bash
128+
pip install pyinstaller
129+
```
130+
131+
### Build
132+
133+
```bash
134+
bash build.sh
135+
```
136+
137+
The script will:
138+
1. Kill any running instance on port 5001
139+
2. Clean previous build artifacts
140+
3. Run PyInstaller with `MarkItDown.spec`
141+
4. Ad-hoc sign the `.app` bundle
142+
5. Report the bundle size and location
143+
144+
Output: `dist/MarkItDown.app` (~166 MB, all dependencies bundled)
145+
146+
> **First launch on another Mac:** Right-click → Open → Open (one-time Gatekeeper bypass). This is expected for apps without an Apple Developer ID.
147+
148+
---
149+
150+
## Troubleshooting
151+
152+
| Problem | Fix |
153+
|---|---|
154+
| "Port 5001 already in use" | Run `lsof -ti :5001 \| xargs kill -9` then restart |
155+
| App won't open on another Mac | Right-click → Open → Open (one-time Gatekeeper step) |
156+
| "command not found: pip" | Use `python3 -m pip install ...` instead |
157+
| Xcode prompt on macOS | Click Install, wait for it to finish, re-run `pip install` |
158+
| Conversion returns empty output | Check the error box in the UI for the full Python traceback |
159+
160+
---
161+
162+
## Project structure
163+
164+
```
165+
CC_Markdown/
166+
├── app.py # Single-file Flask app (HTML/CSS/JS embedded)
167+
├── MarkItDown.spec # PyInstaller build configuration
168+
├── build.sh # Build script (clean → bundle → sign)
169+
├── dist/
170+
│ └── MarkItDown.app # Pre-built macOS application
171+
└── .venv/ # Python virtual environment (not committed)
172+
```
173+
174+
---
175+
176+
## License
177+
178+
MIT — see [LICENSE](LICENSE).
179+
180+
Built on [Microsoft MarkItDown](https://github.com/microsoft/markitdown) (MIT).

0 commit comments

Comments
 (0)