Lattice
A workspace for your research.
Convert PDF, Word, PowerPoint, Excel and more into clean, structured Markdown, right in your browser. Files never leave your device.
ProductivityJavaScript · HTMLGitHub @GrowingRuiOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗MarkFlow is a website that turns PDFs, Office documents, web pages and other files into clean, structured Markdown. You drop in a file and get back Markdown with the headings, lists and tables intact, ready for your docs, a Git repository or an AI agent.
Conversion runs entirely in your browser. Files are never uploaded: the converters, the OCR engine and the fonts are all served from the site itself, so your documents stay on your device.
Copying text out of a PDF or a slide deck breaks it: lines split mid-sentence, bullets turn into stray symbols, and tables collapse into one row of numbers. Markdown keeps the structure as plain text that people, Git and AI tools can all read.
.md file, or download every result together as a ZIP.| Format | Output |
|---|---|
PDF (.pdf) | Headings ranked by font size, bold and italic, lists and paragraphs. Multi-column pages are read in order, paragraphs are joined across page breaks, and running headers, footers and page numbers are dropped. Tables are rebuilt from ruled lines and aligned columns. Scanned pages are read with OCR. |
Word (.docx) | Headings, lists, links and tables. Equations become LaTeX ($…$). |
PowerPoint (.pptx) | A section per slide with its title, bullets and numbering at their original indent, tables, chart data, picture alt text and speaker notes. |
Excel and CSV (.xlsx, .xls, .csv) | A Markdown table for each sheet. CSV files saved in other encodings (such as GBK or Shift-JIS) are detected and decoded. |
Web pages (.html, .htm) | The page content, without scripts and styles. |
Jupyter (.ipynb) | Text cells as Markdown; code and outputs as code blocks. |
JSON and XML (.json, .xml) | Formatted code blocks. RSS and Atom feeds become a list of posts with links, dates and text. |
EPUB (.epub) | Every chapter, in reading order. |
ZIP (.zip) | Each file inside converted, one section per file. |
Images (.png, .jpg, .jpeg, .webp) | The text in the image, read with OCR, including tables, headings and lists. |
Output is GitHub-flavored Markdown, which works in most editors, documentation tools and Git hosts.
Requires Node 20 or later.
npm install
npm run dev # http://localhost:3000, with the API on /api
npm test # converter tests
npm run build # production build in dist/
npm run preview # serve dist/ on http://localhost:3000
| Path | What it is |
|---|---|
index.html | Page markup |
src/main.js | Entry point: fonts, styles, UI setup |
src/styles.css | Page styles and Tailwind layers |
src/ui/ | Converter panel, result panel, FAQ, language menu |
src/convert/ | One module per format. index.js picks the converter and loads it on demand |
src/ui/account.js | Sign-in dialog, account menu, daily limit |
server/ | API handlers, auth, database access. plans.js holds the limits |
api/ | Vercel Function entry points, one per route |
tests/ | Vitest tests; __snapshots__/ holds the expected Markdown for each fixture |
scripts/make-fixtures.mjs | Builds the sample files in tests/fixtures/ |
scripts/make-fixtures.mjs if the change needs one, then run npm run fixtures.npm test. If the output changed on purpose, review the diff in tests/__snapshots__/ and accept it with npx vitest run -u.npm run real-docs downloads public test files into real-docs/, and with npm run dev running, npm run real-docs:convert converts them into real-docs/out/.Text recognition uses Tesseract.js with English data. vite.config.js copies the worker, the WebAssembly core and eng.traineddata.gz from node_modules into tesseract/ at build time, so OCR works without a CDN.
Conversion runs in the browser, so the server only counts finished conversions and the page enforces the limit (see server/plans.js). Without the API (a plain static host), the page hides sign-in and converts without limits.
| Route | What it does |
|---|---|
POST /api/signup, POST /api/signin | Email and password. Passwords are hashed with scrypt; sessions are an HttpOnly cookie |
POST /api/signout | Ends the session |
GET /api/me | Who is signed in, and today's usage |
POST /api/usage | Counts one conversion |
Locally the API uses PGlite, an embedded Postgres stored in .data/. Delete that folder to start over.
DATABASE_URL=... npm run db:migrate once.api/ into functions.DATABASE_URL and SESSION_SECRET (any long random string) in the project's environment variables.