Files
sm-bm-plugin/internal/pdftest/pdf.go
Jakub Zych 412821ec56 feat: index the text of attached PDFs
- jz_bm_material_file_texts caches the pdftotext output per file
- the River job jz.bm.extract_material_text extracts and resyncs
- the management multipart attach queues it inside its transaction
- file_texts in the document and a file snippet with its name
2026-11-08 20:11:19 +01:00

43 lines
1.4 KiB
Go

// Package pdftest builds small PDFs for the jz.bm tests. Only tests import
// it.
package pdftest
import (
"bytes"
"fmt"
"strings"
)
// OnePage is a one-page PDF that shows text in the base-14 Helvetica font,
// so pdftotext extracts it without any embedded font. text must be ASCII
// and hold no parentheses or backslashes. The xref offsets are computed from
// the objects as written.
func OnePage(text string) []byte {
if strings.ContainsAny(text, "()\\") {
panic("pdftest: text holds a parenthesis or a backslash")
}
stream := "BT /F1 24 Tf 72 700 Td (" + text + ") Tj ET"
objects := []string{
"<< /Type /Catalog /Pages 2 0 R >>",
"<< /Type /Pages /Kids [3 0 R] /Count 1 >>",
"<< /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792] /Contents 4 0 R /Resources << /Font << /F1 5 0 R >> >> >>",
fmt.Sprintf("<< /Length %d >>\nstream\n%s\nendstream", len(stream), stream),
"<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica >>",
}
var b bytes.Buffer
b.WriteString("%PDF-1.4\n")
offsets := make([]int, len(objects))
for i, obj := range objects {
offsets[i] = b.Len()
fmt.Fprintf(&b, "%d 0 obj\n%s\nendobj\n", i+1, obj)
}
xref := b.Len()
fmt.Fprintf(&b, "xref\n0 %d\n", len(objects)+1)
b.WriteString("0000000000 65535 f \n")
for _, off := range offsets {
fmt.Fprintf(&b, "%010d 00000 n \n", off)
}
fmt.Fprintf(&b, "trailer\n<< /Size %d /Root 1 0 R >>\nstartxref\n%d\n%%%%EOF\n", len(objects)+1, xref)
return b.Bytes()
}