Skip to content
xanv754Public

About

Tool that converts handwritten PDF notes into structured Markdown files using AI.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Sharkdown

sharkdown

Sharkdown is a local-first CLI and REST API that converts handwritten PDF notes into structured Markdown files.

You supply a PDF of your handwritten notes, and Sharkdown gives you back a clean .md file with the content transcribed and organized — titles, lists, callouts, and all.

How it works

PDF → page images (pdf2image) → AI Vision (OCR + structuring) → .md file

Each page is rendered as an image and sent to the selected AI model in a single call. The model handles both transcription and Markdown structuring at once, keeping the pipeline simple and the output consistent.

Output conventions

Content type Output
General text Markdown with headings, lists, paragraphs
Text in a cloud / box Callout > [!NOTE]
Diagrams or visual schemas Placeholder [DIAGRAMA]
Illegible words Placeholder [ILEGIBLE]

Supported models

Model CLI flag API endpoint Tier
Gemini 2.5 Flash --model gemini (default) POST /convert/gemini Free
Claude --model claude POST /convert/claude Paid

Requirements

System

  • Python 3.11+

  • Poppler — required by pdf2image to render PDF pages:

    # Debian / Ubuntu
    sudo apt install poppler-utils
    
    # macOS
    brew install poppler
    
    # Arch 
    sudo pacman -S poppler

    If you get a PopplerNotInstalled error at runtime, this is the dependency to check.

Python dependencies

All Python dependencies are declared in pyproject.toml and installed with pip install ..

Library Purpose
pdf2image Renders each PDF page as a PIL.Image.Image
Pillow Image type used across the pipeline
google-genai Official Gemini SDK (Vision + text generation)
anthropic Official Anthropic SDK (Claude)
fastapi + uvicorn REST API server
pydantic / pydantic-settings Data validation and settings management
click CLI interface

Installation

pip install .
pip install uvicorn python-multipart   # only needed for the API

Environment variables

Create a .env file at the project root. Use .env.example as a reference:

cp .env.example .env
Variable Required Description
GEMINI_API_KEY Only if using Gemini API key from Google AI Studio
ANTHROPIC_API_KEY Only if using Claude API key from Anthropic Console
CORS_ORIGINS No Comma-separated list of allowed frontend origins (see Web UI)

Usage

CLI

# Convert with Gemini (default)
sharkdown img --file path/to/notes.pdf

# Convert with Claude
sharkdown img --file path/to/notes.pdf --model claude

The output .md file is saved alongside the original PDF.

API

Start the server:

uvicorn sharkdown.api.app:app --host 0.0.0.0 --port 8000

Convert a PDF:

curl -X POST http://localhost:8000/convert/gemini \
  -F "file=@notes.pdf" \
  -o notes.md

Interactive docs: http://localhost:8000/docs

Web UI (optional)

A browser-based interface is available in the client/ directory. See client/README.md for setup instructions.


Docker

Both images include Poppler — no extra system setup needed.

docker-compose (recommended)

Runs the backend and the web UI together behind an nginx reverse proxy.

cp .env.example .env   # fill in your API key(s)
make up                # build and start both services

The web UI will be available at http://localhost:7070.

Command Description
make up Build (if needed) and start all services
make down Stop and remove containers
make restart Restart all services without rebuilding
make build Force a full image rebuild (no cache)
make logs Follow logs from all services
make ps Show running containers
make clean Stop containers and remove project-built images

CORS_ORIGINS is automatically set to http://localhost in docker-compose — no manual change needed.

Backend only (standalone)

docker build -t sharkdown .

# Pass the API key directly
docker run -d -p 8000:8000 --name sharkdown -e GEMINI_API_KEY=your_key sharkdown

# Or use a .env file
docker run -d -p 8000:8000 --name sharkdown --env-file .env sharkdown

The API will be available at http://localhost:8000.

Frontend only (standalone)

# Default: empty VITE_API_BASE → relative URLs (expects a proxy in front)
docker build -t sharkdown-client ./client

# With a specific backend URL baked in
docker build --build-arg VITE_API_BASE=http://localhost:8000 -t sharkdown-client ./client

docker run -d -p 80:80 sharkdown-client

About

Tool that converts handwritten PDF notes into structured Markdown files using AI.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages