Files
zeekay 2d0675063a extract: initial v0.1.0
Document text extraction service. Drop-in replacement for Huly's
rekoni — listens on :4004 and serves /v1/extract, /v1/extract/url,
/v1/health.

- Pure Go, no CGo, no shelled binaries
- Format detection by magic bytes (filename ignored)
- PDF via ledongthuc/pdf; DOCX/XLSX/PPTX via native ZIP+XML walk;
  HTML via x/net/html with script/style strip; RTF via small native
  parser; plain text and markdown pass-through
- Bearer JWT auth against IAM JWKS (RS256/RS512), 10m cache
- 25 MB streaming upload cap, distroless static runtime
- Tests for every format (real fixtures in testdata/)

Image OCR is out of scope for v0.1 and returns HTTP 415.
2026-05-18 13:57:26 -07:00

39 lines
921 B
Go

// PDF text extraction via github.com/ledongthuc/pdf — MIT-licensed,
// pure Go, no LGPL transitive deps. We use GetPlainText (visible-page
// text walker) rather than Reader.Rows so we get a single concatenated
// stream that matches what rekoni emitted.
package extract
import (
"bytes"
"fmt"
"io"
"github.com/ledongthuc/pdf"
)
type pdfExtractor struct{}
func init() { register(FormatPDF, pdfExtractor{}) }
func (pdfExtractor) Extract(data []byte) (Result, error) {
r, err := pdf.NewReader(bytes.NewReader(data), int64(len(data)))
if err != nil {
return Result{}, fmt.Errorf("pdf parse: %w", err)
}
tr, err := r.GetPlainText()
if err != nil {
return Result{}, fmt.Errorf("pdf text: %w", err)
}
out, err := io.ReadAll(tr)
if err != nil {
return Result{}, fmt.Errorf("pdf read: %w", err)
}
return Result{
Text: string(out),
Metadata: map[string]any{
"pages": r.NumPage(),
},
}, nil
}