From 6fc4107e3c3a0809ae7f51251b2c73284c05a5fa Mon Sep 17 00:00:00 2001 From: John O'Keefe Date: Mon, 17 Aug 2026 08:04:30 -0400 Subject: [PATCH] feat(reader): in-book search for PDFs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PDFs have fully searchable text (pdf.js text layer) — the previous reflowable-only gate existed only because foliate's generic search needs DOM documents that PDF sections don't provide. This adds a PDF pipeline alongside it: - Fork d065495 exposes the pdf.js document proxy as book.pdf so the host can drive text extraction directly. - New web/src/reader/pdf-search.ts: extractPdfPages() pulls each page's textContent with item geometry (progress-reported, cached after first search). PDF text items often omit inter-word spaces (gaps are positional), so pages are joined gap-aware — baseline changes, hasEOL, or horizontal gaps past a font-size threshold become spaces — recording a char→item map. searchPdfPages() does case-insensitive matching over the joined text and maps each hit back to the page-fraction rects of the items it spans, with ellipsized pre/match/post excerpts. Pure functions, unit-sanity checked (cross-item 'brave new' → two rects). - runSearch branches: EPUB keeps foliate's DOM search; PDFs search the extracted pages, group hits per page ('Page 12'), and render on-page hit rectangles through the existing fraction-rect overlay (addRectAnnotation) — which re-render automatically when pages revisit, same as highlights. Clearing the query removes them. - Results navigate by page index; the 🔍 button and '/' shortcut now appear for PDFs too (comics remain without searchable text). --- package.json | 2 +- templates/reader.templ | 6 +- templates/reader_templ.go | 4 +- web/src/reader/pdf-search.ts | 163 +++++++++++++++++++++++++++++++++++ web/src/reader/reader.ts | 113 ++++++++++++++++++------ 5 files changed, 258 insertions(+), 30 deletions(-) create mode 100644 web/src/reader/pdf-search.ts diff --git a/package.json b/package.json index c254683..42d8583 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "dev": "npm run build:ts:dev && npm run build:css" }, "dependencies": { - "@bookhoard/foliate-js": "git+https://github.com/john-okeefe/foliate-js.git#1c0ebf3", + "@bookhoard/foliate-js": "git+https://github.com/john-okeefe/foliate-js.git#d065495", "alpinejs": "^3.15.8", "chart.js": "^4.5.1", "highlight.js": "^11.11.1", diff --git a/templates/reader.templ b/templates/reader.templ index ca64ba1..6154e32 100644 --- a/templates/reader.templ +++ b/templates/reader.templ @@ -246,7 +246,7 @@ templ ReaderChrome(metadata ReaderMetadata, progress ReadingProgress) {

{ metadata.Title }

- +
@@ -541,10 +541,10 @@ templ ReaderSearchDrawer() {
-