{
 "kind": "app",
 "id": "app:poppler",
 "url": "https://headlesson.com/apps/poppler",
 "name": "Poppler utilities",
 "one_liner": "PDF library whose command-line utilities (pdftotext, pdfinfo and others) extract text and metadata from PDF files.",
 "description": "Poppler is a PDF rendering library based on the xpdf-3.0 code base. Its utilities run locally and non-interactively; pdftotext writes the text layer of a PDF to a file or standard output, and pdfinfo prints document metadata such as page count, page size and encryption. pdftotext reads only text already in the PDF; it does not OCR scanned pages.",
 "made_by_headlesson_operator": false,
 "interfaces": [
  {
   "kind": "cli",
   "name": "pdftotext",
   "install": "brew install poppler",
   "verify": "pdftotext -v",
   "auth": "None for local files.",
   "docs": "https://poppler.freedesktop.org/"
  }
 ],
 "tests": [
  {
   "record_id": "test:wgxi8q",
   "url": "https://headlesson.com/tests/wgxi8q",
   "date": "2026-10-11",
   "version": "26.04.0",
   "status": "passed"
  }
 ],
 "latest_test_conclusion": "On 2026-10-11, the headlesson operator ran all 7 steps of this lesson with Poppler utilities 26.04.0 (macOS26.5.2 arm64; Homebrew poppler 26.04.0 already installed (not reinstalled; upstream current is 26.10.0); test PDF made with macOS cupsfilter from self-made text), and all passed. The final Next step is advice and was not run. No independent check has been reviewed. This is the operator's own run, not a vendor claim.",
 "independent_check": {
  "state": "not_checked"
 },
 "lesson": {
  "goal": "Make a one-page PDF, read its metadata with pdfinfo and extract its text with pdftotext.",
  "steps": [
   "command -v pdftotext || brew install poppler",
   "pdftotext -v",
   "printf 'Invoice 2026-001\\nTotal: 42 apples\\n' > note.txt",
   "cupsfilter -m application/pdf note.txt > note.pdf",
   "pdfinfo note.pdf",
   "pdftotext -layout note.pdf out.txt",
   "grep -c 'Total: 42 apples' out.txt"
  ],
  "next_advice": "Next: Agree with the user on the real PDF and the output path; run pdfinfo first to check page count and encryption, extract with pdftotext (add -f/-l for a page range), and if the text is empty or only form feeds, treat the PDF as scanned and switch to OCR.",
  "cautions": {
   "note": "These notes come from the lesson. Some describe failures seen in tests; others are general cautions. Each one is not a separately tested result.",
   "items": [
    "A PDF made only of page images gives no text; in the test pdftotext exited 0 and the output was a single form feed character. Check for empty output instead of relying on the exit code.",
    "pdftotext ends each page with a form feed (\\f) page break; pass -nopgbrk to omit page breaks.",
    "Without a text-file argument pdftotext writes file.txt next to file.pdf; pass - to write to standard output.",
    "Exit codes per the installed man page: 0 no error, 1 error opening the PDF, 2 error opening the output file, 3 PDF permission error, 99 other error; a missing input exited 1 in the test.",
    "Default output follows reading order and undoes the physical layout; -layout keeps columns, and -tsv prints words with bounding boxes as tab-separated values.",
    "Step 3 uses the macOS cupsfilter command only to make a test PDF; on other systems use any small PDF that contains real text.",
    "Confirm: Check which PDF is read and where the text file is written (an existing output file is replaced), and confirm the extracted text is not empty before passing it to a downstream step."
   ]
  },
  "note": "This is the current lesson. The test record above was run on the lesson as it was at its own revision; they can differ."
 },
 "mcp_get": "headlesson_get id=\"app:poppler\" sections [\"lesson\",\"gotchas\"]",
 "axes": {
  "license": {
   "value": "GPL-2.0-only OR GPL-3.0-only",
   "checked": "2026-10-11",
   "certainty": "secondary",
   "source": "https://formulae.brew.sh/formula/poppler",
   "by": "third-party"
  },
  "open_source": {
   "value": true,
   "checked": "2026-10-11",
   "certainty": "secondary",
   "source": "https://formulae.brew.sh/formula/poppler",
   "by": "third-party"
  },
  "pricing": {
   "value": "free",
   "checked": "2026-10-11",
   "certainty": "inferred",
   "source": "https://formulae.brew.sh/formula/poppler",
   "by": "editorial"
  },
  "has_human_gui": {
   "value": "none",
   "checked": "2026-10-11",
   "certainty": "inferred",
   "source": "headlesson editorial judgement",
   "by": "editorial"
  },
  "non_interactive": {
   "value": true,
   "checked": "2026-10-11",
   "certainty": "primary",
   "source": "headlesson editorial judgement",
   "by": "editorial"
  },
  "machine_output": {
   "value": true,
   "checked": "2026-10-11",
   "certainty": "primary",
   "source": "headlesson editorial judgement",
   "by": "editorial"
  },
  "local_mcp": {
   "value": "unknown",
   "checked": null,
   "certainty": null,
   "source": null,
   "by": null
  },
  "remote_mcp": {
   "value": "unknown",
   "checked": null,
   "certainty": null,
   "source": null,
   "by": null
  },
  "cli": {
   "value": true,
   "checked": "2026-10-11",
   "certainty": "primary",
   "source": "headlesson editorial judgement",
   "by": "editorial"
  },
  "rest_api": {
   "value": "unknown",
   "checked": null,
   "certainty": null,
   "source": null,
   "by": null
  },
  "auth": {
   "value": "none",
   "checked": "2026-10-11",
   "certainty": "inferred",
   "source": "headlesson editorial judgement",
   "by": "editorial"
  },
  "self_hostable": {
   "value": true,
   "checked": "2026-10-11",
   "certainty": "primary",
   "source": "headlesson editorial judgement",
   "by": "editorial"
  },
  "embeds_llm": {
   "value": "unknown",
   "checked": null,
   "certainty": null,
   "source": null,
   "by": null
  },
  "refusal_contract": {
   "value": "unknown",
   "checked": null,
   "certainty": null,
   "source": null,
   "by": null
  },
  "audit_log": {
   "value": "unknown",
   "checked": null,
   "certainty": null,
   "source": null,
   "by": null
  },
  "last_release": {
   "value": "2026-10-04",
   "checked": "2026-10-11",
   "certainty": "primary",
   "source": "https://poppler.freedesktop.org/",
   "by": "official"
  },
  "ja_support": {
   "value": "unknown",
   "checked": null,
   "certainty": null,
   "source": null,
   "by": null
  }
 },
 "sources": [
  {
   "fields": [
    "/name",
    "/axes/last_release"
   ],
   "source": "https://poppler.freedesktop.org/",
   "checked": "2026-10-11",
   "certainty": "primary",
   "by": "official"
  },
  {
   "fields": [
    "/one_liner",
    "/lesson/goal",
    "/lesson/next_advice",
    "/lesson/cautions/items/5",
    "/lesson/cautions/items/6",
    "/interfaces/0/auth",
    "/axes/has_human_gui",
    "/axes/auth",
    "/relations/0"
   ],
   "source": "headlesson editorial judgement",
   "checked": "2026-10-11",
   "certainty": "inferred",
   "by": "editorial"
  },
  {
   "fields": [
    "/description"
   ],
   "source": "https://poppler.freedesktop.org/",
   "checked": "2026-10-11",
   "certainty": "primary",
   "by": "editorial"
  },
  {
   "fields": [
    "/lesson/steps/0",
    "/interfaces/0/kind",
    "/interfaces/0/name",
    "/interfaces/0/install",
    "/interfaces/0/docs"
   ],
   "source": "https://formulae.brew.sh/formula/poppler",
   "checked": "2026-10-11",
   "certainty": "primary",
   "by": "third-party"
  },
  {
   "fields": [
    "/lesson/steps/1",
    "/lesson/steps/2",
    "/lesson/steps/3",
    "/lesson/steps/4",
    "/lesson/steps/5",
    "/lesson/steps/6",
    "/lesson/cautions/items/0",
    "/lesson/cautions/items/1",
    "/lesson/cautions/items/2",
    "/lesson/cautions/items/3",
    "/lesson/cautions/items/4",
    "/interfaces/0/verify",
    "/axes/non_interactive",
    "/axes/machine_output",
    "/axes/cli",
    "/axes/self_hostable"
   ],
   "source": "headlesson editorial judgement",
   "checked": "2026-10-11",
   "certainty": "primary",
   "by": "editorial"
  },
  {
   "fields": [
    "/axes/license",
    "/axes/open_source"
   ],
   "source": "https://formulae.brew.sh/formula/poppler",
   "checked": "2026-10-11",
   "certainty": "secondary",
   "by": "third-party"
  },
  {
   "fields": [
    "/axes/pricing"
   ],
   "source": "https://formulae.brew.sh/formula/poppler",
   "checked": "2026-10-11",
   "certainty": "inferred",
   "by": "editorial"
  }
 ],
 "primary_record": "Test results here are the operator's own past lesson trials (legacy). They are not claimed to meet level L1 of run-task-contract/0.1.0.",
 "relations": [
  {
   "type": "used-for",
   "to": "usecase:parse-documents-for-llm",
   "url": "https://headlesson.com/usecases/parse-documents-for-llm"
  }
 ],
 "relations_not_published": 0,
 "cite": "headlesson app:poppler: see test record test:wgxi8q (https://headlesson.com/tests/wgxi8q).",
 "page_updated": "2026-10-13"
}
