{"id":51646504,"url":"https://github.com/avvertix/liteparse-php","last_synced_at":"2026-07-13T23:03:33.808Z","repository":{"id":369903061,"uuid":"1292070520","full_name":"avvertix/liteparse-php","owner":"avvertix","description":"LiteParse binding for PHP via FFI","archived":false,"fork":false,"pushed_at":"2026-07-07T11:38:02.000Z","size":2058,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-07T12:19:42.195Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/avvertix.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-07-07T09:19:24.000Z","updated_at":"2026-07-07T10:45:18.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/avvertix/liteparse-php","commit_stats":null,"previous_names":["avvertix/liteparse-php"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/avvertix/liteparse-php","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avvertix%2Fliteparse-php","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avvertix%2Fliteparse-php/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avvertix%2Fliteparse-php/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avvertix%2Fliteparse-php/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/avvertix","download_url":"https://codeload.github.com/avvertix/liteparse-php/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avvertix%2Fliteparse-php/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35439220,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-13T02:00:06.543Z","response_time":119,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-07-13T23:03:33.380Z","updated_at":"2026-07-13T23:03:33.803Z","avatar_url":"https://github.com/avvertix.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# liteparse-php\n\nNative PHP bindings for [LiteParse](https://github.com/run-llama/liteparse), local PDF and document parsing with spatial text extraction powered by Rust and PDFium.\n\nGiven a PDF this package extracts text with bounding boxes and renders it as structured JSON, plain text, or layout-aware Markdown (headings, lists, tables, figure references). The parsing happens directly from PHP, via a compiled Rust `cdylib` loaded through PHP's `FFI` extension.\n\n\n\u003e [!NOTE]\n\u003e The native bindings are tested only for PDF files. Support for DOC/DOCX/XLS/XLSX/PPT/PPTX, and images is not tested and not provided so far.\n\n\n## Requirements\n\n- PHP 8.3+ with `ext-ffi` enabled (`ffi.enable=On` in php.ini; CLI defaults to on)\n- A compiled `liteparse_php` native library for your platform (see [Installation](#installation))\n- Optional, for OCR: an HTTP OCR server implementing [`LiteParse OCR_API_SPEC.md`](https://github.com/run-llama/liteparse/blob/main/OCR_API_SPEC.md) (reference servers for EasyOCR/PaddleOCR/SuryaOCR ship in the [LiteParse repo](https://github.com/run-llama/liteparse/tree/main/ocr)). This binding does **not** bundle the Tesseract engine as would increase the complexity of the build and distribution pipeline, point `Config::$ocrServerUrl` at a server instead.\n\n## Installation\n\nGet the package via Composer and install the native library for your platform.\n\n```bash\ncomposer require avvertix/liteparse-php\nvendor/bin/liteparse-php install\n```\n\n`install` downloads the compiled `liteparse_php` library and its PDFium dependency for your platform from the package's GitHub Releases into `vendor/avvertix/liteparse-php/lib/`. The specific installed versions are recorded in a `natives.lock` file in the root of your project, commit this alongside `composer.lock` to install the same version of the compiled binary. Run `vendor/bin/liteparse-php update` after upgrading the package to fetch the matching native library.\n\n\n\n## Quick start\n\n```php\nuse LiteParse\\Config;\nuse LiteParse\\OutputFormat;\nuse LiteParse\\LiteParse;\n\n$parser = new LiteParse(new Config(outputFormat: OutputFormat::Markdown));\n\n$result = $parser-\u003eparseFile('/path/to/document.pdf');\n\necho $result-\u003epageCount();   // int\necho $result-\u003etext();        // plain text, \"--- Page N ---\" headers\necho $result-\u003emarkdown();    // headings/lists/tables/figure refs reconstructed from layout\necho json_encode($result-\u003ejson());  // structured per-page text items: bbox + font size + fill/stroke color, per item\necho json_encode($result-\u003elines());  // structured per-page projected lines: merged bbox + style + column geometry\n```\n\n`json()` returns `liteparse`'s full per-item `TextItem` — not the lean `{text, x, y, width, height}` shape the upstream `lit` CLI's own `--format json` produces. Each item carries its bounding box together with `font_size` and `fill_color`/`stroke_color` (ARGB hex, e.g. `\"ff000000\"`) on the same record, plus rotation, links, strikethrough, and OCR confidence where applicable. Font/color fields are only populated for native PDF text; OCR-derived items carry `null` there instead.\n\n`lines()` sits between `json()` and `markdown()`: each entry is a merged visual line (one or more `TextItem`s sharing a baseline) carrying its own bounding box, dominant font/style, and `region_path` — the xy-cut column/region position `liteparse` uses internally to group paragraphs and tables. Each line's `spans` field keeps the original `TextItem`s that merged into it, so per-run font/color survives even where the line's own `text` concatenates multiple items. Unlike `markdown()`, nothing here is reformatted or dropped when the heuristic table/heading detection misfires — you get the raw geometry and can reconstruct rows/columns/headings yourself from `region_path` and bbox positions. There is no heading/paragraph/list \"role\" label at this layer.\n\nEvery `ParseResult` accessor (`text()`, `markdown()`, `json()`, `lines()`) renders on demand from the same underlying parsed pages.\n\n## Features\n\n- **`LiteParse::parseFile()` / `parseBytes()`** — parse from a file path or an in-memory buffer (e.g. a PDF downloaded over the network).\n- **`LiteParse::isComplexFile()` / `isComplexBytes()`** — a cheap per-page pre-check (no OCR, no rendering) reporting whether each page looks scanned, sparse, garbled, or image-heavy — useful for deciding whether a document needs OCR before committing to a full parse.\n- **`LiteParse::screenshotFile()` / `screenshotBytes()`** — render selected pages (or the whole document) to PNG bytes.\n- **`ParseResult::search()`** — search already-parsed text for phrase matches, with bounding boxes, merged across text items that were split mid-phrase.\n\n```php\n// Complexity pre-check\n$stats = $parser-\u003eisComplexFile('scan.pdf');\n$needsOcr = array_filter($stats, fn ($page) =\u003e $page['needs_ocr']);\n\n// Screenshots\n$screenshots = $parser-\u003escreenshotFile('doc.pdf', pageNumbers: [1, 2]); // null = all pages\nforeach ($screenshots as $shot) {\n    file_put_contents(\"page-{$shot-\u003epageNumber}.png\", $shot-\u003ebytes);\n}\n\n// Search\n$result = $parser-\u003eparseFile('doc.pdf');\nforeach ($result-\u003esearch('quarterly revenue') as $match) {\n    printf(\"page %d at (%.0f, %.0f)\\n\", $match['page_number'], $match['x'], $match['y']);\n}\n```\n\nSee [`examples/`](./examples/) for runnable scripts.\n\n## Configuration\n\n`Config` mirrors `liteparse`'s Rust `LiteParseConfig` field-for-field:\n\n| Field | Default | Notes |\n|---|---|---|\n| `ocrLanguage` | `'eng'` | Tesseract-format language code |\n| `ocrEnabled` | `false` | Requires `ocrServerUrl` — this binding has no built-in OCR engine |\n| `ocrServerUrl` | `null` | HTTP OCR server URL |\n| `ocrServerHeaders` | `[]` | `[[name, value], ...]` sent with every OCR request |\n| `maxPages` | `1000` | |\n| `targetPages` | `null` | e.g. `\"1-5,10,15-20\"`; `null` = all pages |\n| `dpi` | `150.0` | Used for OCR and screenshots |\n| `outputFormat` | `OutputFormat::Json` | Informational only in this binding — `text()`/`markdown()`/`json()` are always available regardless |\n| `preserveVerySmallText` | `false` | |\n| `password` | `null` | For encrypted/protected documents |\n| `quiet` | `true` | Suppresses `liteparse`'s stderr progress logging (Rust default is `false`) |\n| `numWorkers` | `1` | Concurrent OCR requests to the HTTP server |\n| `imageMode` | `ImageMode::Placeholder` | Affects `markdown()` image references only |\n| `extractLinks` | `true` | Hyperlinks as `[text](url)` in markdown |\n| `ocrFailureFatal` | `true` | Abort the whole parse on systemic OCR failure vs. return degraded results |\n| `ocrHedgeDelaysMs` | `[]` | Request-hedging schedule for the HTTP OCR engine |\n| `emitWordBoxes` | `false` | Per-word sub-boxes on each text item (roughly doubles payload size) |\n\n## How it works\n\nLiteParse Rust create is exposed as C library to be consumed by the PHP Foreign Function Interface (FFI). The shared library is defined in `rust/` exposing handles for the parser/result/screenshot-list lifecycle, plus configuration and exceptions. LiteParse's API is `async` (tokio-based); the FFI layer owns a single process-wide tokio runtime and `block_on`s each call, since PHP FFI calls are synchronous. `cbindgen` generates the committed `include/liteparse_php.h` header that PHP's `FFI::cdef()` loads.\n\nPDFium (a separate native dependency `liteparse` links against) is discovered at runtime by `pdfium-sys`'s loader relative to whichever shared library loaded it.\n\n## Development\n\n```bash\n./scripts/build.sh          # cargo build --release, stage lib/\ncomposer install\ncomposer test               # PHPUnit, against the compiled library\ncomposer lint               # PHPStan\n```\n\nAdding a new FFI function: add the `extern \"C\"` function in `rust/src/ffi/`, rebuild (`cbindgen` regenerates `include/liteparse_php.h` automatically via `build.rs`), add the corresponding `@method` annotation to `LiteParseFfi`, and wrap it in a PHP class.\n\n\n### Building from source\n\nIf you're working in this repository directly (or no prebuilt release exists yet for your platform):\n\n```bash\n./scripts/build.sh release   # cargo build --release + stage lib/liteparse_php.* and lib/libpdfium.*\ncomposer install\ncomposer test\n```\n\n`scripts/build.sh` compiles the Rust crate in `rust/` and copies the resulting native library, plus its PDFium runtime dependency, into `lib/`.\n\n## License\n\nThe project is dual licenced. The PHP wrapper code is licenced under [MIT](./LICENSE.md). The Rust binding to expose via FFI are licenced under [Apache-2.0](./rust/LICENCE.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Favvertix%2Fliteparse-php","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Favvertix%2Fliteparse-php","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Favvertix%2Fliteparse-php/lists"}