Genealogy tooling to dig useful records out of online archive documents.
The main tool is a browser-based extractor: drop a PDF or a plain image from departmental archives and it extracts the useful metadata and the full-resolution scan, ready to be cropped and saved with a consistent, genealogy-friendly filename.
Live version: https://ludow.github.io/pioche/
- Extracts from an AD62 archives PDF or any archives image files.
- Displays the embedded scan at full resolution with zoom (mouse wheel), pan (Ctrl+drag, middle-click or Space) and a crop selection with resize handles.
- Downloads the full image or the cropped selection as PNG or JPG.
- Copies the selection to the clipboard as an image, ready to paste anywhere (a chat, a document…).
- Handles records split across columns: Shift+drag adds extra selection zones, assembled into a single output image (stacked vertically or side by side, in drawing order). An "adjust assembly" dialog lets each part be shifted on the transverse axis to align the pieces.
- Handles records split across pages: a multi-page PDF, or several image files loaded together, become the pages of the viewer; zones selected on different pages assemble into the same output image.
- Builds structured filenames from the metadata fields:
PlaceCode_PlaceName_Date_ActCode_Individuals_Reference_Viewe.g.59_Hazebrouck_17670114_MA_WERREBROUCK_Pierre_x_VERLEY_Marie_5-Mi-035-R-020_191D - Fully client-side: the PDF never leaves the browser, no server involved.
The interface is in French, as the tool targets users of the French archives.
A second page, served at /coat-of-arms/, pads an image to a square canvas —
centered, transparent background, no distortion (typical use: Wikipedia coats
of arms, e.g. 500×550 → 550×550). It accepts drag & drop, clipboard paste
(Ctrl+V) or a direct image URL (Wikimedia allows cross-origin fetches), and
exports the result as a PNG download or straight to the clipboard.
No build step — the app is plain ES modules served as static files:
npm run web # serves web/ at http://localhost:5173
# or: node web/serve.mjs 8080 to pick another portThen open the page and drop a PDF or an image (see samples/ for examples).
| Path | Role |
|---|---|
web/index.html, web/styles.css |
Interface |
web/app.js |
UI orchestration: viewer, crop selection, copy, download |
web/pdf.mjs |
pdf.js loading + extraction of the largest embedded image (the scan) |
web/parse.mjs |
Reference / view / link extraction from PDF text or image filename (pure, testable) |
samples/ |
Real-world input examples (AD62 PDF, AD02 and AD59 images), used by the e2e check |
web/coat-of-arms/ |
Coat-of-arms tool: pads an image to a square with a transparent background |
web/serve.mjs |
Dependency-free static server for local development |
web/vendor/ |
pdf.js build (pdfjs-dist) copied from node_modules |
.github/workflows/pages.yml |
GitHub Pages deployment (publishes web/) |
End-to-end check with a headless browser:
npm i --no-save puppeteer && npx puppeteer browsers install chrome
node web/serve.mjs 5199 & # in one terminal
node web/e2e-check.mjs # checks the PDF, Aisne and Nord sample filespdf.js is vendored so the app works without a build step:
npm update pdfjs-dist
cp node_modules/pdfjs-dist/build/pdf.min.mjs web/vendor/
cp node_modules/pdfjs-dist/build/pdf.worker.min.mjs web/vendor/Every push to main triggers the GitHub Actions workflow in
.github/workflows/pages.yml, which publishes the web/ folder to GitHub Pages.