// Package pdfinfo extracts basic facts from PDF bytes with a tiny parser — // no third-party PDF library, just enough to count pages in golden tests // and smoke checks. package pdfinfo import ( "bytes" "fmt" "regexp" "strconv" ) // Pages returns the page count of a PDF by scanning for the /Type /Pages // objects' /Count entries (the catalog root carries the total; we take the // maximum to be safe with nested page trees). func Pages(pdf []byte) (int, error) { if len(pdf) == 0 || !bytes.HasPrefix(pdf, []byte("%PDF-")) { return 0, fmt.Errorf("pdfinfo: not a PDF (missing %%%%PDF- header)") } re := regexp.MustCompile(`/Type\s*/Pages[^>]*?/Count\s+(\d+)`) best := 0 for _, m := range re.FindAllStringSubmatch(string(pdf), -1) { if n, err := strconv.Atoi(m[1]); err == nil && n > best { best = n } } if best == 0 { // Compressed object streams can hide the count; require at least // the header then fall back to /Type /Page occurrences (\b keeps // /Pages from matching). pageRe := regexp.MustCompile(`/Type\s*/Page\b`) best = len(pageRe.FindAll(pdf, -1)) if best == 0 { return 0, fmt.Errorf("pdfinfo: no page count found") } } return best, nil }